import { ImplStaticThis, trait } from "@thilawyn/traitify-ts" import { Class, HasRequiredKeys } from "type-fest" import { z } from "zod" import { StaticMembers, parseZodSchemaEffect } from "../util" type ParseParamsArgs = [] | [params: Partial] type NewZodSchemaInstanceArgs = ( HasRequiredKeys extends true ? [values: Input, ...args: ParseParamsArgs] : [] | [values: Input, ...args: ParseParamsArgs] ) export const ZodSchemaObject = < 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, >( schema: z.ZodObject, schemaWithDefaultValues: z.ZodObject, ) => trait .implement(Super => class ZodSchemaObject extends Super { static readonly schema = schema static readonly schemaWithDefaultsValues = schemaWithDefaultValues static instantiationTransform< Instance extends Values, T extends z.ZodRawShape, UnknownKeys extends z.UnknownKeysParam, Catchall extends z.ZodTypeAny, Output extends Values, Input, >( this: Class, schema: z.ZodObject, ) { return schema.transform(values => new this(values)) } static create< Instance extends Values >( this: ( Class & StaticMembers> ), ...[values, params]: NewZodSchemaInstanceArgs ) { return this .instantiationTransform(this.schemaWithDefaultsValues) .parse(values, params) } static createPromise< Instance extends Values >( this: ( Class & StaticMembers> ), ...[values, params]: NewZodSchemaInstanceArgs ) { return this .instantiationTransform(this.schemaWithDefaultsValues) .parseAsync(values, params) } static createEffect< Instance extends Values >( this: ( Class & StaticMembers> ), ...[values, params]: NewZodSchemaInstanceArgs ) { return parseZodSchemaEffect( this.instantiationTransform(this.schemaWithDefaultsValues), values, params, ) } }) .build() export type ZodSchemaObjectTrait< 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, > = ( ReturnType< typeof ZodSchemaObject< SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaWithDefaultValuesT, SchemaWithDefaultValuesUnknownKeys, SchemaWithDefaultValuesCatchall, Values, PartialValues > > )