mirror of
https://github.com/tiennm99/tiennm99bot.git
synced 2026-10-20 00:15:50 +00:00
72 lines
2.2 KiB
JavaScript
72 lines
2.2 KiB
JavaScript
import {z} from 'zod';
|
|
|
|
export const themes = ['classic', 'festival', 'mono'];
|
|
export const allowedSizes = [384, 480, 512];
|
|
export const allowedFps = [12, 15, 20];
|
|
const themeSchema = z.union([z.literal('classic'), z.literal('festival'), z.literal('mono')]);
|
|
|
|
/**
|
|
* @typedef {object} WheelRequestLimits
|
|
* @property {number} maxOptions
|
|
* @property {number} maxOptionChars
|
|
*/
|
|
|
|
/**
|
|
* @typedef {object} WheelRenderRequest
|
|
* @property {string[]} options
|
|
* @property {number} winnerIndex
|
|
* @property {number} durationMs
|
|
* @property {number} holdMs
|
|
* @property {12 | 15 | 20} fps
|
|
* @property {384 | 480 | 512} size
|
|
* @property {'classic' | 'festival' | 'mono'} theme
|
|
*/
|
|
|
|
/**
|
|
* @param {WheelRequestLimits} limits
|
|
*/
|
|
export const createWheelRequestSchema = (limits) =>
|
|
z
|
|
.object({
|
|
options: z
|
|
.array(z.string())
|
|
.transform((options) => options.map((option) => option.trim()))
|
|
.pipe(
|
|
z
|
|
.array(z.string().min(1).max(limits.maxOptionChars))
|
|
.min(1)
|
|
.max(limits.maxOptions),
|
|
),
|
|
winnerIndex: z.number().int().nonnegative().optional(),
|
|
durationMs: z.number().int().min(3000).max(10000).default(6500),
|
|
holdMs: z.number().int().min(500).max(2500).default(1200),
|
|
fps: z.union([z.literal(12), z.literal(15), z.literal(20)]).default(15),
|
|
size: z.union([z.literal(384), z.literal(480), z.literal(512)]).default(512),
|
|
theme: themeSchema.default('classic'),
|
|
})
|
|
.strict()
|
|
.superRefine((value, context) => {
|
|
if (value.winnerIndex !== undefined && value.winnerIndex >= value.options.length) {
|
|
context.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
path: ['winnerIndex'],
|
|
message: 'winnerIndex must be within options range',
|
|
});
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @param {unknown} input
|
|
* @param {WheelRequestLimits} limits
|
|
* @param {(optionCount: number) => number} pickWinner
|
|
* @returns {WheelRenderRequest}
|
|
*/
|
|
export const parseWheelRequest = (input, limits, pickWinner) => {
|
|
const parsed = createWheelRequestSchema(limits).parse(input);
|
|
|
|
return {
|
|
...parsed,
|
|
winnerIndex: parsed.winnerIndex ?? pickWinner(parsed.options.length),
|
|
};
|
|
};
|