Compare commits

...

104 Commits

Author SHA1 Message Date
Julien Valverdé
b1f73a2671 Traitify upgrade
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-28 01:29:36 +01:00
Julien Valverdé
af8d4e5f86 Cleanup
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-27 05:25:55 +01:00
Julien Valverdé
9f8cc4f895 Cleanup
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-27 04:01:08 +01:00
Julien Valverdé
0e956c0c78 InstantiableZodSchemaObject fix
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-27 03:59:21 +01:00
Julien Valverdé
2d69785add InstantiableZodSchemaObject work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-27 03:44:08 +01:00
Julien Valverdé
a6414b680c InstantiableZodSchemaObject work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-27 02:49:53 +01:00
Julien Valverdé
055caf1320 SchemaWithDefaultValues
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-26 22:55:44 +01:00
Julien Valverdé
c652aae238 ZodSchemaClassExtender work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-26 00:59:58 +01:00
Julien Valverdé
fdd267adb0 ZodSchemaClassExtender work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-26 00:54:21 +01:00
Julien Valverdé
0b0af7b128 ZodSchemaClassExtender.jsonifiable work
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-25 23:57:46 +01:00
Julien Valverdé
f79143d821 jsonifiable
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-25 23:13:27 +01:00
Julien Valverdé
2ad276b84d jsonifiable
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-25 18:11:48 +01:00
Julien Valverdé
b7030be720 Fix
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-25 06:18:13 +01:00
Julien Valverdé
e5e7d48b4c Fixed MobXObservableZodSchemaObject
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-25 06:06:35 +01:00
Julien Valverdé
8ca2805f4f MobXObservableZodSchemaObject
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-25 05:49:50 +01:00
Julien Valverdé
93edcde258 Extend fix
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-25 05:38:27 +01:00
Julien Valverdé
29d539ec32 Override
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-25 05:21:35 +01:00
Julien Valverdé
1a6bd44c05 Extend work
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-25 04:49:04 +01:00
Julien Valverdé
bf429fc63b ExtendableZodSchemaObject
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-25 04:45:58 +01:00
Julien Valverdé
e7c65c0a07 ZodSchemaClassExtender
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-25 04:32:09 +01:00
Julien Valverdé
34ae4b9375 Dependencies upgrade
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-25 03:35:01 +01:00
Julien Valverdé
997ea4a95b ZodSchemaClassBuilder
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-24 23:48:09 +01:00
Julien Valverdé
af279116bc Dependencies upgrade
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-24 23:43:51 +01:00
Julien Valverdé
4672a7e0b8 ZodSchemaClassBuilder work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-24 23:37:42 +01:00
Julien Valverdé
957cfdf6b8 ZodSchemaClassBuilder work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-24 23:25:50 +01:00
Julien Valverdé
aa15e053a7 ZodSchemaClassBuilder work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-24 23:11:24 +01:00
Julien Valverdé
ac5e6e444e ZodSchemaClassBuilder work
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-24 05:48:07 +01:00
Julien Valverdé
9a9b0edf5b Tests
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-24 05:27:17 +01:00
Julien Valverdé
7da3d50bcc Box tests
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-24 04:10:01 +01:00
Julien Valverdé
9e18a4a0ee Generic tests
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-24 03:03:43 +01:00
Julien Valverdé
eb071bfe86 ZodSchemaClassBuilder.extends
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-24 02:21:42 +01:00
Julien Valverdé
466b51aa79 Legacy cleanup
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-24 01:00:57 +01:00
Julien Valverdé
f731ed407f JsonifiableZodSchemaObject
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-24 00:54:46 +01:00
Julien Valverdé
5009537839 Fix
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-24 00:47:56 +01:00
Julien Valverdé
3e8dbce574 ZodSchemaClass fix
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-24 00:37:18 +01:00
Julien Valverdé
ec2b940f5c ZodSchemaClass work
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-24 00:11:06 +01:00
Julien Valverdé
53bd30aa7a ZodSchemaClass work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-23 23:45:03 +01:00
Julien Valverdé
dce10c3b6d JsonifiableZodSchemaObject
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-23 22:49:52 +01:00
Julien Valverdé
ed6b8c5979 Tests
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-23 21:35:22 +01:00
Julien Valverdé
cffc56e7f6 DejsonifiableZodSchemaObject
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-23 20:11:06 +01:00
Julien Valverdé
03b769b74f DejsonifiableZodSchemaObject
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-23 18:01:51 +01:00
Julien Valverdé
6c6e2cce7c Jsonifiable schemas
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-22 23:59:28 +01:00
Julien Valverdé
68b39f4997 ZodSchemaClassBuilder work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-22 21:42:35 +01:00
Julien Valverdé
70012fdaf2 ZodSchemaClassBuilder work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-22 21:24:37 +01:00
Julien Valverdé
bddbe428a7 ZodSchemaClassBuilder work
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-22 21:00:14 +01:00
Julien Valverdé
55d8bb0c1b ZodSchemaClassBuilder work
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-22 06:06:40 +01:00
Julien Valverdé
46461cd373 ZodSchemaClassBuilder.schema fix
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-22 05:37:17 +01:00
Julien Valverdé
a58b441094 ZodSchemaClassBuilder work
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-22 04:52:36 +01:00
Julien Valverdé
718a32052d ZodSchemaClassBuilder work
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-22 04:44:24 +01:00
Julien Valverdé
26453038a2 ZodSchemaClassBuilder work
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-22 04:35:41 +01:00
Julien Valverdé
586eddc898 ZodSchemaClassBuilder
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-22 04:00:39 +01:00
Julien Valverdé
a6214c470e Dependencies upgrade
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-22 01:10:18 +01:00
Julien Valverdé
5f18d2310c JsonifiableZodSchemaClass
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-21 21:22:56 +01:00
Julien Valverdé
cf12c2f617 Dependencies upgrade
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-21 17:46:16 +01:00
Julien Valverdé
e18817be0f Cleanup
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-21 05:48:43 +01:00
Julien Valverdé
79c763fe15 Tests fix
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-21 04:48:14 +01:00
Julien Valverdé
0c7e1d2ab5 Dependencies upgrade
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-21 04:46:20 +01:00
Julien Valverdé
1b9fa09186 ObservableZodSchemaObject
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-21 04:45:43 +01:00
Julien Valverdé
4020f99d18 Fix
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-20 16:45:37 +01:00
Julien Valverdé
eaaef3bfd1 ZodSchemaClassOf refactoring
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-20 16:40:05 +01:00
Julien Valverdé
8297685453 Dependencies upgrade
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-20 03:56:39 +01:00
Julien Valverdé
c00fc1f517 Tests
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-20 03:39:20 +01:00
Julien Valverdé
43876391fe Tests
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-20 03:21:39 +01:00
Julien Valverdé
021928da8c Made ObservableZodSchemaObject into a subtrait
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-20 02:07:50 +01:00
Julien Valverdé
ad197fe585 Changed constraints
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-20 02:06:24 +01:00
Julien Valverdé
a788f0ddb2 Dependencies upgrade
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-20 01:59:03 +01:00
Julien Valverdé
0e609f7185 Fix
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-20 01:48:55 +01:00
Julien Valverdé
7af7fe9b65 Package upgrade
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-20 01:44:19 +01:00
Julien Valverdé
f2d932f534 Package upgrade 2024-02-20 01:44:13 +01:00
Julien Valverdé
73ce4e11ff Cleanup
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-20 01:19:51 +01:00
Julien Valverdé
93f1038e27 ZodSchemaClassOf
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-20 01:08:22 +01:00
Julien Valverdé
3bf22f1f49 Traitify API update
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-20 00:55:21 +01:00
Julien Valverdé
880d77019d Fix
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-09 01:16:36 +01:00
Julien Valverdé
a4d4c87f54 Fixed instance inference
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-09 01:15:23 +01:00
Julien Valverdé
0d20e7ad69 Package upgrade
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-08 20:04:45 +01:00
Julien Valverdé
443ae01d2d Tests
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-08 18:35:16 +01:00
Julien Valverdé
65602eac7d types -> shapes
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-08 18:33:58 +01:00
Julien Valverdé
99f071147d Cleanup
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-08 18:28:39 +01:00
Julien Valverdé
5f7fd30459 Working extendable
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-08 18:26:37 +01:00
Julien Valverdé
041b3f566e ExtendableZodSchemaObject work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-08 03:25:10 +01:00
Julien Valverdé
9adfe2366c Refactoring
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-08 03:11:11 +01:00
Julien Valverdé
408d3a7f3a Tests
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-08 02:52:27 +01:00
Julien Valverdé
e1c298c08a Fixed InstantiableZodSchemaObject
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-08 02:50:16 +01:00
Julien Valverdé
ae4abf6b9c defaultValues fix
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-08 02:42:02 +01:00
Julien Valverdé
ed3f8fb643 ZodSchemaClassOf extend
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-08 02:39:38 +01:00
Julien Valverdé
ffce582e03 ZodSchemaClass work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-08 01:17:01 +01:00
Julien Valverdé
fa7d222f76 ZodSchemaClass work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-07 00:39:37 +01:00
Julien Valverdé
f40bebbc9b InstantiableZodSchemaObject
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-07 00:32:23 +01:00
Julien Valverdé
6ee9337426 Trait work
Some checks failed
continuous-integration/drone/push Build is failing
2024-02-06 05:24:00 +01:00
Julien Valverdé
5297468d17 ZodSchemaClass.old.ts
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-06 03:32:52 +01:00
Julien Valverdé
ff9bbb37e8 Dependencies
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-06 03:30:23 +01:00
Julien Valverdé
9ba149fb4c instantiate -> create
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-28 16:36:02 +01:00
Julien Valverdé
d867a3b83a Refactoring
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-28 16:31:44 +01:00
Julien Valverdé
e35db63da8 Refactoring
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-28 02:33:05 +01:00
Julien Valverdé
a4b8166af8 Inheritance logic refactoring
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-28 01:57:58 +01:00
Julien Valverdé
d34885a6e4 Dependencies upgrade
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-28 01:39:10 +01:00
Julien Valverdé
ab328f2cb5 Util refactoring
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-28 01:08:15 +01:00
Julien Valverdé
147034e95d ZodSchemaClassOf refactoring
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-24 21:49:19 +01:00
Julien Valverdé
516ce0ade2 Class type detection
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-24 21:40:27 +01:00
Julien Valverdé
338c750a4b TZodSchemaClass work
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-24 19:06:05 +01:00
Julien Valverdé
b6c2c4bec7 ZodSchemaClassOf work
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-21 23:29:11 +01:00
Julien Valverdé
c073154eeb Working new implementation
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-21 22:58:44 +01:00
Julien Valverdé
6873fae86b ZodSchemaClass
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-21 20:15:25 +01:00
Julien Valverdé
fc95a5d53a Moved current version to legacy
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-20 22:02:14 +01:00
52 changed files with 1154 additions and 1728 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -1,6 +1,6 @@
{ {
"name": "@thilawyn/schemable-class", "name": "@thilawyn/schemable-class",
"version": "0.1.1", "version": "0.1.2",
"type": "module", "type": "module",
"publishConfig": { "publishConfig": {
"registry": "https://git.jvalver.de/api/packages/thilawyn/npm/" "registry": "https://git.jvalver.de/api/packages/thilawyn/npm/"
@@ -48,24 +48,25 @@
"clean:node": "rm -rf node_modules" "clean:node": "rm -rf node_modules"
}, },
"dependencies": { "dependencies": {
"@thilawyn/traitify-ts": "^0.1.13",
"decimal.js": "^10.4.3", "decimal.js": "^10.4.3",
"effect": "^2.1.1", "effect": "^2.4.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"mobx": "^6.12.0", "mobx": "^6.12.0",
"type-fest": "^4.9.0", "type-fest": "^4.10.3",
"zod": "^3.22.4" "zod": "^3.22.4"
}, },
"devDependencies": { "devDependencies": {
"@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-node-resolve": "^15.2.3",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"bun-types": "latest", "bun-types": "latest",
"npm-check-updates": "^16.14.12", "npm-check-updates": "^16.14.15",
"npm-sort": "^0.0.4", "npm-sort": "^0.0.4",
"rollup": "^4.9.5", "rollup": "^4.12.0",
"rollup-plugin-cleanup": "^3.2.1", "rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-ts": "^3.4.5", "rollup-plugin-ts": "^3.4.5",
"ts-functional-pipe": "^3.1.2", "ts-functional-pipe": "^3.1.2",
"tsx": "^4.7.0", "tsx": "^4.7.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
} }

View File

@@ -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
}

View File

@@ -0,0 +1,194 @@
import { Trait, TraitExpression, TraitExpressionBuilder } from "@thilawyn/traitify-ts"
import { AbstractClass } from "type-fest"
import { JsonifiableObject } from "type-fest/source/jsonifiable"
import { z } from "zod"
import { ZodSchemaAbstractClass } from "../shapes/ZodSchemaClass"
import { DejsonifiableZodSchemaObject } from "../traits/DejsonifiableZodSchemaObject"
import { ExtendableZodSchemaObject } from "../traits/ExtendableZodSchemaObject"
import { InstantiableZodSchemaObject } from "../traits/InstantiableZodSchemaObject"
import { JsonifiableZodSchemaObject } from "../traits/JsonifiableZodSchemaObject"
import { ZodSchemaObjectInstantiationSchemas } from "../traits/ZodSchemaObjectInstantiationSchemas"
import { StaticMembers } from "../util"
export class ZodSchemaClassBuilder<
Superclass extends AbstractClass<object>,
const Traits extends readonly Trait<any, any, any, any>[],
>
extends TraitExpressionBuilder<Superclass, Traits> {
declare ["constructor"]: typeof ZodSchemaClassBuilder
schema<
Super extends AbstractClass<object, []> & { schema?: never, schemaWithDefaultValues?: never },
SchemaT extends z.ZodRawShape,
SchemaUnknownKeys extends z.UnknownKeysParam,
SchemaCatchall extends z.ZodTypeAny,
SchemaWithDefaultValuesT extends z.ZodRawShape,
SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam,
SchemaWithDefaultValuesCatchall extends z.ZodTypeAny,
Values extends object,
PartialValues extends Partial<Values>,
>(
this: ZodSchemaClassBuilder<Super, Traits>,
props: {
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
schemaWithDefaultValues: (
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
) => z.ZodObject<SchemaWithDefaultValuesT, SchemaWithDefaultValuesUnknownKeys, SchemaWithDefaultValuesCatchall, Values, PartialValues>
},
) {
class Schemas extends (this.expressionSuperclass as AbstractClass<object, []>) {
static readonly schema = props.schema
static readonly schemaWithDefaultValues = props.schemaWithDefaultValues(props.schema)
constructor(values: Values) {
super()
Object.assign(this, values)
}
}
return new this.constructor(
Schemas as unknown as (
AbstractClass<
InstanceType<Super> & Values,
ConstructorParameters<typeof Schemas>
> &
StaticMembers<Super> &
StaticMembers<typeof Schemas>
),
[
...this.expressionTraits,
ZodSchemaObjectInstantiationSchemas,
InstantiableZodSchemaObject,
ExtendableZodSchemaObject,
],
)
}
jsonifiable<
Super extends ZodSchemaAbstractClass<Instance, SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaWithDefaultValuesT, SchemaWithDefaultValuesUnknownKeys, SchemaWithDefaultValuesCatchall, Values, PartialValues>
& { jsonifySchema?: never, dejsonifySchema?: never },
Instance extends Values,
SchemaT extends z.ZodRawShape,
SchemaUnknownKeys extends z.UnknownKeysParam,
SchemaCatchall extends z.ZodTypeAny,
SchemaWithDefaultValuesT extends z.ZodRawShape,
SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam,
SchemaWithDefaultValuesCatchall extends z.ZodTypeAny,
Values extends object,
PartialValues 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,
>(
this: ZodSchemaClassBuilder<
Super | ZodSchemaAbstractClass<Instance, SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaWithDefaultValuesT, SchemaWithDefaultValuesUnknownKeys, SchemaWithDefaultValuesCatchall, Values, PartialValues>,
Traits
>,
props: {
jsonifySchema: (
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
) => z.ZodObject<JsonifySchemaT, JsonifySchemaUnknownKeys, JsonifySchemaCatchall, JsonifiedValues, Values>
dejsonifySchema: (
schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
) => z.ZodObject<DejsonifySchemaT, DejsonifySchemaUnknownKeys, DejsonifySchemaCatchall, Values, JsonifiedValues>
},
) {
const jsonifySchema = props.jsonifySchema(this.expressionSuperclass.schema)
const dejsonifySchema = props.dejsonifySchema(this.expressionSuperclass.schema)
class JsonifiableSchemas extends (this.expressionSuperclass as AbstractClass<object>) {
static readonly jsonifySchema = jsonifySchema
readonly jsonifySchema = jsonifySchema
static readonly dejsonifySchema = dejsonifySchema
readonly dejsonifySchema = dejsonifySchema
}
return new this.constructor(
JsonifiableSchemas as unknown as (
AbstractClass<
Instance & JsonifiableSchemas,
// TODO: for some reason, ConstructorParameters<Super> does not work here. Maybe try to find a fix?
ConstructorParameters<ZodSchemaAbstractClass<Instance, SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaWithDefaultValuesT, SchemaWithDefaultValuesUnknownKeys, SchemaWithDefaultValuesCatchall, Values, PartialValues>>
> &
StaticMembers<Super> &
StaticMembers<typeof JsonifiableSchemas>
),
[
...this.expressionTraits,
JsonifiableZodSchemaObject,
DejsonifiableZodSchemaObject,
],
)
}
}
export interface ZodSchemaClassBuilder<
Superclass extends AbstractClass<object>,
Traits extends readonly Trait<any, any, any, any>[],
> {
extends<
Super extends AbstractClass<object>
>(
// \/ Ensures `extends` can only be called once at the beginning
this: ZodSchemaClassBuilder<typeof TraitExpression.NullSuperclass, Traits>,
superclass: Super,
): ZodSchemaClassBuilder<Super, Traits>
expresses<
const T extends readonly Trait<
TraitExpression<
typeof TraitExpression.NullSuperclass,
readonly Trait<any, any, any, any>[]
>,
any,
any,
any
>[]
>(
...traits: T
): ZodSchemaClassBuilder<
Superclass,
TraitExpressionBuilder.ExpressesReturnTypeTraits<Traits, T>
>
expressesFirst<
const T extends readonly Trait<
TraitExpression<
typeof TraitExpression.NullSuperclass,
readonly Trait<any, any, any, any>[]
>,
any,
any,
any
>[]
>(
...traits: T
): ZodSchemaClassBuilder<
Superclass,
TraitExpressionBuilder.ExpressesFirstReturnTypeTraits<Traits, T>
>
}
export const zodSchemaClass = new ZodSchemaClassBuilder(TraitExpression.NullSuperclass, [])

View File

@@ -0,0 +1,196 @@
import { expression } from "@thilawyn/traitify-ts"
import { AbstractClass, Simplify } from "type-fest"
import { JsonifiableObject } from "type-fest/source/jsonifiable"
import { z } from "zod"
import { JsonifiableZodSchemaAbstractClass } from "../shapes/JsonifiableZodSchemaClass"
import { ZodSchemaAbstractClass } from "../shapes/ZodSchemaClass"
import { Extend, Override, StaticMembers } from "../util"
export class ZodSchemaClassExtender<
Superclass extends AbstractClass<object>,
Subclass extends AbstractClass<object>,
> {
declare ["constructor"]: typeof ZodSchemaClassExtender
constructor(
readonly superclass: Superclass,
readonly subclass: Subclass,
) {}
schema<
Super extends ZodSchemaAbstractClass<any, SuperSchemaT, SuperSchemaUnknownKeys, SuperSchemaCatchall, SuperValues, SuperDefaultValues>,
SuperSchemaT extends z.ZodRawShape,
SuperSchemaUnknownKeys extends z.UnknownKeysParam,
SuperSchemaCatchall extends z.ZodTypeAny,
SuperValues extends object,
SuperDefaultValues extends Partial<SuperValues>,
SchemaT extends z.ZodRawShape,
SchemaUnknownKeys extends z.UnknownKeysParam,
SchemaCatchall extends z.ZodTypeAny,
Values extends SuperValues,
DefaultValues extends Partial<Values>,
>(
this: ZodSchemaClassExtender<
Super | ZodSchemaAbstractClass<any, SuperSchemaT, SuperSchemaUnknownKeys, SuperSchemaCatchall, SuperValues, SuperDefaultValues>,
any
>,
props: {
schema: (schema: Super["schema"]) => z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
defaultValues: (defaultValues: SuperDefaultValues) => DefaultValues
},
) {
const schema = props.schema(this.superclass.schema)
const defaultValues = props.defaultValues(this.superclass.defaultValues)
class Schemas extends (this.superclass as AbstractClass<object, any[]>) {
static readonly schema = schema
static readonly defaultValues = defaultValues
}
return new this.constructor(
this.superclass as Super,
Schemas as unknown as AbstractClass<
Simplify<
Extend<[InstanceType<Super>, Values]>
>,
[values: Values]
> &
Simplify<
Override<[
StaticMembers<Super>,
StaticMembers<typeof Schemas>,
]>
>
)
}
jsonifiable<
/** Superclass jsonifiable schemas */
Super extends JsonifiableZodSchemaAbstractClass<
any,
SuperJsonifySchemaT,
SuperJsonifySchemaUnknownKeys,
SuperJsonifySchemaCatchall,
SuperDejsonifySchemaT,
SuperDejsonifySchemaUnknownKeys,
SuperDejsonifySchemaCatchall,
SuperJsonifiedValues,
SuperValues
>,
SuperJsonifySchemaT extends z.ZodRawShape,
SuperJsonifySchemaUnknownKeys extends z.UnknownKeysParam,
SuperJsonifySchemaCatchall extends z.ZodTypeAny,
SuperDejsonifySchemaT extends z.ZodRawShape,
SuperDejsonifySchemaUnknownKeys extends z.UnknownKeysParam,
SuperDejsonifySchemaCatchall extends z.ZodTypeAny,
SuperJsonifiedValues extends JsonifiableObject,
SuperValues extends object,
/** New schemas */
Self extends ZodSchemaAbstractClass<any, SelfSchemaT, SelfSchemaUnknownKeys, SelfSchemaCatchall, SelfValues, SelfDefaultValues>,
SelfSchemaT extends z.ZodRawShape,
SelfSchemaUnknownKeys extends z.UnknownKeysParam,
SelfSchemaCatchall extends z.ZodTypeAny,
SelfValues extends object,
SelfDefaultValues extends Partial<SelfValues>,
/* New jsonifiable schemas */
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 SuperJsonifiedValues,
Values extends SelfValues,
>(
this: ZodSchemaClassExtender<
Super | JsonifiableZodSchemaAbstractClass<
any,
SuperJsonifySchemaT,
SuperJsonifySchemaUnknownKeys,
SuperJsonifySchemaCatchall,
SuperDejsonifySchemaT,
SuperDejsonifySchemaUnknownKeys,
SuperDejsonifySchemaCatchall,
SuperJsonifiedValues,
SuperValues
>,
Self | ZodSchemaAbstractClass<any, SelfSchemaT, SelfSchemaUnknownKeys, SelfSchemaCatchall, SelfValues, SelfDefaultValues>
>,
props: {
jsonifySchema: (
schema: Self["schema"],
jsonifySchema: Super["jsonifySchema"],
) => z.ZodObject<JsonifySchemaT, JsonifySchemaUnknownKeys, JsonifySchemaCatchall, JsonifiedValues, Values>
dejsonifySchema: (
schema: Self["schema"],
dejsonifySchema: Super["dejsonifySchema"],
) => z.ZodObject<DejsonifySchemaT, DejsonifySchemaUnknownKeys, DejsonifySchemaCatchall, Values, JsonifiedValues>
},
) {
const jsonifySchema = props.jsonifySchema(this.subclass.schema, this.superclass.jsonifySchema)
const dejsonifySchema = props.dejsonifySchema(this.subclass.schema, this.superclass.dejsonifySchema)
class JsonifiableSchemas extends (this.subclass as AbstractClass<object>) {
static readonly jsonifySchema = jsonifySchema
readonly jsonifySchema = jsonifySchema
static readonly dejsonifySchema = dejsonifySchema
readonly dejsonifySchema = dejsonifySchema
}
return new this.constructor(
this.superclass as Super,
JsonifiableSchemas as unknown as AbstractClass<
Simplify<
Override<[InstanceType<Self>, JsonifiableSchemas]>
>,
ConstructorParameters<
ZodSchemaAbstractClass<any, SelfSchemaT, SelfSchemaUnknownKeys, SelfSchemaCatchall, SelfValues, SelfDefaultValues>
>
> &
Simplify<
Override<[
StaticMembers<Self>,
StaticMembers<typeof JsonifiableSchemas>,
]>
>,
)
}
toClass() {
return this.subclass
}
toExpressionBuilder() {
return expression.extends(this.subclass)
}
}

View File

@@ -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>
}

