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
>
>
)