diff --git a/src/traits/ZodSchemaObject.ts b/src/traits/ZodSchemaObject.ts new file mode 100644 index 0000000..20d5fba --- /dev/null +++ b/src/traits/ZodSchemaObject.ts @@ -0,0 +1,73 @@ +import { ImplStaticThis, trait } from "@thilawyn/traitify-ts" +import { Class, HasRequiredKeys } from "type-fest" +import { z } from "zod" +import { StaticMembers } 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< + Instance extends Values + >( + this: ( + Class & + StaticMembers> + ) + ) { + return this.schema.transform(values => new this(values)) + } + + static instantiationSchemaWithDefaultValues< + Instance extends Values + >( + this: ( + Class & + StaticMembers> + ) + ) { + return this.schema.transform(values => new this(values)) + } + + + static create< + Instance extends Values + >( + this: ( + Class & + StaticMembers> + ), + ...[values, params]: NewZodSchemaInstanceArgs + ) { + return this.instantiationSchema().parse(values, params) + } + }) + .build()