View File

@@ -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,
}
)
}

View File

@@ -1,5 +0,0 @@
export * from "./SchemableClass"
export * from "./defineDefaultValues"
export * from "./extendSchemableClass"
export * from "./makeSchemableClass"
export * from "./newSchemable"

View File

@@ -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
>
}
)

View File

@@ -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>),
)
}

View File

@@ -1,4 +0,0 @@
export * from "./JsonifiableSchemableClass"
export * from "./dejsonifySchemable"
export * from "./makeJsonifiableSchemableClass"
export * from "./schema"

View File

@@ -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>,
}
)
}

View File

@@ -1,4 +0,0 @@
export * from "./bigint"
export * from "./date"
export * from "./decimal"
export * from "./schemable"

View File

@@ -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)
}

View File

@@ -1,90 +0,0 @@
import { Class } from "type-fest"
import { z } from "zod"
/**
* Configuration for creating a schemable object with validation schemas.
* @template Values - The type representing the expected values.
* @template Input - The type representing the input values.
* @template SchemaT - The type representing the base validation schema.
* @template SchemaUnknownKeys - The type representing the unknown keys behavior in the base validation schema.
* @template SchemaCatchall - The type representing the catchall behavior in the base validation schema.
* @template SchemaWithDefaultValuesT - The type representing the validation schema with default values.
* @template SchemaWithDefaultValuesUnknownKeys - The type representing the unknown keys behavior in the validation schema with default values.
* @template SchemaWithDefaultValuesCatchall - The type representing the catchall behavior in the validation schema with default values.
*/
export type SchemableConfig<
Values extends {} = {},
Input extends {} = {},
SchemaT extends z.ZodRawShape = z.ZodRawShape,
SchemaUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam,
SchemaCatchall extends z.ZodTypeAny = z.ZodTypeAny,
SchemaWithDefaultValuesT extends z.ZodRawShape = z.ZodRawShape,
SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam,
SchemaWithDefaultValuesCatchall extends z.ZodTypeAny = z.ZodTypeAny,
> = {
readonly values: Values
readonly input: Input
readonly schema: z.ZodObject<
SchemaT,
SchemaUnknownKeys,
SchemaCatchall,
Values,
Values
>
readonly schemaWithDefaultValues: z.ZodObject<
SchemaWithDefaultValuesT,
SchemaWithDefaultValuesUnknownKeys,
SchemaWithDefaultValuesCatchall,
Values,
Input
>
}
/**
* Represents a class with validation schemas.
* @template $Config - The configuration type for the schemable object.
*/
export type SchemableClass<
$Config extends SchemableConfig
> = (
Class<
SchemableObject<$Config>,
SchemableClassConstructorParams<$Config>
> & {
readonly $schemableConfig: $Config
readonly schema: $Config["schema"]
readonly schemaWithDefaultValues: $Config["schemaWithDefaultValues"]
}
)
/**
* 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"]
)

View File

@@ -1,3 +0,0 @@
export * from "./SchemableClass"
export * from "./makeSchemableClass"
export * from "./newSchemable"

View File

@@ -1,66 +0,0 @@
import { Effect } from "effect"
import { Class } from "type-fest"
import { JsonifiableObject } from "type-fest/source/jsonifiable"
import { z } from "zod"
import { SchemableClassConstructorParams, SchemableConfig } from ".."
export type JsonifiableSchemableConfig<
$SchemableConfig extends SchemableConfig = SchemableConfig,
JsonifiedValues extends JsonifiableObject = {},
JsonifySchemaT extends z.ZodRawShape = z.ZodRawShape,
JsonifySchemaUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam,
JsonifySchemaCatchall extends z.ZodTypeAny = z.ZodTypeAny,
DejsonifySchemaT extends z.ZodRawShape = z.ZodRawShape,
DejsonifySchemaUnknownKeys extends z.UnknownKeysParam = z.UnknownKeysParam,
DejsonifySchemaCatchall extends z.ZodTypeAny = z.ZodTypeAny,
> = {
readonly $schemableConfig: $SchemableConfig
readonly jsonifiedValues: JsonifiedValues
readonly jsonifySchema: z.ZodObject<
JsonifySchemaT,
JsonifySchemaUnknownKeys,
JsonifySchemaCatchall,
JsonifiedValues,
$SchemableConfig["values"]
>
readonly dejsonifySchema: z.ZodObject<
DejsonifySchemaT,
DejsonifySchemaUnknownKeys,
DejsonifySchemaCatchall,
$SchemableConfig["values"],
JsonifiedValues
>
}
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"]>
}

View File

@@ -1,47 +0,0 @@
import { Effect, pipe } from "effect"
import { z } from "zod"
import { JsonifiableSchemableClass, JsonifiableSchemableConfig } from "."
import { parseZodTypeEffect } from "../util"
export const dejsonifySchemable = <
C extends JsonifiableSchemableClass<$Config>,
$Config extends JsonifiableSchemableConfig,
>(
class_: C | JsonifiableSchemableClass<$Config>,
values: $Config["jsonifiedValues"],
params?: Partial<z.ParseParams>,
) =>
new class_(class_.dejsonifySchema.parse(values, params)) as InstanceType<C>
export const dejsonifySchemablePromise = async <
C extends JsonifiableSchemableClass<$Config>,
$Config extends JsonifiableSchemableConfig,
>(
class_: C | JsonifiableSchemableClass<$Config>,
values: $Config["jsonifiedValues"],
params?: Partial<z.ParseParams>,
) =>
new class_(await class_.dejsonifySchema.parseAsync(values, params)) as InstanceType<C>
export const dejsonifySchemableEffect = <
C extends JsonifiableSchemableClass<$Config>,
$Config extends JsonifiableSchemableConfig,
>(
class_: C | JsonifiableSchemableClass<$Config>,
values: $Config["jsonifiedValues"],
params?: Partial<z.ParseParams>,
) => pipe(
parseZodTypeEffect<
z.output<typeof class_.dejsonifySchema>,
z.input<typeof class_.dejsonifySchema>
>(
class_.dejsonifySchema,
values,
params,
),
Effect.map(values => new class_(values) as InstanceType<C>),
)

View File

@@ -1,4 +0,0 @@
export * from "./JsonifiableSchemableClass"
export * from "./dejsonifySchemable"
export * from "./makeJsonifiableSchemableClass"
export * from "./schema"

View File

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

View File

@@ -1,18 +0,0 @@
import { z } from "zod"
export const jsonifyBigIntSchema = <S extends z.ZodBigInt>(schema: S) =>
schema.transform(v => v.toString())
export const dejsonifyBigIntSchema = <S extends z.ZodBigInt>(schema: S) =>
z
.string()
.transform(v => {
try {
return BigInt(v)
}
catch (e) {
return v
}
})
.pipe(schema)

View File

@@ -1,18 +0,0 @@
import { z } from "zod"
export const jsonifyDateSchema = <S extends z.ZodDate>(schema: S) =>
schema.transform(v => v.toString())
export const dejsonifyDateSchema = <S extends z.ZodDate>(schema: S) =>
z
.string()
.transform(v => {
try {
return new Date(v)
}
catch (e) {
return v
}
})
.pipe(schema)

View File

@@ -1,19 +0,0 @@
import { Decimal } from "decimal.js"
import { z } from "zod"
export const jsonifyDecimalSchema = <S extends z.ZodType<Decimal, z.ZodTypeDef, Decimal>>(schema: S) =>
schema.transform(v => v.toJSON())
export const dejsonifyDecimalSchema = <S extends z.ZodType<Decimal, z.ZodTypeDef, Decimal>>(schema: S) =>
z
.string()
.transform(v => {
try {
return new Decimal(v)
}
catch (e) {
return v
}
})
.pipe(schema)

View File

@@ -1,4 +0,0 @@
export * from "./bigint"
export * from "./date"
export * from "./decimal"
export * from "./schemable"

View File

@@ -1,25 +0,0 @@
import { z } from "zod"
import { JsonifiableSchemableClass, JsonifiableSchemableConfig } from ".."
// TODO: try to find a way to get rid of the 'class_' arg
export const jsonifySchemableSchema = <
C extends JsonifiableSchemableClass<$Config>,
$Config extends JsonifiableSchemableConfig,
S extends z.ZodType<InstanceType<C>, z.ZodTypeDef, InstanceType<C>>,
>(
class_: C | JsonifiableSchemableClass<$Config>,
schema: S,
) =>
schema.pipe(class_.jsonifySchema)
// 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>,
schema: S,
) =>
class_.dejsonifySchema.transform(v => new class_(v)).pipe(schema)

View File

@@ -1,49 +0,0 @@
import { z } from "zod"
import { SchemableClass, SchemableConfig } from "."
import { zodObjectRemoveDefaults } from "./util"
export function makeSchemableClass<
SchemaWithDefaultValuesT extends z.ZodRawShape,
SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam,
SchemaWithDefaultValuesCatchall extends z.ZodTypeAny,
SchemaWithDefaultValuesOutput extends SchemaWithDefaultValuesInput, // TODO: apply "StripSchemaInputDefaults"?
SchemaWithDefaultValuesInput extends {},
>(
{
schema: schemaWithDefaultValues
}: {
schema: z.ZodObject<
SchemaWithDefaultValuesT,
SchemaWithDefaultValuesUnknownKeys,
SchemaWithDefaultValuesCatchall,
SchemaWithDefaultValuesOutput,
SchemaWithDefaultValuesInput
>
}
) {
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>
}

View File

@@ -1,77 +0,0 @@
import { Effect, pipe } from "effect"
import { HasRequiredKeys } from "type-fest"
import { z } from "zod"
import { SchemableClass, SchemableConfig } from "."
import { parseZodTypeEffect } from "./util"
type ParamsArgs = [] | [Partial<z.ParseParams>]
type NewSchemableArgs<Input extends object> =
HasRequiredKeys<Input> extends true
? [Input, ...ParamsArgs]
: [] | [Input, ...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,
>(
class_: C | SchemableClass<$Config>,
...[values, params]: NewSchemableArgs<$Config["input"]>
) =>
new class_(class_.schemaWithDefaultValues.parse(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,
>(
class_: C | SchemableClass<$Config>,
...[values, params]: NewSchemableArgs<$Config["input"]>
) =>
new class_(await class_.schemaWithDefaultValues.parseAsync(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,
>(
class_: C | SchemableClass<$Config>,
...[values, params]: NewSchemableArgs<$Config["input"]>
) => pipe(
parseZodTypeEffect<
z.output<typeof class_.schemaWithDefaultValues>,
z.input<typeof class_.schemaWithDefaultValues>
>(
class_.schemaWithDefaultValues,
values || {},
params,
),
Effect.map(values => new class_(values) as InstanceType<C>),
)

View File

@@ -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)

View File

@@ -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
View File

@@ -0,0 +1 @@
export { ExtendableZodSchemaObject } from "./traits/ExtendableZodSchemaObject"

View File

@@ -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)
}

View File

@@ -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>),
)
}

View File

@@ -1 +0,0 @@
export * from "./makeSchemableClassObservable"

View File

@@ -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
}

View File

@@ -1,6 +1,6 @@
import { identity } from "lodash-es"
import { Opaque } from "type-fest" import { Opaque } from "type-fest"
import { z } from "zod" import { z } from "zod"
import { identity } from "../../util"
export type JsonifiedBigInt = Opaque<string, "@thilawyn/schemable-class/JsonifiedBigInt"> export type JsonifiedBigInt = Opaque<string, "@thilawyn/schemable-class/JsonifiedBigInt">

View File

@@ -1,6 +1,6 @@
import { identity } from "lodash-es"
import { Opaque } from "type-fest" import { Opaque } from "type-fest"
import { z } from "zod" import { z } from "zod"
import { identity } from "../../util"
export type JsonifiedDate = Opaque<string, "@thilawyn/schemable-class/JsonifiedDate"> export type JsonifiedDate = Opaque<string, "@thilawyn/schemable-class/JsonifiedDate">

View File

@@ -1,7 +1,7 @@
import { Decimal } from "decimal.js" import { Decimal } from "decimal.js"
import { identity } from "lodash-es"
import { Opaque } from "type-fest" import { Opaque } from "type-fest"
import { z } from "zod" import { z } from "zod"
import { identity } from "../../util"
export type JsonifiedDecimal = Opaque<string, "@thilawyn/schemable-class/JsonifiedDecimal"> export type JsonifiedDecimal = Opaque<string, "@thilawyn/schemable-class/JsonifiedDecimal">

View File

@@ -0,0 +1,16 @@
import { dejsonifyBigIntSchema, jsonifyBigIntSchema } from "./bigint"
import { dejsonifyDateSchema, jsonifyDateSchema } from "./date"
import { dejsonifyDecimalSchema, jsonifyDecimalSchema } from "./decimal"
export const jsonify = {
bigint: jsonifyBigIntSchema,
date: jsonifyDateSchema,
decimal: jsonifyDecimalSchema,
} as const
export const dejsonify = {
bigint: dejsonifyBigIntSchema,
date: dejsonifyDateSchema,
decimal: dejsonifyDecimalSchema,
} as const

View File

@@ -0,0 +1,78 @@
import { AbstractClass, Class } from "type-fest"
import { JsonifiableObject } from "type-fest/source/jsonifiable"
import { z } from "zod"
export type JsonifiableZodSchemaClass<
Instance extends 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,
Values extends object,
> = (
Class<Instance, [values: Values]> &
JsonifiableZodSchemas<
JsonifySchemaT,
JsonifySchemaUnknownKeys,
JsonifySchemaCatchall,
DejsonifySchemaT,
DejsonifySchemaUnknownKeys,
DejsonifySchemaCatchall,
JsonifiedValues,
Values
>
)
export type JsonifiableZodSchemaAbstractClass<
Instance extends 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,
Values extends object,
> = (
AbstractClass<Instance, [values: Values]> &
JsonifiableZodSchemas<
JsonifySchemaT,
JsonifySchemaUnknownKeys,
JsonifySchemaCatchall,
DejsonifySchemaT,
DejsonifySchemaUnknownKeys,
DejsonifySchemaCatchall,
JsonifiedValues,
Values
>
)
export type JsonifiableZodSchemas<
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,
Values extends object,
> = {
readonly jsonifySchema: z.ZodObject<JsonifySchemaT, JsonifySchemaUnknownKeys, JsonifySchemaCatchall, JsonifiedValues, Values>
readonly dejsonifySchema: z.ZodObject<DejsonifySchemaT, DejsonifySchemaUnknownKeys, DejsonifySchemaCatchall, Values, JsonifiedValues>
}

View File

@@ -0,0 +1,55 @@
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,
SchemaWithDefaultValuesT extends z.ZodRawShape,
SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam,
SchemaWithDefaultValuesCatchall extends z.ZodTypeAny,
Values extends object,
PartialValues extends Partial<Values>,
> = (
Class<Instance, [values: Values]> &
ZodSchemas<SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaWithDefaultValuesT, SchemaWithDefaultValuesUnknownKeys, SchemaWithDefaultValuesCatchall, Values, PartialValues>
)
export type ZodSchemaAbstractClass<
Instance extends Values,
SchemaT extends z.ZodRawShape,
SchemaUnknownKeys extends z.UnknownKeysParam,
SchemaCatchall extends z.ZodTypeAny,
SchemaWithDefaultValuesT extends z.ZodRawShape,
SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam,
SchemaWithDefaultValuesCatchall extends z.ZodTypeAny,
Values extends object,
PartialValues extends Partial<Values>,
> = (
AbstractClass<Instance, [values: Values]> &
ZodSchemas<SchemaT, SchemaUnknownKeys, SchemaCatchall, SchemaWithDefaultValuesT, SchemaWithDefaultValuesUnknownKeys, SchemaWithDefaultValuesCatchall, Values, PartialValues>
)
export type ZodSchemas<
SchemaT extends z.ZodRawShape,
SchemaUnknownKeys extends z.UnknownKeysParam,
SchemaCatchall extends z.ZodTypeAny,
SchemaWithDefaultValuesT extends z.ZodRawShape,
SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam,
SchemaWithDefaultValuesCatchall extends z.ZodTypeAny,
Values extends object,
PartialValues extends Partial<Values>,
> = {
readonly schema: z.ZodObject<SchemaT, SchemaUnknownKeys, SchemaCatchall, Values, Values>
readonly schemaWithDefaultValues: z.ZodObject<SchemaWithDefaultValuesT, SchemaWithDefaultValuesUnknownKeys, SchemaWithDefaultValuesCatchall, Values, PartialValues>
}

View File

@@ -1,63 +1,66 @@
import { pipeInto } from "ts-functional-pipe" import { Implements } from "@thilawyn/traitify-ts"
import { z } from "zod" import { z } from "zod"
import { defineDefaultValues, extendSchemableClass, makeSchemableClass, newSchemable } from "." import { zodSchemaClass } from "./builders/ZodSchemaClassBuilder"
import { dejsonifyBigIntSchema, dejsonifySchemable, jsonifyBigIntSchema, makeJsonifiableSchemableClass } from "./jsonifiable" import { dejsonify, jsonify } from "./schema/jsonify"
import { makeSchemableClassObservable } from "./observable" import { MobXObservableZodSchemaObject } from "./traits/MobXObservableZodSchemaObject"
const UserLevel = z.enum(["User", "Admin"]) const exp = zodSchemaClass
.schema({
class User extends pipeInto(
makeSchemableClass({
schema: z.object({ schema: z.object({
id: z.bigint(), /** User ID */
name: z.string(), id: z.bigint(),
level: UserLevel,
/** Username */
name: z.string(),
}), }),
defaultValues: defineDefaultValues({ schemaWithDefaultValues: s => s.extend({
level: "User" as const id: s.shape.id.default(-1n),
}), }),
}), })
.jsonifiable({
v => makeSchemableClassObservable(v), jsonifySchema: s => s.extend({
id: jsonify.bigint(s.shape.id)
v => makeJsonifiableSchemableClass(v, {
jsonifySchema: ({ schema, shape }) => schema.extend({
id: jsonifyBigIntSchema(shape.id)
}), }),
dejsonifySchema: ({ schema, shape }) => schema.extend({ dejsonifySchema: s => s.extend({
id: dejsonifyBigIntSchema(shape.id) id: dejsonify.bigint(s.shape.id)
}), }),
}), })
) {} .expresses(MobXObservableZodSchemaObject)
.build()
User.schema @exp.staticImplements
class User extends exp.extends implements Implements<typeof exp> {}
const test = User.schema.extend({
prout: z.string()
}).merge(
User.schemaWithDefaultValues
)
const inst = User.create({ id: 1n, name: "User" })
// console.log(inst.name)
const instEffect = User.createEffect({ id: 1n, name: "User" })
// const jsonifiedUser = await inst.jsonifyPromise()
// const AdminUserProto = User.extend()
// .schema({
// schema: s => s.extend({
// name: z.literal("Admin"),
// prout: z.string(),
// }),
// defaultValues: v => ({ ...v, name: "Admin" as const }),
// })
// .jsonifiable({
// jsonifySchema: (s, json) => json.extend({
// prout: s.shape.prout
// })
// })
const user1 = newSchemable(User, { id: 1n, name: "User" }) // class AdminUser extends AdminUserProto.toClass() {}
user1.schema // const subInst = await AdminUser.createPromise({ id: 2n, prout: "" })
// console.log(subInst)
const jsonifiedUser1 = user1.jsonify()
console.log(jsonifiedUser1)
console.log(dejsonifySchemable(User, jsonifiedUser1))
const UserWithPhone = extendSchemableClass(User, {
schema: ({ schema }) => schema.extend({
phone: z.string()
}),
defaultValues: defaultValues => defineDefaultValues({
...defaultValues,
phone: "+33600000000",
}),
})
UserWithPhone.defaultValues
// const user2 = newSchemable(UserWithPhone, { id: 1n, name: "User" })
// console.log(user2.jsonify())

