diff --git a/packages/server-shared/src/type-utilities/query-array-preprocessor.ts b/packages/server-shared/src/type-utilities/query-array-preprocessor.ts index 39300f668..a1c663e4a 100644 --- a/packages/server-shared/src/type-utilities/query-array-preprocessor.ts +++ b/packages/server-shared/src/type-utilities/query-array-preprocessor.ts @@ -1,5 +1,27 @@ import { z } from 'zod'; +/** + * The core preprocessing logic for converting query parameters into arrays + */ +const queryArrayPreprocessFn = (val: unknown) => { + // Handle no value + if (!val) return undefined; + + // Already an array, pass through + if (Array.isArray(val)) return val; + + // Handle string input (single or comma-separated) + if (typeof val === 'string') { + return val + .split(',') + .map((item) => item.trim()) + .filter(Boolean); + } + + // Single value case (wrap in array) + return [val]; +}; + /** * Creates a preprocessor that converts query parameter strings into arrays. * Handles various input formats: @@ -9,46 +31,12 @@ import { z } from 'zod'; * - No value: undefined → undefined */ export const createQueryArrayPreprocessor = (schema: z.ZodArray>) => { - return z.preprocess((val) => { - // Handle no value - if (!val) return undefined; - - // Already an array, pass through - if (Array.isArray(val)) return val; - - // Handle string input (single or comma-separated) - if (typeof val === 'string') { - return val - .split(',') - .map((item) => item.trim()) - .filter(Boolean); - } - - // Single value case (wrap in array) - return [val]; - }, schema); + return z.preprocess(queryArrayPreprocessFn, schema); }; /** * Type-safe helper for creating optional query array preprocessors */ export const createOptionalQueryArrayPreprocessor = (itemSchema: z.ZodType) => { - return z.preprocess((val) => { - // Handle no value - if (!val) return undefined; - - // Already an array, pass through - if (Array.isArray(val)) return val; - - // Handle string input (single or comma-separated) - if (typeof val === 'string') { - return val - .split(',') - .map((item) => item.trim()) - .filter(Boolean); - } - - // Single value case (wrap in array) - return [val]; - }, z.array(itemSchema).optional()); + return z.preprocess(queryArrayPreprocessFn, z.array(itemSchema).optional()); };