refactor(discord): reuse canonical interactive component renderer (#129031)

This commit is contained in:
Peter Steinberger
2026-08-24 23:30:25 -07:00
committed by GitHub
parent 6335d97771
commit 0a79ae5fd0
3 changed files with 56 additions and 23 deletions
-1
View File
@@ -436,7 +436,6 @@ extensions/discord/src/send.shared.ts 4
extensions/discord/src/send.webhook.ts 1
extensions/discord/src/setup-account-state.ts 1
extensions/discord/src/setup-core.ts 1
extensions/discord/src/shared-interactive.ts 1
extensions/discord/src/shared.ts 1
extensions/discord/src/status-issues.ts 1
extensions/discord/src/target-parsing.ts 1
@@ -98,6 +98,59 @@ describe("buildDiscordInteractiveComponents", () => {
});
});
it.each([
{
name: "approval",
action: {
type: "approval" as const,
approvalId: "approval-1",
approvalKind: "exec" as const,
decision: "allow-once" as const,
},
expected: {
internalCustomId: "execapproval:kind=exec;id=approval-1;action=allow-once",
},
},
{
name: "callback",
action: { type: "callback" as const, value: "plugin:opaque|value" },
expected: { callbackData: "plugin:opaque|value", callbackDataKind: "callback" },
},
{
name: "command",
action: { type: "command" as const, command: "/codex inspect" },
expected: { callbackData: "/codex inspect", callbackDataKind: "command" },
},
{
name: "question",
action: {
type: "question" as const,
questionId: "ask_0123456789abcdef0123456789abcdef",
optionValue: "Production",
},
expected: { internalCustomId: "ocq:id=ask_0123456789abcdef0123456789abcdef;i=1" },
},
])("preserves typed $name authority through the legacy renderer", ({ action, expected }) => {
expect(
buildDiscordInteractiveComponents({
blocks: [
{
type: "buttons",
buttons: [
{
label: "Unavailable",
action: { type: "web-app", widgetId: "invalid" },
},
{ label: "Continue", action },
],
},
],
}),
).toMatchObject({
blocks: [{ type: "actions", buttons: [{ label: "Continue", ...expected }] }],
});
});
it.each(["url", "web-app"] as const)(
"renders typed %s actions as Discord link buttons",
(type) => {
+3 -22
View File
@@ -1,6 +1,6 @@
// Discord plugin module implements shared interactive behavior.
import {
reduceLegacyInteractiveReply,
legacyInteractiveReplyToPresentation,
resolveMessagePresentationActionValue,
resolveMessagePresentationButtonAction,
resolveMessagePresentationOptionAction,
@@ -180,28 +180,9 @@ function appendDiscordSelectBlock(
export function buildDiscordInteractiveComponents(
interactive?: LegacyInteractiveReply,
): DiscordComponentMessageSpec | undefined {
const blocks = reduceLegacyInteractiveReply(
interactive,
[] as NonNullable<DiscordComponentMessageSpec["blocks"]>,
(state, block) => {
if (block.type === "text") {
const text = block.text.trim();
if (text) {
state.push({ type: "text", text });
}
return state;
}
if (block.type === "buttons") {
appendDiscordButtonBlocks(state, block.buttons);
return state;
}
if (block.type === "select") {
appendDiscordSelectBlock(state, block);
}
return state;
},
return buildDiscordPresentationComponents(
interactive ? legacyInteractiveReplyToPresentation(interactive) : undefined,
);
return blocks.length > 0 ? { blocks } : undefined;
}
export function buildDiscordPresentationComponents(