View File

@@ -0,0 +1,122 @@
import { trait } from "@thilawyn/traitify-ts"
import { Effect } from "effect"
import { JsonifiableObject } from "type-fest/source/jsonifiable"
import { z } from "zod"
import { JsonifiableZodSchemaClass } from "../shapes/JsonifiableZodSchemaClass"
import { parseZodTypeEffect } from "../util"
export const DejsonifiableZodSchemaObject = trait
.implement(Super => class DejsonifiableZodSchemaObject extends Super {
static dejsonify<
Instance extends 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,
Values extends object,
>(
this: JsonifiableZodSchemaClass<
Instance,
JsonifySchemaT,
JsonifySchemaUnknownKeys,
JsonifySchemaCatchall,
DejsonifySchemaT,
DejsonifySchemaUnknownKeys,
DejsonifySchemaCatchall,
JsonifiedValues,
Values
>,
values: JsonifiedValues,
params?: Partial<z.ParseParams>,
) {
return new this(
this.dejsonifySchema.parse(values, params)
)
}
static async dejsonifyPromise<
Instance extends 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,
Values extends object,
>(
this: JsonifiableZodSchemaClass<
Instance,
JsonifySchemaT,
JsonifySchemaUnknownKeys,
JsonifySchemaCatchall,
DejsonifySchemaT,
DejsonifySchemaUnknownKeys,
DejsonifySchemaCatchall,
JsonifiedValues,
Values
>,
values: JsonifiedValues,
params?: Partial<z.ParseParams>,
) {
return new this(
await this.dejsonifySchema.parseAsync(values, params)
)
}
static dejsonifyEffect<
Instance extends 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,
Values extends object,
>(
this: JsonifiableZodSchemaClass<
Instance,
JsonifySchemaT,
JsonifySchemaUnknownKeys,
JsonifySchemaCatchall,
DejsonifySchemaT,
DejsonifySchemaUnknownKeys,
DejsonifySchemaCatchall,
JsonifiedValues,
Values
>,
values: JsonifiedValues,
params?: Partial<z.ParseParams>,
) {
return parseZodTypeEffect(this.dejsonifySchema, values, params).pipe(
Effect.map(values => new this(values)),
)
}
})
.build()

