import { Effect, pipe } from "effect" import { HasRequiredKeys } from "type-fest" import { z } from "zod" import { SchemableClass, SchemableClassInput } from "." import { parseZodTypeEffect } from "./util" type ParamsArgs = [] | [Partial] type NewSchemableArgs = HasRequiredKeys extends true ? [Input, ...ParamsArgs] : [] | [Input, ...ParamsArgs] export const newSchemable = < C extends SchemableClass< SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, DefaultValues, "Class" >, SchemaT extends z.ZodRawShape, SchemaUnknownKeys extends z.UnknownKeysParam, SchemaCatchall extends z.ZodTypeAny, Values extends {}, DefaultValues extends Partial, >( class_: C | SchemableClass< SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, DefaultValues, "Class" >, ...[values, params]: NewSchemableArgs< SchemableClassInput > ) => new class_( class_.schema.parse({ ...class_.defaultValues, ...values }, params) ) as InstanceType export const newSchemablePromise = async < C extends SchemableClass< SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, DefaultValues, "Class" >, SchemaT extends z.ZodRawShape, SchemaUnknownKeys extends z.UnknownKeysParam, SchemaCatchall extends z.ZodTypeAny, Values extends {}, DefaultValues extends Partial, >( class_: C | SchemableClass< SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, DefaultValues, "Class" >, ...[values, params]: NewSchemableArgs< SchemableClassInput > ) => new class_( await class_.schema.parseAsync({ ...class_.defaultValues, ...values }, params) ) as InstanceType export const newSchemableEffect = < C extends SchemableClass< SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, DefaultValues, "Class" >, SchemaT extends z.ZodRawShape, SchemaUnknownKeys extends z.UnknownKeysParam, SchemaCatchall extends z.ZodTypeAny, Values extends {}, DefaultValues extends Partial, >( class_: C | SchemableClass< SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, DefaultValues, "Class" >, ...[values, params]: NewSchemableArgs< SchemableClassInput > ) => pipe( parseZodTypeEffect( class_.schema, { ...class_.defaultValues, ...values }, params, ), Effect.map(values => new class_(values) as InstanceType), )