perf(test): narrow discord component import path

This commit is contained in:
Vincent Koc 2026-04-01 23:58:06 +09:00
parent 0453d355fd
commit c942812e5d
4 changed files with 99 additions and 88 deletions

View File

@ -0,0 +1,72 @@
import { parseCustomId, type ComponentParserResult } from "@buape/carbon";
export const DISCORD_COMPONENT_CUSTOM_ID_KEY = "occomp";
export const DISCORD_MODAL_CUSTOM_ID_KEY = "ocmodal";
export function buildDiscordComponentCustomId(params: {
componentId: string;
modalId?: string;
}): string {
const base = `${DISCORD_COMPONENT_CUSTOM_ID_KEY}:cid=${params.componentId}`;
return params.modalId ? `${base};mid=${params.modalId}` : base;
}
export function buildDiscordModalCustomId(modalId: string): string {
return `${DISCORD_MODAL_CUSTOM_ID_KEY}:mid=${modalId}`;
}
export function parseDiscordComponentCustomId(
id: string,
): { componentId: string; modalId?: string } | null {
const parsed = parseCustomId(id);
if (parsed.key !== DISCORD_COMPONENT_CUSTOM_ID_KEY) {
return null;
}
const componentId = parsed.data.cid;
if (typeof componentId !== "string" || !componentId.trim()) {
return null;
}
const modalId = parsed.data.mid;
return {
componentId,
modalId: typeof modalId === "string" && modalId.trim() ? modalId : undefined,
};
}
export function parseDiscordModalCustomId(id: string): string | null {
const parsed = parseCustomId(id);
if (parsed.key !== DISCORD_MODAL_CUSTOM_ID_KEY) {
return null;
}
const modalId = parsed.data.mid;
if (typeof modalId !== "string" || !modalId.trim()) {
return null;
}
return modalId;
}
function isDiscordComponentWildcardRegistrationId(id: string): boolean {
return /^__openclaw_discord_component_[a-z_]+_wildcard__$/.test(id);
}
export function parseDiscordComponentCustomIdForCarbon(id: string): ComponentParserResult {
if (id === "*" || isDiscordComponentWildcardRegistrationId(id)) {
return { key: "*", data: {} };
}
const parsed = parseCustomId(id);
if (parsed.key !== DISCORD_COMPONENT_CUSTOM_ID_KEY) {
return parsed;
}
return { key: "*", data: parsed.data };
}
export function parseDiscordModalCustomIdForCarbon(id: string): ComponentParserResult {
if (id === "*" || isDiscordComponentWildcardRegistrationId(id)) {
return { key: "*", data: {} };
}
const parsed = parseCustomId(id);
if (parsed.key !== DISCORD_MODAL_CUSTOM_ID_KEY) {
return parsed;
}
return { key: "*", data: parsed.data };
}

View File