View File

@@ -0,0 +1,16 @@
import { trait } from "@thilawyn/traitify-ts"
import { ZodSchemaClassExtender } from "../builders/ZodSchemaClassExtender"
import { ZodSchemaClass } from "../shapes/ZodSchemaClass"
export const ExtendableZodSchemaObject = trait
.implement(Super => class ExtendableZodSchemaObject extends Super {
static extend<
Self extends ZodSchemaClass<any, any, any, any, any, any, any, any, any>,
>(
this: Self
) {
return new ZodSchemaClassExtender(this, this)
}
})
.build()

View File

@@ -0,0 +1,90 @@
import { TraitStaticMembers, trait } from "@thilawyn/traitify-ts"
import { HasRequiredKeys } from "type-fest"
import { z } from "zod"
import { ZodSchemaClass } from "../shapes/ZodSchemaClass"
import { parseZodTypeEffect } from "../util"
import { ZodSchemaObjectInstantiationSchemas } from "./ZodSchemaObjectInstantiationSchemas"
type ZodSchemaObjectInstantiationSchemasStaticMembers = TraitStaticMembers<typeof ZodSchemaObjectInstantiationSchemas>
type NewZodSchemaInstanceInput<
Values extends object,
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,
SchemaWithDefaultValuesT extends z.ZodRawShape,
SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam,
SchemaWithDefaultValuesCatchall extends z.ZodTypeAny,
Values extends object,
PartialValues extends Partial<Values>,
>(
this: (
ZodSchemaClass<Instance, any, any, any, SchemaWithDefaultValuesT, SchemaWithDefaultValuesUnknownKeys, SchemaWithDefaultValuesCatchall, Values, PartialValues> &
ZodSchemaObjectInstantiationSchemasStaticMembers
),
...[values, params]: NewZodSchemaInstanceArgs<PartialValues>
) {
return this.instantiationSchemaWithDefaultValues().parse(values, params)
}
static async createPromise<
Instance extends Values,
SchemaWithDefaultValuesT extends z.ZodRawShape,
SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam,
SchemaWithDefaultValuesCatchall extends z.ZodTypeAny,
Values extends object,
PartialValues extends Partial<Values>,
>(
this: (
ZodSchemaClass<Instance, any, any, any, SchemaWithDefaultValuesT, SchemaWithDefaultValuesUnknownKeys, SchemaWithDefaultValuesCatchall, Values, PartialValues> &
ZodSchemaObjectInstantiationSchemasStaticMembers
),
...[values, params]: NewZodSchemaInstanceArgs<PartialValues>
) {
return this.instantiationSchemaWithDefaultValues().parseAsync(values, params)
}
static createEffect<
Instance extends Values,
SchemaWithDefaultValuesT extends z.ZodRawShape,
SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam,
SchemaWithDefaultValuesCatchall extends z.ZodTypeAny,
Values extends object,
PartialValues extends Partial<Values>,
>(
this: (
ZodSchemaClass<Instance, any, any, any, SchemaWithDefaultValuesT, SchemaWithDefaultValuesUnknownKeys, SchemaWithDefaultValuesCatchall, Values, PartialValues> &
ZodSchemaObjectInstantiationSchemasStaticMembers
),
...[values, params]: NewZodSchemaInstanceArgs<PartialValues>
) {
return parseZodTypeEffect(this.instantiationSchemaWithDefaultValues(), values, params)
}
})
.build()

