diff --git a/package.json b/package.json index 2ab619a..fdbbe23 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@thilawyn/schemable-class", - "version": "0.1.1", + "version": "0.1.2", "type": "module", "publishConfig": { "registry": "https://git.jvalver.de/api/packages/thilawyn/npm/" diff --git a/src/SchemableClass.ts b/src/SchemableClass.ts deleted file mode 100644 index f54a32f..0000000 --- a/src/SchemableClass.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { z } from "zod" -import { Class, ClassType } from "./util" - - -export type SchemableClass< - SchemaT extends z.ZodRawShape, - SchemaUnknownKeys extends z.UnknownKeysParam, - SchemaCatchall extends z.ZodTypeAny, - - Values extends {}, - DefaultValues extends Partial, - - Type extends ClassType = "AbstractClass" -> = ( - Class< - Type, - - { - readonly schema: z.ZodObject< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - Values, - Values - > - - readonly defaultValues: DefaultValues - } & Values, - - Parameters<(values: Values) => never> - > & { - readonly schema: z.ZodObject< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - Values, - Values - > - - readonly defaultValues: DefaultValues - } -) - - -export type SchemableClassInput< - Values extends {}, - DefaultValues extends Partial, -> = { - [Key in Exclude]: Values[Key] -} & { - [Key in keyof DefaultValues]?: Key extends keyof Values - ? Values[Key] - : never -} diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index 4b4c248..0000000 --- a/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./SchemableClass" -export * from "./defineDefaultValues" -export * from "./extendSchemableClass" -export * from "./makeSchemableClass" -export * from "./newSchemable" diff --git a/src/jsonifiable/JsonifiableSchemableClass.ts b/src/jsonifiable/JsonifiableSchemableClass.ts deleted file mode 100644 index da145d6..0000000 --- a/src/jsonifiable/JsonifiableSchemableClass.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Effect } from "effect" -import { JsonifiableObject } from "type-fest/source/jsonifiable" -import { z } from "zod" -import { SchemableClass } from ".." -import { Class, ClassType } from "../util" - - -export type JsonifiableSchemableClass< - 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" -> = ( - SchemableClass< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - Values, - DefaultValues, - Type - > & - - Class< - Type, - - { - readonly jsonifySchema: z.ZodObject< - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - JsonifiedValues, - Values - > - - readonly dejsonifySchema: z.ZodObject< - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - Values, - JsonifiedValues - > - - jsonify(): JsonifiedValues - jsonifyPromise(): Promise - jsonifyEffect(): Effect.Effect, JsonifiedValues> - }, - - any[] - > & { - readonly jsonifySchema: z.ZodObject< - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - JsonifiedValues, - Values - > - - readonly dejsonifySchema: z.ZodObject< - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - Values, - JsonifiedValues - > - } -) diff --git a/src/jsonifiable/dejsonifySchemable.ts b/src/jsonifiable/dejsonifySchemable.ts deleted file mode 100644 index b8e7f80..0000000 --- a/src/jsonifiable/dejsonifySchemable.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { Effect, pipe } from "effect" -import { JsonifiableObject } from "type-fest/source/jsonifiable" -import { z } from "zod" -import { JsonifiableSchemableClass } from "." -import { parseZodTypeEffect } from "../util" - - -export function dejsonifySchemable< - C extends JsonifiableSchemableClass< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - - Values, - DefaultValues, - - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - - JsonifiedValues, - - "Class" - >, - - 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, ->( - class_: C | JsonifiableSchemableClass< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - - Values, - DefaultValues, - - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - - JsonifiedValues, - - "Class" - >, - - values: JsonifiedValues, - params?: Partial, -) { - return new class_( - class_.dejsonifySchema.parse(values, params) - ) as InstanceType -} - - -export async function dejsonifySchemablePromise< - C extends JsonifiableSchemableClass< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - - Values, - DefaultValues, - - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - - JsonifiedValues, - - "Class" - >, - - 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, ->( - class_: C | JsonifiableSchemableClass< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - - Values, - DefaultValues, - - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - - JsonifiedValues, - - "Class" - >, - - values: JsonifiedValues, - params?: Partial, -) { - return new class_( - await class_.dejsonifySchema.parseAsync(values, params) - ) as InstanceType -} - - -export function dejsonifySchemableEffect< - C extends JsonifiableSchemableClass< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - - Values, - DefaultValues, - - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - - JsonifiedValues, - - "Class" - >, - - 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, ->( - class_: C | JsonifiableSchemableClass< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - - Values, - DefaultValues, - - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - - JsonifiedValues, - - "Class" - >, - - values: JsonifiedValues, - params?: Partial, -) { - return pipe( - parseZodTypeEffect(class_.dejsonifySchema, values, params), - Effect.map(values => new class_(values) as InstanceType), - ) -} diff --git a/src/jsonifiable/index.ts b/src/jsonifiable/index.ts deleted file mode 100644 index 74e7d23..0000000 --- a/src/jsonifiable/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./JsonifiableSchemableClass" -export * from "./dejsonifySchemable" -export * from "./makeJsonifiableSchemableClass" -export * from "./schema" diff --git a/src/jsonifiable/makeJsonifiableSchemableClass.ts b/src/jsonifiable/makeJsonifiableSchemableClass.ts deleted file mode 100644 index 691a3f2..0000000 --- a/src/jsonifiable/makeJsonifiableSchemableClass.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { Effect } from "effect" -import { AbstractClass, Class as ConcreteClass } from "type-fest" -import { JsonifiableObject } from "type-fest/source/jsonifiable" -import { z } from "zod" -import { SchemableClass } from ".." -import { 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, ->( - extend: C | SchemableClass< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - Values, - DefaultValues - >, - - props: { - jsonifySchema: (props: { - schema: z.ZodObject< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - Values, - Values - > - - shape: SchemaT - }) => z.ZodObject< - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - JsonifiedValues, - Values - > - - dejsonifySchema: (props: { - schema: z.ZodObject< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - Values, - Values - > - - shape: SchemaT - }) => z.ZodObject< - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - Values, - JsonifiedValues - > - }, -) { - type Class = ( - C extends ConcreteClass - ? ConcreteClass - : AbstractClass - ) - - const jsonifySchema = props.jsonifySchema({ - schema: extend.schema, - shape: extend.schema.shape, - }) - - const dejsonifySchema = props.dejsonifySchema({ - schema: extend.schema, - shape: extend.schema.shape, - }) - - return class extends 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< - InstanceType & { - readonly jsonifySchema: z.ZodObject, - readonly dejsonifySchema: z.ZodObject, - - jsonify(): JsonifiedValues - jsonifyPromise(): Promise - jsonifyEffect(): Effect.Effect, JsonifiedValues> - }, - - ConstructorParameters - > & - - StaticMembers & { - readonly jsonifySchema: z.ZodObject, - readonly dejsonifySchema: z.ZodObject, - } - ) -} diff --git a/src/jsonifiable/schema/bigint.ts b/src/jsonifiable/schema/bigint.ts deleted file mode 100644 index 76a605d..0000000 --- a/src/jsonifiable/schema/bigint.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Opaque } from "type-fest" -import { z } from "zod" -import { identity } from "../../util" - - -export type JsonifiedBigInt = Opaque - - -export function jsonifyBigIntSchema(schema: S) { - return schema.transform(v => v.toString() as JsonifiedBigInt) -} - -export function dejsonifyBigIntSchema(schema: S) { - return z - .custom(identity) - .pipe(z - .string() - .transform(v => { - try { - return BigInt(v) - } - catch (e) { - return v - } - }) - .pipe(schema) - ) -} diff --git a/src/jsonifiable/schema/date.ts b/src/jsonifiable/schema/date.ts deleted file mode 100644 index c70b2ed..0000000 --- a/src/jsonifiable/schema/date.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Opaque } from "type-fest" -import { z } from "zod" -import { identity } from "../../util" - - -export type JsonifiedDate = Opaque - - -export function jsonifyDateSchema(schema: S) { - return schema.transform(v => v.toString() as JsonifiedDate) -} - -export function dejsonifyDateSchema(schema: S) { - return z - .custom(identity) - .pipe(z - .string() - .transform(v => { - try { - return new Date(v) - } - catch (e) { - return v - } - }) - .pipe(schema) - ) -} diff --git a/src/jsonifiable/schema/decimal.ts b/src/jsonifiable/schema/decimal.ts deleted file mode 100644 index be387ee..0000000 --- a/src/jsonifiable/schema/decimal.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Decimal } from "decimal.js" -import { Opaque } from "type-fest" -import { z } from "zod" -import { identity } from "../../util" - - -export type JsonifiedDecimal = Opaque - - -export function jsonifyDecimalSchema< - S extends z.ZodType ->(schema: S) { - return schema.transform(v => v.toJSON() as JsonifiedDecimal) -} - -export function dejsonifyDecimalSchema< - S extends z.ZodType ->(schema: S) { - return z - .custom(identity) - .pipe(z - .string() - .transform(v => { - try { - return new Decimal(v) - } - catch (e) { - return v - } - }) - .pipe(schema) - ) -} diff --git a/src/jsonifiable/schema/index.ts b/src/jsonifiable/schema/index.ts deleted file mode 100644 index 08ecef8..0000000 --- a/src/jsonifiable/schema/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./bigint" -export * from "./date" -export * from "./decimal" -export * from "./schemable" diff --git a/src/jsonifiable/schema/schemable.ts b/src/jsonifiable/schema/schemable.ts deleted file mode 100644 index b0a72bc..0000000 --- a/src/jsonifiable/schema/schemable.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { JsonifiableObject } from "type-fest/source/jsonifiable" -import { z } from "zod" -import { JsonifiableSchemableClass } from ".." - - -export function jsonifySchemableSchema< - C extends JsonifiableSchemableClass< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - - Values, - DefaultValues, - - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - - JsonifiedValues, - - "Class" - >, - - 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, - - S extends z.ZodType, z.ZodTypeDef, InstanceType>, ->( - class_: C | JsonifiableSchemableClass< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - - Values, - DefaultValues, - - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - - JsonifiedValues, - - "Class" - >, - - schema: S, -) { - return schema.pipe(class_.jsonifySchema) -} - - -export function dejsonifySchemableSchema< - C extends JsonifiableSchemableClass< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - - Values, - DefaultValues, - - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - - JsonifiedValues, - - "Class" - >, - - 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, - - S extends z.ZodType, z.ZodTypeDef, InstanceType>, ->( - class_: C | JsonifiableSchemableClass< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - - Values, - DefaultValues, - - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - - JsonifiedValues, - - "Class" - >, - - schema: S, -) { - return class_.dejsonifySchema.transform(v => new class_(v)).pipe(schema) -} diff --git a/src/legacy/SchemableClass.ts b/src/legacy/SchemableClass.ts index f85216c..5716471 100644 --- a/src/legacy/SchemableClass.ts +++ b/src/legacy/SchemableClass.ts @@ -1,90 +1,54 @@ -import { Class } from "type-fest" import { z } from "zod" +import { Class, ClassType } from "../util" -/** - * Configuration for creating a schemable object with validation schemas. - * @template Values - The type representing the expected values. - * @template Input - The type representing the input values. - * @template SchemaT - The type representing the base validation schema. - * @template SchemaUnknownKeys - The type representing the unknown keys behavior in the base validation schema. - * @template SchemaCatchall - The type representing the catchall behavior in the base validation schema. - * @template SchemaWithDefaultValuesT - The type representing the validation schema with default values. - * @template SchemaWithDefaultValuesUnknownKeys - The type representing the unknown keys behavior in the validation schema with default values. - * @template SchemaWithDefaultValuesCatchall - The type representing the catchall behavior in the validation schema with default values. - */ -export type SchemableConfig< - Values extends {} = {}, - Input extends {} = {}, - - SchemaT extends z.ZodRawShape = z.ZodRawShape, - SchemaUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam, - SchemaCatchall extends z.ZodTypeAny = z.ZodTypeAny, - - SchemaWithDefaultValuesT extends z.ZodRawShape = z.ZodRawShape, - SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam, - SchemaWithDefaultValuesCatchall extends z.ZodTypeAny = z.ZodTypeAny, -> = { - readonly values: Values - readonly input: Input - - readonly schema: z.ZodObject< - SchemaT, - SchemaUnknownKeys, - SchemaCatchall, - Values, - Values - > - - readonly schemaWithDefaultValues: z.ZodObject< - SchemaWithDefaultValuesT, - SchemaWithDefaultValuesUnknownKeys, - SchemaWithDefaultValuesCatchall, - Values, - Input - > -} - - -/** - * Represents a class with validation schemas. - * @template $Config - The configuration type for the schemable object. - */ export type SchemableClass< - $Config extends SchemableConfig + SchemaT extends z.ZodRawShape, + SchemaUnknownKeys extends z.UnknownKeysParam, + SchemaCatchall extends z.ZodTypeAny, + + Values extends {}, + DefaultValues extends Partial, + + Type extends ClassType = "AbstractClass" > = ( Class< - SchemableObject<$Config>, - SchemableClassConstructorParams<$Config> + Type, + + { + readonly schema: z.ZodObject< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + Values, + Values + > + + readonly defaultValues: DefaultValues + } & Values, + + Parameters<(values: Values) => never> > & { - readonly $schemableConfig: $Config - readonly schema: $Config["schema"] - readonly schemaWithDefaultValues: $Config["schemaWithDefaultValues"] + readonly schema: z.ZodObject< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + Values, + Values + > + + readonly defaultValues: DefaultValues } ) -/** - * Represents the constructor parameters for the schemable object class. - * @template $Config - The configuration type for the schemable object. - */ -export type SchemableClassConstructorParams< - $Config extends SchemableConfig -> = ( - Parameters< - (data: $Config["values"]) => void - > -) -/** - * Represents an object with validation schemas. - * @template $Config - The configuration type for the schemable object. - */ -export type SchemableObject< - $Config extends SchemableConfig -> = ( - { - readonly $schemableConfig: $Config - readonly schema: $Config["schema"] - readonly schemaWithDefaultValues: $Config["schemaWithDefaultValues"] - } & $Config["values"] -) +export type SchemableClassInput< + Values extends {}, + DefaultValues extends Partial, +> = { + [Key in Exclude]: Values[Key] +} & { + [Key in keyof DefaultValues]?: Key extends keyof Values + ? Values[Key] + : never +} diff --git a/src/defineDefaultValues.ts b/src/legacy/defineDefaultValues.ts similarity index 100% rename from src/defineDefaultValues.ts rename to src/legacy/defineDefaultValues.ts diff --git a/src/extendSchemableClass.ts b/src/legacy/extendSchemableClass.ts similarity index 98% rename from src/extendSchemableClass.ts rename to src/legacy/extendSchemableClass.ts index bb392e1..2c630b9 100644 --- a/src/extendSchemableClass.ts +++ b/src/legacy/extendSchemableClass.ts @@ -1,7 +1,7 @@ import { AbstractClass, Class as ConcreteClass, Opaque } from "type-fest" import { z } from "zod" import { DefinedDefaultValuesTag, SchemableClass } from "." -import { StaticMembers } from "./util" +import { StaticMembers } from "../util" export function extendSchemableClass< diff --git a/src/legacy/index.ts b/src/legacy/index.ts index 17d8b56..4b4c248 100644 --- a/src/legacy/index.ts +++ b/src/legacy/index.ts @@ -1,3 +1,5 @@ export * from "./SchemableClass" +export * from "./defineDefaultValues" +export * from "./extendSchemableClass" export * from "./makeSchemableClass" export * from "./newSchemable" diff --git a/src/legacy/jsonifiable/JsonifiableSchemableClass.ts b/src/legacy/jsonifiable/JsonifiableSchemableClass.ts index c0dc3c0..b0612c4 100644 --- a/src/legacy/jsonifiable/JsonifiableSchemableClass.ts +++ b/src/legacy/jsonifiable/JsonifiableSchemableClass.ts @@ -1,66 +1,80 @@ import { Effect } from "effect" -import { Class } from "type-fest" import { JsonifiableObject } from "type-fest/source/jsonifiable" import { z } from "zod" -import { SchemableClassConstructorParams, SchemableConfig } from ".." - - -export type JsonifiableSchemableConfig< - $SchemableConfig extends SchemableConfig = SchemableConfig, - - JsonifiedValues extends JsonifiableObject = {}, - - JsonifySchemaT extends z.ZodRawShape = z.ZodRawShape, - JsonifySchemaUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam, - JsonifySchemaCatchall extends z.ZodTypeAny = z.ZodTypeAny, - - DejsonifySchemaT extends z.ZodRawShape = z.ZodRawShape, - DejsonifySchemaUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam, - DejsonifySchemaCatchall extends z.ZodTypeAny = z.ZodTypeAny, -> = { - readonly $schemableConfig: $SchemableConfig - - readonly jsonifiedValues: JsonifiedValues - - readonly jsonifySchema: z.ZodObject< - JsonifySchemaT, - JsonifySchemaUnknownKeys, - JsonifySchemaCatchall, - JsonifiedValues, - $SchemableConfig["values"] - > - - readonly dejsonifySchema: z.ZodObject< - DejsonifySchemaT, - DejsonifySchemaUnknownKeys, - DejsonifySchemaCatchall, - $SchemableConfig["values"], - JsonifiedValues - > -} +import { SchemableClass } from ".." +import { Class, ClassType } from "../../util" export type JsonifiableSchemableClass< - $Config extends JsonifiableSchemableConfig + 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" > = ( + SchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + Values, + DefaultValues, + Type + > & + Class< - JsonifiableSchemableObject<$Config>, - SchemableClassConstructorParams<$Config["$schemableConfig"]> + Type, + + { + readonly jsonifySchema: z.ZodObject< + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + JsonifiedValues, + Values + > + + readonly dejsonifySchema: z.ZodObject< + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + Values, + JsonifiedValues + > + + jsonify(): JsonifiedValues + jsonifyPromise(): Promise + jsonifyEffect(): Effect.Effect, JsonifiedValues> + }, + + any[] > & { - readonly $jsonifiableSchemableConfig: $Config - readonly jsonifySchema: $Config["jsonifySchema"] - readonly dejsonifySchema: $Config["dejsonifySchema"] + readonly jsonifySchema: z.ZodObject< + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + JsonifiedValues, + Values + > + + readonly dejsonifySchema: z.ZodObject< + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + Values, + JsonifiedValues + > } ) - -export type JsonifiableSchemableObject< - $Config extends JsonifiableSchemableConfig -> = { - readonly $jsonifiableSchemableConfig: $Config - readonly jsonifySchema: $Config["jsonifySchema"] - readonly dejsonifySchema: $Config["dejsonifySchema"] - - jsonify(): $Config["jsonifiedValues"] - jsonifyPromise(): Promise<$Config["jsonifiedValues"]> - jsonifyEffect(): Effect.Effect, $Config["jsonifiedValues"]> -} diff --git a/src/legacy/jsonifiable/dejsonifySchemable.ts b/src/legacy/jsonifiable/dejsonifySchemable.ts index 35ceafb..b5395db 100644 --- a/src/legacy/jsonifiable/dejsonifySchemable.ts +++ b/src/legacy/jsonifiable/dejsonifySchemable.ts @@ -1,47 +1,213 @@ import { Effect, pipe } from "effect" +import { JsonifiableObject } from "type-fest/source/jsonifiable" import { z } from "zod" -import { JsonifiableSchemableClass, JsonifiableSchemableConfig } from "." -import { parseZodTypeEffect } from "../util" +import { JsonifiableSchemableClass } from "." +import { parseZodTypeEffect } from "../../util" -export const dejsonifySchemable = < - C extends JsonifiableSchemableClass<$Config>, - $Config extends JsonifiableSchemableConfig, +export function dejsonifySchemable< + C extends JsonifiableSchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + + Values, + DefaultValues, + + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + + JsonifiedValues, + + "Class" + >, + + 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, >( - class_: C | JsonifiableSchemableClass<$Config>, - values: $Config["jsonifiedValues"], + class_: C | JsonifiableSchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + + Values, + DefaultValues, + + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + + JsonifiedValues, + + "Class" + >, + + values: JsonifiedValues, params?: Partial, -) => - new class_(class_.dejsonifySchema.parse(values, params)) as InstanceType +) { + return new class_( + class_.dejsonifySchema.parse(values, params) + ) as InstanceType +} -export const dejsonifySchemablePromise = async < - C extends JsonifiableSchemableClass<$Config>, - $Config extends JsonifiableSchemableConfig, +export async function dejsonifySchemablePromise< + C extends JsonifiableSchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + + Values, + DefaultValues, + + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + + JsonifiedValues, + + "Class" + >, + + 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, >( - class_: C | JsonifiableSchemableClass<$Config>, - values: $Config["jsonifiedValues"], + class_: C | JsonifiableSchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + + Values, + DefaultValues, + + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + + JsonifiedValues, + + "Class" + >, + + values: JsonifiedValues, params?: Partial, -) => - new class_(await class_.dejsonifySchema.parseAsync(values, params)) as InstanceType +) { + return new class_( + await class_.dejsonifySchema.parseAsync(values, params) + ) as InstanceType +} -export const dejsonifySchemableEffect = < - C extends JsonifiableSchemableClass<$Config>, - $Config extends JsonifiableSchemableConfig, +export function dejsonifySchemableEffect< + C extends JsonifiableSchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + + Values, + DefaultValues, + + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + + JsonifiedValues, + + "Class" + >, + + 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, >( - class_: C | JsonifiableSchemableClass<$Config>, - values: $Config["jsonifiedValues"], - params?: Partial, -) => pipe( - parseZodTypeEffect< - z.output, - z.input - >( - class_.dejsonifySchema, - values, - params, - ), + class_: C | JsonifiableSchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, - Effect.map(values => new class_(values) as InstanceType), -) + Values, + DefaultValues, + + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + + JsonifiedValues, + + "Class" + >, + + values: JsonifiedValues, + params?: Partial, +) { + return pipe( + parseZodTypeEffect(class_.dejsonifySchema, values, params), + Effect.map(values => new class_(values) as InstanceType), + ) +} diff --git a/src/legacy/jsonifiable/makeJsonifiableSchemableClass.ts b/src/legacy/jsonifiable/makeJsonifiableSchemableClass.ts index a956b0b..d8b47ff 100644 --- a/src/legacy/jsonifiable/makeJsonifiableSchemableClass.ts +++ b/src/legacy/jsonifiable/makeJsonifiableSchemableClass.ts @@ -1,16 +1,26 @@ -import { Class } from "type-fest" +import { Effect } from "effect" +import { AbstractClass, Class as ConcreteClass } 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" +import { SchemableClass } from ".." +import { StaticMembers, parseZodTypeEffect } from "../../util" export function makeJsonifiableSchemableClass< - C extends SchemableClass<$SchemableConfig>, - $SchemableConfig extends SchemableConfig, + C extends SchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + Values, + DefaultValues + >, - JsonifiedValues extends JsonifiableObject, + 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, @@ -19,59 +29,77 @@ export function makeJsonifiableSchemableClass< DejsonifySchemaT extends z.ZodRawShape, DejsonifySchemaUnknownKeys extends z.UnknownKeysParam, DejsonifySchemaCatchall extends z.ZodTypeAny, + + JsonifiedValues extends JsonifiableObject, >( - class_: C | SchemableClass<$SchemableConfig>, + extend: C | SchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + Values, + DefaultValues + >, props: { jsonifySchema: (props: { - schema: $SchemableConfig["schema"] - s: $SchemableConfig["schema"]["shape"] + schema: z.ZodObject< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + Values, + Values + > + + shape: SchemaT }) => z.ZodObject< JsonifySchemaT, JsonifySchemaUnknownKeys, JsonifySchemaCatchall, JsonifiedValues, - $SchemableConfig["values"] + Values > dejsonifySchema: (props: { - schema: $SchemableConfig["schema"] - s: $SchemableConfig["schema"]["shape"] + schema: z.ZodObject< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + Values, + Values + > + + shape: SchemaT }) => z.ZodObject< DejsonifySchemaT, DejsonifySchemaUnknownKeys, DejsonifySchemaCatchall, - $SchemableConfig["values"], + Values, JsonifiedValues > }, ) { + type Class = ( + C extends ConcreteClass + ? ConcreteClass + : AbstractClass + ) const jsonifySchema = props.jsonifySchema({ - schema: class_.schema, - s: class_.schema.shape, + schema: extend.schema, + shape: extend.schema.shape, }) const dejsonifySchema = props.dejsonifySchema({ - schema: class_.schema, - s: class_.schema.shape, + schema: extend.schema, + shape: extend.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 + return class extends extend { + static readonly jsonifySchema = jsonifySchema + readonly jsonifySchema = jsonifySchema - 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 + static readonly dejsonifySchema = dejsonifySchema + readonly dejsonifySchema = dejsonifySchema jsonify() { return this.jsonifySchema.parse(this) @@ -84,15 +112,23 @@ export function makeJsonifiableSchemableClass< jsonifyEffect() { return parseZodTypeEffect(this.jsonifySchema, this) } - } satisfies JsonifiableSchemableClass - - return jsonifiableClass as unknown as ( + } as unknown as ( Class< - InstanceType & JsonifiableSchemableObject, + InstanceType & { + readonly jsonifySchema: z.ZodObject, + readonly dejsonifySchema: z.ZodObject, + + jsonify(): JsonifiedValues + jsonifyPromise(): Promise + jsonifyEffect(): Effect.Effect, JsonifiedValues> + }, + ConstructorParameters > & - StaticMembers & - StaticMembers> - ) + StaticMembers & { + readonly jsonifySchema: z.ZodObject, + readonly dejsonifySchema: z.ZodObject, + } + ) } diff --git a/src/legacy/jsonifiable/schema/bigint.ts b/src/legacy/jsonifiable/schema/bigint.ts index b0f0093..aece7e4 100644 --- a/src/legacy/jsonifiable/schema/bigint.ts +++ b/src/legacy/jsonifiable/schema/bigint.ts @@ -1,18 +1,28 @@ +import { Opaque } from "type-fest" import { z } from "zod" +import { identity } from "../../../util" -export const jsonifyBigIntSchema = (schema: S) => - schema.transform(v => v.toString()) +export type JsonifiedBigInt = Opaque -export const dejsonifyBigIntSchema = (schema: S) => - z - .string() - .transform(v => { - try { - return BigInt(v) - } - catch (e) { - return v - } - }) - .pipe(schema) + +export function jsonifyBigIntSchema(schema: S) { + return schema.transform(v => v.toString() as JsonifiedBigInt) +} + +export function dejsonifyBigIntSchema(schema: S) { + return z + .custom(identity) + .pipe(z + .string() + .transform(v => { + try { + return BigInt(v) + } + catch (e) { + return v + } + }) + .pipe(schema) + ) +} diff --git a/src/legacy/jsonifiable/schema/date.ts b/src/legacy/jsonifiable/schema/date.ts index b5ac677..eddc7eb 100644 --- a/src/legacy/jsonifiable/schema/date.ts +++ b/src/legacy/jsonifiable/schema/date.ts @@ -1,18 +1,28 @@ +import { Opaque } from "type-fest" import { z } from "zod" +import { identity } from "../../../util" -export const jsonifyDateSchema = (schema: S) => - schema.transform(v => v.toString()) +export type JsonifiedDate = Opaque -export const dejsonifyDateSchema = (schema: S) => - z - .string() - .transform(v => { - try { - return new Date(v) - } - catch (e) { - return v - } - }) - .pipe(schema) + +export function jsonifyDateSchema(schema: S) { + return schema.transform(v => v.toString() as JsonifiedDate) +} + +export function dejsonifyDateSchema(schema: S) { + return z + .custom(identity) + .pipe(z + .string() + .transform(v => { + try { + return new Date(v) + } + catch (e) { + return v + } + }) + .pipe(schema) + ) +} diff --git a/src/legacy/jsonifiable/schema/decimal.ts b/src/legacy/jsonifiable/schema/decimal.ts index 58c492d..ea7f4ee 100644 --- a/src/legacy/jsonifiable/schema/decimal.ts +++ b/src/legacy/jsonifiable/schema/decimal.ts @@ -1,19 +1,33 @@ import { Decimal } from "decimal.js" +import { Opaque } from "type-fest" import { z } from "zod" +import { identity } from "../../../util" -export const jsonifyDecimalSchema = >(schema: S) => - schema.transform(v => v.toJSON()) +export type JsonifiedDecimal = Opaque -export const dejsonifyDecimalSchema = >(schema: S) => - z - .string() - .transform(v => { - try { - return new Decimal(v) - } - catch (e) { - return v - } - }) - .pipe(schema) + +export function jsonifyDecimalSchema< + S extends z.ZodType +>(schema: S) { + return schema.transform(v => v.toJSON() as JsonifiedDecimal) +} + +export function dejsonifyDecimalSchema< + S extends z.ZodType +>(schema: S) { + return z + .custom(identity) + .pipe(z + .string() + .transform(v => { + try { + return new Decimal(v) + } + catch (e) { + return v + } + }) + .pipe(schema) + ) +} diff --git a/src/legacy/jsonifiable/schema/schemable.ts b/src/legacy/jsonifiable/schema/schemable.ts index c6e2a2d..b0a72bc 100644 --- a/src/legacy/jsonifiable/schema/schemable.ts +++ b/src/legacy/jsonifiable/schema/schemable.ts @@ -1,25 +1,139 @@ +import { JsonifiableObject } from "type-fest/source/jsonifiable" import { z } from "zod" -import { JsonifiableSchemableClass, JsonifiableSchemableConfig } from ".." +import { JsonifiableSchemableClass } from ".." -// TODO: try to find a way to get rid of the 'class_' arg -export const jsonifySchemableSchema = < - C extends JsonifiableSchemableClass<$Config>, - $Config extends JsonifiableSchemableConfig, - S extends z.ZodType, z.ZodTypeDef, InstanceType>, +export function jsonifySchemableSchema< + C extends JsonifiableSchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + + Values, + DefaultValues, + + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + + JsonifiedValues, + + "Class" + >, + + 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, + + S extends z.ZodType, z.ZodTypeDef, InstanceType>, >( - class_: C | JsonifiableSchemableClass<$Config>, - schema: S, -) => - schema.pipe(class_.jsonifySchema) + class_: C | JsonifiableSchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, -// TODO: try to find a way to get rid of the 'class_' arg -export const dejsonifySchemableSchema = < - C extends JsonifiableSchemableClass<$Config>, - $Config extends JsonifiableSchemableConfig, - S extends z.ZodType, z.ZodTypeDef, InstanceType>, + Values, + DefaultValues, + + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + + JsonifiedValues, + + "Class" + >, + + schema: S, +) { + return schema.pipe(class_.jsonifySchema) +} + + +export function dejsonifySchemableSchema< + C extends JsonifiableSchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + + Values, + DefaultValues, + + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + + JsonifiedValues, + + "Class" + >, + + 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, + + S extends z.ZodType, z.ZodTypeDef, InstanceType>, >( - class_: C | JsonifiableSchemableClass<$Config>, - schema: S, -) => - class_.dejsonifySchema.transform(v => new class_(v)).pipe(schema) + class_: C | JsonifiableSchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + + Values, + DefaultValues, + + JsonifySchemaT, + JsonifySchemaUnknownKeys, + JsonifySchemaCatchall, + + DejsonifySchemaT, + DejsonifySchemaUnknownKeys, + DejsonifySchemaCatchall, + + JsonifiedValues, + + "Class" + >, + + schema: S, +) { + return class_.dejsonifySchema.transform(v => new class_(v)).pipe(schema) +} diff --git a/src/legacy/makeSchemableClass.ts b/src/legacy/makeSchemableClass.ts index 88bcf72..5962882 100644 --- a/src/legacy/makeSchemableClass.ts +++ b/src/legacy/makeSchemableClass.ts @@ -1,49 +1,82 @@ +import { AbstractClass, Class as ConcreteClass, Opaque } from "type-fest" import { z } from "zod" -import { SchemableClass, SchemableConfig } from "." -import { zodObjectRemoveDefaults } from "./util" +import { DefinedDefaultValuesTag } from "." +import { StaticMembers } from "../util" + + +export function makeSchemableClassFrom< + C extends AbstractClass<{ + schema?: never + defaultValues?: never + }, []> & { + schema?: never + defaultValues?: never + }, + + SchemaT extends z.ZodRawShape, + SchemaUnknownKeys extends z.UnknownKeysParam, + SchemaCatchall extends z.ZodTypeAny, + + Values extends {}, + DefaultValues extends Partial, +>( + extend: C, + + { schema, defaultValues }: { + schema: z.ZodObject + defaultValues: Opaque + }, +) { + type Class = ( + C extends ConcreteClass + ? ConcreteClass + : AbstractClass + ) + + return class extends (extend as unknown as ConcreteClass) { + static readonly schema = schema + readonly schema = schema + + static readonly defaultValues = defaultValues + readonly defaultValues = defaultValues + + constructor(values: Values) { + super() + Object.assign(this, values) + } + } as unknown as ( + Class< + InstanceType & + { + readonly schema: z.ZodObject, + readonly defaultValues: DefaultValues, + } & + Values, + + Parameters<(values: Values) => void> + > & + + StaticMembers & + { + readonly schema: z.ZodObject, + readonly defaultValues: DefaultValues, + } + ) +} export function makeSchemableClass< - SchemaWithDefaultValuesT extends z.ZodRawShape, - SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam, - SchemaWithDefaultValuesCatchall extends z.ZodTypeAny, - SchemaWithDefaultValuesOutput extends SchemaWithDefaultValuesInput, // TODO: apply "StripSchemaInputDefaults"? - SchemaWithDefaultValuesInput extends {}, + SchemaT extends z.ZodRawShape, + SchemaUnknownKeys extends z.UnknownKeysParam, + SchemaCatchall extends z.ZodTypeAny, + + Values extends {}, + DefaultValues extends Partial, >( - { - schema: schemaWithDefaultValues - }: { - schema: z.ZodObject< - SchemaWithDefaultValuesT, - SchemaWithDefaultValuesUnknownKeys, - SchemaWithDefaultValuesCatchall, - SchemaWithDefaultValuesOutput, - SchemaWithDefaultValuesInput - > + props: { + schema: z.ZodObject + defaultValues: Opaque } ) { - - const schema = zodObjectRemoveDefaults(schemaWithDefaultValues) - - const $schemableConfig = { - values: undefined as unknown as z.output, - input: undefined as unknown as z.input, - schema: undefined as unknown as typeof schema, - schemaWithDefaultValues: undefined as unknown as typeof schemaWithDefaultValues, - } as const satisfies SchemableConfig - - return class SchemableObject { - static readonly $schemableConfig = $schemableConfig - static readonly schema = schema - static readonly schemaWithDefaultValues = schemaWithDefaultValues - - readonly $schemableConfig = $schemableConfig - readonly schema = schema - readonly schemaWithDefaultValues = schemaWithDefaultValues - - constructor(data: z.output) { - Object.assign(this, data) - } - } as SchemableClass - + return makeSchemableClassFrom(Object, props) } diff --git a/src/legacy/newSchemable.ts b/src/legacy/newSchemable.ts index da0be36..628b632 100644 --- a/src/legacy/newSchemable.ts +++ b/src/legacy/newSchemable.ts @@ -1,77 +1,127 @@ import { Effect, pipe } from "effect" import { HasRequiredKeys } from "type-fest" import { z } from "zod" -import { SchemableClass, SchemableConfig } from "." -import { parseZodTypeEffect } from "./util" +import { SchemableClass, SchemableClassInput } from "." +import { parseZodTypeEffect } from "../util" -type ParamsArgs = [] | [Partial] +type ParamsArgs = [] | [params: Partial] type NewSchemableArgs = HasRequiredKeys extends true - ? [Input, ...ParamsArgs] - : [] | [Input, ...ParamsArgs] + ? [values: Input, ...args: ParamsArgs] + : [] | [values: Input, ...args: 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, +export function 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<$Config>, - ...[values, params]: NewSchemableArgs<$Config["input"]> -) => - new class_(class_.schemaWithDefaultValues.parse(values || {}, params)) as InstanceType + class_: C | SchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + Values, + DefaultValues, + "Class" + >, + + ...[values, params]: NewSchemableArgs< + SchemableClassInput + > +) { + return new class_( + class_.schema.parse({ ...class_.defaultValues, ...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, +export async function newSchemablePromise< + 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<$Config>, - ...[values, params]: NewSchemableArgs<$Config["input"]> -) => - new class_(await class_.schemaWithDefaultValues.parseAsync(values || {}, params)) as InstanceType + class_: C | SchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + Values, + DefaultValues, + "Class" + >, + + ...[values, params]: NewSchemableArgs< + SchemableClassInput + > +) { + return new class_( + await class_.schema.parseAsync({ ...class_.defaultValues, ...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, +export function 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<$Config>, - ...[values, params]: NewSchemableArgs<$Config["input"]> -) => pipe( - parseZodTypeEffect< - z.output, - z.input - >( - class_.schemaWithDefaultValues, - values || {}, - params, - ), + class_: C | SchemableClass< + SchemaT, + SchemaUnknownKeys, + SchemaCatchall, + Values, + DefaultValues, + "Class" + >, - Effect.map(values => new class_(values) as InstanceType), -) + ...[values, params]: NewSchemableArgs< + SchemableClassInput + > +) { + return pipe( + parseZodTypeEffect( + class_.schema, + { ...class_.defaultValues, ...values }, + params, + ), + + Effect.map(values => new class_(values) as InstanceType), + ) +} diff --git a/src/observable/index.ts b/src/legacy/observable/index.ts similarity index 100% rename from src/observable/index.ts rename to src/legacy/observable/index.ts diff --git a/src/observable/makeSchemableClassObservable.ts b/src/legacy/observable/makeSchemableClassObservable.ts similarity index 100% rename from src/observable/makeSchemableClassObservable.ts rename to src/legacy/observable/makeSchemableClassObservable.ts diff --git a/src/legacy/tests.ts b/src/legacy/tests.ts deleted file mode 100644 index c19daf7..0000000 --- a/src/legacy/tests.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { z } from "zod" -import { makeSchemableClass, newSchemable } from "." -import { dejsonifyBigIntSchema, dejsonifySchemable, dejsonifySchemableSchema, jsonifyBigIntSchema, jsonifySchemableSchema, makeJsonifiableSchemableClass } from "./jsonifiable" - - -const GroupSchema = z.object({ - /** Group ID */ - id: z.bigint(), - - /** Group name */ - name: z.string(), -}) - -const GroupSchemableObject = makeSchemableClass({ schema: GroupSchema }) - -const GroupJsonifiableSchemableObject = makeJsonifiableSchemableClass(GroupSchemableObject, { - jsonifySchema: ({ schema, s }) => schema.extend({ - id: jsonifyBigIntSchema(s.id) - }), - - dejsonifySchema: ({ schema, s }) => schema.extend({ - id: dejsonifyBigIntSchema(s.id) - }), -}) - -class Group extends GroupJsonifiableSchemableObject {} - - -const UserSchema = z.object({ - /** User ID */ - id: z.bigint(), - - /** Name string */ - name: z.string(), - - /** User group */ - group: z.instanceof(Group), -}) - -const UserSchemableObject = makeSchemableClass({ schema: UserSchema }) - -const UserJsonifiableSchemableObject = makeJsonifiableSchemableClass(UserSchemableObject, { - jsonifySchema: ({ schema, s }) => schema.extend({ - id: jsonifyBigIntSchema(s.id), - group: jsonifySchemableSchema(Group, s.group), - }), - - dejsonifySchema: ({ schema, s }) => schema.extend({ - id: dejsonifyBigIntSchema(s.id), - group: dejsonifySchemableSchema(Group, s.group), - }), -}) - -class User extends UserJsonifiableSchemableObject {} - - -const group1 = new Group({ id: 1n, name: "Group 1" }) - -const user1 = new User({ id: 1n, name: "User 1", group: group1 }) -const user2 = newSchemable(User, { id: 2n, name: "User 2", group: group1 }) - -const jsonifiedUser2 = user2.jsonify() -const dejsonifiedUser2 = dejsonifySchemable(User, jsonifiedUser2) -console.log(dejsonifiedUser2) diff --git a/src/legacy/util.ts b/src/legacy/util.ts deleted file mode 100644 index 2cf7b08..0000000 --- a/src/legacy/util.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { Effect, pipe } from "effect" -import { mapValues } from "lodash-es" -import { z } from "zod" - - -/** - * Represents the static members of a class. - * @template C - The class type. - */ -export type StaticMembers = { - [Key in keyof C as Key extends "prototype" ? never : Key]: C[Key] -} - - -/** - * Removes default values from a ZodObject schema and returns a new schema. - * - * @param schema - The ZodObject schema to process. - * @returns A new ZodObject schema with default values removed. - */ -export const zodObjectRemoveDefaults = < - T extends z.ZodRawShape, - UnknownKeys extends z.UnknownKeysParam, - Catchall extends z.ZodTypeAny, - Output extends {}, - Input extends {}, ->( - schema: z.ZodObject< - T, - UnknownKeys, - Catchall, - Output, - Input - > -) => - schema.extend(zodShapeRemoveDefaults(schema.shape)) - -/** - * Removes default values from a ZodObject shape and returns a new shape. - * - * @param shape - The ZodObject shape to process. - * @returns A new shape with default values removed. - */ -export const zodShapeRemoveDefaults = < - Shape extends z.ZodRawShape ->( - shape: Shape -): { - [K in keyof Shape]: - Shape[K] extends z.ZodDefault - ? T - : Shape[K] -} => - mapValues(shape, el => - el instanceof z.ZodDefault - ? el.removeDefault() - : el - ) - - -/** - * Parses a value using a ZodType schema wrapped in an Effect monad. - * - * @param schema - The ZodType schema to use for parsing. - * @param args - The arguments to pass to the `safeParseAsync` method of the schema. - * @returns An Effect monad representing the parsing result. - */ -export const parseZodTypeEffect = < - Output, - Input, ->( - schema: z.ZodType, - ...args: Parameters -) => pipe( - Effect.promise(() => schema.safeParseAsync(...args)), - - Effect.flatMap(response => - response.success - ? Effect.succeed(response.data) - : Effect.fail(response.error) - ), -) diff --git a/src/makeSchemableClass.ts b/src/makeSchemableClass.ts deleted file mode 100644 index 0345eb7..0000000 --- a/src/makeSchemableClass.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { AbstractClass, Class as ConcreteClass, Opaque } from "type-fest" -import { z } from "zod" -import { DefinedDefaultValuesTag } from "." -import { StaticMembers } from "./util" - - -export function makeSchemableClassFrom< - C extends AbstractClass<{ - schema?: never - defaultValues?: never - }, []> & { - schema?: never - defaultValues?: never - }, - - SchemaT extends z.ZodRawShape, - SchemaUnknownKeys extends z.UnknownKeysParam, - SchemaCatchall extends z.ZodTypeAny, - - Values extends {}, - DefaultValues extends Partial, ->( - extend: C, - - { schema, defaultValues }: { - schema: z.ZodObject - defaultValues: Opaque - }, -) { - type Class = ( - C extends ConcreteClass - ? ConcreteClass - : AbstractClass - ) - - return class extends (extend as unknown as ConcreteClass) { - static readonly schema = schema - readonly schema = schema - - static readonly defaultValues = defaultValues - readonly defaultValues = defaultValues - - constructor(values: Values) { - super() - Object.assign(this, values) - } - } as unknown as ( - Class< - InstanceType & - { - readonly schema: z.ZodObject, - readonly defaultValues: DefaultValues, - } & - Values, - - Parameters<(values: Values) => void> - > & - - StaticMembers & - { - readonly schema: z.ZodObject, - readonly defaultValues: DefaultValues, - } - ) -} - - -export function makeSchemableClass< - SchemaT extends z.ZodRawShape, - SchemaUnknownKeys extends z.UnknownKeysParam, - SchemaCatchall extends z.ZodTypeAny, - - Values extends {}, - DefaultValues extends Partial, ->( - props: { - schema: z.ZodObject - defaultValues: Opaque - } -) { - return makeSchemableClassFrom(Object, props) -} diff --git a/src/newSchemable.ts b/src/newSchemable.ts deleted file mode 100644 index 98a5498..0000000 --- a/src/newSchemable.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { Effect, pipe } from "effect" -import { HasRequiredKeys } from "type-fest" -import { z } from "zod" -import { SchemableClass, SchemableClassInput } from "." -import { parseZodTypeEffect } from "./util" - - -type ParamsArgs = [] | [params: Partial] - -type NewSchemableArgs = - HasRequiredKeys extends true - ? [values: Input, ...args: ParamsArgs] - : [] | [values: Input, ...args: ParamsArgs] - - -export function 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 - > -) { - return new class_( - class_.schema.parse({ ...class_.defaultValues, ...values }, params) - ) as InstanceType -} - - -export async function newSchemablePromise< - 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 - > -) { - return new class_( - await class_.schema.parseAsync({ ...class_.defaultValues, ...values }, params) - ) as InstanceType -} - - -export function 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 - > -) { - return pipe( - parseZodTypeEffect( - class_.schema, - { ...class_.defaultValues, ...values }, - params, - ), - - Effect.map(values => new class_(values) as InstanceType), - ) -} diff --git a/src/tests.ts b/src/tests.ts index 6015710..e69de29 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,63 +0,0 @@ -import { pipeInto } from "ts-functional-pipe" -import { z } from "zod" -import { defineDefaultValues, extendSchemableClass, makeSchemableClass, newSchemable } from "." -import { dejsonifyBigIntSchema, dejsonifySchemable, jsonifyBigIntSchema, makeJsonifiableSchemableClass } from "./jsonifiable" -import { makeSchemableClassObservable } from "./observable" - - -const UserLevel = z.enum(["User", "Admin"]) - - -class User extends pipeInto( - makeSchemableClass({ - schema: z.object({ - id: z.bigint(), - name: z.string(), - level: UserLevel, - }), - - defaultValues: defineDefaultValues({ - level: "User" as const - }), - }), - - v => makeSchemableClassObservable(v), - - v => makeJsonifiableSchemableClass(v, { - jsonifySchema: ({ schema, shape }) => schema.extend({ - id: jsonifyBigIntSchema(shape.id) - }), - - dejsonifySchema: ({ schema, shape }) => schema.extend({ - id: dejsonifyBigIntSchema(shape.id) - }), - }), -) {} - -User.schema - - -const user1 = newSchemable(User, { id: 1n, name: "User" }) -user1.schema - -const jsonifiedUser1 = user1.jsonify() -console.log(jsonifiedUser1) -console.log(dejsonifySchemable(User, jsonifiedUser1)) - - -const UserWithPhone = extendSchemableClass(User, { - schema: ({ schema }) => schema.extend({ - phone: z.string() - }), - - defaultValues: defaultValues => defineDefaultValues({ - ...defaultValues, - phone: "+33600000000", - }), -}) - -UserWithPhone.defaultValues - - -// const user2 = newSchemable(UserWithPhone, { id: 1n, name: "User" }) -// console.log(user2.jsonify())