import { Effect, pipe } from "effect" import { HasRequiredKeys } from "type-fest" import { z } from "zod" import { SchemableClass, SchemableConfig } from "." import { parseZodTypeEffect } from "./util" type ParamsArgs = [] | [Partial] type NewSchemableArgs = HasRequiredKeys extends true ? [Input, ...ParamsArgs] : [] | [Input, ...ParamsArgs] /** * Creates a new instance of a SchemableClass with default values. * * @param class_ - The SchemableClass. * @param values - The values to be parsed and used to create the instance. * @param params - Optional parameters for parsing. * @returns A new instance of the specified SchemableClass. */ export const newSchemable = < C extends SchemableClass<$Config>, $Config extends SchemableConfig, >( class_: C | SchemableClass<$Config>, ...[values, params]: NewSchemableArgs<$Config["input"]> ) => new class_(class_.schemaWithDefaultValues.parse(values || {}, params)) as InstanceType /** * Creates a new instance of a SchemableClass with default values asynchronously. * * @param class_ - The SchemableClass. * @param values - The values to be parsed and used to create the instance. * @param params - Optional parameters for parsing. * @returns A Promise resolving to a new instance of the specified SchemableClass. */ export const newSchemablePromise = async < C extends SchemableClass<$Config>, $Config extends SchemableConfig, >( class_: C | SchemableClass<$Config>, ...[values, params]: NewSchemableArgs<$Config["input"]> ) => new class_(await class_.schemaWithDefaultValues.parseAsync(values || {}, params)) as InstanceType /** * Creates a new instance of a SchemableClass with default values as an Effect. * * @param class_ - The SchemableClass. * @param values - The values to be parsed and used to create the instance. * @param params - Optional parameters for parsing. * @returns An Effect producing a new instance of the specified SchemableClass. */ export const newSchemableEffect = < C extends SchemableClass<$Config>, $Config extends SchemableConfig, >( class_: C | SchemableClass<$Config>, ...[values, params]: NewSchemableArgs<$Config["input"]> ) => pipe( parseZodTypeEffect< z.output, z.input >( class_.schemaWithDefaultValues, values || {}, params, ), Effect.map(values => new class_(values) as InstanceType), )