import { Class } from "type-fest" import { JsonifiableObject } from "type-fest/source/jsonifiable" import { z } from "zod" import { JsonifiableSchemableClass, JsonifiableSchemableConfig, JsonifiableSchemableObject } from "." import { SchemableClass, SchemableConfig } from ".." import { StaticMembers, parseZodTypeEffect } from "../util" export function makeJsonifiableSchemableClass< C extends SchemableClass<$SchemableConfig>, $SchemableConfig extends SchemableConfig, JsonifiedValues extends JsonifiableObject, JsonifySchemaT extends z.ZodRawShape, JsonifySchemaUnknownKeys extends z.UnknownKeysParam, JsonifySchemaCatchall extends z.ZodTypeAny, DejsonifySchemaT extends z.ZodRawShape, DejsonifySchemaUnknownKeys extends z.UnknownKeysParam, DejsonifySchemaCatchall extends z.ZodTypeAny, >( class_: C | SchemableClass<$SchemableConfig>, props: { jsonifySchema: (props: { schema: $SchemableConfig["schema"] s: $SchemableConfig["schema"]["shape"] }) => z.ZodObject< JsonifySchemaT, JsonifySchemaUnknownKeys, JsonifySchemaCatchall, JsonifiedValues, $SchemableConfig["values"] > dejsonifySchema: (props: { schema: $SchemableConfig["schema"] s: $SchemableConfig["schema"]["shape"] }) => z.ZodObject< DejsonifySchemaT, DejsonifySchemaUnknownKeys, DejsonifySchemaCatchall, $SchemableConfig["values"], JsonifiedValues > }, ) { const jsonifySchema = props.jsonifySchema({ schema: class_.schema, s: class_.schema.shape, }) const dejsonifySchema = props.dejsonifySchema({ schema: class_.schema, s: class_.schema.shape, }) const $jsonifiableSchemableConfig = { $schemableConfig: class_.$schemableConfig, jsonifiedValues: undefined as unknown as JsonifiedValues, jsonifySchema: undefined as unknown as typeof jsonifySchema, dejsonifySchema: undefined as unknown as typeof dejsonifySchema, } as const satisfies JsonifiableSchemableConfig const jsonifiableClass = class JsonifiableSchemableObject extends class_ { static readonly $jsonifiableSchemableConfig = $jsonifiableSchemableConfig static readonly jsonifySchema = jsonifySchema static readonly dejsonifySchema = dejsonifySchema readonly $jsonifiableSchemableConfig = $jsonifiableSchemableConfig readonly jsonifySchema = jsonifySchema readonly dejsonifySchema = dejsonifySchema jsonify() { return this.jsonifySchema.parse(this) } jsonifyPromise() { return this.jsonifySchema.parseAsync(this) } jsonifyEffect() { return parseZodTypeEffect(this.jsonifySchema, this) } } satisfies JsonifiableSchemableClass return jsonifiableClass as unknown as ( Class< InstanceType & JsonifiableSchemableObject, ConstructorParameters > & StaticMembers & StaticMembers> ) }