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: ( schema: z.ZodObject ) => z.ZodObject, ) => trait .implement(Super => class ZodSchemaObject extends Super { static readonly schema = schema static readonly schemaWithDefaultsValues = schemaWithDefaultValues(schema) static instantiationSchema< Self extends StaticMembers>, Instance extends Values, >( this: Class & Self ) { return this.schema.transform(values => new this(values)) } static instantiationSchemaWithDefaultValues< Self extends StaticMembers>, Instance extends Values, >( this: Class & Self ) { return this.schemaWithDefaultsValues.transform(values => new this(values)) } static create< Self extends StaticMembers>, Instance extends Values, >( this: Class & Self, ...[values, params]: NewZodSchemaInstanceArgs ) { return this.instantiationSchemaWithDefaultValues().parse(values, params) } static createPromise< Self extends StaticMembers>, Instance extends Values, >( this: Class & Self, ...[values, params]: NewZodSchemaInstanceArgs ) { return this.instantiationSchemaWithDefaultValues().parseAsync(values, params) } static createEffect< Self extends StaticMembers>, Instance extends Values, >( this: Class & Self, ...[values, params]: NewZodSchemaInstanceArgs ) { return parseZodSchemaEffect(this.instantiationSchemaWithDefaultValues(), 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 > > )