From dff0499cd8375ff6a6ebcc62bafad5080b116009 Mon Sep 17 00:00:00 2001 From: sanny-io Date: Tue, 26 May 2026 08:55:34 +0000 Subject: [PATCH 1/5] fix(zod): `DateTime` field inference for `z.input` --- packages/zod/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/zod/src/types.ts b/packages/zod/src/types.ts index 7715a534d..41384798b 100644 --- a/packages/zod/src/types.ts +++ b/packages/zod/src/types.ts @@ -108,7 +108,7 @@ type FieldTypeZodMap = { Float: z.ZodNumber; Decimal: z.ZodType; Boolean: z.ZodBoolean; - DateTime: z.ZodType; + DateTime: z.ZodDate; Bytes: z.ZodType; Json: JsonZodType; }; From 3c9b946eeaeb00777b6b3442d22f6c8d8075d163 Mon Sep 17 00:00:00 2001 From: sanny-io Date: Tue, 26 May 2026 08:55:48 +0000 Subject: [PATCH 2/5] chore: add tests --- packages/zod/test/factory.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/zod/test/factory.test.ts b/packages/zod/test/factory.test.ts index 0dd616c2d..8a1a3ee44 100644 --- a/packages/zod/test/factory.test.ts +++ b/packages/zod/test/factory.test.ts @@ -208,6 +208,12 @@ describe('SchemaFactory - makeModelSchema', () => { expect(userSchema.safeParse({ ...validUser, metadata: { key: BigInt(1) } }).success).toBe(false); expect(userSchema.safeParse({ ...validUser, metadata: [BigInt(1)] }).success).toBe(false); }); + + it('infers correct input types for DateTime fields', () => { + const _userSchema = factory.makeModelSchema('User'); + type UserInput = z.input; + expectTypeOf().toEqualTypeOf(); + }); }); describe('string validation attributes', () => { From 198f2a9659a1c3bcacad79adfebe5e206693a6e2 Mon Sep 17 00:00:00 2001 From: sanny-io Date: Fri, 29 May 2026 22:22:49 +0000 Subject: [PATCH 3/5] fix: missing `Decimal` and `Bytes` support --- packages/zod/src/types.ts | 6 +++--- packages/zod/src/utils.ts | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/zod/src/types.ts b/packages/zod/src/types.ts index 41384798b..029282c23 100644 --- a/packages/zod/src/types.ts +++ b/packages/zod/src/types.ts @@ -17,8 +17,8 @@ import type { TypeDefFieldIsArray, TypeDefFieldIsOptional, } from '@zenstackhq/schema'; -import type Decimal from 'decimal.js'; import type z from 'zod'; +import type { decimalSchema, bytesSchema } from './utils'; /** * Scalar-only shape returned by the no-options `makeModelSchema` overload. @@ -106,10 +106,10 @@ type FieldTypeZodMap = { Int: z.ZodNumber; BigInt: z.ZodBigInt; Float: z.ZodNumber; - Decimal: z.ZodType; + Decimal: typeof decimalSchema; Boolean: z.ZodBoolean; DateTime: z.ZodDate; - Bytes: z.ZodType; + Bytes: typeof bytesSchema; Json: JsonZodType; }; diff --git a/packages/zod/src/utils.ts b/packages/zod/src/utils.ts index 9081c1c86..69d4ebff1 100644 --- a/packages/zod/src/utils.ts +++ b/packages/zod/src/utils.ts @@ -12,6 +12,9 @@ import Decimal from 'decimal.js'; import { z } from 'zod'; import { SchemaFactoryError } from './error'; +export const decimalSchema = z.custom((val) => Decimal.isDecimal(val)); +export const bytesSchema = z.instanceof(Uint8Array); + function getArgValue(expr: Expression | undefined): T | undefined { if (!expr || !ExpressionUtils.isLiteral(expr)) { return undefined; From 3e80f6a9ca456871424f7e1d7b542cb621e08f23 Mon Sep 17 00:00:00 2001 From: sanny-io Date: Fri, 29 May 2026 22:23:05 +0000 Subject: [PATCH 4/5] chore: add tests --- packages/zod/test/factory.test.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/zod/test/factory.test.ts b/packages/zod/test/factory.test.ts index 8a1a3ee44..365496f90 100644 --- a/packages/zod/test/factory.test.ts +++ b/packages/zod/test/factory.test.ts @@ -66,7 +66,7 @@ describe('SchemaFactory - makeModelSchema', () => { expectTypeOf().toEqualTypeOf(); // optional Bytes - expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf | null | undefined>(); // optional Json expectTypeOf().toHaveProperty('metadata'); @@ -209,10 +209,12 @@ describe('SchemaFactory - makeModelSchema', () => { expect(userSchema.safeParse({ ...validUser, metadata: [BigInt(1)] }).success).toBe(false); }); - it('infers correct input types for DateTime fields', () => { + it('infers correct input types for fields', () => { const _userSchema = factory.makeModelSchema('User'); type UserInput = z.input; expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf | null | undefined>(); }); }); From f61fb775f3ef3deea82259853aabbfd96c4cf12d Mon Sep 17 00:00:00 2001 From: sanny-io Date: Fri, 29 May 2026 22:48:06 +0000 Subject: [PATCH 5/5] fix: restore previous typing --- packages/zod/src/utils.ts | 2 +- packages/zod/test/factory.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/zod/src/utils.ts b/packages/zod/src/utils.ts index 69d4ebff1..564fb2e50 100644 --- a/packages/zod/src/utils.ts +++ b/packages/zod/src/utils.ts @@ -13,7 +13,7 @@ import { z } from 'zod'; import { SchemaFactoryError } from './error'; export const decimalSchema = z.custom((val) => Decimal.isDecimal(val)); -export const bytesSchema = z.instanceof(Uint8Array); +export const bytesSchema = z.instanceof(Uint8Array) as z.ZodCustom, Uint8Array>; function getArgValue(expr: Expression | undefined): T | undefined { if (!expr || !ExpressionUtils.isLiteral(expr)) { diff --git a/packages/zod/test/factory.test.ts b/packages/zod/test/factory.test.ts index 365496f90..43afddc85 100644 --- a/packages/zod/test/factory.test.ts +++ b/packages/zod/test/factory.test.ts @@ -66,7 +66,7 @@ describe('SchemaFactory - makeModelSchema', () => { expectTypeOf().toEqualTypeOf(); // optional Bytes - expectTypeOf().toEqualTypeOf | null | undefined>(); + expectTypeOf().toEqualTypeOf(); // optional Json expectTypeOf().toHaveProperty('metadata'); @@ -214,7 +214,7 @@ describe('SchemaFactory - makeModelSchema', () => { type UserInput = z.input; expectTypeOf().toEqualTypeOf(); expectTypeOf().toEqualTypeOf(); - expectTypeOf().toEqualTypeOf | null | undefined>(); + expectTypeOf().toEqualTypeOf(); }); });