Created
July 6, 2025 16:09
-
-
Save JWPapi/8c083af942a017780721016cf74f4471 to your computer and use it in GitHub Desktop.
transform schema to be client conform nextjs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
z, | |
ZodType, | |
ZodObject, | |
ZodArray, | |
ZodOptional, | |
ZodNullable, | |
ZodDate, | |
ZodCustom, | |
ZodPipe, | |
ZodTransform | |
} from 'zod/v4' | |
import { ObjectId } from 'mongodb' | |
export type ToClientZodType<T extends ZodType> = T extends ZodDate | |
? ZodPipe<ZodDate, ZodTransform<string, Date>> | |
: T extends ZodCustom<ObjectId, ObjectId> | |
? ZodPipe<ZodCustom<ObjectId, ObjectId>, ZodTransform<string, ObjectId>> | |
: T extends ZodOptional<infer Inner> | |
? ZodOptional<ToClientZodType<Inner extends ZodType ? Inner : never>> | |
: T extends ZodNullable<infer Inner> | |
? ZodNullable<ToClientZodType<Inner extends ZodType ? Inner : never>> | |
: T extends ZodArray<infer Element> | |
? ZodArray<ToClientZodType<Element extends ZodType ? Element : never>> | |
: T extends ZodObject<infer Shape> | |
? ZodObject<{ [K in keyof Shape]: Shape[K] extends ZodType ? ToClientZodType<Shape[K]> : Shape[K] }> | |
: T | |
export function toClientSchema<T extends ZodType>(schema: T): ToClientZodType<T> { | |
// Base case: Handle Date transformation | |
if (schema instanceof ZodDate) { | |
const zodDate = schema as ZodDate | |
return zodDate.transform(date => date.toISOString()) as unknown as ToClientZodType<T> | |
} | |
// Base case: Handle ObjectId transformation by checking metadata | |
if (schema instanceof ZodCustom && schema.meta()?.bsonType === 'objectId') { | |
const zodCustom = schema as ZodCustom<ObjectId, ObjectId> | |
return zodCustom.transform(id => id.toString()) as unknown as ToClientZodType<T> | |
} | |
// --- Recursive cases for unwrapping and re-wrapping schemas --- | |
if (schema instanceof ZodOptional) { | |
const zodOptional = schema as unknown as ZodOptional<any> | |
return toClientSchema(zodOptional.unwrap()).optional() as unknown as ToClientZodType<T> | |
} | |
if (schema instanceof ZodNullable) { | |
const zodNullable = schema as unknown as ZodNullable<T> | |
return toClientSchema(zodNullable.unwrap()).nullable() as unknown as ToClientZodType<T> | |
} | |
if (schema instanceof ZodArray) { | |
const zodArray = schema as ZodArray<any> | |
return z.array(toClientSchema(zodArray.element)) as unknown as ToClientZodType<T> | |
} | |
if (schema instanceof ZodObject) { | |
const newShape: { [k: string]: ZodType } = {} | |
for (const key in schema.shape) { | |
newShape[key] = toClientSchema(schema.shape[key]) | |
} | |
return z.object(newShape) as unknown as ToClientZodType<T> | |
} | |
// Return the original schema if no transformation is needed | |
return schema as unknown as ToClientZodType<T> | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment