diff --git a/src/jsonifiable/index.ts b/src/jsonifiable/index.ts index 4269365..5d4869f 100644 --- a/src/jsonifiable/index.ts +++ b/src/jsonifiable/index.ts @@ -1,2 +1,3 @@ export * from "./JsonifiableSchemable" export * from "./JsonifiableSchemableClass" +export * from "./makeJsonifiableSchemableClass" diff --git a/src/jsonifiable/makeJsonifiableSchemableClass.ts b/src/jsonifiable/makeJsonifiableSchemableClass.ts new file mode 100644 index 0000000..36f0ad5 --- /dev/null +++ b/src/jsonifiable/makeJsonifiableSchemableClass.ts @@ -0,0 +1,118 @@ +import { Effect } from "effect" +import { JsonifiableObject } from "type-fest/source/jsonifiable" +import { z } from "zod" +import { SchemableClass } from ".." +import { Class, ClassType, StaticMembers, parseZodTypeEffect } from "../util" + + +export function makeJsonifiableSchemableClass< + C extends SchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + Values, + DefaultValues + >, + + SchemaT extends z.ZodRawShape, + SchemaUnknownKeys extends z.UnknownKeysParam, + SchemaCatchall extends z.ZodTypeAny, + + Values extends {}, + DefaultValues extends Partial, + + JsonifySchemaT extends z.ZodRawShape, + JsonifySchemaUnknownKeys extends z.UnknownKeysParam, + JsonifySchemaCatchall extends z.ZodTypeAny, + + DejsonifySchemaT extends z.ZodRawShape, + DejsonifySchemaUnknownKeys extends z.UnknownKeysParam, + DejsonifySchemaCatchall extends z.ZodTypeAny, + + JsonifiedValues extends JsonifiableObject, + + Type extends ClassType = "AbstractClass" +>( + props: { + extend: C | SchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + Values, + DefaultValues, + Type + > + + jsonifySchema: (props: { + schema: C["schema"] + shape: C["schema"]["shape"] + }) => z.ZodObject< + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + JsonifiedValues, + Values + > + + dejsonifySchema: (props: { + schema: C["schema"] + shape: C["schema"]["shape"] + }) => z.ZodObject< + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + Values, + JsonifiedValues + > + } +) { + const jsonifySchema = props.jsonifySchema({ + schema: props.extend.schema, + shape: props.extend.schema.shape, + }) + + const dejsonifySchema = props.dejsonifySchema({ + schema: props.extend.schema, + shape: props.extend.schema.shape, + }) + + return class extends props.extend { + static readonly jsonifySchema = jsonifySchema + readonly jsonifySchema = jsonifySchema + + static readonly dejsonifySchema = dejsonifySchema + readonly dejsonifySchema = dejsonifySchema + + jsonify() { + return this.jsonifySchema.parse(this) + } + + jsonifyPromise() { + return this.jsonifySchema.parseAsync(this) + } + + jsonifyEffect() { + return parseZodTypeEffect(this.jsonifySchema, this) + } + } as unknown as ( + Class< + Type, + + InstanceType & { + readonly jsonifySchema: typeof jsonifySchema, + readonly dejsonifySchema: typeof dejsonifySchema, + + jsonify(): JsonifiedValues + jsonifyPromise(): Promise + jsonifyEffect(): Effect.Effect, JsonifiedValues> + }, + + ConstructorParameters + > & + + StaticMembers & { + readonly jsonifySchema: typeof jsonifySchema, + readonly dejsonifySchema: typeof dejsonifySchema, + } + ) +} diff --git a/src/makeSchemableClass.ts b/src/makeSchemableClass.ts index fbe30da..7c334eb 100644 --- a/src/makeSchemableClass.ts +++ b/src/makeSchemableClass.ts @@ -3,14 +3,16 @@ import { z } from "zod" import { StaticMembers } from "./util" +type MakeSchemableClassFromInputClass = AbstractClass<{ + schema?: never + defaultValues?: never +}, []> & { + schema?: never + defaultValues?: never +} + export function makeSchemableClassFrom< - C extends AbstractClass<{ - schema?: never - defaultValues?: never - }, []> & { - schema?: never - defaultValues?: never - }, + C extends MakeSchemableClassFromInputClass, SchemaT extends z.ZodRawShape, SchemaUnknownKeys extends z.UnknownKeysParam, @@ -87,13 +89,7 @@ export function createMakeSchemableClassFromUnary< defaultValues: DefaultValues, ) { return < - C extends AbstractClass<{ - schema?: never - defaultValues?: never - }, []> & { - schema?: never - defaultValues?: never - } + C extends MakeSchemableClassFromInputClass >(extend: C) => makeSchemableClassFrom(extend, schema, defaultValues) }