From de6a97e0a6861c2910e98e107e8b2d331726a9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 2 Jan 2024 01:50:44 +0100 Subject: [PATCH] makeJsonifiableSchemableClass --- rollup.config.js | 10 ++- src/jsonifiable/JsonifiableSchemableClass.ts | 61 +++++++++++++++++++ src/jsonifiable/index.ts | 1 + .../makeJsonifiableSchemableClass.ts | 49 ++++++++++----- src/makeSchemableClass.ts | 8 +-- src/tests.ts | 17 +++--- 6 files changed, 119 insertions(+), 27 deletions(-) create mode 100644 src/jsonifiable/JsonifiableSchemableClass.ts diff --git a/rollup.config.js b/rollup.config.js index da6b231..aa4dbe2 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -12,11 +12,19 @@ export default defineConfig({ file: pkg.exports["."].import.default, format: "esm", }, - { file: pkg.exports["."].require.default, format: "cjs", }, + + { + file: pkg.exports["./jsonifiable"].import.default, + format: "esm", + }, + { + file: pkg.exports["./jsonifiable"].require.default, + format: "cjs", + }, ], plugins: [ diff --git a/src/jsonifiable/JsonifiableSchemableClass.ts b/src/jsonifiable/JsonifiableSchemableClass.ts new file mode 100644 index 0000000..41298f7 --- /dev/null +++ b/src/jsonifiable/JsonifiableSchemableClass.ts @@ -0,0 +1,61 @@ +import { Class } from "type-fest" +import { JsonifiableObject } from "type-fest/source/jsonifiable" +import { z } from "zod" +import { SchemableClassConstructorParams, SchemableConfig } from ".." + + +export type JsonifiableSchemableConfig< + $SchemableConfig extends SchemableConfig = SchemableConfig, + + JsonifiedValues extends JsonifiableObject = {}, + + JsonifySchemaT extends z.ZodRawShape = z.ZodRawShape, + JsonifySchemaUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam, + JsonifySchemaCatchall extends z.ZodTypeAny = z.ZodTypeAny, + + DejsonifySchemaT extends z.ZodRawShape = z.ZodRawShape, + DejsonifySchemaUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam, + DejsonifySchemaCatchall extends z.ZodTypeAny = z.ZodTypeAny, +> = { + readonly $schemableConfig: $SchemableConfig + + readonly jsonifiedValues: JsonifiedValues + + readonly jsonifySchema: z.ZodObject< + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + JsonifiedValues, + $SchemableConfig["values"] + > + + readonly dejsonifySchema: z.ZodObject< + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + $SchemableConfig["values"], + JsonifiedValues + > +} + + +export type JsonifiableSchemableClass< + $Config extends JsonifiableSchemableConfig +> = ( + Class< + JsonifiableSchemableObject<$Config>, + SchemableClassConstructorParams<$Config["$schemableConfig"]> + > & { + readonly $jsonifiableSchemableConfig: $Config + readonly jsonifySchema: $Config["jsonifySchema"] + readonly dejsonifySchema: $Config["dejsonifySchema"] + } +) + +export type JsonifiableSchemableObject< + $Config extends JsonifiableSchemableConfig +> = { + readonly $jsonifiableSchemableConfig: $Config + readonly jsonifySchema: $Config["jsonifySchema"] + readonly dejsonifySchema: $Config["dejsonifySchema"] +} diff --git a/src/jsonifiable/index.ts b/src/jsonifiable/index.ts index ae3e8e2..831c7de 100644 --- a/src/jsonifiable/index.ts +++ b/src/jsonifiable/index.ts @@ -1,2 +1,3 @@ +export * from "./JsonifiableSchemableClass" export * from "./makeJsonifiableSchemableClass" export * from "./schema" diff --git a/src/jsonifiable/makeJsonifiableSchemableClass.ts b/src/jsonifiable/makeJsonifiableSchemableClass.ts index 99d0029..332299e 100644 --- a/src/jsonifiable/makeJsonifiableSchemableClass.ts +++ b/src/jsonifiable/makeJsonifiableSchemableClass.ts @@ -1,12 +1,14 @@ +import { Class } from "type-fest" import { JsonifiableObject } from "type-fest/source/jsonifiable" import { z } from "zod" +import { JsonifiableSchemableConfig } from "." import { SchemableClass, SchemableConfig } from ".." -import { parseZodTypeEffect } from "../util" +import { StaticMembers, parseZodTypeEffect } from "../util" export function makeJsonifiableSchemableClass< - C extends SchemableClass<$Config>, - $Config extends SchemableConfig, + C extends SchemableClass<$SchemableConfig>, + $SchemableConfig extends SchemableConfig, JsonifiedValues extends JsonifiableObject, @@ -18,28 +20,28 @@ export function makeJsonifiableSchemableClass< DejsonifySchemaUnknownKeys extends z.UnknownKeysParam, DejsonifySchemaCatchall extends z.ZodTypeAny, >( - class_: C | SchemableClass<$Config>, + class_: C | SchemableClass<$SchemableConfig>, props: { jsonifySchema: (props: { - schema: $Config["schema"] - s: $Config["schema"]["shape"] + schema: $SchemableConfig["schema"] + s: $SchemableConfig["schema"]["shape"] }) => z.ZodObject< JsonifySchemaT, JsonifySchemaUnknownKeys, JsonifySchemaCatchall, JsonifiedValues, - $Config["values"] + $SchemableConfig["values"] > dejsonifySchema: (props: { - schema: $Config["schema"] - s: $Config["schema"]["shape"] + schema: $SchemableConfig["schema"] + s: $SchemableConfig["schema"]["shape"] }) => z.ZodObject< DejsonifySchemaT, DejsonifySchemaUnknownKeys, DejsonifySchemaCatchall, - $Config["values"], + $SchemableConfig["values"], JsonifiedValues > }, @@ -55,13 +57,21 @@ export function makeJsonifiableSchemableClass< s: class_.schema.shape, }) + const $jsonifiableSchemableConfig = { + $schemableConfig: class_.$schemableConfig, + jsonifiedValues: undefined as unknown as JsonifiedValues, + jsonifySchema: undefined as unknown as typeof jsonifySchema, + dejsonifySchema: undefined as unknown as typeof dejsonifySchema, + } as const satisfies JsonifiableSchemableConfig - return class JsonifiableSchemableObject extends class_ { - static readonly jsonifySchema = jsonifySchema - static readonly dejsonifySchema = dejsonifySchema + const jsonifiableClass = class JsonifiableSchemableObject extends class_ { + static readonly $jsonifiableSchemableConfig = $jsonifiableSchemableConfig + static readonly jsonifySchema = jsonifySchema + static readonly dejsonifySchema = dejsonifySchema - readonly jsonifySchema = jsonifySchema - readonly dejsonifySchema = dejsonifySchema + readonly $jsonifiableSchemableConfig = $jsonifiableSchemableConfig + readonly jsonifySchema = jsonifySchema + readonly dejsonifySchema = dejsonifySchema jsonify() { return this.jsonifySchema.parse(this) @@ -76,4 +86,13 @@ export function makeJsonifiableSchemableClass< } } + return jsonifiableClass as ( + Class< + InstanceType & InstanceType, + ConstructorParameters + > & + StaticMembers & + StaticMembers + ) + } diff --git a/src/makeSchemableClass.ts b/src/makeSchemableClass.ts index d7c35dc..88bcf72 100644 --- a/src/makeSchemableClass.ts +++ b/src/makeSchemableClass.ts @@ -26,10 +26,10 @@ export function makeSchemableClass< const schema = zodObjectRemoveDefaults(schemaWithDefaultValues) const $schemableConfig = { - values: {} as z.output, - input: {} as z.input, - schema, - schemaWithDefaultValues, + values: undefined as unknown as z.output, + input: undefined as unknown as z.input, + schema: undefined as unknown as typeof schema, + schemaWithDefaultValues: undefined as unknown as typeof schemaWithDefaultValues, } as const satisfies SchemableConfig return class SchemableObject { diff --git a/src/tests.ts b/src/tests.ts index ca96997..b20c473 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,5 +1,6 @@ import { z } from "zod" import { makeSchemableClass, newSchemable } from "." +import { dejsonifyBigIntSchema, jsonifyBigIntSchema, makeJsonifiableSchemableClass } from "./jsonifiable" const UserSchema = z.object({ @@ -10,15 +11,17 @@ const UserSchema = z.object({ const UserSchemableObject = makeSchemableClass({ schema: UserSchema }) -// const UserJsonifiableSchemableObject = makeJsonifiableSchemableClass(UserSchemableObject, { -// jsonifySchema: ({ schema, s }) => schema.extend({ -// }), +const UserJsonifiableSchemableObject = makeJsonifiableSchemableClass(UserSchemableObject, { + jsonifySchema: ({ schema, s }) => schema.extend({ + id: jsonifyBigIntSchema(s.id) + }), -// dejsonifySchema: ({ schema, s }) => schema.extend({ -// }), -// }) + dejsonifySchema: ({ schema, s }) => schema.extend({ + id: dejsonifyBigIntSchema(s.id) + }), +}) -class User extends UserSchemableObject {} +class User extends UserJsonifiableSchemableObject {} const user1 = new User({ id: 1n }) const user2 = newSchemable(User, { id: 2n })