Skip to content

Commit 9d98924

Browse files
committed
creating the ZodValidatorFromConvex in zod.ts file and using it in convexToZod function output
1 parent 045e361 commit 9d98924

File tree

1 file changed

+56
-3
lines changed
  • packages/convex-helpers/server

1 file changed

+56
-3
lines changed

packages/convex-helpers/server/zod.ts

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,14 +1314,65 @@ export function zBrand<
13141314
/** Simple type conversion from a Convex validator to a Zod validator. */
13151315
export type ConvexToZod<V extends GenericValidator> = z.ZodType<Infer<V>>;
13161316

1317+
/** Better type conversion from a Convex validator to a Zod validator where the output is not a generetic ZodType but it's more specific.
1318+
*
1319+
* ES: z.ZodString instead of z.ZodType<string, z.ZodTypeDef, string>
1320+
* so you can use methods of z.ZodString like .min() or .email()
1321+
*/
1322+
1323+
type ZodFromValidatorBase<V extends GenericValidator> =
1324+
V extends VId<GenericId<infer TableName extends string>>
1325+
? Zid<TableName>
1326+
: V extends VString<any, any>
1327+
? z.ZodString
1328+
: V extends VFloat64<any, any>
1329+
? z.ZodNumber
1330+
: V extends VInt64<any, any>
1331+
? z.ZodBigInt
1332+
: V extends VBoolean<any, any>
1333+
? z.ZodBoolean
1334+
: V extends VNull<any, any>
1335+
? z.ZodNull
1336+
: V extends VLiteral<any, any>
1337+
? z.ZodLiteral<V["value"]>
1338+
: V extends VObject<any, any, any, any>
1339+
? z.ZodObject<{
1340+
[K in keyof V["fields"]]: ZodValidatorFromConvex<
1341+
V["fields"][K]
1342+
>;
1343+
}>
1344+
: V extends VRecord<any, infer Key, any, any, any>
1345+
? Key extends VId<GenericId<infer TableName>>
1346+
? z.ZodRecord<
1347+
Zid<TableName>,
1348+
ZodValidatorFromConvex<V["value"]>
1349+
>
1350+
: z.ZodRecord<
1351+
z.ZodString,
1352+
ZodValidatorFromConvex<V["value"]>
1353+
>
1354+
: V extends VArray<any, any>
1355+
? z.ZodArray<ZodValidatorFromConvex<V["element"]>>
1356+
: V extends VUnion<any, any, any, any>
1357+
? z.ZodUnion<
1358+
[ZodValidatorFromConvex<V["members"][number]>]
1359+
>
1360+
: z.ZodTypeAny; // fallback for unknown validators
1361+
1362+
/** Main type with optional handling. */
1363+
export type ZodValidatorFromConvex<V extends GenericValidator> =
1364+
V extends Validator<any, "optional", any>
1365+
? z.ZodOptional<ZodFromValidatorBase<V>>
1366+
: ZodFromValidatorBase<V>;
1367+
13171368
/**
13181369
* Turn a Convex validator into a Zod validator.
13191370
* @param convexValidator Convex validator can be any validator from "convex/values" e.g. `v.string()`
13201371
* @returns Zod validator (e.g. `z.string()`) with inferred type matching the Convex validator
13211372
*/
13221373
export function convexToZod<V extends GenericValidator>(
13231374
convexValidator: V,
1324-
): z.ZodType<Infer<V>> {
1375+
): ZodValidatorFromConvex<V> {
13251376
const isOptional = (convexValidator as any).isOptional === "optional";
13261377

13271378
let zodValidator: z.ZodTypeAny;
@@ -1393,7 +1444,9 @@ export function convexToZod<V extends GenericValidator>(
13931444
throw new Error(`Unknown convex validator type: ${convexValidator.kind}`);
13941445
}
13951446

1396-
return isOptional ? z.optional(zodValidator) : zodValidator;
1447+
return isOptional
1448+
? (z.optional(zodValidator) as ZodValidatorFromConvex<V>)
1449+
: (zodValidator as ZodValidatorFromConvex<V>);
13971450
}
13981451

13991452
/**
@@ -1408,5 +1461,5 @@ export function convexToZodFields<C extends PropertyValidators>(
14081461
) {
14091462
return Object.fromEntries(
14101463
Object.entries(convexValidators).map(([k, v]) => [k, convexToZod(v)]),
1411-
) as { [k in keyof C]: z.ZodType<Infer<C[k]>> };
1464+
) as { [k in keyof C]: ZodValidatorFromConvex<C[k]> };
14121465
}

0 commit comments

Comments
 (0)