"use strict"; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); const createError = require("@fastify/error"); const fp = require("fastify-plugin"); const zod = require("zod"); const _interopDefaultCompat = (e) => e && typeof e === "object" && "default" in e ? e : { default: e }; const createError__default = /* @__PURE__ */ _interopDefaultCompat(createError); const fp__default = /* @__PURE__ */ _interopDefaultCompat(fp); const FASTIFY_ZOD_QUERY_COERCION_PROCESSED = Symbol("FASTIFY_ZOD_QUERY_COERCION_PROCESSED"); function isZodType(schema, typeName) { var _a; return ((_a = schema == null ? void 0 : schema._def) == null ? void 0 : _a.typeName) === typeName; } const isValidNumber = (str) => { return !isNaN(Number(str)) && isFinite(Number(str)); }; const isValidDate = (str) => { const isoDateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{0,3})?Z$/; return isoDateRegex.test(str); }; class UnsupportedZodType extends Error { constructor(typeName) { super(`Unsupported schema type for query coercion: ${typeName}`); this.name = "UnsupportedZodType"; } } function transformSchema(schema) { if (isZodType(schema, "ZodEffects")) { if (schema._def.effect.type === "preprocess") { return schema; } return new zod.z.ZodEffects({ ...schema._def, schema: transformSchema(schema._def.schema) }); } if (isZodType(schema, "ZodLiteral")) { if (typeof schema._def.value === "symbol") throw new UnsupportedZodType("ZodLiteral with symbol"); return zod.z.preprocess((val) => { if (typeof schema._def.value === "symbol") return val; if (typeof schema._def.value === "undefined") return val; if ("" + schema._def.value === val) return schema._def.value; return val; }, schema); } if (isZodType(schema, "ZodString")) { return schema; } if (isZodType(schema, "ZodNumber")) { return zod.z.preprocess((val) => { if (typeof val === "string" && isValidNumber(val)) return Number(val); return val; }, schema); } if (isZodType(schema, "ZodBigInt")) { return zod.z.preprocess((val) => { try { if (typeof val === "string") return BigInt(val); return val; } catch { return val; } }, schema); } if (isZodType(schema, "ZodBoolean")) { return zod.z.preprocess((val) => { if (val === "true") return true; if (val === "false") return false; return val; }, schema); } if (isZodType(schema, "ZodDate")) { return zod.z.preprocess((val) => { if (typeof val === "string") { if (isValidNumber(val)) return new Date(Number(val)); if (isValidDate(val)) return new Date(val); } return val; }, schema); } if (isZodType(schema, "ZodEnum")) { return schema; } if (isZodType(schema, "ZodNull")) { return zod.z.preprocess((val) => { if (val === "null") return null; return val; }, schema); } if (isZodType(schema, "ZodNullable")) { return zod.z.preprocess((val) => { if (val === "null") return null; return val; }, new zod.z.ZodNullable({ ...schema._def, innerType: transformSchema(schema._def.innerType) })); } if (isZodType(schema, "ZodOptional")) { return new zod.z.ZodOptional({ ...schema._def, innerType: transformSchema(schema._def.innerType) }); } if (isZodType(schema, "ZodArray")) { return zod.z.preprocess((val) => { if (typeof val === "string") return [val]; return val; }, new zod.z.ZodArray({ ...schema._def, type: transformSchema(schema._def.type) })); } if (isZodType(schema, "ZodTuple")) { return zod.z.preprocess((val) => { if (typeof val === "string") return [val]; return val; }, new zod.z.ZodTuple({ ...schema._def, items: schema._def.items.map(transformSchema), rest: schema._def.rest ? transformSchema(schema._def.rest) : null })); } if (isZodType(schema, "ZodSet")) { return zod.z.preprocess((val) => { if (typeof val === "string") return /* @__PURE__ */ new Set([val]); if (Array.isArray(val) && val.every((v) => typeof v === "string")) return new Set(val); return val; }, new zod.z.ZodSet({ ...schema._def, valueType: transformSchema(schema._def.valueType) })); } if (isZodType(schema, "ZodUnion")) { return new zod.z.ZodUnion({ ...schema._def, options: schema._def.options.map(transformSchema) }); } if (isZodType(schema, "ZodIntersection")) { return new zod.z.ZodIntersection({ ...schema._def, left: transformSchema(schema._def.left), right: transformSchema(schema._def.right) }); } if (isZodType(schema, "ZodCatch")) { return new zod.z.ZodCatch({ ...schema._def, innerType: transformSchema(schema._def.innerType) }); } if (isZodType(schema, "ZodDefault")) { return new zod.z.ZodDefault({ ...schema._def, innerType: transformSchema(schema._def.innerType) }); } if (isZodType(schema, "ZodPipeline")) { return new zod.z.ZodPipeline({ ...schema._def, in: transformSchema(schema._def.in) }); } if (isZodType(schema, "ZodUndefined")) { return schema; } if (isZodType(schema, "ZodVoid")) { return schema; } if (isZodType(schema, "ZodAny")) { return schema; } if (isZodType(schema, "ZodUnknown")) { return schema; } if (isZodType(schema, "ZodNever")) { return schema; } throw new UnsupportedZodType(schema.constructor.name); } const FST_ZOD_QUERY_COERCION_ERROR = createError__default.default("FST_ZOD_QUERY_COERCION_ERROR", '%s at "%s"'); const plugin = async (fastify, opts) => { const coerceTypes = opts.coerceTypes ?? ["querystring"]; fastify.addHook("onRoute", (route) => { coerceTypes.forEach((coerceType) => { var _a; if (isZodType((_a = route.schema) == null ? void 0 : _a[coerceType], "ZodObject") && !route.schema[coerceType][FASTIFY_ZOD_QUERY_COERCION_PROCESSED]) { route.schema[coerceType] = transformObject(route.schema[coerceType]); route.schema[coerceType][FASTIFY_ZOD_QUERY_COERCION_PROCESSED] = true; } }); }); }; function transformObject(schema) { const newShape = Object.entries(schema.shape).reduce((acc, [key, value]) => { try { acc[key] = transformSchema(value); } catch (error) { if (error instanceof UnsupportedZodType) { throw FST_ZOD_QUERY_COERCION_ERROR(error.message, key); } throw error; } return acc; }, {}); return new zod.z.ZodObject({ ...schema._def, shape: () => newShape }); } const fastifyZodQueryCoercion = fp__default.default(plugin, { fastify: ">=4", name: "fastify-zod-query-coercion" }); exports.FASTIFY_ZOD_QUERY_COERCION_PROCESSED = FASTIFY_ZOD_QUERY_COERCION_PROCESSED; exports.default = fastifyZodQueryCoercion; exports.fastifyZodQueryCoercion = fastifyZodQueryCoercion;