diff --git a/typescript/src/zod/validate.ts b/typescript/src/zod/validate.ts index 4babb5cc..b58fd7cc 100644 --- a/typescript/src/zod/validate.ts +++ b/typescript/src/zod/validate.ts @@ -176,6 +176,8 @@ export function getZodSchemaAsTypeScript(schema: Record): str return appendUnionOrIntersectionTypes([(type._zod.def as z.core.$ZodOptionalDef).innerType as z.ZodType, z.undefined()], TypePrecedence.Union); case "readonly": return appendReadonlyType(type); + case "pipe": + return appendType((type._zod.def as z.core.$ZodPipeDef).in as z.ZodType); } append("any"); } diff --git a/typescript/test/zod.test.ts b/typescript/test/zod.test.ts index f77d1648..37db6c6e 100644 --- a/typescript/test/zod.test.ts +++ b/typescript/test/zod.test.ts @@ -408,6 +408,41 @@ describe("getZodSchemaAsTypeScript", () => { }); + // ----------------------------------------------------------------------- + // Input schemas for transformations and pipelines + // ----------------------------------------------------------------------- + + describe("z.transform() and z.pipe()", () => { + + it("emits the JSON input type for a transform pipeline", () => { + const DateTime = z.iso.datetime().transform(value => new Date(value)); + assert.match(schemaOf("DateTime", DateTime), /type DateTime = string;/); + }); + + it("emits the input schema for a pipeline", () => { + const NumberFromString = z.string().pipe(z.coerce.number()); + assert.match(schemaOf("NumberFromString", NumberFromString), /type NumberFromString = string;/); + }); + + it("preserves transformed runtime values during validation", () => { + const Event = { + Event: z.object({ + dateTime: z.iso.datetime().transform(value => new Date(value)), + }), + }; + const validator = createZodJsonValidator(Event, "Event"); + assert.match(validator.getSchemaText(), /dateTime: string;/); + + const result = validator.validate({ dateTime: "2022-08-20T08:30:00.000Z" }); + assert.ok(result.success, "expected ISO date-time validation to succeed"); + assert.ok(result.data.dateTime instanceof Date); + + const invalidResult = validator.validate({ dateTime: "not-a-date" }); + assert.ok(!invalidResult.success, "expected invalid date-time validation to fail"); + }); + + }); + // ----------------------------------------------------------------------- // Fallthrough: unknown type kind → any // -----------------------------------------------------------------------