View File

@@ -0,0 +1,100 @@
import { trait } from "@thilawyn/traitify-ts"
import { JsonifiableObject } from "type-fest/source/jsonifiable"
import { z } from "zod"
import { JsonifiableZodSchemas } from "../shapes/JsonifiableZodSchemaClass"
import { parseZodTypeEffect } from "../util"
export const JsonifiableZodSchemaObject = trait
.implement(Super => class JsonifiableZodSchemaObject extends Super {
jsonify<
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,
Values extends object,
>(
this: Values & JsonifiableZodSchemas<
JsonifySchemaT,
JsonifySchemaUnknownKeys,
JsonifySchemaCatchall,
DejsonifySchemaT,
DejsonifySchemaUnknownKeys,
DejsonifySchemaCatchall,
JsonifiedValues,
Values
>,
params?: Partial<z.ParseParams>,
) {
return this.jsonifySchema.parse(this, params)
}
async jsonifyPromise<
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,
Values extends object,
>(
this: Values & JsonifiableZodSchemas<
JsonifySchemaT,
JsonifySchemaUnknownKeys,
JsonifySchemaCatchall,
DejsonifySchemaT,
DejsonifySchemaUnknownKeys,
DejsonifySchemaCatchall,
JsonifiedValues,
Values
>,
params?: Partial<z.ParseParams>,
) {
return this.jsonifySchema.parseAsync(this, params)
}
jsonifyEffect<
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,
Values extends object,
>(
this: Values & JsonifiableZodSchemas<
JsonifySchemaT,
JsonifySchemaUnknownKeys,
JsonifySchemaCatchall,
DejsonifySchemaT,
DejsonifySchemaUnknownKeys,
DejsonifySchemaCatchall,
JsonifiedValues,
Values
>,
params?: Partial<z.ParseParams>,
) {
return parseZodTypeEffect(this.jsonifySchema, this, params)
}
})
.build()

