diff --git a/src/builders/ZodSchemaClassBuilder.ts b/src/builders/ZodSchemaClassBuilder.ts index ddadfde..5c09c25 100644 --- a/src/builders/ZodSchemaClassBuilder.ts +++ b/src/builders/ZodSchemaClassBuilder.ts @@ -12,10 +12,12 @@ import { StaticMembers } from "../util" export class ZodSchemaClassBuilder< Superclass extends AbstractClass, const Traits extends readonly Trait[], -> -extends TraitExpressionBuilder { +> { declare ["constructor"]: typeof ZodSchemaClassBuilder + constructor(readonly expression: TraitExpressionBuilder) {} + + schema< Super extends AbstractClass & { schema?: never, schemaWithDefaultValues?: never }, @@ -40,7 +42,7 @@ extends TraitExpressionBuilder { ) => z.ZodObject }, ) { - class ZodSchemaObjectConstructor extends (this.expressionSuperclass as AbstractClass) { + class ZodSchemaObjectConstructor extends (this.expression.expressionSuperclass as AbstractClass) { constructor(values: Values) { super() Object.assign(this, values) @@ -48,15 +50,17 @@ extends TraitExpressionBuilder { } return new this.constructor( - ZodSchemaObjectConstructor as unknown as ( - AbstractClass< - InstanceType & Values, - [values: Values] - > & - StaticMembers - ), - - [...this.expressionTraits, ZodSchemaObject(schema, schemaWithDefaultValues(schema))], + this.expression + .extends( + ZodSchemaObjectConstructor as unknown as ( + AbstractClass< + InstanceType & Values, + [values: Values] + > & + StaticMembers + ) + ) + .expresses(ZodSchemaObject(schema, schemaWithDefaultValues(schema))) ) } @@ -101,10 +105,10 @@ extends TraitExpressionBuilder { ) => z.ZodObject }, ) { - const jsonifySchema = props.jsonifySchema(this.expressionSuperclass.schema) - const dejsonifySchema = props.dejsonifySchema(this.expressionSuperclass.schema) + const jsonifySchema = props.jsonifySchema(this.expression.expressionSuperclass.schema) + const dejsonifySchema = props.dejsonifySchema(this.expression.expressionSuperclass.schema) - class JsonifiableSchemas extends (this.expressionSuperclass as AbstractClass) { + class JsonifiableSchemas extends (this.expression.expressionSuperclass as AbstractClass) { static readonly jsonifySchema = jsonifySchema readonly jsonifySchema = jsonifySchema static readonly dejsonifySchema = dejsonifySchema @@ -132,52 +136,5 @@ extends TraitExpressionBuilder { } } -export interface ZodSchemaClassBuilder< - Superclass extends AbstractClass, - Traits extends readonly Trait[], -> { - extends< - Super extends AbstractClass - >( - // \/ Ensures `extends` can only be called once at the beginning - this: ZodSchemaClassBuilder, - superclass: Super, - ): ZodSchemaClassBuilder - - expresses< - const T extends readonly Trait< - TraitExpression< - typeof TraitExpression.NullSuperclass, - readonly Trait[] - >, - any, - any, - any - >[] - >( - ...traits: T - ): ZodSchemaClassBuilder< - Superclass, - TraitExpressionBuilder.ExpressesReturnTypeTraits - > - - expressesFirst< - const T extends readonly Trait< - TraitExpression< - typeof TraitExpression.NullSuperclass, - readonly Trait[] - >, - any, - any, - any - >[] - >( - ...traits: T - ): ZodSchemaClassBuilder< - Superclass, - TraitExpressionBuilder.ExpressesFirstReturnTypeTraits - > -} - export const zodSchemaClass = new ZodSchemaClassBuilder(TraitExpression.NullSuperclass, []) diff --git a/src/tests.ts b/src/tests.ts index fa638e9..2c15f27 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -18,6 +18,7 @@ const exp = zodSchemaClass id: s.shape.id.default(-1n), }), }) + .expression .expresses(MobXObservableZodSchemaObject) .build() diff --git a/src/traits/JsonifiableZodSchemaObject.ts b/src/traits/JsonifiableZodSchemaObject.ts index b9b4a15..d4e915e 100644 --- a/src/traits/JsonifiableZodSchemaObject.ts +++ b/src/traits/JsonifiableZodSchemaObject.ts @@ -1,11 +1,91 @@ -import { trait } from "@thilawyn/traitify-ts" +import { ImplStatic, expression } from "@thilawyn/traitify-ts" +import { Class } from "type-fest" import { JsonifiableObject } from "type-fest/source/jsonifiable" import { z } from "zod" -import { JsonifiableZodSchemas } from "../shapes/JsonifiableZodSchemaClass" -import { parseZodTypeEffect } from "../util" +import { parseZodSchemaEffect } from "../util" +import { ZodSchemaObject } from "./ZodSchemaObject" -export const JsonifiableZodSchemaObject = trait - .implement(Super => class JsonifiableZodSchemaObject extends Super { - }) +export const JsonifiableZodSchemaObject = < + SchemaT extends z.ZodRawShape, + SchemaUnknownKeys extends z.UnknownKeysParam, + SchemaCatchall extends z.ZodTypeAny, + + SchemaWithDefaultValuesT extends z.ZodRawShape, + SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam, + SchemaWithDefaultValuesCatchall extends z.ZodTypeAny, + + Values extends object, + PartialValues extends Partial, + + JsonifySchemaT extends z.ZodRawShape, + JsonifySchemaUnknownKeys extends z.UnknownKeysParam, + JsonifySchemaCatchall extends z.ZodTypeAny, + + DejsonifySchemaT extends z.ZodRawShape, + DejsonifySchemaUnknownKeys extends z.UnknownKeysParam, + DejsonifySchemaCatchall extends z.ZodTypeAny, + + JsonifiedValues extends JsonifiableObject, +>( + schema: z.ZodObject, + schemaWithDefaultValues: z.ZodObject, + jsonifySchema: z.ZodObject, + dejsonifySchema: z.ZodObject, +) => expression + .expresses(ZodSchemaObject(schema, schemaWithDefaultValues)) .build() + .subtrait() + .implement(Super => class JsonifiableZodSchemaObject extends Super { + static readonly jsonifySchema = jsonifySchema + static readonly dejsonifySchema = dejsonifySchema + + + static dejsonify< + Instance extends Values + >( + this: ( + Class & + ImplStatic + ), + values: JsonifiedValues, + params?: Partial, + ) { + return this + .transform(this.dejsonifySchema) + .parse(values, params) + } + + static dejsonifyPromise< + Instance extends Values + >( + this: ( + Class & + ImplStatic + ), + values: JsonifiedValues, + params?: Partial, + ) { + return this + .transform(this.dejsonifySchema) + .parseAsync(values, params) + } + + static dejsonifyEffect< + Instance extends Values + >( + this: ( + Class & + ImplStatic + ), + values: JsonifiedValues, + params?: Partial, + ) { + return parseZodSchemaEffect( + this.transform(this.dejsonifySchema), + values, + params, + ) + } + }) + .build()