import { a as normalizeLowercaseStringOrEmpty } from "./string-coerce-DW4mBlAt.js";
import "./string-coerce-runtime-DsF17V0Z.js";
import { c as buildDiscordModalCustomId, m as parseDiscordModalCustomIdForInteraction, s as buildDiscordComponentCustomId } from "./shared-interactive-W7Ml9AE_.js";
import { A as Modal, B as RoleSelectMenu, F as Container, G as TextDisplay, H as Section, I as File, K as Thumbnail, Kt as MessageFlags, L as LinkButton, M as TextInput, N as Button, O as CheckboxGroup, P as ChannelSelectMenu, R as MediaGallery, U as Separator, V as Row, W as StringSelectMenu, Zt as TextInputStyle, j as RadioGroup, k as Label, q as UserSelectMenu, z as MentionableSelectMenu, zt as ButtonStyle } from "./discord-CLDOAtfS.js";
import crypto from "node:crypto";
//#region extensions/discord/src/components.parse.ts
const DISCORD_COMPONENT_ATTACHMENT_PREFIX = "attachment://";
const BLOCK_ALIASES = /* @__PURE__ */ new Map([["row", "actions"], ["action-row", "actions"]]);
function requireObject(value, label) {
	if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${label} must be an object`);
	return value;
}
function readString(value, label, opts) {
	if (typeof value !== "string") throw new Error(`${label} must be a string`);
	const trimmed = value.trim();
	if (!opts?.allowEmpty && !trimmed) throw new Error(`${label} cannot be empty`);
	return opts?.allowEmpty ? value : trimmed;
}
function readOptionalString(value) {
	if (typeof value !== "string") return;
	const trimmed = value.trim();
	return trimmed ? trimmed : void 0;
}
function readOptionalCallbackDataKind(value, label) {
	const kind = readOptionalString(value);
	if (kind === void 0) return;
	if (kind === "command" || kind === "callback") return kind;
	throw new Error(`${label} must be one of command, callback`);
}
function readOptionalStringArray(value, label) {
	if (value === void 0) return;
	if (!Array.isArray(value)) throw new Error(`${label} must be an array`);
	if (value.length === 0) return;
	return value.map((entry, index) => readString(entry, `${label}[${index}]`));
}
function readOptionalInteger(value, label, bounds) {
	if (value == null) return;
	if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value)) throw new Error(`${label} must be an integer`);
	if (bounds?.min !== void 0 && value < bounds.min) throw new Error(`${label} must be at least ${bounds.min}`);
	if (bounds?.max !== void 0 && value > bounds.max) throw new Error(`${label} must be at most ${bounds.max}`);
	return value;
}
function readOptionalEmoji(value, label) {
	if (!value || typeof value !== "object" || Array.isArray(value)) return;
	const obj = value;
	return {
		name: readString(obj.name, `${label}.name`),
		id: readOptionalString(obj.id),
		animated: typeof obj.animated === "boolean" ? obj.animated : void 0
	};
}
function normalizeModalFieldName(value, index) {
	const trimmed = value?.trim();
	if (trimmed) return trimmed;
	return `field_${index + 1}`;
}
function normalizeAttachmentRef(value, label) {
	const trimmed = value.trim();
	if (!trimmed.startsWith("attachment://")) throw new Error(`${label} must start with "${DISCORD_COMPONENT_ATTACHMENT_PREFIX}"`);
	const attachmentName = trimmed.slice(13).trim();
	if (!attachmentName) throw new Error(`${label} must include an attachment filename`);
	return `${DISCORD_COMPONENT_ATTACHMENT_PREFIX}${attachmentName}`;
}
function resolveDiscordComponentAttachmentName(value) {
	const trimmed = value.trim();
	if (!trimmed.startsWith("attachment://")) throw new Error(`Attachment reference must start with "${DISCORD_COMPONENT_ATTACHMENT_PREFIX}"`);
	const attachmentName = trimmed.slice(13).trim();
	if (!attachmentName) throw new Error("Attachment reference must include a filename");
	return attachmentName;
}
function mapButtonStyle(style) {
	switch (normalizeLowercaseStringOrEmpty(style ?? "primary")) {
		case "secondary": return ButtonStyle.Secondary;
		case "success": return ButtonStyle.Success;
		case "danger": return ButtonStyle.Danger;
		case "link": return ButtonStyle.Link;
		default: return ButtonStyle.Primary;
	}
}
function mapTextInputStyle(style) {
	return style === "paragraph" ? TextInputStyle.Paragraph : TextInputStyle.Short;
}
function normalizeBlockType(raw) {
	const lowered = normalizeLowercaseStringOrEmpty(raw);
	return BLOCK_ALIASES.get(lowered) ?? lowered;
}
function parseSelectOptions(raw, label) {
	if (raw === void 0) return;
	if (!Array.isArray(raw)) throw new Error(`${label} must be an array`);
	return raw.map((entry, index) => {
		const obj = requireObject(entry, `${label}[${index}]`);
		return {
			label: readString(obj.label, `${label}[${index}].label`),
			value: readString(obj.value, `${label}[${index}].value`),
			description: readOptionalString(obj.description),
			emoji: readOptionalEmoji(obj.emoji, `${label}[${index}].emoji`),
			default: typeof obj.default === "boolean" ? obj.default : void 0
		};
	});
}
function parseButtonSpec(raw, label) {
	const obj = requireObject(raw, label);
	const style = readOptionalString(obj.style);
	const url = readOptionalString(obj.url);
	if ((style === "link" || url) && !url) throw new Error(`${label}.url is required for link buttons`);
	return {
		label: readString(obj.label, `${label}.label`),
		style,
		url,
		callbackData: readOptionalString(obj.callbackData),
		callbackDataKind: readOptionalCallbackDataKind(obj.callbackDataKind, `${label}.callbackDataKind`),
		emoji: readOptionalEmoji(obj.emoji, `${label}.emoji`),
		disabled: typeof obj.disabled === "boolean" ? obj.disabled : void 0,
		allowedUsers: readOptionalStringArray(obj.allowedUsers, `${label}.allowedUsers`)
	};
}
function parseSelectSpec(raw, label) {
	const obj = requireObject(raw, label);
	const type = readOptionalString(obj.type);
	const allowedTypes = [
		"string",
		"user",
		"role",
		"mentionable",
		"channel"
	];
	if (type && !allowedTypes.includes(type)) throw new Error(`${label}.type must be one of ${allowedTypes.join(", ")}`);
	return {
		type,
		callbackData: readOptionalString(obj.callbackData),
		callbackDataKind: readOptionalCallbackDataKind(obj.callbackDataKind, `${label}.callbackDataKind`),
		placeholder: readOptionalString(obj.placeholder),
		minValues: readOptionalInteger(obj.minValues, `${label}.minValues`, {
			min: 0,
			max: 25
		}),
		maxValues: readOptionalInteger(obj.maxValues, `${label}.maxValues`, {
			min: 1,
			max: 25
		}),
		options: parseSelectOptions(obj.options, `${label}.options`),
		allowedUsers: readOptionalStringArray(obj.allowedUsers, `${label}.allowedUsers`)
	};
}
function parseModalField(raw, label, index) {
	const obj = requireObject(raw, label);
	const type = normalizeLowercaseStringOrEmpty(readString(obj.type, `${label}.type`));
	const supported = [
		"text",
		"checkbox",
		"radio",
		"select",
		"role-select",
		"user-select"
	];
	if (!supported.includes(type)) throw new Error(`${label}.type must be one of ${supported.join(", ")}`);
	const options = parseSelectOptions(obj.options, `${label}.options`);
	if ([
		"checkbox",
		"radio",
		"select"
	].includes(type) && (!options || options.length === 0)) throw new Error(`${label}.options is required for ${type} fields`);
	if (type === "radio" && (obj.minValues != null || obj.maxValues != null)) throw new Error(`${label}.minValues/maxValues are not supported for radio fields`);
	const required = typeof obj.required === "boolean" ? obj.required : void 0;
	const maxValues = type === "checkbox" ? 10 : 25;
	return {
		type,
		name: normalizeModalFieldName(readOptionalString(obj.name), index),
		label: readString(obj.label, `${label}.label`),
		description: readOptionalString(obj.description),
		placeholder: readOptionalString(obj.placeholder),
		required,
		options,
		minValues: readOptionalInteger(obj.minValues, `${label}.minValues`, {
			min: required === false ? 0 : 1,
			max: maxValues
		}),
		maxValues: readOptionalInteger(obj.maxValues, `${label}.maxValues`, {
			min: 1,
			max: maxValues
		}),
		minLength: readOptionalInteger(obj.minLength, `${label}.minLength`, {
			min: 0,
			max: 4e3
		}),
		maxLength: readOptionalInteger(obj.maxLength, `${label}.maxLength`, {
			min: 1,
			max: 4e3
		}),
		style: readOptionalString(obj.style)
	};
}
function parseComponentBlock(raw, label) {
	const obj = requireObject(raw, label);
	switch (normalizeBlockType(normalizeLowercaseStringOrEmpty(readString(obj.type, `${label}.type`)))) {
		case "text": return {
			type: "text",
			text: readString(obj.text, `${label}.text`)
		};
		case "section": {
			const text = readOptionalString(obj.text);
			const textsRaw = obj.texts;
			const texts = Array.isArray(textsRaw) ? textsRaw.map((entry, idx) => readString(entry, `${label}.texts[${idx}]`)) : void 0;
			if (!text && (!texts || texts.length === 0)) throw new Error(`${label}.text or ${label}.texts is required for section blocks`);
			let accessory;
			if (obj.accessory !== void 0) {
				const accessoryObj = requireObject(obj.accessory, `${label}.accessory`);
				const accessoryType = normalizeLowercaseStringOrEmpty(readString(accessoryObj.type, `${label}.accessory.type`));
				if (accessoryType === "thumbnail") accessory = {
					type: "thumbnail",
					url: readString(accessoryObj.url, `${label}.accessory.url`)
				};
				else if (accessoryType === "button") accessory = {
					type: "button",
					button: parseButtonSpec(accessoryObj.button, `${label}.accessory.button`)
				};
				else throw new Error(`${label}.accessory.type must be "thumbnail" or "button"`);
			}
			return {
				type: "section",
				text,
				texts,
				accessory
			};
		}
		case "separator": {
			const spacingRaw = obj.spacing;
			let spacing;
			if (spacingRaw === "small" || spacingRaw === "large") spacing = spacingRaw;
			else if (spacingRaw === 1 || spacingRaw === 2) spacing = spacingRaw;
			else if (spacingRaw !== void 0) throw new Error(`${label}.spacing must be "small", "large", 1, or 2`);
			const divider = typeof obj.divider === "boolean" ? obj.divider : void 0;
			return {
				type: "separator",
				spacing,
				divider
			};
		}
		case "actions": {
			const buttonsRaw = obj.buttons;
			const buttons = Array.isArray(buttonsRaw) ? buttonsRaw.map((entry, idx) => parseButtonSpec(entry, `${label}.buttons[${idx}]`)) : void 0;
			const select = obj.select ? parseSelectSpec(obj.select, `${label}.select`) : void 0;
			if ((!buttons || buttons.length === 0) && !select) throw new Error(`${label} requires buttons or select`);
			if (buttons && select) throw new Error(`${label} cannot include both buttons and select`);
			return {
				type: "actions",
				buttons,
				select
			};
		}
		case "media-gallery": {
			const itemsRaw = obj.items;
			if (!Array.isArray(itemsRaw) || itemsRaw.length === 0) throw new Error(`${label}.items must be a non-empty array`);
			return {
				type: "media-gallery",
				items: itemsRaw.map((entry, idx) => {
					const itemObj = requireObject(entry, `${label}.items[${idx}]`);
					return {
						url: readString(itemObj.url, `${label}.items[${idx}].url`),
						description: readOptionalString(itemObj.description),
						spoiler: typeof itemObj.spoiler === "boolean" ? itemObj.spoiler : void 0
					};
				})
			};
		}
		case "file": return {
			type: "file",
			file: normalizeAttachmentRef(readString(obj.file, `${label}.file`), `${label}.file`),
			spoiler: typeof obj.spoiler === "boolean" ? obj.spoiler : void 0
		};
		default: throw new Error(`${label}.type must be a supported component block`);
	}
}
function readDiscordComponentSpec(raw) {
	if (raw === void 0 || raw === null) return null;
	const obj = requireObject(raw, "components");
	const blocksRaw = obj.blocks;
	const blocks = Array.isArray(blocksRaw) ? blocksRaw.map((entry, idx) => parseComponentBlock(entry, `components.blocks[${idx}]`)) : void 0;
	const modalRaw = obj.modal;
	const reusable = typeof obj.reusable === "boolean" ? obj.reusable : void 0;
	let modal;
	if (modalRaw !== void 0) {
		const modalObj = requireObject(modalRaw, "components.modal");
		const fieldsRaw = modalObj.fields;
		if (!Array.isArray(fieldsRaw) || fieldsRaw.length === 0) throw new Error("components.modal.fields must be a non-empty array");
		if (fieldsRaw.length > 5) throw new Error("components.modal.fields supports up to 5 inputs");
		const fields = fieldsRaw.map((entry, idx) => parseModalField(entry, `components.modal.fields[${idx}]`, idx));
		modal = {
			title: readString(modalObj.title, "components.modal.title"),
			callbackData: readOptionalString(modalObj.callbackData),
			triggerLabel: readOptionalString(modalObj.triggerLabel),
			triggerStyle: readOptionalString(modalObj.triggerStyle),
			allowedUsers: readOptionalStringArray(modalObj.allowedUsers, "components.modal.allowedUsers"),
			fields
		};
	}
	return {
		text: readOptionalString(obj.text),
		reusable,
		container: typeof obj.container === "object" && obj.container && !Array.isArray(obj.container) ? {
			accentColor: obj.container.accentColor,
			spoiler: typeof obj.container.spoiler === "boolean" ? obj.container.spoiler : void 0
		} : void 0,
		blocks,
		modal
	};
}
//#endregion
//#region extensions/discord/src/components.builders.ts
function createShortId(prefix) {
	return `${prefix}${crypto.randomBytes(6).toString("base64url")}`;
}
function buildTextDisplays(text, texts) {
	if (texts && texts.length > 0) return texts.map((entry) => new TextDisplay(entry));
	if (text) return [new TextDisplay(text)];
	return [];
}
function createButtonComponent(params) {
	const style = mapButtonStyle(params.spec.style);
	if (style === ButtonStyle.Link || Boolean(params.spec.url)) {
		if (!params.spec.url) throw new Error("Link buttons require a url");
		const linkUrl = params.spec.url;
		class DynamicLinkButton extends LinkButton {
			constructor(..._args) {
				super(..._args);
				this.label = params.spec.label;
				this.url = linkUrl;
				this.disabled = params.spec.disabled ?? false;
			}
		}
		return { component: new DynamicLinkButton() };
	}
	const componentId = params.componentId ?? createShortId("btn_");
	const internalCustomId = typeof params.spec.internalCustomId === "string" && params.spec.internalCustomId.trim() ? params.spec.internalCustomId.trim() : void 0;
	const customId = internalCustomId ?? buildDiscordComponentCustomId({
		componentId,
		modalId: params.modalId
	});
	class DynamicButton extends Button {
		constructor(..._args2) {
			super(..._args2);
			this.label = params.spec.label;
			this.customId = customId;
			this.style = style;
			this.emoji = params.spec.emoji;
			this.disabled = params.spec.disabled ?? false;
		}
	}
	if (internalCustomId) return { component: new DynamicButton() };
	return {
		component: new DynamicButton(),
		entry: {
			id: componentId,
			kind: params.modalId ? "modal-trigger" : "button",
			label: params.spec.label,
			...params.spec.callbackData !== void 0 ? { callbackData: params.spec.callbackData } : {},
			...params.spec.callbackDataKind !== void 0 ? { callbackDataKind: params.spec.callbackDataKind } : {},
			...params.modalId !== void 0 ? { modalId: params.modalId } : {},
			...params.spec.reusable !== void 0 ? { reusable: params.spec.reusable } : {},
			...params.spec.allowedUsers !== void 0 ? { allowedUsers: params.spec.allowedUsers } : {}
		}
	};
}
function createSelectComponent(params) {
	const type = normalizeLowercaseStringOrEmpty(params.spec.type ?? "string");
	const componentId = params.componentId ?? createShortId("sel_");
	const customId = buildDiscordComponentCustomId({ componentId });
	const createEntry = (selectType, label, options) => ({
		id: componentId,
		kind: "select",
		label,
		...params.spec.callbackData !== void 0 ? { callbackData: params.spec.callbackData } : {},
		...params.spec.callbackDataKind !== void 0 ? { callbackDataKind: params.spec.callbackDataKind } : {},
		selectType,
		...options ? { options } : {},
		...params.spec.allowedUsers !== void 0 ? { allowedUsers: params.spec.allowedUsers } : {}
	});
	if (type === "string") {
		const options = params.spec.options ?? [];
		if (options.length === 0) throw new Error("String select menus require options");
		class DynamicStringSelect extends StringSelectMenu {
			constructor(..._args3) {
				super(..._args3);
				this.customId = customId;
				this.options = options;
				this.minValues = params.spec.minValues;
				this.maxValues = params.spec.maxValues;
				this.placeholder = params.spec.placeholder;
				this.disabled = false;
			}
		}
		return {
			component: new DynamicStringSelect(),
			entry: createEntry("string", params.spec.placeholder ?? "select", options.map((option) => ({
				value: option.value,
				label: option.label
			})))
		};
	}
	if (type === "user") {
		class DynamicUserSelect extends UserSelectMenu {
			constructor(..._args4) {
				super(..._args4);
				this.customId = customId;
				this.minValues = params.spec.minValues;
				this.maxValues = params.spec.maxValues;
				this.placeholder = params.spec.placeholder;
				this.disabled = false;
			}
		}
		return {
			component: new DynamicUserSelect(),
			entry: createEntry("user", params.spec.placeholder ?? "user select")
		};
	}
	if (type === "role") {
		class DynamicRoleSelect extends RoleSelectMenu {
			constructor(..._args5) {
				super(..._args5);
				this.customId = customId;
				this.minValues = params.spec.minValues;
				this.maxValues = params.spec.maxValues;
				this.placeholder = params.spec.placeholder;
				this.disabled = false;
			}
		}
		return {
			component: new DynamicRoleSelect(),
			entry: createEntry("role", params.spec.placeholder ?? "role select")
		};
	}
	if (type === "mentionable") {
		class DynamicMentionableSelect extends MentionableSelectMenu {
			constructor(..._args6) {
				super(..._args6);
				this.customId = customId;
				this.minValues = params.spec.minValues;
				this.maxValues = params.spec.maxValues;
				this.placeholder = params.spec.placeholder;
				this.disabled = false;
			}
		}
		return {
			component: new DynamicMentionableSelect(),
			entry: createEntry("mentionable", params.spec.placeholder ?? "mentionable select")
		};
	}
	class DynamicChannelSelect extends ChannelSelectMenu {
		constructor(..._args7) {
			super(..._args7);
			this.customId = customId;
			this.minValues = params.spec.minValues;
			this.maxValues = params.spec.maxValues;
			this.placeholder = params.spec.placeholder;
			this.disabled = false;
		}
	}
	return {
		component: new DynamicChannelSelect(),
		entry: createEntry("channel", params.spec.placeholder ?? "channel select")
	};
}
function isSelectComponent(component) {
	return component instanceof StringSelectMenu || component instanceof UserSelectMenu || component instanceof RoleSelectMenu || component instanceof MentionableSelectMenu || component instanceof ChannelSelectMenu;
}
function buildDiscordComponentMessage(params) {
	const entries = [];
	const consumptionGroupId = createShortId("grp_");
	const modals = [];
	const components = [];
	const containerChildren = [];
	const addEntry = (entry) => {
		const reusable = entry.reusable ?? params.spec.reusable;
		entries.push({
			...entry,
			...params.sessionKey !== void 0 ? { sessionKey: params.sessionKey } : {},
			...params.agentId !== void 0 ? { agentId: params.agentId } : {},
			...params.accountId !== void 0 ? { accountId: params.accountId } : {},
			...reusable !== void 0 ? { reusable } : {},
			consumptionGroupId
		});
	};
	const text = params.spec.text ?? params.fallbackText;
	if (text) containerChildren.push(new TextDisplay(text));
	for (const block of params.spec.blocks ?? []) {
		if (block.type === "text") {
			containerChildren.push(new TextDisplay(block.text));
			continue;
		}
		if (block.type === "section") {
			const displays = buildTextDisplays(block.text, block.texts);
			if (displays.length > 3) throw new Error("Section blocks support up to 3 text displays");
			let accessory;
			if (block.accessory?.type === "thumbnail") accessory = new Thumbnail(block.accessory.url);
			else if (block.accessory?.type === "button") {
				const { component, entry } = createButtonComponent({ spec: block.accessory.button });
				accessory = component;
				if (entry) addEntry(entry);
			}
			containerChildren.push(new Section(displays, accessory));
			continue;
		}
		if (block.type === "separator") {
			containerChildren.push(new Separator({
				spacing: block.spacing,
				divider: block.divider
			}));
			continue;
		}
		if (block.type === "media-gallery") {
			containerChildren.push(new MediaGallery(block.items));
			continue;
		}
		if (block.type === "file") {
			containerChildren.push(new File(block.file, block.spoiler));
			continue;
		}
		if (block.type === "actions") {
			const rowComponents = [];
			if (block.buttons) {
				if (block.buttons.length > 5) throw new Error("Action rows support up to 5 buttons");
				for (const button of block.buttons) {
					const { component, entry } = createButtonComponent({ spec: button });
					rowComponents.push(component);
					if (entry) addEntry(entry);
				}
			} else if (block.select) {
				const { component, entry } = createSelectComponent({ spec: block.select });
				rowComponents.push(component);
				addEntry(entry);
			}
			containerChildren.push(new Row(rowComponents));
		}
	}
	if (params.spec.modal) {
		const modalId = createShortId("mdl_");
		const fields = params.spec.modal.fields.map((field, index) => ({
			id: createShortId("fld_"),
			name: normalizeModalFieldName(field.name, index),
			label: field.label,
			type: field.type,
			...field.description !== void 0 ? { description: field.description } : {},
			...field.placeholder !== void 0 ? { placeholder: field.placeholder } : {},
			...field.required !== void 0 ? { required: field.required } : {},
			...field.options !== void 0 ? { options: field.options } : {},
			...field.minValues !== void 0 ? { minValues: field.minValues } : {},
			...field.maxValues !== void 0 ? { maxValues: field.maxValues } : {},
			...field.minLength !== void 0 ? { minLength: field.minLength } : {},
			...field.maxLength !== void 0 ? { maxLength: field.maxLength } : {},
			...field.style !== void 0 ? { style: field.style } : {}
		}));
		modals.push({
			id: modalId,
			title: params.spec.modal.title,
			fields,
			...params.spec.modal.callbackData !== void 0 ? { callbackData: params.spec.modal.callbackData } : {},
			...params.sessionKey !== void 0 ? { sessionKey: params.sessionKey } : {},
			...params.agentId !== void 0 ? { agentId: params.agentId } : {},
			...params.accountId !== void 0 ? { accountId: params.accountId } : {},
			...params.spec.reusable !== void 0 ? { reusable: params.spec.reusable } : {},
			...params.spec.modal.allowedUsers !== void 0 ? { allowedUsers: params.spec.modal.allowedUsers } : {}
		});
		const { component, entry } = createButtonComponent({
			spec: {
				label: params.spec.modal.triggerLabel ?? "Open form",
				style: params.spec.modal.triggerStyle ?? "primary",
				allowedUsers: params.spec.modal.allowedUsers
			},
			modalId
		});
		if (entry) addEntry(entry);
		const lastChild = containerChildren.at(-1);
		if (lastChild instanceof Row) {
			const row = lastChild;
			const hasSelect = row.components.some((entryLocal) => isSelectComponent(entryLocal));
			if (row.components.length < 5 && !hasSelect) row.addComponent(component);
			else containerChildren.push(new Row([component]));
		} else containerChildren.push(new Row([component]));
	}
	if (containerChildren.length === 0) throw new Error("components must include at least one block, text, or modal trigger");
	const container = new Container(containerChildren, params.spec.container);
	components.push(container);
	const consumptionGroupEntryIds = entries.map((entry) => entry.id);
	for (const entry of entries) entry.consumptionGroupEntryIds = consumptionGroupEntryIds;
	return {
		components,
		entries,
		modals
	};
}
function buildDiscordComponentMessageFlags(components) {
	return components.some((component) => component.isV2) ? MessageFlags.IsComponentsV2 : void 0;
}
//#endregion
//#region extensions/discord/src/components.modal.ts
const ModalBase = Modal ?? function ModalFallback() {};
function createModalFieldComponent(field) {
	if (field.type === "text") {
		class DynamicTextInput extends TextInput {
			constructor(..._args) {
				super(..._args);
				this.customId = field.id;
				this.style = mapTextInputStyle(field.style);
				this.placeholder = field.placeholder;
				this.required = field.required;
				this.minLength = field.minLength;
				this.maxLength = field.maxLength;
			}
		}
		return new DynamicTextInput();
	}
	if (field.type === "select") {
		const options = field.options ?? [];
		class DynamicModalSelect extends StringSelectMenu {
			constructor(..._args2) {
				super(..._args2);
				this.customId = field.id;
				this.options = options;
				this.required = field.required;
				this.minValues = field.minValues;
				this.maxValues = field.maxValues;
				this.placeholder = field.placeholder;
			}
		}
		return new DynamicModalSelect();
	}
	if (field.type === "role-select") {
		class DynamicModalRoleSelect extends RoleSelectMenu {
			constructor(..._args3) {
				super(..._args3);
				this.customId = field.id;
				this.required = field.required;
				this.minValues = field.minValues;
				this.maxValues = field.maxValues;
				this.placeholder = field.placeholder;
			}
		}
		return new DynamicModalRoleSelect();
	}
	if (field.type === "user-select") {
		class DynamicModalUserSelect extends UserSelectMenu {
			constructor(..._args4) {
				super(..._args4);
				this.customId = field.id;
				this.required = field.required;
				this.minValues = field.minValues;
				this.maxValues = field.maxValues;
				this.placeholder = field.placeholder;
			}
		}
		return new DynamicModalUserSelect();
	}
	if (field.type === "checkbox") {
		const options = field.options ?? [];
		class DynamicCheckboxGroup extends CheckboxGroup {
			constructor(..._args5) {
				super(..._args5);
				this.customId = field.id;
				this.options = options;
				this.required = field.required;
				this.minValues = field.minValues;
				this.maxValues = field.maxValues;
			}
		}
		return new DynamicCheckboxGroup();
	}
	const options = field.options ?? [];
	class DynamicRadioGroup extends RadioGroup {
		constructor(..._args6) {
			super(..._args6);
			this.customId = field.id;
			this.options = options;
			this.required = field.required;
		}
	}
	return new DynamicRadioGroup();
}
var DiscordFormModal = class extends ModalBase {
	constructor(params) {
		super();
		this.customIdParser = parseDiscordModalCustomIdForInteraction;
		this.title = params.title;
		this.customId = buildDiscordModalCustomId(params.modalId);
		this.components = params.fields.map((field) => {
			const component = createModalFieldComponent(field);
			class DynamicLabel extends Label {
				constructor(..._args7) {
					super(..._args7);
					this.label = field.label;
					this.description = field.description;
					this.component = component;
					this.customId = field.id;
				}
			}
			return new DynamicLabel(component);
		});
	}
	async run() {
		throw new Error("Modal handler is not registered for dynamic forms");
	}
};
function createDiscordFormModal(entry) {
	return new DiscordFormModal({
		modalId: entry.id,
		title: entry.title,
		fields: entry.fields
	});
}
//#endregion
//#region extensions/discord/src/components.ts
function formatDiscordComponentEventText(params) {
	if (params.kind === "button") return `Clicked "${params.label}".`;
	const values = params.values ?? [];
	if (values.length === 0) return `Updated "${params.label}".`;
	return `Selected ${values.join(", ")} from "${params.label}".`;
}
//#endregion
export { buildDiscordComponentMessageFlags as a, resolveDiscordComponentAttachmentName as c, buildDiscordComponentMessage as i, DiscordFormModal as n, DISCORD_COMPONENT_ATTACHMENT_PREFIX as o, createDiscordFormModal as r, readDiscordComponentSpec as s, formatDiscordComponentEventText as t };
