Compare commits
35 Commits
next
...
73ce4e11ff
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73ce4e11ff | ||
|
|
93f1038e27 | ||
|
|
3bf22f1f49 | ||
|
|
880d77019d | ||
|
|
a4d4c87f54 | ||
|
|
0d20e7ad69 | ||
|
|
443ae01d2d | ||
|
|
65602eac7d | ||
|
|
99f071147d | ||
|
|
5f7fd30459 | ||
|
|
041b3f566e | ||
|
|
9adfe2366c | ||
|
|
408d3a7f3a | ||
|
|
e1c298c08a | ||
|
|
ae4abf6b9c | ||
|
|
ed3f8fb643 | ||
|
|
ffce582e03 | ||
|
|
fa7d222f76 | ||
|
|
f40bebbc9b | ||
|
|
6ee9337426 | ||
|
|
5297468d17 | ||
|
|
ff9bbb37e8 | ||
|
|
9ba149fb4c | ||
|
|
d867a3b83a | ||
|
|
e35db63da8 | ||
|
|
a4b8166af8 | ||
|
|
d34885a6e4 | ||
|
|
ab328f2cb5 | ||
|
|
147034e95d | ||
|
|
516ce0ade2 | ||
|
|
338c750a4b | ||
|
|
b6c2c4bec7 | ||
|
|
c073154eeb | ||
|
|
6873fae86b | ||
|
|
fc95a5d53a |
11
package.json
11
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/"
|
||||
@@ -48,20 +48,21 @@
|
||||
"clean:node": "rm -rf node_modules"
|
||||
},
|
||||
"dependencies": {
|
||||
"@thilawyn/traitify-ts": "^0.1.3",
|
||||
"decimal.js": "^10.4.3",
|
||||
"effect": "^2.1.1",
|
||||
"effect": "^2.2.5",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mobx": "^6.12.0",
|
||||
"type-fest": "^4.9.0",
|
||||
"type-fest": "^4.10.2",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"bun-types": "latest",
|
||||
"npm-check-updates": "^16.14.12",
|
||||
"npm-check-updates": "^16.14.14",
|
||||
"npm-sort": "^0.0.4",
|
||||
"rollup": "^4.9.5",
|
||||
"rollup": "^4.9.6",
|
||||
"rollup-plugin-cleanup": "^3.2.1",
|
||||
"rollup-plugin-ts": "^3.4.5",
|
||||
"ts-functional-pipe": "^3.1.2",
|
||||
|
||||
@@ -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<Values>,
|
||||
|
||||
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<Values>,
|
||||
> = {
|
||||
[Key in Exclude<keyof Values, keyof DefaultValues>]: Values[Key]
|
||||
} & {
|
||||
[Key in keyof DefaultValues]?: Key extends keyof Values
|
||||
? Values[Key]
|
||||
: never
|
||||
}
|
||||
74
src/ZodSchemaClass.ts
Normal file
74
src/ZodSchemaClass.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { expression } from "@thilawyn/traitify-ts"
|
||||
import { AbstractClass } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { ExtendableZodSchemaObject } from "./traits/ExtendableZodSchemaObject"
|
||||
import { InstantiableZodSchemaObject } from "./traits/InstantiableZodSchemaObject"
|
||||
import { Extend, StaticMembers } from "./util"
|
||||
|
||||
|
||||
export function ZodSchemaClassOf<
|
||||
Super extends AbstractClass<object, []>,
|
||||
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
|
||||
Values extends {},
|
||||
DefaultValues extends Partial<Values>,
|
||||
>(
|
||||
of: Super,
|
||||
|
||||
{ schema, defaultValues }: {
|
||||
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
|
||||
defaultValues: DefaultValues
|
||||
},
|
||||
) {
|
||||
const exp = expression
|
||||
.extends(class extends (of as AbstractClass<{}, []>) {
|
||||
static readonly schema = schema
|
||||
static readonly defaultValues = defaultValues
|
||||
|
||||
constructor(values: Values) {
|
||||
super()
|
||||
Object.assign(this, values)
|
||||
}
|
||||
})
|
||||
.expresses(
|
||||
InstantiableZodSchemaObject,
|
||||
ExtendableZodSchemaObject,
|
||||
)
|
||||
.build()
|
||||
|
||||
return exp.extends as AbstractClass<
|
||||
Extend<[
|
||||
InstanceType<Super>,
|
||||
InstanceType<typeof exp.extends>,
|
||||
Values,
|
||||
]>,
|
||||
|
||||
ConstructorParameters<typeof exp.extends>
|
||||
> &
|
||||
Extend<[
|
||||
StaticMembers<Super>,
|
||||
StaticMembers<typeof exp.extends>,
|
||||
]>
|
||||
}
|
||||
|
||||
|
||||
class DefaultRoot {}
|
||||
|
||||
export function ZodSchemaClass<
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
|
||||
Values extends {},
|
||||
DefaultValues extends Partial<Values>,
|
||||
>(
|
||||
props: {
|
||||
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
|
||||
defaultValues: DefaultValues
|
||||
},
|
||||
) {
|
||||
return ZodSchemaClassOf(DefaultRoot, props)
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
export * from "./SchemableClass"
|
||||
export * from "./defineDefaultValues"
|
||||
export * from "./extendSchemableClass"
|
||||
export * from "./makeSchemableClass"
|
||||
export * from "./newSchemable"
|
||||
@@ -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<Values>,
|
||||
|
||||
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<JsonifiedValues>
|
||||
jsonifyEffect(): Effect.Effect<never, z.ZodError<Values>, JsonifiedValues>
|
||||
},
|
||||
|
||||
any[]
|
||||
> & {
|
||||
readonly jsonifySchema: z.ZodObject<
|
||||
JsonifySchemaT,
|
||||
JsonifySchemaUnknownKeys,
|
||||
JsonifySchemaCatchall,
|
||||
JsonifiedValues,
|
||||
Values
|
||||
>
|
||||
|
||||
readonly dejsonifySchema: z.ZodObject<
|
||||
DejsonifySchemaT,
|
||||
DejsonifySchemaUnknownKeys,
|
||||
DejsonifySchemaCatchall,
|
||||
Values,
|
||||
JsonifiedValues
|
||||
>
|
||||
}
|
||||
)
|
||||
@@ -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<Values>,
|
||||
|
||||
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<z.ParseParams>,
|
||||
) {
|
||||
return new class_(
|
||||
class_.dejsonifySchema.parse(values, params)
|
||||
) as InstanceType<C>
|
||||
}
|
||||
|
||||
|
||||
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<Values>,
|
||||
|
||||
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<z.ParseParams>,
|
||||
) {
|
||||
return new class_(
|
||||
await class_.dejsonifySchema.parseAsync(values, params)
|
||||
) as InstanceType<C>
|
||||
}
|
||||
|
||||
|
||||
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<Values>,
|
||||
|
||||
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<z.ParseParams>,
|
||||
) {
|
||||
return pipe(
|
||||
parseZodTypeEffect(class_.dejsonifySchema, values, params),
|
||||
Effect.map(values => new class_(values) as InstanceType<C>),
|
||||
)
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export * from "./JsonifiableSchemableClass"
|
||||
export * from "./dejsonifySchemable"
|
||||
export * from "./makeJsonifiableSchemableClass"
|
||||
export * from "./schema"
|
||||
@@ -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<Values>,
|
||||
|
||||
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<T, Arguments extends unknown[]> = (
|
||||
C extends ConcreteClass<any>
|
||||
? ConcreteClass<T, Arguments>
|
||||
: AbstractClass<T, Arguments>
|
||||
)
|
||||
|
||||
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<C> & {
|
||||
readonly jsonifySchema: z.ZodObject<JsonifySchemaT, JsonifySchemaUnknownKeys, JsonifySchemaCatchall, JsonifiedValues, Values>,
|
||||
readonly dejsonifySchema: z.ZodObject<DejsonifySchemaT, DejsonifySchemaUnknownKeys, DejsonifySchemaCatchall, Values, JsonifiedValues>,
|
||||
|
||||
jsonify(): JsonifiedValues
|
||||
jsonifyPromise(): Promise<JsonifiedValues>
|
||||
jsonifyEffect(): Effect.Effect<never, z.ZodError<Values>, JsonifiedValues>
|
||||
},
|
||||
|
||||
ConstructorParameters<C>
|
||||
> &
|
||||
|
||||
StaticMembers<C> & {
|
||||
readonly jsonifySchema: z.ZodObject<JsonifySchemaT, JsonifySchemaUnknownKeys, JsonifySchemaCatchall, JsonifiedValues, Values>,
|
||||
readonly dejsonifySchema: z.ZodObject<DejsonifySchemaT, DejsonifySchemaUnknownKeys, DejsonifySchemaCatchall, Values, JsonifiedValues>,
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { Opaque } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { identity } from "../../util"
|
||||
|
||||
|
||||
export type JsonifiedBigInt = Opaque<string, "@thilawyn/schemable-class/JsonifiedBigInt">
|
||||
|
||||
|
||||
export function jsonifyBigIntSchema<S extends z.ZodBigInt>(schema: S) {
|
||||
return schema.transform(v => v.toString() as JsonifiedBigInt)
|
||||
}
|
||||
|
||||
export function dejsonifyBigIntSchema<S extends z.ZodBigInt>(schema: S) {
|
||||
return z
|
||||
.custom<JsonifiedBigInt>(identity)
|
||||
.pipe(z
|
||||
.string()
|
||||
.transform(v => {
|
||||
try {
|
||||
return BigInt(v)
|
||||
}
|
||||
catch (e) {
|
||||
return v
|
||||
}
|
||||
})
|
||||
.pipe(schema)
|
||||
)
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { Opaque } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { identity } from "../../util"
|
||||
|
||||
|
||||
export type JsonifiedDate = Opaque<string, "@thilawyn/schemable-class/JsonifiedDate">
|
||||
|
||||
|
||||
export function jsonifyDateSchema<S extends z.ZodDate>(schema: S) {
|
||||
return schema.transform(v => v.toString() as JsonifiedDate)
|
||||
}
|
||||
|
||||
export function dejsonifyDateSchema<S extends z.ZodDate>(schema: S) {
|
||||
return z
|
||||
.custom<JsonifiedDate>(identity)
|
||||
.pipe(z
|
||||
.string()
|
||||
.transform(v => {
|
||||
try {
|
||||
return new Date(v)
|
||||
}
|
||||
catch (e) {
|
||||
return v
|
||||
}
|
||||
})
|
||||
.pipe(schema)
|
||||
)
|
||||
}
|
||||
@@ -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<string, "@thilawyn/schemable-class/JsonifiedDecimal">
|
||||
|
||||
|
||||
export function jsonifyDecimalSchema<
|
||||
S extends z.ZodType<Decimal, z.ZodTypeDef, Decimal>
|
||||
>(schema: S) {
|
||||
return schema.transform(v => v.toJSON() as JsonifiedDecimal)
|
||||
}
|
||||
|
||||
export function dejsonifyDecimalSchema<
|
||||
S extends z.ZodType<Decimal, z.ZodTypeDef, Decimal>
|
||||
>(schema: S) {
|
||||
return z
|
||||
.custom<JsonifiedDecimal>(identity)
|
||||
.pipe(z
|
||||
.string()
|
||||
.transform(v => {
|
||||
try {
|
||||
return new Decimal(v)
|
||||
}
|
||||
catch (e) {
|
||||
return v
|
||||
}
|
||||
})
|
||||
.pipe(schema)
|
||||
)
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export * from "./bigint"
|
||||
export * from "./date"
|
||||
export * from "./decimal"
|
||||
export * from "./schemable"
|
||||
@@ -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<Values>,
|
||||
|
||||
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<InstanceType<C>, z.ZodTypeDef, InstanceType<C>>,
|
||||
>(
|
||||
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<Values>,
|
||||
|
||||
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<InstanceType<C>, z.ZodTypeDef, InstanceType<C>>,
|
||||
>(
|
||||
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)
|
||||
}
|
||||
@@ -1,33 +1,21 @@
|
||||
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 {} = {},
|
||||
export type SchemableClass<
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
|
||||
SchemaT extends z.ZodRawShape = z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny = z.ZodTypeAny,
|
||||
Values extends {},
|
||||
DefaultValues extends Partial<Values>,
|
||||
|
||||
SchemaWithDefaultValuesT extends z.ZodRawShape = z.ZodRawShape,
|
||||
SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam,
|
||||
SchemaWithDefaultValuesCatchall extends z.ZodTypeAny = z.ZodTypeAny,
|
||||
> = {
|
||||
readonly values: Values
|
||||
readonly input: Input
|
||||
Type extends ClassType = "AbstractClass"
|
||||
> = (
|
||||
Class<
|
||||
Type,
|
||||
|
||||
{
|
||||
readonly schema: z.ZodObject<
|
||||
SchemaT,
|
||||
SchemaUnknownKeys,
|
||||
@@ -36,55 +24,31 @@ export type SchemableConfig<
|
||||
Values
|
||||
>
|
||||
|
||||
readonly schemaWithDefaultValues: z.ZodObject<
|
||||
SchemaWithDefaultValuesT,
|
||||
SchemaWithDefaultValuesUnknownKeys,
|
||||
SchemaWithDefaultValuesCatchall,
|
||||
Values,
|
||||
Input
|
||||
>
|
||||
}
|
||||
readonly defaultValues: DefaultValues
|
||||
} & Values,
|
||||
|
||||
|
||||
/**
|
||||
* Represents a class with validation schemas.
|
||||
* @template $Config - The configuration type for the schemable object.
|
||||
*/
|
||||
export type SchemableClass<
|
||||
$Config extends SchemableConfig
|
||||
> = (
|
||||
Class<
|
||||
SchemableObject<$Config>,
|
||||
SchemableClassConstructorParams<$Config>
|
||||
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<Values>,
|
||||
> = {
|
||||
[Key in Exclude<keyof Values, keyof DefaultValues>]: Values[Key]
|
||||
} & {
|
||||
[Key in keyof DefaultValues]?: Key extends keyof Values
|
||||
? Values[Key]
|
||||
: never
|
||||
}
|
||||
|
||||
@@ -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<
|
||||
@@ -1,3 +1,5 @@
|
||||
export * from "./SchemableClass"
|
||||
export * from "./defineDefaultValues"
|
||||
export * from "./extendSchemableClass"
|
||||
export * from "./makeSchemableClass"
|
||||
export * from "./newSchemable"
|
||||
|
||||
@@ -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 ".."
|
||||
import { SchemableClass } from ".."
|
||||
import { Class, ClassType } from "../../util"
|
||||
|
||||
|
||||
export type JsonifiableSchemableConfig<
|
||||
$SchemableConfig extends SchemableConfig = SchemableConfig,
|
||||
export type JsonifiableSchemableClass<
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
|
||||
JsonifiedValues extends JsonifiableObject = {},
|
||||
Values extends {},
|
||||
DefaultValues extends Partial<Values>,
|
||||
|
||||
JsonifySchemaT extends z.ZodRawShape = z.ZodRawShape,
|
||||
JsonifySchemaUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam,
|
||||
JsonifySchemaCatchall extends z.ZodTypeAny = z.ZodTypeAny,
|
||||
JsonifySchemaT extends z.ZodRawShape,
|
||||
JsonifySchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
JsonifySchemaCatchall extends z.ZodTypeAny,
|
||||
|
||||
DejsonifySchemaT extends z.ZodRawShape = z.ZodRawShape,
|
||||
DejsonifySchemaUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam,
|
||||
DejsonifySchemaCatchall extends z.ZodTypeAny = z.ZodTypeAny,
|
||||
> = {
|
||||
readonly $schemableConfig: $SchemableConfig
|
||||
DejsonifySchemaT extends z.ZodRawShape,
|
||||
DejsonifySchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
DejsonifySchemaCatchall extends z.ZodTypeAny,
|
||||
|
||||
readonly jsonifiedValues: JsonifiedValues
|
||||
JsonifiedValues extends JsonifiableObject,
|
||||
|
||||
Type extends ClassType = "AbstractClass"
|
||||
> = (
|
||||
SchemableClass<
|
||||
SchemaT,
|
||||
SchemaUnknownKeys,
|
||||
SchemaCatchall,
|
||||
Values,
|
||||
DefaultValues,
|
||||
Type
|
||||
> &
|
||||
|
||||
Class<
|
||||
Type,
|
||||
|
||||
{
|
||||
readonly jsonifySchema: z.ZodObject<
|
||||
JsonifySchemaT,
|
||||
JsonifySchemaUnknownKeys,
|
||||
JsonifySchemaCatchall,
|
||||
JsonifiedValues,
|
||||
$SchemableConfig["values"]
|
||||
Values
|
||||
>
|
||||
|
||||
readonly dejsonifySchema: z.ZodObject<
|
||||
DejsonifySchemaT,
|
||||
DejsonifySchemaUnknownKeys,
|
||||
DejsonifySchemaCatchall,
|
||||
$SchemableConfig["values"],
|
||||
Values,
|
||||
JsonifiedValues
|
||||
>
|
||||
|
||||
jsonify(): JsonifiedValues
|
||||
jsonifyPromise(): Promise<JsonifiedValues>
|
||||
jsonifyEffect(): Effect.Effect<never, z.ZodError<Values>, JsonifiedValues>
|
||||
},
|
||||
|
||||
any[]
|
||||
> & {
|
||||
readonly jsonifySchema: z.ZodObject<
|
||||
JsonifySchemaT,
|
||||
JsonifySchemaUnknownKeys,
|
||||
JsonifySchemaCatchall,
|
||||
JsonifiedValues,
|
||||
Values
|
||||
>
|
||||
|
||||
readonly dejsonifySchema: z.ZodObject<
|
||||
DejsonifySchemaT,
|
||||
DejsonifySchemaUnknownKeys,
|
||||
DejsonifySchemaCatchall,
|
||||
Values,
|
||||
JsonifiedValues
|
||||
>
|
||||
}
|
||||
|
||||
|
||||
export type JsonifiableSchemableClass<
|
||||
$Config extends JsonifiableSchemableConfig
|
||||
> = (
|
||||
Class<
|
||||
JsonifiableSchemableObject<$Config>,
|
||||
SchemableClassConstructorParams<$Config["$schemableConfig"]>
|
||||
> & {
|
||||
readonly $jsonifiableSchemableConfig: $Config
|
||||
readonly jsonifySchema: $Config["jsonifySchema"]
|
||||
readonly dejsonifySchema: $Config["dejsonifySchema"]
|
||||
}
|
||||
)
|
||||
|
||||
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<never, z.ZodError<$Config["$schemableConfig"]["values"]>, $Config["jsonifiedValues"]>
|
||||
}
|
||||
|
||||
@@ -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<Values>,
|
||||
|
||||
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<z.ParseParams>,
|
||||
) =>
|
||||
new class_(class_.dejsonifySchema.parse(values, params)) as InstanceType<C>
|
||||
) {
|
||||
return new class_(
|
||||
class_.dejsonifySchema.parse(values, params)
|
||||
) as InstanceType<C>
|
||||
}
|
||||
|
||||
|
||||
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<Values>,
|
||||
|
||||
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<z.ParseParams>,
|
||||
) =>
|
||||
new class_(await class_.dejsonifySchema.parseAsync(values, params)) as InstanceType<C>
|
||||
) {
|
||||
return new class_(
|
||||
await class_.dejsonifySchema.parseAsync(values, params)
|
||||
) as InstanceType<C>
|
||||
}
|
||||
|
||||
|
||||
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<Values>,
|
||||
|
||||
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<z.ParseParams>,
|
||||
) => pipe(
|
||||
parseZodTypeEffect<
|
||||
z.output<typeof class_.dejsonifySchema>,
|
||||
z.input<typeof class_.dejsonifySchema>
|
||||
>(
|
||||
class_.dejsonifySchema,
|
||||
values,
|
||||
params,
|
||||
),
|
||||
|
||||
) {
|
||||
return pipe(
|
||||
parseZodTypeEffect(class_.dejsonifySchema, values, params),
|
||||
Effect.map(values => new class_(values) as InstanceType<C>),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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<Values>,
|
||||
|
||||
JsonifySchemaT extends z.ZodRawShape,
|
||||
JsonifySchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
@@ -19,58 +29,76 @@ 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<T, Arguments extends unknown[]> = (
|
||||
C extends ConcreteClass<any>
|
||||
? ConcreteClass<T, Arguments>
|
||||
: AbstractClass<T, Arguments>
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
const jsonifiableClass = class JsonifiableSchemableObject extends class_ {
|
||||
static readonly $jsonifiableSchemableConfig = $jsonifiableSchemableConfig
|
||||
return class extends extend {
|
||||
static readonly jsonifySchema = jsonifySchema
|
||||
static readonly dejsonifySchema = dejsonifySchema
|
||||
|
||||
readonly $jsonifiableSchemableConfig = $jsonifiableSchemableConfig
|
||||
readonly jsonifySchema = jsonifySchema
|
||||
|
||||
static readonly dejsonifySchema = dejsonifySchema
|
||||
readonly dejsonifySchema = dejsonifySchema
|
||||
|
||||
jsonify() {
|
||||
@@ -84,15 +112,23 @@ export function makeJsonifiableSchemableClass<
|
||||
jsonifyEffect() {
|
||||
return parseZodTypeEffect(this.jsonifySchema, this)
|
||||
}
|
||||
} satisfies JsonifiableSchemableClass<typeof $jsonifiableSchemableConfig>
|
||||
|
||||
return jsonifiableClass as unknown as (
|
||||
} as unknown as (
|
||||
Class<
|
||||
InstanceType<C> & JsonifiableSchemableObject<typeof $jsonifiableSchemableConfig>,
|
||||
InstanceType<C> & {
|
||||
readonly jsonifySchema: z.ZodObject<JsonifySchemaT, JsonifySchemaUnknownKeys, JsonifySchemaCatchall, JsonifiedValues, Values>,
|
||||
readonly dejsonifySchema: z.ZodObject<DejsonifySchemaT, DejsonifySchemaUnknownKeys, DejsonifySchemaCatchall, Values, JsonifiedValues>,
|
||||
|
||||
jsonify(): JsonifiedValues
|
||||
jsonifyPromise(): Promise<JsonifiedValues>
|
||||
jsonifyEffect(): Effect.Effect<never, z.ZodError<Values>, JsonifiedValues>
|
||||
},
|
||||
|
||||
ConstructorParameters<C>
|
||||
> &
|
||||
StaticMembers<C> &
|
||||
StaticMembers<JsonifiableSchemableClass<typeof $jsonifiableSchemableConfig>>
|
||||
)
|
||||
|
||||
StaticMembers<C> & {
|
||||
readonly jsonifySchema: z.ZodObject<JsonifySchemaT, JsonifySchemaUnknownKeys, JsonifySchemaCatchall, JsonifiedValues, Values>,
|
||||
readonly dejsonifySchema: z.ZodObject<DejsonifySchemaT, DejsonifySchemaUnknownKeys, DejsonifySchemaCatchall, Values, JsonifiedValues>,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
import { Opaque } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { identity } from "../../../util"
|
||||
|
||||
|
||||
export const jsonifyBigIntSchema = <S extends z.ZodBigInt>(schema: S) =>
|
||||
schema.transform(v => v.toString())
|
||||
export type JsonifiedBigInt = Opaque<string, "@thilawyn/schemable-class/JsonifiedBigInt">
|
||||
|
||||
export const dejsonifyBigIntSchema = <S extends z.ZodBigInt>(schema: S) =>
|
||||
z
|
||||
|
||||
export function jsonifyBigIntSchema<S extends z.ZodBigInt>(schema: S) {
|
||||
return schema.transform(v => v.toString() as JsonifiedBigInt)
|
||||
}
|
||||
|
||||
export function dejsonifyBigIntSchema<S extends z.ZodBigInt>(schema: S) {
|
||||
return z
|
||||
.custom<JsonifiedBigInt>(identity)
|
||||
.pipe(z
|
||||
.string()
|
||||
.transform(v => {
|
||||
try {
|
||||
@@ -16,3 +24,5 @@ export const dejsonifyBigIntSchema = <S extends z.ZodBigInt>(schema: S) =>
|
||||
}
|
||||
})
|
||||
.pipe(schema)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
import { Opaque } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { identity } from "../../../util"
|
||||
|
||||
|
||||
export const jsonifyDateSchema = <S extends z.ZodDate>(schema: S) =>
|
||||
schema.transform(v => v.toString())
|
||||
export type JsonifiedDate = Opaque<string, "@thilawyn/schemable-class/JsonifiedDate">
|
||||
|
||||
export const dejsonifyDateSchema = <S extends z.ZodDate>(schema: S) =>
|
||||
z
|
||||
|
||||
export function jsonifyDateSchema<S extends z.ZodDate>(schema: S) {
|
||||
return schema.transform(v => v.toString() as JsonifiedDate)
|
||||
}
|
||||
|
||||
export function dejsonifyDateSchema<S extends z.ZodDate>(schema: S) {
|
||||
return z
|
||||
.custom<JsonifiedDate>(identity)
|
||||
.pipe(z
|
||||
.string()
|
||||
.transform(v => {
|
||||
try {
|
||||
@@ -16,3 +24,5 @@ export const dejsonifyDateSchema = <S extends z.ZodDate>(schema: S) =>
|
||||
}
|
||||
})
|
||||
.pipe(schema)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
import { Decimal } from "decimal.js"
|
||||
import { Opaque } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { identity } from "../../../util"
|
||||
|
||||
|
||||
export const jsonifyDecimalSchema = <S extends z.ZodType<Decimal, z.ZodTypeDef, Decimal>>(schema: S) =>
|
||||
schema.transform(v => v.toJSON())
|
||||
export type JsonifiedDecimal = Opaque<string, "@thilawyn/schemable-class/JsonifiedDecimal">
|
||||
|
||||
export const dejsonifyDecimalSchema = <S extends z.ZodType<Decimal, z.ZodTypeDef, Decimal>>(schema: S) =>
|
||||
z
|
||||
|
||||
export function jsonifyDecimalSchema<
|
||||
S extends z.ZodType<Decimal, z.ZodTypeDef, Decimal>
|
||||
>(schema: S) {
|
||||
return schema.transform(v => v.toJSON() as JsonifiedDecimal)
|
||||
}
|
||||
|
||||
export function dejsonifyDecimalSchema<
|
||||
S extends z.ZodType<Decimal, z.ZodTypeDef, Decimal>
|
||||
>(schema: S) {
|
||||
return z
|
||||
.custom<JsonifiedDecimal>(identity)
|
||||
.pipe(z
|
||||
.string()
|
||||
.transform(v => {
|
||||
try {
|
||||
@@ -17,3 +29,5 @@ export const dejsonifyDecimalSchema = <S extends z.ZodType<Decimal, z.ZodTypeDef
|
||||
}
|
||||
})
|
||||
.pipe(schema)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
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<Values>,
|
||||
|
||||
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<InstanceType<C>, z.ZodTypeDef, InstanceType<C>>,
|
||||
>(
|
||||
class_: C | JsonifiableSchemableClass<$Config>,
|
||||
schema: S,
|
||||
) =>
|
||||
schema.pipe(class_.jsonifySchema)
|
||||
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<Values>,
|
||||
|
||||
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,
|
||||
|
||||
// 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<InstanceType<C>, z.ZodTypeDef, InstanceType<C>>,
|
||||
>(
|
||||
class_: C | JsonifiableSchemableClass<$Config>,
|
||||
class_: C | JsonifiableSchemableClass<
|
||||
SchemaT,
|
||||
SchemaUnknownKeys,
|
||||
SchemaCatchall,
|
||||
|
||||
Values,
|
||||
DefaultValues,
|
||||
|
||||
JsonifySchemaT,
|
||||
JsonifySchemaUnknownKeys,
|
||||
JsonifySchemaCatchall,
|
||||
|
||||
DejsonifySchemaT,
|
||||
DejsonifySchemaUnknownKeys,
|
||||
DejsonifySchemaCatchall,
|
||||
|
||||
JsonifiedValues,
|
||||
|
||||
"Class"
|
||||
>,
|
||||
|
||||
schema: S,
|
||||
) =>
|
||||
class_.dejsonifySchema.transform(v => new class_(v)).pipe(schema)
|
||||
) {
|
||||
return class_.dejsonifySchema.transform(v => new class_(v)).pipe(schema)
|
||||
}
|
||||
|
||||
@@ -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<Values>,
|
||||
>(
|
||||
extend: C,
|
||||
|
||||
{ schema, defaultValues }: {
|
||||
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
|
||||
defaultValues: Opaque<DefaultValues, DefinedDefaultValuesTag>
|
||||
},
|
||||
) {
|
||||
type Class<T, Arguments extends unknown[]> = (
|
||||
C extends ConcreteClass<any>
|
||||
? ConcreteClass<T, Arguments>
|
||||
: AbstractClass<T, Arguments>
|
||||
)
|
||||
|
||||
return class extends (extend as unknown as ConcreteClass<any, []>) {
|
||||
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<C> &
|
||||
{
|
||||
readonly schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>,
|
||||
readonly defaultValues: DefaultValues,
|
||||
} &
|
||||
Values,
|
||||
|
||||
Parameters<(values: Values) => void>
|
||||
> &
|
||||
|
||||
StaticMembers<C> &
|
||||
{
|
||||
readonly schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>,
|
||||
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<Values>,
|
||||
>(
|
||||
{
|
||||
schema: schemaWithDefaultValues
|
||||
}: {
|
||||
schema: z.ZodObject<
|
||||
SchemaWithDefaultValuesT,
|
||||
SchemaWithDefaultValuesUnknownKeys,
|
||||
SchemaWithDefaultValuesCatchall,
|
||||
SchemaWithDefaultValuesOutput,
|
||||
SchemaWithDefaultValuesInput
|
||||
>
|
||||
props: {
|
||||
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
|
||||
defaultValues: Opaque<DefaultValues, DefinedDefaultValuesTag>
|
||||
}
|
||||
) {
|
||||
|
||||
const schema = zodObjectRemoveDefaults(schemaWithDefaultValues)
|
||||
|
||||
const $schemableConfig = {
|
||||
values: undefined as unknown as z.output<typeof schemaWithDefaultValues>,
|
||||
input: undefined as unknown as z.input<typeof schemaWithDefaultValues>,
|
||||
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<typeof schema>) {
|
||||
Object.assign(this, data)
|
||||
}
|
||||
} as SchemableClass<typeof $schemableConfig>
|
||||
|
||||
return makeSchemableClassFrom(Object, props)
|
||||
}
|
||||
|
||||
@@ -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<z.ParseParams>]
|
||||
type ParamsArgs = [] | [params: Partial<z.ParseParams>]
|
||||
|
||||
type NewSchemableArgs<Input extends object> =
|
||||
HasRequiredKeys<Input> 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<Values>,
|
||||
>(
|
||||
class_: C | SchemableClass<$Config>,
|
||||
...[values, params]: NewSchemableArgs<$Config["input"]>
|
||||
) =>
|
||||
new class_(class_.schemaWithDefaultValues.parse(values || {}, params)) as InstanceType<C>
|
||||
class_: C | SchemableClass<
|
||||
SchemaT,
|
||||
SchemaUnknownKeys,
|
||||
SchemaCatchall,
|
||||
Values,
|
||||
DefaultValues,
|
||||
"Class"
|
||||
>,
|
||||
|
||||
...[values, params]: NewSchemableArgs<
|
||||
SchemableClassInput<Values, DefaultValues>
|
||||
>
|
||||
) {
|
||||
return new class_(
|
||||
class_.schema.parse({ ...class_.defaultValues, ...values }, params)
|
||||
) as InstanceType<C>
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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<Values>,
|
||||
>(
|
||||
class_: C | SchemableClass<$Config>,
|
||||
...[values, params]: NewSchemableArgs<$Config["input"]>
|
||||
) =>
|
||||
new class_(await class_.schemaWithDefaultValues.parseAsync(values || {}, params)) as InstanceType<C>
|
||||
class_: C | SchemableClass<
|
||||
SchemaT,
|
||||
SchemaUnknownKeys,
|
||||
SchemaCatchall,
|
||||
Values,
|
||||
DefaultValues,
|
||||
"Class"
|
||||
>,
|
||||
|
||||
...[values, params]: NewSchemableArgs<
|
||||
SchemableClassInput<Values, DefaultValues>
|
||||
>
|
||||
) {
|
||||
return new class_(
|
||||
await class_.schema.parseAsync({ ...class_.defaultValues, ...values }, params)
|
||||
) as InstanceType<C>
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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<Values>,
|
||||
>(
|
||||
class_: C | SchemableClass<$Config>,
|
||||
...[values, params]: NewSchemableArgs<$Config["input"]>
|
||||
) => pipe(
|
||||
parseZodTypeEffect<
|
||||
z.output<typeof class_.schemaWithDefaultValues>,
|
||||
z.input<typeof class_.schemaWithDefaultValues>
|
||||
>(
|
||||
class_.schemaWithDefaultValues,
|
||||
values || {},
|
||||
class_: C | SchemableClass<
|
||||
SchemaT,
|
||||
SchemaUnknownKeys,
|
||||
SchemaCatchall,
|
||||
Values,
|
||||
DefaultValues,
|
||||
"Class"
|
||||
>,
|
||||
|
||||
...[values, params]: NewSchemableArgs<
|
||||
SchemableClassInput<Values, DefaultValues>
|
||||
>
|
||||
) {
|
||||
return pipe(
|
||||
parseZodTypeEffect(
|
||||
class_.schema,
|
||||
{ ...class_.defaultValues, ...values },
|
||||
params,
|
||||
),
|
||||
|
||||
Effect.map(values => new class_(values) as InstanceType<C>),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -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<C> = {
|
||||
[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<infer T>
|
||||
? 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<Output, z.ZodTypeDef, Input>,
|
||||
...args: Parameters<typeof schema.safeParseAsync>
|
||||
) => pipe(
|
||||
Effect.promise(() => schema.safeParseAsync(...args)),
|
||||
|
||||
Effect.flatMap(response =>
|
||||
response.success
|
||||
? Effect.succeed(response.data)
|
||||
: Effect.fail(response.error)
|
||||
),
|
||||
)
|
||||
1
src/lib.ts
Normal file
1
src/lib.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { ExtendableZodSchemaObject } from "./traits/ExtendableZodSchemaObject"
|
||||
@@ -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<Values>,
|
||||
>(
|
||||
extend: C,
|
||||
|
||||
{ schema, defaultValues }: {
|
||||
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
|
||||
defaultValues: Opaque<DefaultValues, DefinedDefaultValuesTag>
|
||||
},
|
||||
) {
|
||||
type Class<T, Arguments extends unknown[]> = (
|
||||
C extends ConcreteClass<any>
|
||||
? ConcreteClass<T, Arguments>
|
||||
: AbstractClass<T, Arguments>
|
||||
)
|
||||
|
||||
return class extends (extend as unknown as ConcreteClass<any, []>) {
|
||||
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<C> &
|
||||
{
|
||||
readonly schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>,
|
||||
readonly defaultValues: DefaultValues,
|
||||
} &
|
||||
Values,
|
||||
|
||||
Parameters<(values: Values) => void>
|
||||
> &
|
||||
|
||||
StaticMembers<C> &
|
||||
{
|
||||
readonly schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>,
|
||||
readonly defaultValues: DefaultValues,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export function makeSchemableClass<
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
|
||||
Values extends {},
|
||||
DefaultValues extends Partial<Values>,
|
||||
>(
|
||||
props: {
|
||||
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
|
||||
defaultValues: Opaque<DefaultValues, DefinedDefaultValuesTag>
|
||||
}
|
||||
) {
|
||||
return makeSchemableClassFrom(Object, props)
|
||||
}
|
||||
@@ -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<z.ParseParams>]
|
||||
|
||||
type NewSchemableArgs<Input extends object> =
|
||||
HasRequiredKeys<Input> 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<Values>,
|
||||
>(
|
||||
class_: C | SchemableClass<
|
||||
SchemaT,
|
||||
SchemaUnknownKeys,
|
||||
SchemaCatchall,
|
||||
Values,
|
||||
DefaultValues,
|
||||
"Class"
|
||||
>,
|
||||
|
||||
...[values, params]: NewSchemableArgs<
|
||||
SchemableClassInput<Values, DefaultValues>
|
||||
>
|
||||
) {
|
||||
return new class_(
|
||||
class_.schema.parse({ ...class_.defaultValues, ...values }, params)
|
||||
) as InstanceType<C>
|
||||
}
|
||||
|
||||
|
||||
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<Values>,
|
||||
>(
|
||||
class_: C | SchemableClass<
|
||||
SchemaT,
|
||||
SchemaUnknownKeys,
|
||||
SchemaCatchall,
|
||||
Values,
|
||||
DefaultValues,
|
||||
"Class"
|
||||
>,
|
||||
|
||||
...[values, params]: NewSchemableArgs<
|
||||
SchemableClassInput<Values, DefaultValues>
|
||||
>
|
||||
) {
|
||||
return new class_(
|
||||
await class_.schema.parseAsync({ ...class_.defaultValues, ...values }, params)
|
||||
) as InstanceType<C>
|
||||
}
|
||||
|
||||
|
||||
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<Values>,
|
||||
>(
|
||||
class_: C | SchemableClass<
|
||||
SchemaT,
|
||||
SchemaUnknownKeys,
|
||||
SchemaCatchall,
|
||||
Values,
|
||||
DefaultValues,
|
||||
"Class"
|
||||
>,
|
||||
|
||||
...[values, params]: NewSchemableArgs<
|
||||
SchemableClassInput<Values, DefaultValues>
|
||||
>
|
||||
) {
|
||||
return pipe(
|
||||
parseZodTypeEffect(
|
||||
class_.schema,
|
||||
{ ...class_.defaultValues, ...values },
|
||||
params,
|
||||
),
|
||||
|
||||
Effect.map(values => new class_(values) as InstanceType<C>),
|
||||
)
|
||||
}
|
||||
43
src/shapes/ZodSchemaClass.ts
Normal file
43
src/shapes/ZodSchemaClass.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { AbstractClass, Class } from "type-fest"
|
||||
import { z } from "zod"
|
||||
|
||||
|
||||
export type ZodSchemaClass<
|
||||
Instance extends Values,
|
||||
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
|
||||
Values extends {},
|
||||
DefaultValues extends Partial<Values>,
|
||||
> = (
|
||||
Class<Instance, [values: Values]> &
|
||||
ZodSchemaClassStatic<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, DefaultValues>
|
||||
)
|
||||
|
||||
export type ZodSchemaAbstractClass<
|
||||
Instance extends Values,
|
||||
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
|
||||
Values extends {},
|
||||
DefaultValues extends Partial<Values>,
|
||||
> = (
|
||||
AbstractClass<Instance, [values: Values]> &
|
||||
ZodSchemaClassStatic<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, DefaultValues>
|
||||
)
|
||||
|
||||
export type ZodSchemaClassStatic<
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
|
||||
Values extends {},
|
||||
DefaultValues extends Partial<Values>,
|
||||
> = {
|
||||
readonly schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
|
||||
readonly defaultValues: DefaultValues
|
||||
}
|
||||
78
src/tests.ts
78
src/tests.ts
@@ -1,63 +1,43 @@
|
||||
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"
|
||||
import { ZodSchemaClass } from "./ZodSchemaClass"
|
||||
|
||||
|
||||
const UserLevel = z.enum(["User", "Admin"])
|
||||
|
||||
|
||||
class User extends pipeInto(
|
||||
makeSchemableClass({
|
||||
class Test extends ZodSchemaClass({
|
||||
schema: z.object({
|
||||
id: z.bigint(),
|
||||
name: z.string(),
|
||||
level: UserLevel,
|
||||
}),
|
||||
|
||||
defaultValues: defineDefaultValues({
|
||||
level: "User" as const
|
||||
}),
|
||||
defaultValues: { id: -1n },
|
||||
}) {}
|
||||
|
||||
const Test2 = ZodSchemaClass({
|
||||
schema: z.object({
|
||||
id: z.bigint(),
|
||||
name: z.string(),
|
||||
}),
|
||||
|
||||
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",
|
||||
}),
|
||||
defaultValues: { id: -1n },
|
||||
})
|
||||
|
||||
UserWithPhone.defaultValues
|
||||
Test.defaultValues
|
||||
const inst = Test.create({ id: 1n, name: "" })
|
||||
console.log(inst)
|
||||
|
||||
|
||||
// const user2 = newSchemable(UserWithPhone, { id: 1n, name: "User" })
|
||||
// console.log(user2.jsonify())
|
||||
class SubTest extends Test.extend({
|
||||
schema: ({ schema }) => schema.extend({
|
||||
prout: z.string()
|
||||
}),
|
||||
|
||||
defaultValues: defaultValues => ({
|
||||
...defaultValues
|
||||
}),
|
||||
}) {}
|
||||
|
||||
const subInst = await SubTest.createPromise({ name: "", prout: "" })
|
||||
console.log(subInst)
|
||||
|
||||
// class ChildTest extends Test {}
|
||||
|
||||
// ChildTest.instantiate({ name: "" })
|
||||
|
||||
58
src/traits/ExtendableZodSchemaObject.ts
Normal file
58
src/traits/ExtendableZodSchemaObject.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { trait } from "@thilawyn/traitify-ts"
|
||||
import { AbstractClass } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { ZodSchemaAbstractClass } from "../shapes/ZodSchemaClass"
|
||||
import { Extend, StaticMembers } from "../util"
|
||||
|
||||
|
||||
export const ExtendableZodSchemaObject = trait
|
||||
.implement(Super => class ExtendableZodSchemaObject extends Super {
|
||||
static extend<
|
||||
Super extends ZodSchemaAbstractClass<SuperInstance, SuperSchemaT, SuperSchemaUnknownKeys, SuperSchemaCatchall, SuperValues, SuperDefaultValues>,
|
||||
SuperInstance extends SuperValues,
|
||||
|
||||
SuperSchemaT extends z.ZodRawShape,
|
||||
SuperSchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SuperSchemaCatchall extends z.ZodTypeAny,
|
||||
SuperValues extends {},
|
||||
SuperDefaultValues extends Partial<SuperValues>,
|
||||
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
Values extends SuperValues,
|
||||
DefaultValues extends Partial<Values>,
|
||||
>(
|
||||
this: Super | ZodSchemaAbstractClass<SuperInstance, SuperSchemaT, SuperSchemaUnknownKeys, SuperSchemaCatchall, SuperValues, SuperDefaultValues>,
|
||||
|
||||
props: {
|
||||
schema: (props: {
|
||||
schema: Super["schema"]
|
||||
shape: Super["schema"]["shape"]
|
||||
}) => z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
|
||||
|
||||
defaultValues: (defaultValues: SuperDefaultValues) => DefaultValues
|
||||
},
|
||||
): (
|
||||
AbstractClass<
|
||||
Extend<[SuperInstance, Values]>,
|
||||
[values: Values]
|
||||
> &
|
||||
Extend<[
|
||||
StaticMembers<Super>,
|
||||
{
|
||||
readonly schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>,
|
||||
readonly defaultValues: DefaultValues,
|
||||
},
|
||||
]>
|
||||
) {
|
||||
const schema = props.schema({ schema: this.schema, shape: this.schema.shape })
|
||||
const defaultValues = props.defaultValues(this.defaultValues)
|
||||
|
||||
return class extends this {
|
||||
static readonly schema = schema
|
||||
static readonly defaultValues = defaultValues
|
||||
} as any
|
||||
}
|
||||
})
|
||||
.build()
|
||||
104
src/traits/InstantiableZodSchemaObject.ts
Normal file
104
src/traits/InstantiableZodSchemaObject.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { trait } from "@thilawyn/traitify-ts"
|
||||
import { Effect, pipe } from "effect"
|
||||
import { HasRequiredKeys } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { ZodSchemaClass } from "../shapes/ZodSchemaClass"
|
||||
import { parseZodTypeEffect } from "../util"
|
||||
|
||||
|
||||
type NewZodSchemaInstanceInput<
|
||||
Values extends {},
|
||||
DefaultValues extends Partial<Values>,
|
||||
> = {
|
||||
[Key in Exclude<keyof Values, keyof DefaultValues>]: Values[Key]
|
||||
} & {
|
||||
[Key in keyof DefaultValues]?: Key extends keyof Values
|
||||
? Values[Key]
|
||||
: never
|
||||
}
|
||||
|
||||
type ParseParamsArgs = [] | [params: Partial<z.ParseParams>]
|
||||
|
||||
type NewZodSchemaInstanceArgs<Input extends object> = (
|
||||
HasRequiredKeys<Input> extends true
|
||||
? [values: Input, ...args: ParseParamsArgs]
|
||||
: [] | [values: Input, ...args: ParseParamsArgs]
|
||||
)
|
||||
|
||||
|
||||
export const InstantiableZodSchemaObject = trait
|
||||
.implement(Super => class InstantiableZodSchemaObject extends Super {
|
||||
static create<
|
||||
Instance extends Values,
|
||||
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
|
||||
Values extends {},
|
||||
DefaultValues extends Partial<Values>,
|
||||
>(
|
||||
this: ZodSchemaClass<Instance, SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, DefaultValues>,
|
||||
|
||||
...[values, params]: NewZodSchemaInstanceArgs<
|
||||
NewZodSchemaInstanceInput<Values, DefaultValues>
|
||||
>
|
||||
) {
|
||||
return new this(
|
||||
this.schema.parse({ ...this.defaultValues, ...values }, params)
|
||||
)
|
||||
}
|
||||
|
||||
static async createPromise<
|
||||
Instance extends Values,
|
||||
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
|
||||
Values extends {},
|
||||
DefaultValues extends Partial<Values>,
|
||||
>(
|
||||
this: ZodSchemaClass<Instance, SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, DefaultValues>,
|
||||
|
||||
...[values, params]: NewZodSchemaInstanceArgs<
|
||||
NewZodSchemaInstanceInput<Values, DefaultValues>
|
||||
>
|
||||
) {
|
||||
return new this(
|
||||
await this.schema.parseAsync({ ...this.defaultValues, ...values }, params)
|
||||
)
|
||||
}
|
||||
|
||||
static createEffect<
|
||||
Instance extends Values,
|
||||
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
|
||||
Values extends {},
|
||||
DefaultValues extends Partial<Values>,
|
||||
>(
|
||||
this: ZodSchemaClass<Instance, SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, DefaultValues>,
|
||||
|
||||
...[values, params]: NewZodSchemaInstanceArgs<
|
||||
NewZodSchemaInstanceInput<Values, DefaultValues>
|
||||
>
|
||||
) {
|
||||
return pipe(
|
||||
parseZodTypeEffect(
|
||||
this.schema,
|
||||
{ ...this.defaultValues, ...values },
|
||||
params,
|
||||
),
|
||||
|
||||
Effect.map(values => new this(values)),
|
||||
)
|
||||
}
|
||||
|
||||
protected static initialize() {
|
||||
|
||||
}
|
||||
})
|
||||
.build()
|
||||
10
src/traits/ObservableZodSchemaObject.ts
Normal file
10
src/traits/ObservableZodSchemaObject.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { trait } from "@thilawyn/traitify-ts"
|
||||
|
||||
|
||||
export const ObservableZodSchemaObject = trait
|
||||
.implement(Super => class ObservableZodSchemaObject extends Super {
|
||||
constructor(...args: any[]) {
|
||||
super(...args)
|
||||
}
|
||||
})
|
||||
.build()
|
||||
101
src/util/class.ts
Normal file
101
src/util/class.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { AbstractClass, Class as ConcreteClass } from "type-fest"
|
||||
|
||||
|
||||
/**
|
||||
* Represents the possible types of a class.
|
||||
*/
|
||||
export type ClassType = "AbstractClass" | "Class"
|
||||
|
||||
/**
|
||||
* Represents a class based on the specified type.
|
||||
* @template Type - The type of the class ("AbstractClass" or "Class").
|
||||
* @template T - The type parameter of the class.
|
||||
* @template Arguments - The type of arguments the class constructor takes.
|
||||
*/
|
||||
export type Class<
|
||||
Type extends ClassType,
|
||||
T,
|
||||
Arguments extends unknown[] = any[],
|
||||
> = (
|
||||
Type extends "AbstractClass"
|
||||
? AbstractClass<T, Arguments>
|
||||
: Type extends "Class"
|
||||
? ConcreteClass<T, Arguments>
|
||||
: never
|
||||
)
|
||||
|
||||
/**
|
||||
* Gets the type of a class (either "Class" or "AbstractClass").
|
||||
* @template C - The class type to determine.
|
||||
*/
|
||||
export type GetClassType<C> = (
|
||||
C extends ConcreteClass<any>
|
||||
? "Class"
|
||||
: C extends AbstractClass<any>
|
||||
? "AbstractClass"
|
||||
: never
|
||||
)
|
||||
|
||||
/**
|
||||
* Represents an array of instances corresponding to the provided classes.
|
||||
* @template Classes - An array of classes extending AbstractClass.
|
||||
*/
|
||||
export type ClassesInstances<Classes extends readonly AbstractClass<any>[]> = (
|
||||
Classes extends [infer Class, ...infer Rest]
|
||||
? Class extends AbstractClass<any>
|
||||
? Rest extends AbstractClass<any>[]
|
||||
? [InstanceType<Class>, ...ClassesInstances<Rest>]
|
||||
: never
|
||||
: never
|
||||
: []
|
||||
)
|
||||
|
||||
/**
|
||||
* Represents an intersection of instances of the provided classes.
|
||||
* @template Classes - An array of classes extending AbstractClass.
|
||||
*/
|
||||
export type ClassesInstancesIntersection<Classes extends readonly AbstractClass<any>[]> = (
|
||||
Classes extends [infer Class, ...infer Rest]
|
||||
? Class extends AbstractClass<any>
|
||||
? Rest extends AbstractClass<any>[]
|
||||
? InstanceType<Class> & ClassesInstancesIntersection<Rest>
|
||||
: never
|
||||
: never
|
||||
: {}
|
||||
)
|
||||
|
||||
/**
|
||||
* Represents the static members of a class.
|
||||
* @template Class - A class extending AbstractClass.
|
||||
*/
|
||||
export type StaticMembers<Class extends AbstractClass<any>> = (
|
||||
Omit<Class, "prototype">
|
||||
)
|
||||
|
||||
/**
|
||||
* Represents an array of static members corresponding to the provided classes.
|
||||
* @template Classes - An array of classes extending AbstractClass.
|
||||
*/
|
||||
export type ClassesStaticMembers<Classes extends readonly AbstractClass<any>[]> = (
|
||||
Classes extends [infer Class, ...infer Rest]
|
||||
? Class extends AbstractClass<any>
|
||||
? Rest extends AbstractClass<any>[]
|
||||
? [StaticMembers<Class>, ...ClassesStaticMembers<Rest>]
|
||||
: never
|
||||
: never
|
||||
: []
|
||||
)
|
||||
|
||||
/**
|
||||
* Represents an intersection of static members of the provided classes.
|
||||
* @template Classes - An array of classes extending AbstractClass.
|
||||
*/
|
||||
export type ClassesStaticMembersIntersection<Classes extends readonly AbstractClass<any>[]> = (
|
||||
Classes extends [infer Class, ...infer Rest]
|
||||
? Class extends AbstractClass<any>
|
||||
? Rest extends AbstractClass<any>[]
|
||||
? StaticMembers<Class> & ClassesStaticMembersIntersection<Rest>
|
||||
: never
|
||||
: never
|
||||
: {}
|
||||
)
|
||||
@@ -1,37 +1,7 @@
|
||||
import { Effect, pipe } from "effect"
|
||||
import { AbstractClass, Class as ConcreteClass } from "type-fest"
|
||||
import { z } from "zod"
|
||||
|
||||
|
||||
export function identity<T>(value: T) {
|
||||
return value
|
||||
}
|
||||
|
||||
|
||||
export type ClassType = "AbstractClass" | "Class"
|
||||
|
||||
export type Class<
|
||||
Type extends ClassType,
|
||||
T,
|
||||
Arguments extends unknown[] = any[],
|
||||
> = (
|
||||
Type extends "AbstractClass"
|
||||
? AbstractClass<T, Arguments>
|
||||
: Type extends "Class"
|
||||
? ConcreteClass<T, Arguments>
|
||||
: never
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
* Represents the static members of a class.
|
||||
* @template C - The class type.
|
||||
*/
|
||||
export type StaticMembers<C> = {
|
||||
[Key in keyof C as Key extends "prototype" ? never : Key]: C[Key]
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a value using a ZodType schema wrapped in an Effect monad.
|
||||
*
|
||||
40
src/util/extend.ts
Normal file
40
src/util/extend.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Represents the common keys between two types.
|
||||
* @template A - The first type.
|
||||
* @template B - The second type.
|
||||
*/
|
||||
export type CommonKeys<A, B> = Extract<keyof A, keyof B>
|
||||
|
||||
export type Extend<T extends readonly object[]> = (
|
||||
T extends [
|
||||
infer Super,
|
||||
infer Self,
|
||||
...infer Rest extends object[],
|
||||
]
|
||||
? Pick<Self, CommonKeys<Self, Super>> extends Pick<Super, CommonKeys<Self, Super>>
|
||||
? Extend<[
|
||||
Omit<Super, CommonKeys<Self, Super>> & Self,
|
||||
...Rest,
|
||||
]>
|
||||
: never
|
||||
: T extends [infer Self]
|
||||
? Self
|
||||
: {}
|
||||
)
|
||||
|
||||
/**
|
||||
* Merges an inheritance tree defined by an array of types without allowing overrides.
|
||||
* @template T - An array of types representing the inheritance tree.
|
||||
*/
|
||||
export type ExtendWithoutOverriding<T extends readonly any[]> = (
|
||||
T extends [infer Super, infer Self, ...infer Rest]
|
||||
? Pick<Self, CommonKeys<Self, Super>> extends Pick<Super, CommonKeys<Self, Super>>
|
||||
? ExtendWithoutOverriding<[
|
||||
Super & Self,
|
||||
...Rest,
|
||||
]>
|
||||
: never
|
||||
: T extends [infer Self]
|
||||
? Self
|
||||
: void
|
||||
)
|
||||
4
src/util/index.ts
Normal file
4
src/util/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from "./class"
|
||||
export * from "./effect"
|
||||
export * from "./extend"
|
||||
export * from "./misc"
|
||||
3
src/util/misc.ts
Normal file
3
src/util/misc.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export function identity<T>(value: T) {
|
||||
return value
|
||||
}
|
||||
Reference in New Issue
Block a user