import { Trait, TraitExpressionBuilder } from "@thilawyn/traitify-ts" import { AbstractClass, Simplify } from "type-fest" import { JsonifiableObject } from "type-fest/source/jsonifiable" import { z } from "zod" import { ZodSchemaAbstractClass } from "./shapes/ZodSchemaClass" import { DejsonifiableZodSchemaObject } from "./traits/DejsonifiableZodSchemaObject" import { ExtendableZodSchemaObject } from "./traits/ExtendableZodSchemaObject" import { InstantiableZodSchemaObject } from "./traits/InstantiableZodSchemaObject" import { JsonifiableZodSchemaObject } from "./traits/JsonifiableZodSchemaObject" import { Extend, StaticMembers } from "./util" export class ZodSchemaClassBuilder< Superclass extends AbstractClass, const Traits extends Trait[], > extends TraitExpressionBuilder { // extends< // This extends ZodSchemaClassBuilder< // typeof TraitExpression.NullSuperclass, // Ensures `extends` can only be called when the expression does not have a superclass // Traits // >, // Super extends AbstractClass, // >( // this: This, // superclass: Super, // ) { // return new ZodSchemaClassBuilder( // this.expressionBuilder.extends(superclass) // ) // } schema< Superclass extends AbstractClass & { schema?: never, defaultValues?: never }, SchemaT extends z.ZodRawShape, SchemaUnknownKeys extends z.UnknownKeysParam, SchemaCatchall extends z.ZodTypeAny, Values extends object, DefaultValues extends Partial, >( this: ZodSchemaClassBuilder, { schema, defaultValues }: { schema: z.ZodObject defaultValues: DefaultValues }, ) { class Schemas extends (this.expressionSuperclass as AbstractClass) { static readonly schema = schema static readonly defaultValues = defaultValues constructor(values: Values) { super() Object.assign(this, values) } } return new ZodSchemaClassBuilder( Schemas as unknown as ( AbstractClass< InstanceType & Values, ConstructorParameters > & StaticMembers & StaticMembers ), [ ...this.expressionTraits, InstantiableZodSchemaObject, ExtendableZodSchemaObject, ], ) } jsonifiable< Superclass extends ZodSchemaAbstractClass & { jsonifySchema?: never, dejsonifySchema?: never }, Instance extends Values, SchemaT extends z.ZodRawShape, SchemaUnknownKeys extends z.UnknownKeysParam, SchemaCatchall extends z.ZodTypeAny, Values extends object, DefaultValues extends Partial, JsonifiedValues extends JsonifiableObject, JsonifySchemaT extends z.ZodRawShape, JsonifySchemaUnknownKeys extends z.UnknownKeysParam, JsonifySchemaCatchall extends z.ZodTypeAny, DejsonifySchemaT extends z.ZodRawShape, DejsonifySchemaUnknownKeys extends z.UnknownKeysParam, DejsonifySchemaCatchall extends z.ZodTypeAny, >( this: ZodSchemaClassBuilder< Superclass | ZodSchemaAbstractClass, Traits >, props: { jsonifySchema: (props: { schema: z.ZodObject shape: SchemaT }) => z.ZodObject dejsonifySchema: (props: { schema: z.ZodObject shape: SchemaT }) => z.ZodObject }, ) { const jsonifySchema = props.jsonifySchema({ schema: this.expressionSuperclass.schema, shape: this.expressionSuperclass.schema.shape, }) const dejsonifySchema = props.dejsonifySchema({ schema: this.expressionSuperclass.schema, shape: this.expressionSuperclass.schema.shape, }) class JsonifiableSchemas extends (this.expressionSuperclass as AbstractClass) { static readonly jsonifySchema = jsonifySchema readonly jsonifySchema = jsonifySchema static readonly dejsonifySchema = dejsonifySchema readonly dejsonifySchema = dejsonifySchema } return new ZodSchemaClassBuilder( JsonifiableSchemas as unknown as ( AbstractClass< InstanceType & JsonifiableSchemas, ConstructorParameters > & StaticMembers & StaticMembers ), [ ...this.expressionTraits, JsonifiableZodSchemaObject, DejsonifiableZodSchemaObject, ], ) } }