From c672e1f2bb8cf3c7aefee220c2ffe8ea7f6d2df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 17 Mar 2024 15:27:05 +0100 Subject: [PATCH] JsonifiedZodSchemaObject --- src/tests.ts | 20 ++++++++++++- src/traits/JsonifiedZodSchemaObject.ts | 40 ++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/traits/JsonifiedZodSchemaObject.ts diff --git a/src/tests.ts b/src/tests.ts index ed5f0b6..de3601a 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,6 +1,8 @@ -import { Implements } from "@thilawyn/traitify-ts" +import { Implements, expression } from "@thilawyn/traitify-ts" import { z } from "zod" import { ZodSchemaClass } from "./ZodSchemaClass" +import { dejsonify, jsonify } from "./schema/jsonifiable" +import { JsonifiedZodSchemaObject } from "./traits/JsonifiedZodSchemaObject" import { MobXObservableZodSchemaObject } from "./traits/MobXObservableZodSchemaObject" @@ -27,6 +29,22 @@ const inst = User.create({ id: 1n, name: "User" }) const instEffect = User.createEffect({ id: 1n, name: "User" }) +const jsonifiedUserExp = expression.expresses( + JsonifiedZodSchemaObject(User, { + jsonifySchema: s => s.extend({ + id: jsonify.bigint(s.shape.id) + }), + + dejsonifySchema: s => s.extend({ + id: dejsonify.bigint(s.shape.id) + }), + }) +).build() + +@jsonifiedUserExp.staticImplements +class JsonifiedUser extends jsonifiedUserExp.extends implements Implements {} + + const adminUserExp = User.extend(s => s.extend({ role: z.literal("Admin").default("Admin") })).build() diff --git a/src/traits/JsonifiedZodSchemaObject.ts b/src/traits/JsonifiedZodSchemaObject.ts new file mode 100644 index 0000000..2e6c93c --- /dev/null +++ b/src/traits/JsonifiedZodSchemaObject.ts @@ -0,0 +1,40 @@ +import { TraitClass, expression } from "@thilawyn/traitify-ts" +import { Jsonifiable } from "type-fest" +import { z } from "zod" +import { ZodSchemaObject, ZodSchemaObjectTrait } from "./ZodSchemaObject" + + +export const JsonifiedZodSchemaObject = < + Of extends TraitClass>, + T extends z.ZodRawShape, + Catchall extends z.ZodTypeAny, + Values extends object, + PartialValues extends Partial, + + JsonifyT extends z.ZodRawShape, + JsonifyCatchall extends z.ZodTypeAny, + DejsonifyT extends z.ZodRawShape, + DejsonifyCatchall extends z.ZodTypeAny, + JsonifiedValues extends Jsonifiable, +>( + of: Of | TraitClass>, + + props: { + jsonifySchema: ( + schema: typeof of.schema + ) => z.ZodObject, + + dejsonifySchema: ( + schema: typeof of.schema + ) => z.ZodObject, + }, +) => expression + .expresses(ZodSchemaObject(of.schemaWithDefaults)) + .build() + .subtrait() + .implement(Super => class JsonifiedZodSchemaObjectImpl extends Super { + static readonly of = of as Of + static readonly jsonifySchema = props.jsonifySchema(of.schema) + static readonly dejsonifySchema = props.dejsonifySchema(of.schema) + }) + .build()