


















@@ -62,10 +62,23 @@ function readOptionalStringArray(value: unknown, label: string): string[] | unde
6262return value.map((entry, index) => readString(entry, `${label}[${index}]`));
6363}
646465-function readOptionalNumber(value: unknown): number | undefined {
66-if (typeof value !== "number" || !Number.isFinite(value)) {
65+function readOptionalInteger(
66+value: unknown,
67+label: string,
68+bounds?: { min?: number; max?: number },
69+): number | undefined {
70+if (value == null) {
6771return undefined;
6872}
73+if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value)) {
74+throw new Error(`${label} must be an integer`);
75+}
76+if (bounds?.min !== undefined && value < bounds.min) {
77+throw new Error(`${label} must be at least ${bounds.min}`);
78+}
79+if (bounds?.max !== undefined && value > bounds.max) {
80+throw new Error(`${label} must be at most ${bounds.max}`);
81+}
6982return value;
7083}
7184@@ -197,8 +210,8 @@ function parseSelectSpec(raw: unknown, label: string): DiscordComponentSelectSpe
197210 type,
198211callbackData: readOptionalString(obj.callbackData),
199212placeholder: readOptionalString(obj.placeholder),
200-minValues: readOptionalNumber(obj.minValues),
201-maxValues: readOptionalNumber(obj.maxValues),
213+minValues: readOptionalInteger(obj.minValues, `${label}.minValues`, { min: 0, max: 25 }),
214+maxValues: readOptionalInteger(obj.maxValues, `${label}.maxValues`, { min: 1, max: 25 }),
202215options: parseSelectOptions(obj.options, `${label}.options`),
203216allowedUsers: readOptionalStringArray(obj.allowedUsers, `${label}.allowedUsers`),
204217};
@@ -224,18 +237,29 @@ function parseModalField(raw: unknown, label: string, index: number): DiscordMod
224237if (["checkbox", "radio", "select"].includes(type) && (!options || options.length === 0)) {
225238throw new Error(`${label}.options is required for ${type} fields`);
226239}
240+if (type === "radio" && (obj.minValues != null || obj.maxValues != null)) {
241+throw new Error(`${label}.minValues/maxValues are not supported for radio fields`);
242+}
243+const required = typeof obj.required === "boolean" ? obj.required : undefined;
244+const maxValues = type === "checkbox" ? 10 : 25;
227245return {
228246 type,
229247name: normalizeModalFieldName(readOptionalString(obj.name), index),
230248label: readString(obj.label, `${label}.label`),
231249description: readOptionalString(obj.description),
232250placeholder: readOptionalString(obj.placeholder),
233-required: typeof obj.required === "boolean" ? obj.required : undefined,
251+ required,
234252 options,
235-minValues: readOptionalNumber(obj.minValues),
236-maxValues: readOptionalNumber(obj.maxValues),
237-minLength: readOptionalNumber(obj.minLength),
238-maxLength: readOptionalNumber(obj.maxLength),
253+minValues: readOptionalInteger(obj.minValues, `${label}.minValues`, {
254+min: required === false ? 0 : 1,
255+max: maxValues,
256+}),
257+maxValues: readOptionalInteger(obj.maxValues, `${label}.maxValues`, {
258+min: 1,
259+max: maxValues,
260+}),
261+minLength: readOptionalInteger(obj.minLength, `${label}.minLength`, { min: 0, max: 4000 }),
262+maxLength: readOptionalInteger(obj.maxLength, `${label}.maxLength`, { min: 1, max: 4000 }),
239263style: readOptionalString(obj.style) as DiscordModalFieldSpec["style"],
240264};
241265}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。