View File

@@ -0,0 +1,23 @@
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 ObservableZodSchemaObject extends Super {
constructor(...args: any[]) {
super(...args)
makeObservable(this,
mapValues(
(this.constructor as typeof ObservableZodSchemaObject).schema.shape,
() => observable,
)
)
}
})
.build()

View File

@@ -0,0 +1,37 @@
import { trait } from "@thilawyn/traitify-ts"
import { z } from "zod"
import { ZodSchemaClass } from "../shapes/ZodSchemaClass"
export const ZodSchemaObjectInstantiationSchemas = trait
.implement(Super => class ZodSchemaObjectInstantiationSchemas extends Super {
static instantiationSchema<
Instance extends Values,
SchemaT extends z.ZodRawShape,
SchemaUnknownKeys extends z.UnknownKeysParam,
SchemaCatchall extends z.ZodTypeAny,
Values extends object,
>(
this: ZodSchemaClass<Instance, SchemaT, SchemaUnknownKeys, SchemaCatchall, any, any, any, Values, any>,
) {
return this.schema.transform(values => new this(values))
}
static instantiationSchemaWithDefaultValues<
Instance extends Values,
SchemaWithDefaultValuesT extends z.ZodRawShape,
SchemaWithDefaultValuesUnknownKeys extends z.UnknownKeysParam,
SchemaWithDefaultValuesCatchall extends z.ZodTypeAny,
Values extends object,
PartialValues extends Partial<Values>,
>(
this: ZodSchemaClass<Instance, any, any, any, SchemaWithDefaultValuesT, SchemaWithDefaultValuesUnknownKeys, SchemaWithDefaultValuesCatchall, Values, PartialValues>,
) {
return this.schemaWithDefaultValues.transform(values => new this(values))
}
})
.build()

101
src/util/class.ts Normal file
View 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
: {}
)

View File

@@ -1,37 +1,7 @@
import { Effect, pipe } from "effect" import { Effect, pipe } from "effect"
import { AbstractClass, Class as ConcreteClass } from "type-fest"
import { z } from "zod" 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. * Parses a value using a ZodType schema wrapped in an Effect monad.
* *

55
src/util/extend.ts Normal file
View File

@@ -0,0 +1,55 @@
/**
* 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 readonly [
infer Super,
infer Self,
...infer Rest extends readonly object[],
]
? Pick<Self, CommonKeys<Self, Super>> extends Pick<Super, CommonKeys<Self, Super>>
? Extend<readonly [
Omit<Super, CommonKeys<Self, Super>> & Self,
...Rest,
]>
: never
: 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
: {}
)
/**
* 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
View File

@@ -0,0 +1,4 @@
export * from "./class"
export * from "./effect"
export * from "./extend"
export * from "./misc"

3
src/util/misc.ts Normal file
View File

@@ -0,0 +1,3 @@
export function identity<T>(value: T) {
return value
}