import { ImplStatic, trait } from "@thilawyn/traitify-ts" import { Class, HasRequiredKeys } from "type-fest" import { z } from "zod" import { parseZodSchemaEffect } from "../util" type CreateArgs = ( HasRequiredKeys extends true ? [values: Input, params?: Partial] : [] | [values: Input, params?: Partial] ) 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 schemaWithDefaultValues = schemaWithDefaultValues static transform< 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 & ImplStatic ), ...[values, params]: CreateArgs ) { return this .transform(this.schemaWithDefaultValues) .parse(values, params) } static createPromise< Instance extends Values >( this: ( Class & ImplStatic ), ...[values, params]: CreateArgs ) { return this .transform(this.schemaWithDefaultValues) .parseAsync(values, params) } static createEffect< Instance extends Values >( this: ( Class & ImplStatic ), ...[values, params]: CreateArgs ) { return parseZodSchemaEffect( this.transform(this.schemaWithDefaultValues), 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 > > )