UNPKG

zod-invertible

Version:

declare zod schemas that can be inverted to format from output to input

158 lines 4.55 kB
import z from 'zod'; export class ZodInvertible extends z.ZodPipeline { constructor(inputSchema, parse, outputSchema, format) { super({ ...inputSchema.transform(parse).pipe(outputSchema)._def, inputSchema, outputSchema, parse, format }); } } export function invertible(schema, parse, outSchema, format) { return new ZodInvertible(schema, parse, outSchema, format); } export const IgnoreEffect = Symbol('IgnoreEffect'); export function ignoreEffect(schema) { ; schema[IgnoreEffect] = true; return schema; } export function invert(schema) { switch (schema._def.typeName) { case z.ZodFirstPartyTypeKind.ZodArray: return z.array(invert(schema.element)); case z.ZodFirstPartyTypeKind.ZodObject: { const { shape, _def } = schema; const invertedShape = Object.fromEntries(Object.entries(shape).map(([key, value]) => [key, invert(value)])); return new z.ZodObject({ ..._def, catchall: invert(_def.catchall), shape: () => invertedShape }); } case z.ZodFirstPartyTypeKind.ZodUnion: return z.union(schema.options.map(invert)); case z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion: { const { discriminator, options } = schema; return z.discriminatedUnion(discriminator, options.map(invert)); } case z.ZodFirstPartyTypeKind.ZodIntersection: { const { left, right } = schema._def; return z.intersection(invert(left), invert(right)); } case z.ZodFirstPartyTypeKind.ZodTuple: { const { items, _def: { rest } } = schema; const result = z.tuple(items.map(invert)); return rest ? result.rest(invert(rest)) : result; } case z.ZodFirstPartyTypeKind.ZodRecord: { const { keySchema, valueSchema } = schema; return z.record(invert(keySchema), invert(valueSchema)); } case z.ZodFirstPartyTypeKind.ZodMap: { const { keySchema, valueSchema } = schema; return z.map(invert(keySchema), invert(valueSchema)); } case z.ZodFirstPartyTypeKind.ZodSet: return z.set(invert(schema._def.valueType)); case z.ZodFirstPartyTypeKind.ZodFunction: { const { _def: { args, returns } } = schema; return z.function(args.map(invert), invert(returns)); } case z.ZodFirstPartyTypeKind.ZodLazy: return z.lazy(() => invert(schema.schema)); case z.ZodFirstPartyTypeKind.ZodEffects: { const { _def: { effect, schema: innerType } } = schema; switch (effect.type) { case 'refinement': { const { refinement } = effect; return z.any().superRefine(refinement).pipe(invert(innerType)); } case 'preprocess': case 'transform': if (schema[IgnoreEffect]) { return invert(innerType); } throw new Error(`effect not supported: ${effect.type}`); } break; } case z.ZodFirstPartyTypeKind.ZodOptional: return invert(schema.unwrap()).optional(); case z.ZodFirstPartyTypeKind.ZodNullable: return invert(schema.unwrap()).nullable(); case z.ZodFirstPartyTypeKind.ZodDefault: return invert(schema.removeDefault()); case z.ZodFirstPartyTypeKind.ZodCatch: return invert(schema.removeCatch()); case z.ZodFirstPartyTypeKind.ZodPromise: return z.promise(invert(schema._def.type)); case z.ZodFirstPartyTypeKind.ZodBranded: return invert(schema._def.type); case z.ZodFirstPartyTypeKind.ZodPipeline: { if (schema instanceof ZodInvertible) { const { _def: { inputSchema, outputSchema, parse, format } } = schema; return invertible(invert(outputSchema), format, invert(inputSchema), parse); } const { _def } = schema; return invert(_def.out).pipe(invert(_def.in)); } case z.ZodFirstPartyTypeKind.ZodReadonly: return invert(schema._def.innerType).readonly(); } return schema; } //# sourceMappingURL=index.mjs.map