Compare commits
2 Commits
73ce4e11ff
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07e1eabcf1 | ||
|
|
2e09d9a0e0 |
@@ -16,8 +16,8 @@ local lint_step = {
|
||||
|
||||
local build_step = {
|
||||
name: "build",
|
||||
image: bun_image,
|
||||
commands: ["bun run build"],
|
||||
image: node_image,
|
||||
commands: ["npm run build"],
|
||||
};
|
||||
|
||||
local pack_step = {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# schemable-class
|
||||
# zod-schema-class
|
||||
|
||||
Create TypeScript classes out of Zod schemas
|
||||
|
||||
64
package.json
64
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thilawyn/schemable-class",
|
||||
"version": "0.1.2",
|
||||
"name": "@thilawyn/zod-schema-class",
|
||||
"version": "0.1.3",
|
||||
"type": "module",
|
||||
"publishConfig": {
|
||||
"registry": "https://git.jvalver.de/api/packages/thilawyn/npm/"
|
||||
@@ -8,65 +8,59 @@
|
||||
"files": [
|
||||
"./dist"
|
||||
],
|
||||
"types": "./dist/lib.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/schemable.d.mts",
|
||||
"default": "./dist/schemable.mjs"
|
||||
"types": "./dist/lib.d.ts",
|
||||
"default": "./dist/lib.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/schemable.d.cts",
|
||||
"default": "./dist/schemable.cjs"
|
||||
"types": "./dist/lib.d.cts",
|
||||
"default": "./dist/lib.cjs"
|
||||
}
|
||||
},
|
||||
"./jsonifiable": {
|
||||
"./schema": {
|
||||
"import": {
|
||||
"types": "./dist/jsonifiable.d.mts",
|
||||
"default": "./dist/jsonifiable.mjs"
|
||||
"types": "./dist/schema/lib.d.ts",
|
||||
"default": "./dist/schema/lib.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/jsonifiable.d.cts",
|
||||
"default": "./dist/jsonifiable.cjs"
|
||||
}
|
||||
},
|
||||
"./observable": {
|
||||
"import": {
|
||||
"types": "./dist/observable.d.mts",
|
||||
"default": "./dist/observable.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/observable.d.cts",
|
||||
"default": "./dist/observable.cjs"
|
||||
"types": "./dist/schema/lib.d.cts",
|
||||
"default": "./dist/schema/lib.cjs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rollup -c rollup.config.ts",
|
||||
"build": "tsup",
|
||||
"lint:tsc": "tsc --noEmit",
|
||||
"clean:cache": "rm -f tsconfig.tsbuildinfo",
|
||||
"clean:dist": "rm -rf dist",
|
||||
"clean:node": "rm -rf node_modules"
|
||||
},
|
||||
"dependencies": {
|
||||
"@thilawyn/traitify-ts": "^0.1.3",
|
||||
"decimal.js": "^10.4.3",
|
||||
"effect": "^2.2.5",
|
||||
"@thilawyn/traitify-ts": "^0.1.19",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mobx": "^6.12.0",
|
||||
"type-fest": "^4.10.2",
|
||||
"type-fest": "^4.14.0",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"mobx": "^6.12.1",
|
||||
"decimal.js": "^10.4.3",
|
||||
"effect": "^2.4.11"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"mobx": { "optional": true },
|
||||
"decimal.js": { "optional": true },
|
||||
"effect": { "optional": true }
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"bun-types": "latest",
|
||||
"npm-check-updates": "^16.14.14",
|
||||
"npm-check-updates": "^16.14.17",
|
||||
"npm-sort": "^0.0.4",
|
||||
"rollup": "^4.9.6",
|
||||
"rollup-plugin-cleanup": "^3.2.1",
|
||||
"rollup-plugin-ts": "^3.4.5",
|
||||
"ts-functional-pipe": "^3.1.2",
|
||||
"tsx": "^4.7.0",
|
||||
"typescript": "^5.3.3"
|
||||
"tsup": "^8.0.2",
|
||||
"tsx": "^4.7.1",
|
||||
"typescript": "^5.4.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import { nodeResolve } from "@rollup/plugin-node-resolve"
|
||||
import { defineConfig } from "rollup"
|
||||
import cleanup from "rollup-plugin-cleanup"
|
||||
import ts from "rollup-plugin-ts"
|
||||
import pkg from "./package.json" assert { type: "json" }
|
||||
|
||||
|
||||
export const createBundleConfig = (
|
||||
input: string,
|
||||
name: keyof typeof pkg.exports,
|
||||
) =>
|
||||
defineConfig({
|
||||
input,
|
||||
|
||||
output: [
|
||||
{
|
||||
file: pkg.exports[name].import.default,
|
||||
format: "esm",
|
||||
},
|
||||
{
|
||||
file: pkg.exports[name].require.default,
|
||||
format: "cjs",
|
||||
},
|
||||
],
|
||||
|
||||
external: id => !/^[./]/.test(id),
|
||||
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
ts(),
|
||||
|
||||
cleanup({
|
||||
comments: "jsdoc",
|
||||
extensions: ["ts"],
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
export default [
|
||||
createBundleConfig("src/index.ts", "."),
|
||||
createBundleConfig("src/jsonifiable/index.ts", "./jsonifiable"),
|
||||
createBundleConfig("src/observable/index.ts", "./observable"),
|
||||
]
|
||||
56
src/ExtendZodSchemaClass.ts
Normal file
56
src/ExtendZodSchemaClass.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { TraitInstance, TraitStaticMembers, expression } from "@thilawyn/traitify-ts"
|
||||
import { AbstractClass } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { ZodSchemaObject, ZodSchemaObjectTrait } from "./traits/ZodSchemaObject"
|
||||
import { Extend, StaticMembers } from "./util"
|
||||
|
||||
|
||||
export function ExtendZodSchemaClass<
|
||||
Self extends (
|
||||
AbstractClass<
|
||||
Values & TraitInstance<ZodSchemaObjectTrait<T, Catchall, Values, PartialValues>>,
|
||||
[values: Values]
|
||||
> &
|
||||
TraitStaticMembers<ZodSchemaObjectTrait<T, Catchall, Values, PartialValues>>
|
||||
),
|
||||
|
||||
T extends z.ZodRawShape,
|
||||
Catchall extends z.ZodTypeAny,
|
||||
Values extends object,
|
||||
PartialValues extends Partial<Values>,
|
||||
|
||||
ExtendedT extends z.ZodRawShape,
|
||||
ExtendedCatchall extends z.ZodTypeAny,
|
||||
ExtendedValues extends Values,
|
||||
ExtendedPartialValues extends Partial<ExtendedValues>,
|
||||
>(
|
||||
class_: Self | (
|
||||
AbstractClass<
|
||||
Values & TraitInstance<ZodSchemaObjectTrait<T, Catchall, Values, PartialValues>>,
|
||||
[values: Values]
|
||||
> &
|
||||
TraitStaticMembers<ZodSchemaObjectTrait<T, Catchall, Values, PartialValues>>
|
||||
),
|
||||
|
||||
schemaWithDefaults: (
|
||||
schemaWithDefaults: z.ZodObject<T, "strip", Catchall, Values, PartialValues>
|
||||
) => z.ZodObject<ExtendedT, "strip", ExtendedCatchall, ExtendedValues, ExtendedPartialValues>,
|
||||
) {
|
||||
return expression
|
||||
.extends(
|
||||
class_ as (
|
||||
AbstractClass<
|
||||
Omit<
|
||||
Extend<[InstanceType<Self>, ExtendedValues]>,
|
||||
keyof TraitInstance<ZodSchemaObjectTrait<T, Catchall, Values, PartialValues>>
|
||||
>,
|
||||
[values: ExtendedValues]
|
||||
> &
|
||||
Omit<
|
||||
StaticMembers<Self>,
|
||||
keyof TraitStaticMembers<ZodSchemaObjectTrait<T, Catchall, Values, PartialValues>>
|
||||
>
|
||||
)
|
||||
)
|
||||
.expresses(ZodSchemaObject(schemaWithDefaults((class_ as Self).schemaWithDefaults)))
|
||||
}
|
||||
42
src/JsonifiedZodSchemaClass.ts
Normal file
42
src/JsonifiedZodSchemaClass.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { expression } from "@thilawyn/traitify-ts"
|
||||
import { Class, Jsonifiable } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { JsonifiedZodSchemaObject, OfClass, OfClassInstance } from "./traits/JsonifiedZodSchemaObject"
|
||||
|
||||
|
||||
export function JsonifiedZodSchemaClass<
|
||||
Of extends OfClass<OfInstance, T, Catchall, Values, PartialValues>,
|
||||
OfInstance extends OfClassInstance<T, Catchall, Values, PartialValues>,
|
||||
T extends z.ZodRawShape,
|
||||
Catchall extends z.ZodTypeAny,
|
||||
Values extends object,
|
||||
PartialValues extends Partial<Values>,
|
||||
|
||||
JsonifyT extends z.ZodRawShape,
|
||||
JsonifyCatchall extends z.ZodTypeAny,
|
||||
DejsonifyT extends z.ZodRawShape,
|
||||
DejsonifyCatchall extends z.ZodTypeAny,
|
||||
JsonifiedValues extends object & Jsonifiable,
|
||||
>(
|
||||
of: Of | OfClass<OfInstance, T, Catchall, Values, PartialValues>,
|
||||
|
||||
props: {
|
||||
jsonifySchema: (
|
||||
schema: typeof of.schema
|
||||
) => z.ZodObject<JsonifyT, "strip", JsonifyCatchall, JsonifiedValues, Values>,
|
||||
|
||||
dejsonifySchema: (
|
||||
schema: typeof of.schema
|
||||
) => z.ZodObject<DejsonifyT, "strip", DejsonifyCatchall, Values, JsonifiedValues>,
|
||||
},
|
||||
) {
|
||||
return expression
|
||||
.extends(
|
||||
class JsonifiedZodSchemaObjectConstructor {
|
||||
constructor(values: JsonifiedValues) {
|
||||
Object.assign(this, values)
|
||||
}
|
||||
} as Class<JsonifiedValues, [values: JsonifiedValues]>
|
||||
)
|
||||
.expresses(JsonifiedZodSchemaObject(of as Of, props))
|
||||
}
|
||||
@@ -1,74 +1,24 @@
|
||||
import { expression } from "@thilawyn/traitify-ts"
|
||||
import { AbstractClass } from "type-fest"
|
||||
import { Class } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { ExtendableZodSchemaObject } from "./traits/ExtendableZodSchemaObject"
|
||||
import { InstantiableZodSchemaObject } from "./traits/InstantiableZodSchemaObject"
|
||||
import { Extend, StaticMembers } from "./util"
|
||||
import { ZodSchemaObject } from "./traits/ZodSchemaObject"
|
||||
|
||||
|
||||
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>,
|
||||
T extends z.ZodRawShape,
|
||||
Catchall extends z.ZodTypeAny,
|
||||
Values extends object,
|
||||
PartialValues extends Partial<Values>,
|
||||
>(
|
||||
props: {
|
||||
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
|
||||
defaultValues: DefaultValues
|
||||
},
|
||||
schemaWithDefaults: z.ZodObject<T, "strip", Catchall, Values, PartialValues>
|
||||
) {
|
||||
return ZodSchemaClassOf(DefaultRoot, props)
|
||||
return expression
|
||||
.extends(
|
||||
class ZodSchemaObjectConstructor {
|
||||
constructor(values: Values) {
|
||||
Object.assign(this, values)
|
||||
}
|
||||
} as Class<Values, [values: Values]>
|
||||
)
|
||||
.expresses(ZodSchemaObject(schemaWithDefaults))
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import { Opaque } from "type-fest"
|
||||
|
||||
|
||||
export type DefinedDefaultValuesTag = "@thilawyn/schemable-class/DefinedDefaultValues"
|
||||
|
||||
export function defineDefaultValues<T>(values: T) {
|
||||
return values as Opaque<T, DefinedDefaultValuesTag>
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
import { AbstractClass, Class as ConcreteClass, Opaque } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { DefinedDefaultValuesTag, SchemableClass } from "."
|
||||
import { StaticMembers } from "../util"
|
||||
|
||||
|
||||
export function extendSchemableClass<
|
||||
C extends SchemableClass<
|
||||
ExtendSchemaT,
|
||||
ExtendSchemaUnknownKeys,
|
||||
ExtendSchemaCatchall,
|
||||
ExtendSchemaValues,
|
||||
ExtendDefaultValues
|
||||
>,
|
||||
|
||||
ExtendSchemaT extends z.ZodRawShape,
|
||||
ExtendSchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
ExtendSchemaCatchall extends z.ZodTypeAny,
|
||||
ExtendSchemaValues extends {},
|
||||
ExtendDefaultValues extends Partial<ExtendSchemaValues>,
|
||||
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
SchemaValues extends ExtendSchemaValues,
|
||||
|
||||
DefaultValues extends Partial<SchemaValues>,
|
||||
>(
|
||||
extend: C | SchemableClass<
|
||||
ExtendSchemaT,
|
||||
ExtendSchemaUnknownKeys,
|
||||
ExtendSchemaCatchall,
|
||||
ExtendSchemaValues,
|
||||
ExtendDefaultValues
|
||||
>,
|
||||
|
||||
props: {
|
||||
schema: (props: {
|
||||
schema: z.ZodObject<
|
||||
ExtendSchemaT,
|
||||
ExtendSchemaUnknownKeys,
|
||||
ExtendSchemaCatchall,
|
||||
ExtendSchemaValues,
|
||||
ExtendSchemaValues
|
||||
>
|
||||
|
||||
shape: ExtendSchemaT
|
||||
}) => z.ZodObject<
|
||||
SchemaT,
|
||||
SchemaUnknownKeys,
|
||||
SchemaCatchall,
|
||||
SchemaValues,
|
||||
SchemaValues
|
||||
>
|
||||
|
||||
defaultValues: (defaultValues: ExtendDefaultValues) => Opaque<DefaultValues, DefinedDefaultValuesTag>
|
||||
},
|
||||
) {
|
||||
type Class<T, Arguments extends unknown[]> = (
|
||||
C extends ConcreteClass<any>
|
||||
? ConcreteClass<T, Arguments>
|
||||
: AbstractClass<T, Arguments>
|
||||
)
|
||||
|
||||
const schema = props.schema({
|
||||
schema: extend.schema,
|
||||
shape: extend.schema.shape,
|
||||
})
|
||||
const defaultValues = props.defaultValues(extend.defaultValues)
|
||||
|
||||
return class extends extend {
|
||||
static readonly schema = schema
|
||||
readonly schema = schema
|
||||
|
||||
static readonly defaultValues = defaultValues
|
||||
readonly defaultValues = defaultValues
|
||||
} as unknown as (
|
||||
Class<
|
||||
Omit<InstanceType<C>, "schema" | "defaultValues" | keyof ExtendSchemaValues> &
|
||||
{
|
||||
readonly schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaValues, SchemaValues>,
|
||||
readonly defaultValues: DefaultValues,
|
||||
} &
|
||||
SchemaValues,
|
||||
|
||||
Parameters<(values: SchemaValues) => void>
|
||||
> &
|
||||
|
||||
Omit<StaticMembers<C>, "schema" | "defaultValues"> &
|
||||
{
|
||||
readonly schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaValues, SchemaValues>,
|
||||
readonly defaultValues: DefaultValues,
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -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,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>),
|
||||
)
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export * from "./makeSchemableClassObservable"
|
||||
@@ -1,29 +0,0 @@
|
||||
import { mapValues } from "lodash-es"
|
||||
import { makeObservable, observable } from "mobx"
|
||||
import { AbstractConstructor } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { SchemableClass } from ".."
|
||||
|
||||
|
||||
export function makeSchemableClassObservable<
|
||||
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>,
|
||||
>(
|
||||
extend: C | SchemableClass<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, DefaultValues>
|
||||
) {
|
||||
return class extends (extend as AbstractConstructor<any>) {
|
||||
constructor(...args: any[]) {
|
||||
super(...args)
|
||||
|
||||
makeObservable(this,
|
||||
mapValues(this.schema.shape, () => observable)
|
||||
)
|
||||
}
|
||||
} as unknown as C
|
||||
}
|
||||
@@ -1 +1,6 @@
|
||||
export { ExtendableZodSchemaObject } from "./traits/ExtendableZodSchemaObject"
|
||||
export { ExtendZodSchemaClass } from "./ExtendZodSchemaClass"
|
||||
export { JsonifiedZodSchemaClass } from "./JsonifiedZodSchemaClass"
|
||||
export { ZodSchemaClass } from "./ZodSchemaClass"
|
||||
export { JsonifiedZodSchemaObject } from "./traits/JsonifiedZodSchemaObject"
|
||||
export { MobXObservableZodSchemaObject } from "./traits/MobXObservableZodSchemaObject"
|
||||
export { ZodSchemaObject, ZodSchemaObjectTrait } from "./traits/ZodSchemaObject"
|
||||
|
||||
19
src/schema/bigint.ts
Normal file
19
src/schema/bigint.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { z } from "zod"
|
||||
|
||||
|
||||
type JsonifiedBigIntBrand = "@thilawyn/zod-schema-class/JsonifiedBigInt"
|
||||
|
||||
|
||||
export function jsonify<S extends z.ZodType<bigint>>(schema: S) {
|
||||
return schema
|
||||
.transform(v => v.toString())
|
||||
.brand<JsonifiedBigIntBrand>()
|
||||
}
|
||||
|
||||
export function dejsonify<S extends z.ZodType<bigint>>(schema: S) {
|
||||
return z
|
||||
.custom<string & z.BRAND<JsonifiedBigIntBrand>>()
|
||||
.pipe(z.string())
|
||||
.pipe(z.coerce.bigint())
|
||||
.pipe(schema)
|
||||
}
|
||||
19
src/schema/date.ts
Normal file
19
src/schema/date.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { z } from "zod"
|
||||
|
||||
|
||||
type JsonifiedDateBrand = "@thilawyn/zod-schema-class/JsonifiedDate"
|
||||
|
||||
|
||||
export function jsonify<S extends z.ZodType<Date>>(schema: S) {
|
||||
return schema
|
||||
.transform(v => v.toString())
|
||||
.brand<JsonifiedDateBrand>()
|
||||
}
|
||||
|
||||
export function dejsonify<S extends z.ZodType<Date>>(schema: S) {
|
||||
return z
|
||||
.custom<string & z.BRAND<JsonifiedDateBrand>>()
|
||||
.pipe(z.string())
|
||||
.pipe(z.coerce.date())
|
||||
.pipe(schema)
|
||||
}
|
||||
36
src/schema/decimal.ts
Normal file
36
src/schema/decimal.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import Decimal from "decimal.js"
|
||||
import { z } from "zod"
|
||||
|
||||
|
||||
type JsonifiedDecimalBrand = "@thilawyn/zod-schema-class/JsonifiedDecimal"
|
||||
|
||||
|
||||
export function decimal() {
|
||||
return z.custom<Decimal>(v => Decimal.isDecimal(v))
|
||||
}
|
||||
|
||||
export module decimal {
|
||||
export function jsonifyDecimalSchema<S extends z.ZodType<Decimal>>(schema: S) {
|
||||
return schema
|
||||
.transform(v => v.toJSON())
|
||||
.brand<JsonifiedDecimalBrand>()
|
||||
}
|
||||
|
||||
export function dejsonifyDecimalSchema<S extends z.ZodType<Decimal>>(schema: S) {
|
||||
return z
|
||||
.custom<string & z.BRAND<JsonifiedDecimalBrand>>()
|
||||
.pipe(
|
||||
z
|
||||
.string()
|
||||
.transform(v => {
|
||||
try {
|
||||
return new Decimal(v)
|
||||
}
|
||||
catch (e) {
|
||||
return v
|
||||
}
|
||||
})
|
||||
)
|
||||
.pipe(schema)
|
||||
}
|
||||
}
|
||||
1
src/schema/effect/index.ts
Normal file
1
src/schema/effect/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { option } from "./option"
|
||||
146
src/schema/effect/option.ts
Normal file
146
src/schema/effect/option.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
import { Option } from "effect"
|
||||
import { identity } from "lodash-es"
|
||||
import { z } from "zod"
|
||||
|
||||
|
||||
type JsonifiedEffectOptionSomeBrand = "@thilawyn/zod-schema-class/JsonifiedEffectOptionSome"
|
||||
|
||||
|
||||
export function option<InnerS extends z.ZodTypeAny>(schema: InnerS) {
|
||||
return z.union([option.some(schema), option.none(schema)])
|
||||
}
|
||||
|
||||
export module option {
|
||||
export type Option<InnerS extends z.ZodTypeAny> = ReturnType<typeof option<InnerS>>
|
||||
|
||||
function getSomeSchema<InnerS extends z.ZodTypeAny>(schema: Option<InnerS>): some.Some<InnerS> {
|
||||
return schema.options[0]
|
||||
}
|
||||
function getNoneSchema<InnerS extends z.ZodTypeAny>(schema: Option<InnerS>): none.None<InnerS> {
|
||||
return schema.options[1]
|
||||
}
|
||||
|
||||
|
||||
export function jsonify<
|
||||
InnerS extends z.ZodTypeAny,
|
||||
JsonifiedInnerS extends z.ZodTypeAny = InnerS,
|
||||
>(
|
||||
schema: Option<InnerS>,
|
||||
jsonifySchema: (schema: InnerS) => JsonifiedInnerS = identity,
|
||||
) {
|
||||
return z.union([
|
||||
some.jsonify(getSomeSchema(schema), jsonifySchema),
|
||||
none.jsonify(getNoneSchema(schema), jsonifySchema),
|
||||
])
|
||||
}
|
||||
|
||||
export function dejsonify<
|
||||
InnerS extends z.ZodTypeAny,
|
||||
DejsonifiedInnerS extends z.ZodTypeAny = InnerS,
|
||||
>(
|
||||
schema: Option<InnerS>,
|
||||
dejsonifySchema: (schema: InnerS) => DejsonifiedInnerS = identity,
|
||||
) {
|
||||
return z.union([
|
||||
some.dejsonify(getSomeSchema(schema), dejsonifySchema),
|
||||
none.dejsonify(getNoneSchema(schema), dejsonifySchema),
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
export function some<
|
||||
InnerS extends z.ZodTypeAny
|
||||
>(
|
||||
schema: InnerS
|
||||
) {
|
||||
return z
|
||||
.custom<Option.Some<z.output<InnerS>>>(
|
||||
v => Option.isOption(v) && Option.isSome(v),
|
||||
"Not an Option.Some",
|
||||
)
|
||||
.pipe(z.object({ value: schema }).passthrough())
|
||||
.transform(v => Option.some<z.output<InnerS>>(v.value))
|
||||
}
|
||||
|
||||
export module some {
|
||||
export type Some<InnerS extends z.ZodTypeAny> = ReturnType<typeof some<InnerS>>
|
||||
|
||||
function getInnerSchema<InnerS extends z.ZodTypeAny>(schema: Some<InnerS>): InnerS {
|
||||
return schema._def.schema._def.out.shape.value
|
||||
}
|
||||
|
||||
|
||||
export function jsonify<
|
||||
InnerS extends z.ZodTypeAny,
|
||||
JsonifiedInnerS extends z.ZodTypeAny = InnerS,
|
||||
>(
|
||||
schema: Some<InnerS>,
|
||||
jsonifySchema: (schema: InnerS) => JsonifiedInnerS = identity,
|
||||
) {
|
||||
return schema
|
||||
.transform(v => Option.getOrThrow(v))
|
||||
.pipe(jsonifySchema(getInnerSchema(schema)))
|
||||
.brand<JsonifiedEffectOptionSomeBrand>()
|
||||
}
|
||||
|
||||
export function dejsonify<
|
||||
InnerS extends z.ZodTypeAny,
|
||||
DejsonifiedInnerS extends z.ZodTypeAny = InnerS,
|
||||
>(
|
||||
schema: Some<InnerS>,
|
||||
dejsonifySchema: (schema: InnerS) => DejsonifiedInnerS = identity,
|
||||
) {
|
||||
return z
|
||||
.custom<z.input<DejsonifiedInnerS> & z.BRAND<JsonifiedEffectOptionSomeBrand>>()
|
||||
.pipe(dejsonifySchema(getInnerSchema(schema)))
|
||||
.transform(v => Option.some<z.output<DejsonifiedInnerS>>(v))
|
||||
.pipe(schema)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function none<
|
||||
InnerS extends z.ZodTypeAny | unknown = unknown
|
||||
>(
|
||||
_schema?: InnerS
|
||||
) {
|
||||
return z.custom<
|
||||
Option.None<
|
||||
InnerS extends z.ZodTypeAny
|
||||
? z.output<InnerS>
|
||||
: unknown
|
||||
>
|
||||
>(
|
||||
v => Option.isOption(v) && Option.isNone(v),
|
||||
"Not an Option.None",
|
||||
)
|
||||
}
|
||||
|
||||
export module none {
|
||||
export type None<InnerS extends z.ZodTypeAny> = ReturnType<typeof none<InnerS>>
|
||||
|
||||
|
||||
export function jsonify<
|
||||
InnerS extends z.ZodTypeAny,
|
||||
JsonifiedInnerS extends z.ZodTypeAny = InnerS,
|
||||
>(
|
||||
schema: None<InnerS>,
|
||||
_jsonifySchema?: (schema: InnerS) => JsonifiedInnerS,
|
||||
) {
|
||||
return schema.transform(() => null)
|
||||
}
|
||||
|
||||
export function dejsonify<
|
||||
InnerS extends z.ZodTypeAny,
|
||||
DejsonifiedInnerS extends z.ZodTypeAny = InnerS,
|
||||
>(
|
||||
schema: None<InnerS>,
|
||||
_dejsonifySchema?: (schema: InnerS) => DejsonifiedInnerS,
|
||||
) {
|
||||
return z
|
||||
.null()
|
||||
.transform(() => Option.none<z.output<DejsonifiedInnerS>>())
|
||||
.pipe(schema)
|
||||
}
|
||||
}
|
||||
}
|
||||
12
src/schema/lib.ts
Normal file
12
src/schema/lib.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import * as bigint from "./bigint"
|
||||
import * as date from "./date"
|
||||
import { decimal } from "./decimal"
|
||||
import * as effect from "./effect"
|
||||
|
||||
|
||||
export const s = {
|
||||
bigint,
|
||||
date,
|
||||
decimal,
|
||||
effect,
|
||||
} as const
|
||||
@@ -1,43 +0,0 @@
|
||||
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
|
||||
}
|
||||
75
src/tests.ts
75
src/tests.ts
@@ -1,43 +1,60 @@
|
||||
import { Implements } from "@thilawyn/traitify-ts"
|
||||
import { Option } from "effect"
|
||||
import { z } from "zod"
|
||||
import { ExtendZodSchemaClass } from "./ExtendZodSchemaClass"
|
||||
import { JsonifiedZodSchemaClass } from "./JsonifiedZodSchemaClass"
|
||||
import { ZodSchemaClass } from "./ZodSchemaClass"
|
||||
import { s } from "./schema/lib"
|
||||
import { MobXObservableZodSchemaObject } from "./traits/MobXObservableZodSchemaObject"
|
||||
|
||||
|
||||
class Test extends ZodSchemaClass({
|
||||
schema: z.object({
|
||||
id: z.bigint(),
|
||||
const userExp = ZodSchemaClass(
|
||||
z.object({
|
||||
/** User ID */
|
||||
id: s.effect.option(z.bigint()).default(Option.none()),
|
||||
|
||||
/** Username */
|
||||
name: z.string(),
|
||||
|
||||
/** Role */
|
||||
role: z.enum(["User", "Moderator", "Admin"]).default("User"),
|
||||
})
|
||||
)
|
||||
.expresses(MobXObservableZodSchemaObject)
|
||||
.build()
|
||||
|
||||
@userExp.staticImplements
|
||||
class User extends userExp.extends implements Implements<typeof userExp> {}
|
||||
|
||||
const userInst = User.create({ id: Option.some(1n), name: "User" })
|
||||
const userInstEffect = User.createEffect({ id: Option.some(1n), name: "User" })
|
||||
|
||||
|
||||
const jsonifiedUserExp = JsonifiedZodSchemaClass(User, {
|
||||
jsonifySchema: schema => schema.extend({
|
||||
id: s.effect.option.jsonify(schema.shape.id, s.bigint.jsonify)
|
||||
}),
|
||||
|
||||
defaultValues: { id: -1n },
|
||||
}) {}
|
||||
|
||||
const Test2 = ZodSchemaClass({
|
||||
schema: z.object({
|
||||
id: z.bigint(),
|
||||
name: z.string(),
|
||||
dejsonifySchema: schema => schema.extend({
|
||||
id: s.effect.option.dejsonify(schema.shape.id, s.bigint.dejsonify)
|
||||
}),
|
||||
}).build()
|
||||
|
||||
defaultValues: { id: -1n },
|
||||
})
|
||||
@jsonifiedUserExp.staticImplements
|
||||
class JsonifiedUser extends jsonifiedUserExp.extends implements Implements<typeof jsonifiedUserExp> {}
|
||||
|
||||
Test.defaultValues
|
||||
const inst = Test.create({ id: 1n, name: "" })
|
||||
console.log(inst)
|
||||
const jsonifiedUserInst = JsonifiedUser.jsonify(userInst)
|
||||
// console.log(JSON.stringify(jsonifiedUserInst))
|
||||
console.log(jsonifiedUserInst.dejsonify().id)
|
||||
|
||||
|
||||
class SubTest extends Test.extend({
|
||||
schema: ({ schema }) => schema.extend({
|
||||
prout: z.string()
|
||||
}),
|
||||
const adminUserExp = ExtendZodSchemaClass(User,
|
||||
schema => schema.extend({
|
||||
role: z.literal("Admin").default("Admin")
|
||||
})
|
||||
).build()
|
||||
|
||||
defaultValues: defaultValues => ({
|
||||
...defaultValues
|
||||
}),
|
||||
}) {}
|
||||
@adminUserExp.staticImplements
|
||||
class AdminUser extends adminUserExp.extends implements Implements<typeof adminUserExp> {}
|
||||
|
||||
const subInst = await SubTest.createPromise({ name: "", prout: "" })
|
||||
console.log(subInst)
|
||||
|
||||
// class ChildTest extends Test {}
|
||||
|
||||
// ChildTest.instantiate({ name: "" })
|
||||
const admin = AdminUser.create({ id: Option.some(2n), name: "Admin" })
|
||||
|
||||
20
src/tests2.ts
Normal file
20
src/tests2.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { Option } from "effect"
|
||||
import { z } from "zod"
|
||||
import { s } from "./schema/lib"
|
||||
|
||||
|
||||
const schema = z.object({
|
||||
id: s.effect.option(z.bigint())
|
||||
})
|
||||
|
||||
const jsonifySchema = schema.extend({
|
||||
id: s.effect.option.jsonify(schema.shape.id, s.bigint.jsonify)
|
||||
})
|
||||
|
||||
const dejsonifySchema = schema.extend({
|
||||
id: s.effect.option.dejsonify(schema.shape.id, s.bigint.dejsonify)
|
||||
})
|
||||
|
||||
|
||||
const jsonified = jsonifySchema.parse({ id: Option.some(1n) })
|
||||
console.log(dejsonifySchema.parse(jsonified))
|
||||
@@ -1,58 +1,51 @@
|
||||
import { trait } from "@thilawyn/traitify-ts"
|
||||
import { ImplStatic, expression, implStaticThis } from "@thilawyn/traitify-ts"
|
||||
import { AbstractClass } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { ZodSchemaAbstractClass } from "../shapes/ZodSchemaClass"
|
||||
import { Extend, StaticMembers } from "../util"
|
||||
import { ZodSchemaObject } from "./ZodSchemaObject"
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
})
|
||||
export const ExtendableZodSchemaObject = <
|
||||
T extends z.ZodRawShape,
|
||||
Catchall extends z.ZodTypeAny,
|
||||
Values extends object,
|
||||
PartialValues extends Partial<Values>,
|
||||
>(
|
||||
schemaWithDefaults: z.ZodObject<T, "strip", Catchall, Values, PartialValues>,
|
||||
) => expression
|
||||
.expresses(ZodSchemaObject(schemaWithDefaults))
|
||||
.build()
|
||||
.subtrait()
|
||||
.implement(Super => class ExtendableZodSchemaObjectImpl extends Super {
|
||||
static extend<
|
||||
Self extends AbstractClass<Values, [values: Values]>,
|
||||
|
||||
ExtendedT extends z.ZodRawShape,
|
||||
ExtendedCatchall extends z.ZodTypeAny,
|
||||
ExtendedValues extends Values,
|
||||
ExtendedPartialValues extends Partial<ExtendedValues>,
|
||||
>(
|
||||
this: Self,
|
||||
|
||||
schemaWithDefaults: (
|
||||
schemaWithDefaults: z.ZodObject<T, "strip", Catchall, Values, PartialValues>
|
||||
) => z.ZodObject<ExtendedT, "strip", ExtendedCatchall, ExtendedValues, ExtendedPartialValues>,
|
||||
) {
|
||||
const t = implStaticThis(ExtendableZodSchemaObjectImpl, this)
|
||||
return expression
|
||||
.extends(
|
||||
t as unknown as (
|
||||
AbstractClass<
|
||||
Omit<
|
||||
Extend<[InstanceType<Self>, ExtendedValues]>,
|
||||
keyof ExtendableZodSchemaObjectImpl
|
||||
>,
|
||||
[values: ExtendedValues]
|
||||
> &
|
||||
Omit<StaticMembers<Self>, keyof ImplStatic<typeof ExtendableZodSchemaObjectImpl>>
|
||||
)
|
||||
)
|
||||
.expresses(ExtendableZodSchemaObject(schemaWithDefaults(t.schemaWithDefaults)))
|
||||
}
|
||||
})
|
||||
.build()
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
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()
|
||||
174
src/traits/JsonifiedZodSchemaObject.ts
Normal file
174
src/traits/JsonifiedZodSchemaObject.ts
Normal file
@@ -0,0 +1,174 @@
|
||||
import { TraitInstance, TraitStaticMembers, implStaticInstantiableThis, trait } from "@thilawyn/traitify-ts"
|
||||
import { Class, Jsonifiable } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { parseZodSchemaEffect } from "../util"
|
||||
import { ZodSchemaObjectTrait } from "./ZodSchemaObject"
|
||||
|
||||
|
||||
export type OfClass<
|
||||
Instance extends OfClassInstance<T, Catchall, Values, PartialValues>,
|
||||
|
||||
T extends z.ZodRawShape,
|
||||
Catchall extends z.ZodTypeAny,
|
||||
Values extends object,
|
||||
PartialValues extends Partial<Values>,
|
||||
> = (
|
||||
Class<Instance, [values: Values]> &
|
||||
TraitStaticMembers<ZodSchemaObjectTrait<T, Catchall, Values, PartialValues>>
|
||||
)
|
||||
|
||||
export type OfClassInstance<
|
||||
T extends z.ZodRawShape,
|
||||
Catchall extends z.ZodTypeAny,
|
||||
Values extends object,
|
||||
PartialValues extends Partial<Values>,
|
||||
> = (
|
||||
Values & TraitInstance<ZodSchemaObjectTrait<T, Catchall, Values, PartialValues>>
|
||||
)
|
||||
|
||||
|
||||
export const JsonifiedZodSchemaObject = <
|
||||
Of extends OfClass<OfInstance, T, Catchall, Values, PartialValues>,
|
||||
OfInstance extends OfClassInstance<T, Catchall, Values, PartialValues>,
|
||||
T extends z.ZodRawShape,
|
||||
Catchall extends z.ZodTypeAny,
|
||||
Values extends object,
|
||||
PartialValues extends Partial<Values>,
|
||||
|
||||
JsonifyT extends z.ZodRawShape,
|
||||
JsonifyCatchall extends z.ZodTypeAny,
|
||||
DejsonifyT extends z.ZodRawShape,
|
||||
DejsonifyCatchall extends z.ZodTypeAny,
|
||||
JsonifiedValues extends object & Jsonifiable,
|
||||
>(
|
||||
of: Of | OfClass<OfInstance, T, Catchall, Values, PartialValues>,
|
||||
|
||||
props: {
|
||||
jsonifySchema: (
|
||||
schema: typeof of.schema
|
||||
) => z.ZodObject<JsonifyT, "strip", JsonifyCatchall, JsonifiedValues, Values>,
|
||||
|
||||
dejsonifySchema: (
|
||||
schema: typeof of.schema
|
||||
) => z.ZodObject<DejsonifyT, "strip", DejsonifyCatchall, Values, JsonifiedValues>,
|
||||
},
|
||||
) => trait
|
||||
.implement(Super => class JsonifiedZodSchemaObjectImpl extends Super {
|
||||
declare ["constructor"]: typeof JsonifiedZodSchemaObjectImpl
|
||||
|
||||
static readonly of = of as Of
|
||||
static readonly jsonifySchema = props.jsonifySchema(of.schema)
|
||||
static readonly dejsonifySchema = props.dejsonifySchema(of.schema)
|
||||
|
||||
|
||||
static pipeSchemaIntoInstance<
|
||||
Instance extends JsonifiedValues,
|
||||
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
SchemaOutput extends JsonifiedValues,
|
||||
SchemaInput,
|
||||
>(
|
||||
this: Class<Instance, [values: JsonifiedValues]>,
|
||||
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaOutput, SchemaInput>,
|
||||
) {
|
||||
return schema.transform(values => new this(values))
|
||||
}
|
||||
|
||||
|
||||
static jsonify<
|
||||
Instance extends JsonifiedValues
|
||||
>(
|
||||
this: Class<Instance, [values: JsonifiedValues]>,
|
||||
values: Values,
|
||||
params?: Partial<z.ParseParams>,
|
||||
) {
|
||||
const t = implStaticInstantiableThis(JsonifiedZodSchemaObjectImpl, this)
|
||||
|
||||
return t
|
||||
.pipeSchemaIntoInstance(t.jsonifySchema)
|
||||
.parse(values, params)
|
||||
}
|
||||
|
||||
static jsonifyPromise<
|
||||
Instance extends JsonifiedValues
|
||||
>(
|
||||
this: Class<Instance, [values: JsonifiedValues]>,
|
||||
values: Values,
|
||||
params?: Partial<z.ParseParams>,
|
||||
) {
|
||||
const t = implStaticInstantiableThis(JsonifiedZodSchemaObjectImpl, this)
|
||||
|
||||
return t
|
||||
.pipeSchemaIntoInstance(t.jsonifySchema)
|
||||
.parseAsync(values, params)
|
||||
}
|
||||
|
||||
static jsonifyEffect<
|
||||
Instance extends JsonifiedValues
|
||||
>(
|
||||
this: Class<Instance, [values: JsonifiedValues]>,
|
||||
values: Values,
|
||||
params?: Partial<z.ParseParams>,
|
||||
) {
|
||||
const t = implStaticInstantiableThis(JsonifiedZodSchemaObjectImpl, this)
|
||||
|
||||
return parseZodSchemaEffect(
|
||||
t.pipeSchemaIntoInstance(t.jsonifySchema),
|
||||
values,
|
||||
params,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
static dejsonify(
|
||||
values: JsonifiedValues,
|
||||
params?: Partial<z.ParseParams>,
|
||||
) {
|
||||
return this.of
|
||||
.pipeSchemaIntoInstance(this.dejsonifySchema)
|
||||
.parse(values, params)
|
||||
}
|
||||
|
||||
static dejsonifyPromise(
|
||||
values: JsonifiedValues,
|
||||
params?: Partial<z.ParseParams>,
|
||||
) {
|
||||
return this.of
|
||||
.pipeSchemaIntoInstance(this.dejsonifySchema)
|
||||
.parseAsync(values, params)
|
||||
}
|
||||
|
||||
static dejsonifyEffect(
|
||||
values: JsonifiedValues,
|
||||
params?: Partial<z.ParseParams>,
|
||||
) {
|
||||
return parseZodSchemaEffect(
|
||||
this.of.pipeSchemaIntoInstance(this.dejsonifySchema),
|
||||
values,
|
||||
params,
|
||||
)
|
||||
}
|
||||
|
||||
dejsonify(params?: Partial<z.ParseParams>) {
|
||||
return this.constructor.of.pipeSchemaIntoInstance(
|
||||
this.constructor.dejsonifySchema
|
||||
).parse(this, params)
|
||||
}
|
||||
|
||||
dejsonifyPromise(params?: Partial<z.ParseParams>) {
|
||||
return this.constructor.of.pipeSchemaIntoInstance(
|
||||
this.constructor.dejsonifySchema
|
||||
).parseAsync(this, params)
|
||||
}
|
||||
|
||||
dejsonifyEffect(params?: Partial<z.ParseParams>) {
|
||||
return parseZodSchemaEffect(
|
||||
this.constructor.of.pipeSchemaIntoInstance(this.constructor.dejsonifySchema),
|
||||
this,
|
||||
params,
|
||||
)
|
||||
}
|
||||
})
|
||||
.build()
|
||||
25
src/traits/MobXObservableZodSchemaObject.ts
Normal file
25
src/traits/MobXObservableZodSchemaObject.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { trait } from "@thilawyn/traitify-ts"
|
||||
import { mapValues } from "lodash-es"
|
||||
import { makeObservable, observable } from "mobx"
|
||||
import { z } from "zod"
|
||||
|
||||
|
||||
export const MobXObservableZodSchemaObject = trait
|
||||
.staticAbstract(Super => class extends Super {
|
||||
declare readonly schema: z.ZodObject<z.ZodRawShape, z.UnknownKeysParam, z.ZodTypeAny, object, object>
|
||||
})
|
||||
.implement(Super => class MobXObservableZodSchemaObjectImpl extends Super {
|
||||
declare ["constructor"]: typeof MobXObservableZodSchemaObjectImpl
|
||||
|
||||
constructor(...args: any[]) {
|
||||
super(...args)
|
||||
|
||||
makeObservable(this,
|
||||
mapValues(
|
||||
this.constructor.schema.shape,
|
||||
() => observable,
|
||||
)
|
||||
)
|
||||
}
|
||||
})
|
||||
.build()
|
||||
@@ -1,10 +0,0 @@
|
||||
import { trait } from "@thilawyn/traitify-ts"
|
||||
|
||||
|
||||
export const ObservableZodSchemaObject = trait
|
||||
.implement(Super => class ObservableZodSchemaObject extends Super {
|
||||
constructor(...args: any[]) {
|
||||
super(...args)
|
||||
}
|
||||
})
|
||||
.build()
|
||||
115
src/traits/ZodSchemaObject.ts
Normal file
115
src/traits/ZodSchemaObject.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
import { implStaticInstantiableThis, trait } from "@thilawyn/traitify-ts"
|
||||
import { Class, HasRequiredKeys } from "type-fest"
|
||||
import { z } from "zod"
|
||||
import { parseZodSchemaEffect, stripZodObjectDefaults } from "../util"
|
||||
|
||||
|
||||
type CreateArgs<Input extends object> = (
|
||||
HasRequiredKeys<Input> extends true
|
||||
? [values: Input, params?: Partial<z.ParseParams>]
|
||||
: [] | [values: Input, params?: Partial<z.ParseParams>]
|
||||
)
|
||||
|
||||
|
||||
export const ZodSchemaObject = <
|
||||
T extends z.ZodRawShape,
|
||||
Catchall extends z.ZodTypeAny,
|
||||
Values extends object,
|
||||
PartialValues extends Partial<Values>,
|
||||
>(
|
||||
schemaWithDefaults: z.ZodObject<T, "strip", Catchall, Values, PartialValues>,
|
||||
) => trait
|
||||
.implement(Super => {
|
||||
class ZodSchemaObjectImpl extends Super {
|
||||
static readonly schema = stripZodObjectDefaults(schemaWithDefaults)
|
||||
static readonly schemaWithDefaults = schemaWithDefaults
|
||||
|
||||
|
||||
static pipeSchemaIntoInstance<
|
||||
Instance extends Values,
|
||||
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
SchemaOutput extends Values,
|
||||
SchemaInput,
|
||||
>(
|
||||
this: Class<Instance, [values: Values]>,
|
||||
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaOutput, SchemaInput>,
|
||||
) {
|
||||
return schema.transform(values => new this(values))
|
||||
}
|
||||
|
||||
static pipeInstanceIntoSchema<
|
||||
Self extends Class<Values, [values: Values]>,
|
||||
|
||||
SchemaT extends z.ZodRawShape,
|
||||
SchemaUnknownKeys extends z.UnknownKeysParam,
|
||||
SchemaCatchall extends z.ZodTypeAny,
|
||||
SchemaOutput,
|
||||
SchemaInput extends Values,
|
||||
>(
|
||||
this: Self,
|
||||
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaOutput, SchemaInput>,
|
||||
) {
|
||||
return z.instanceof(this).pipe(schema)
|
||||
}
|
||||
|
||||
|
||||
static create<
|
||||
Instance extends Values
|
||||
>(
|
||||
this: Class<Instance, [values: Values]>,
|
||||
...[values, params]: CreateArgs<PartialValues>
|
||||
) {
|
||||
const t = implStaticInstantiableThis(ZodSchemaObjectImpl, this)
|
||||
|
||||
return t
|
||||
.pipeSchemaIntoInstance(t.schemaWithDefaults)
|
||||
.parse(values, params)
|
||||
}
|
||||
|
||||
static createPromise<
|
||||
Instance extends Values
|
||||
>(
|
||||
this: Class<Instance, [values: Values]>,
|
||||
...[values, params]: CreateArgs<PartialValues>
|
||||
) {
|
||||
const t = implStaticInstantiableThis(ZodSchemaObjectImpl, this)
|
||||
|
||||
return t
|
||||
.pipeSchemaIntoInstance(t.schemaWithDefaults)
|
||||
.parseAsync(values, params)
|
||||
}
|
||||
|
||||
static createEffect<
|
||||
Instance extends Values
|
||||
>(
|
||||
this: Class<Instance, [values: Values]>,
|
||||
...[values, params]: CreateArgs<PartialValues>
|
||||
) {
|
||||
const t = implStaticInstantiableThis(ZodSchemaObjectImpl, this)
|
||||
|
||||
return parseZodSchemaEffect(
|
||||
t.pipeSchemaIntoInstance(t.schemaWithDefaults),
|
||||
values,
|
||||
params,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return ZodSchemaObjectImpl
|
||||
})
|
||||
.build()
|
||||
|
||||
|
||||
export type ZodSchemaObjectTrait<
|
||||
T extends z.ZodRawShape,
|
||||
Catchall extends z.ZodTypeAny,
|
||||
Values extends object,
|
||||
PartialValues extends Partial<Values>,
|
||||
> = (
|
||||
ReturnType<
|
||||
typeof ZodSchemaObject<T, Catchall, Values, PartialValues>
|
||||
>
|
||||
)
|
||||
@@ -1,69 +1,6 @@
|
||||
import { AbstractClass, Class as ConcreteClass } from "type-fest"
|
||||
import { AbstractClass } 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.
|
||||
@@ -71,31 +8,3 @@ export type ClassesInstancesIntersection<Classes extends readonly 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
|
||||
: {}
|
||||
)
|
||||
|
||||
@@ -3,16 +3,13 @@ import { z } from "zod"
|
||||
|
||||
|
||||
/**
|
||||
* Parses a value using a ZodType schema wrapped in an Effect monad.
|
||||
* Parses a value using a Zod schema wrapped in an Effect monad.
|
||||
*
|
||||
* @param schema - The ZodType schema to use for parsing.
|
||||
* @param schema - The Zod 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,
|
||||
>(
|
||||
export const parseZodSchemaEffect = <Output, Input>(
|
||||
schema: z.ZodType<Output, z.ZodTypeDef, Input>,
|
||||
...args: Parameters<typeof schema.safeParseAsync>
|
||||
) => pipe(
|
||||
|
||||
@@ -6,18 +6,33 @@
|
||||
export type CommonKeys<A, B> = Extract<keyof A, keyof B>
|
||||
|
||||
export type Extend<T extends readonly object[]> = (
|
||||
T extends [
|
||||
T extends readonly [
|
||||
infer Super,
|
||||
infer Self,
|
||||
...infer Rest extends object[],
|
||||
...infer Rest extends readonly object[],
|
||||
]
|
||||
? Pick<Self, CommonKeys<Self, Super>> extends Pick<Super, CommonKeys<Self, Super>>
|
||||
? Extend<[
|
||||
? Extend<readonly [
|
||||
Omit<Super, CommonKeys<Self, Super>> & Self,
|
||||
...Rest,
|
||||
]>
|
||||
: never
|
||||
: T extends [infer Self]
|
||||
: T extends readonly [infer Self]
|
||||
? Self
|
||||
: {}
|
||||
)
|
||||
|
||||
export type Override<T extends readonly object[]> = (
|
||||
T extends readonly [
|
||||
infer Super,
|
||||
infer Self,
|
||||
...infer Rest extends readonly object[],
|
||||
]
|
||||
? Override<readonly [
|
||||
Omit<Super, CommonKeys<Self, Super>> & Self,
|
||||
...Rest,
|
||||
]>
|
||||
: T extends readonly [infer Self]
|
||||
? Self
|
||||
: {}
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export * from "./class"
|
||||
export * from "./effect"
|
||||
export * from "./extend"
|
||||
export * from "./misc"
|
||||
export * from "./zod"
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export function identity<T>(value: T) {
|
||||
return value
|
||||
}
|
||||
25
src/util/zod.ts
Normal file
25
src/util/zod.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { mapValues } from "lodash-es"
|
||||
import { z } from "zod"
|
||||
|
||||
|
||||
export function stripZodObjectDefaults<
|
||||
T extends z.ZodRawShape,
|
||||
UnknownKeys extends z.UnknownKeysParam,
|
||||
Catchall extends z.ZodTypeAny,
|
||||
Output,
|
||||
Input,
|
||||
>(
|
||||
schema: z.ZodObject<T, UnknownKeys, Catchall, Output, Input>
|
||||
) {
|
||||
return schema.extend(
|
||||
mapValues(schema.shape, v =>
|
||||
v instanceof z.ZodDefault
|
||||
? v.removeDefault()
|
||||
: v
|
||||
) as {
|
||||
[K in keyof T]: T[K] extends z.ZodDefault<z.ZodTypeAny>
|
||||
? ReturnType<T[K]["removeDefault"]>
|
||||
: T[K]
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
// "allowImportingTsExtensions": true,
|
||||
// "noEmit": true,
|
||||
"declaration": true,
|
||||
"composite": true,
|
||||
// "composite": true,
|
||||
"strict": true,
|
||||
"downlevelIteration": true,
|
||||
"skipLibCheck": true,
|
||||
|
||||
11
tsup.config.ts
Normal file
11
tsup.config.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { defineConfig } from "tsup"
|
||||
|
||||
|
||||
export default defineConfig({
|
||||
entry: ["src/lib.ts", "src/schema/lib.ts"],
|
||||
format: ["esm", "cjs"],
|
||||
dts: true,
|
||||
splitting: false,
|
||||
sourcemap: true,
|
||||
clean: true,
|
||||
})
|
||||
Reference in New Issue
Block a user