From c073154eebb46adba431a3ff662404a06d4521b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 21 Jan 2024 22:58:44 +0100 Subject: [PATCH] Working new implementation --- src/TZodSchemaClass.ts | 64 +++++++++++++++++++ src/ZodSchemaClass.ts | 136 ++++++----------------------------------- src/index.ts | 1 + src/tests.ts | 23 +++---- 4 files changed, 93 insertions(+), 131 deletions(-) create mode 100644 src/TZodSchemaClass.ts diff --git a/src/TZodSchemaClass.ts b/src/TZodSchemaClass.ts new file mode 100644 index 0000000..7762a7e --- /dev/null +++ b/src/TZodSchemaClass.ts @@ -0,0 +1,64 @@ +import { Class as ConcreteClass, HasRequiredKeys } from "type-fest" +import { z } from "zod" +import { Class, ClassType } from "./util" + + +export type NewZodSchemaInstanceInput< + Values extends {}, + DefaultValues extends Partial, +> = { + [Key in Exclude]: Values[Key] +} & { + [Key in keyof DefaultValues]?: Key extends keyof Values + ? Values[Key] + : never +} + +export type ParseParamsArgs = [] | [params: Partial] + +export type NewZodSchemaInstanceArgs = + HasRequiredKeys extends true + ? [values: Input, ...args: ParseParamsArgs] + : [] | [values: Input, ...args: ParseParamsArgs] + + +export type TZodSchemaClass< + Schema extends z.ZodObject, + SchemaT extends z.ZodRawShape, + SchemaUnknownKeys extends z.UnknownKeysParam, + SchemaCatchall extends z.ZodTypeAny, + + Values extends {}, + DefaultValues extends Partial, + + Type extends ClassType = "AbstractClass" +> = ( + Class< + Type, + Values, + [values: Values] + > & { + readonly schema: Schema + readonly defaultValues: DefaultValues + + newPromise>( + this: Self, + ...[values, params]: NewZodSchemaInstanceArgs< + NewZodSchemaInstanceInput + > + ): Promise> + + newEffect>( + this: Self, + ...[values, params]: NewZodSchemaInstanceArgs< + NewZodSchemaInstanceInput + > + ): Promise> + + extend< + Parent + >( + this: Parent + ): Parent + } +) diff --git a/src/ZodSchemaClass.ts b/src/ZodSchemaClass.ts index 4dc580d..31513db 100644 --- a/src/ZodSchemaClass.ts +++ b/src/ZodSchemaClass.ts @@ -1,40 +1,9 @@ import { AbstractClass, Class as ConcreteClass, Opaque } from "type-fest" import { z } from "zod" -import { DefinedDefaultValuesTag } from "." +import { DefinedDefaultValuesTag, NewZodSchemaInstanceArgs, NewZodSchemaInstanceInput, TZodSchemaClass } from "." import { StaticMembers } from "./util" -export type TZodSchemaClass< - Schema extends z.ZodObject, - SchemaT extends z.ZodRawShape, - SchemaUnknownKeys extends z.UnknownKeysParam, - SchemaCatchall extends z.ZodTypeAny, - - Values extends {}, - DefaultValues extends Partial, -> = ( - AbstractClass< - { - readonly schema: Schema - readonly defaultValues: DefaultValues - } & Values, - - [values: Values] - > & { - readonly schema: Schema - readonly defaultValues: DefaultValues - - newPromise>(this: Self): Promise> - - extend< - Parent - >( - this: Parent - ): Parent - } -) - - type ExtendableClass = AbstractClass<{ schema?: never defaultValues?: never @@ -43,8 +12,7 @@ type ExtendableClass = AbstractClass<{ defaultValues?: never } -function makeClass< - Self, +export function ZodSchemaClassOf< Parent extends ExtendableClass, Schema extends z.ZodObject, @@ -55,9 +23,9 @@ function makeClass< Values extends {}, DefaultValues extends Partial, >( - { of, schema, defaultValues }: { - self: Self, - of: Parent, + of: Parent, + + { schema, defaultValues }: { schema: Schema | z.ZodObject defaultValues: Opaque }, @@ -68,7 +36,7 @@ function makeClass< : AbstractClass ) - type ZodClass = TZodSchemaClass< + type TZodSchemaClassImpl = TZodSchemaClass< Schema, SchemaT, SchemaUnknownKeys, @@ -80,97 +48,31 @@ function makeClass< return class extends (of as unknown as ConcreteClass) { static readonly schema = schema - readonly schema = schema - static readonly defaultValues = defaultValues - readonly defaultValues = defaultValues constructor(values: Values) { super() Object.assign(this, values) } + + static async newPromise( + ...[values, params]: NewZodSchemaInstanceArgs< + NewZodSchemaInstanceInput + > + ) { + return new this( + await this.schema.parseAsync({ ...this.defaultValues, ...values }, params) + ) + } } as unknown as ( Class< InstanceType & - InstanceType, + InstanceType, - ConstructorParameters + ConstructorParameters > & StaticMembers & - StaticMembers + StaticMembers ) } - - -export function ZodSchemaClassOf() { - return < - Parent extends ExtendableClass, - - Schema extends z.ZodObject, - SchemaT extends z.ZodRawShape, - SchemaUnknownKeys extends z.UnknownKeysParam, - SchemaCatchall extends z.ZodTypeAny, - - Values extends {}, - DefaultValues extends Partial, - >( - of: Parent, - props: Omit< - Parameters< - typeof makeClass< - Self, - Parent, - - Schema, - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - - Values, - DefaultValues - > - >[0], "self" | "of" - >, - ) => makeClass({ - ...props, - self: {} as Self, - of, - }) -} - - -const DefaultParent = Object - -export function ZodSchemaClass() { - return < - Schema extends z.ZodObject, - SchemaT extends z.ZodRawShape, - SchemaUnknownKeys extends z.UnknownKeysParam, - SchemaCatchall extends z.ZodTypeAny, - - Values extends {}, - DefaultValues extends Partial, - >( - props: Omit< - Parameters< - typeof makeClass< - Self, - typeof DefaultParent, - - Schema, - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - - Values, - DefaultValues - > - >[0], "self" | "of" - >, - ) => makeClass({ - ...props, - self: {} as Self, - of: DefaultParent, - }) -} diff --git a/src/index.ts b/src/index.ts index 8302d95..8c02ebc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,3 @@ +export * from "./TZodSchemaClass" export * from "./ZodSchemaClass" export * from "./defineDefaultValues" diff --git a/src/tests.ts b/src/tests.ts index 39bfb8f..c314056 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -2,25 +2,20 @@ import { z } from "zod" import { ZodSchemaClassOf, defineDefaultValues } from "." -class Test extends ZodSchemaClassOf()(Object, { +class Test extends ZodSchemaClassOf(Object, { schema: z.object({ - id: z.bigint() + id: z.bigint(), + name: z.string(), }), defaultValues: defineDefaultValues({ id: -1n }), }) {} -Test.newPromise() -Test.extend() +Test.defaultValues +const inst = await Test.newPromise({ id: 1n, name: "" }) +// Test.extend() -new Test({ id: 1n }).id +console.log(inst) +// class ChildTest extends Test {} -const Test2 = ZodSchemaClassOf()(Object, { - schema: z.object({ - id: z.bigint() - }), - - defaultValues: defineDefaultValues({ id: -1n }), -}) - -Test2.extend() +// ChildTest.newPromise()