@ -20,18 +20,24 @@ import {
TextInput,
Thumbnail,
UserSelectMenu,
parseCustomId,
type ComponentParserResult,
type TopLevelComponents,
} from "@buape/carbon";
import { ButtonStyle, MessageFlags, TextInputStyle } from "discord-api-types/v10";
import {
DISCORD_COMPONENT_CUSTOM_ID_KEY,
DISCORD_MODAL_CUSTOM_ID_KEY,
buildDiscordComponentCustomId,
buildDiscordModalCustomId,
parseDiscordComponentCustomId,
parseDiscordComponentCustomIdForCarbon,
parseDiscordModalCustomId,
parseDiscordModalCustomIdForCarbon,
} from "./component-custom-id.js";
// Some test-only module graphs partially mock `@buape/carbon` and can drop `Modal`.
// Keep dynamic form definitions loadable instead of crashing unrelated suites.
const ModalBase: typeof Modal = (Modal ?? class {}) as typeof Modal;
export const DISCORD_COMPONENT_CUSTOM_ID_KEY = "occomp";
export const DISCORD_MODAL_CUSTOM_ID_KEY = "ocmodal";
export const DISCORD_COMPONENT_ATTACHMENT_PREFIX = "attachment://";
export type DiscordComponentButtonStyle = "primary" | "secondary" | "success" | "danger" | "link";
@ -624,74 +630,6 @@ export function readDiscordComponentSpec(raw: unknown): DiscordComponentMessageS
};
}
export function buildDiscordComponentCustomId(params: {
componentId: string;
modalId?: string;
}): string {
const base = `${DISCORD_COMPONENT_CUSTOM_ID_KEY}:cid=${params.componentId}`;
return params.modalId ? `${base};mid=${params.modalId}` : base;
}
export function buildDiscordModalCustomId(modalId: string): string {
return `${DISCORD_MODAL_CUSTOM_ID_KEY}:mid=${modalId}`;
}
export function parseDiscordComponentCustomId(
id: string,
): { componentId: string; modalId?: string } | null {
const parsed = parseCustomId(id);
if (parsed.key !== DISCORD_COMPONENT_CUSTOM_ID_KEY) {
return null;
}
const componentId = parsed.data.cid;
if (typeof componentId !== "string" || !componentId.trim()) {
return null;
}
const modalId = parsed.data.mid;
return {
componentId,
modalId: typeof modalId === "string" && modalId.trim() ? modalId : undefined,
};
}
export function parseDiscordModalCustomId(id: string): string | null {
const parsed = parseCustomId(id);
if (parsed.key !== DISCORD_MODAL_CUSTOM_ID_KEY) {
return null;
}
const modalId = parsed.data.mid;
if (typeof modalId !== "string" || !modalId.trim()) {
return null;
}
return modalId;
}
function isDiscordComponentWildcardRegistrationId(id: string): boolean {
return /^__openclaw_discord_component_[a-z_]+_wildcard__$/.test(id);
}
export function parseDiscordComponentCustomIdForCarbon(id: string): ComponentParserResult {
if (id === "*" || isDiscordComponentWildcardRegistrationId(id)) {
return { key: "*", data: {} };
}
const parsed = parseCustomId(id);
if (parsed.key !== DISCORD_COMPONENT_CUSTOM_ID_KEY) {
return parsed;
}
return { key: "*", data: parsed.data };
}
export function parseDiscordModalCustomIdForCarbon(id: string): ComponentParserResult {
if (id === "*" || isDiscordComponentWildcardRegistrationId(id)) {
return { key: "*", data: {} };
}
const parsed = parseCustomId(id);
if (parsed.key !== DISCORD_MODAL_CUSTOM_ID_KEY) {
return parsed;
}
return { key: "*", data: parsed.data };
}
function buildTextDisplays(text?: string, texts?: string[]): TextDisplay[] {
if (texts && texts.length > 0) {
return texts.map((entry) => new TextDisplay(entry));

View File

@ -11,23 +11,21 @@ import {
import type { APIStringSelectComponent } from "discord-api-types/v10";
import { ChannelType } from "discord-api-types/v10";
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
import { resolveCommandAuthorizedFromAuthorizers } from "openclaw/plugin-sdk/command-auth";
import { resolveCommandAuthorizedFromAuthorizers } from "openclaw/plugin-sdk/command-auth-native";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import type { DiscordAccountConfig } from "openclaw/plugin-sdk/config-runtime";
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/config-runtime";
import { resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/config-runtime";
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
import { resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
import * as conversationRuntime from "openclaw/plugin-sdk/conversation-runtime";
import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
import * as securityRuntime from "openclaw/plugin-sdk/security-runtime";
import { logError } from "openclaw/plugin-sdk/text-runtime";
import {
createDiscordFormModal,
parseDiscordComponentCustomId,
parseDiscordModalCustomId,
type DiscordComponentEntry,
type DiscordModalEntry,
} from "../components.js";
} from "../component-custom-id.js";
import type { DiscordComponentEntry, DiscordModalEntry } from "../components.js";
import {
type DiscordGuildEntryResolved,
isDiscordGroupAllowedByPolicy,

View File

@ -37,16 +37,13 @@ import {
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
import { createNonExitingRuntime, type RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
import { logDebug, logError } from "openclaw/plugin-sdk/text-runtime";
import { resolveDiscordMaxLinesPerMessage } from "../accounts.js";
import { resolveDiscordComponentEntry, resolveDiscordModalEntry } from "../components-registry.js";
import {
createDiscordFormModal,
formatDiscordComponentEventText,
parseDiscordComponentCustomIdForCarbon,
parseDiscordModalCustomIdForCarbon,
type DiscordComponentEntry,
type DiscordModalEntry,
} from "../components.js";
} from "../component-custom-id.js";
import { resolveDiscordMaxLinesPerMessage } from "../accounts.js";
import { resolveDiscordComponentEntry, resolveDiscordModalEntry } from "../components-registry.js";
import type { DiscordComponentEntry, DiscordModalEntry } from "../components.js";
import {
AGENT_BUTTON_KEY,
AGENT_SELECT_KEY,
@ -93,6 +90,7 @@ import { deliverDiscordReply } from "./reply-delivery.js";
let conversationRuntimePromise:
| Promise<typeof import("openclaw/plugin-sdk/conversation-runtime")>
| undefined;
let componentsRuntimePromise: Promise<typeof import("../components.js")> | undefined;
let pluginRuntimePromise: Promise<typeof import("openclaw/plugin-sdk/plugin-runtime")> | undefined;
let replyRuntimePromise: Promise<typeof import("openclaw/plugin-sdk/reply-runtime")> | undefined;
let replyPipelineRuntimePromise:
@ -106,6 +104,11 @@ async function loadConversationRuntime() {
return await conversationRuntimePromise;
}
async function loadComponentsRuntime() {
componentsRuntimePromise ??= import("../components.js");
return await componentsRuntimePromise;
}
async function loadPluginRuntime() {
pluginRuntimePromise ??= import("openclaw/plugin-sdk/plugin-runtime");
return await pluginRuntimePromise;
@ -739,7 +742,7 @@ async function handleDiscordComponentEvent(params: {
// fallbacks still need their chosen values in the synthesized event text.
const eventText =
(consumed.kind === "button" ? consumed.callbackData?.trim() : undefined) ||
formatDiscordComponentEventText({
(await loadComponentsRuntime()).formatDiscordComponentEventText({
kind: consumed.kind === "select" ? "select" : "button",
label: consumed.label,
values,
@ -898,7 +901,7 @@ async function handleDiscordModalTrigger(params: {
}
try {
await params.interaction.showModal(createDiscordFormModal(modalEntry));
await params.interaction.showModal((await loadComponentsRuntime()).createDiscordFormModal(modalEntry));
} catch (err) {
logError(`${params.label}: failed to show modal: ${String(err)}`);
}