makeJsonifiableSchemableClass

This commit is contained in:
Julien Valverdé
2024-01-02 01:50:44 +01:00
parent 00040fb7df
commit de6a97e0a6
6 changed files with 119 additions and 27 deletions

View File

@@ -12,11 +12,19 @@ export default defineConfig({
file: pkg.exports["."].import.default, file: pkg.exports["."].import.default,
format: "esm", format: "esm",
}, },
{ {
file: pkg.exports["."].require.default, file: pkg.exports["."].require.default,
format: "cjs", format: "cjs",
}, },
{
file: pkg.exports["./jsonifiable"].import.default,
format: "esm",
},
{
file: pkg.exports["./jsonifiable"].require.default,
format: "cjs",
},
], ],
plugins: [ plugins: [

View File

@@ -0,0 +1,61 @@
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"]
}

View File

@@ -1,2 +1,3 @@
export * from "./JsonifiableSchemableClass"
export * from "./makeJsonifiableSchemableClass" export * from "./makeJsonifiableSchemableClass"
export * from "./schema" export * from "./schema"

View File

@@ -1,12 +1,14 @@
import { Class } from "type-fest"
import { JsonifiableObject } from "type-fest/source/jsonifiable" import { JsonifiableObject } from "type-fest/source/jsonifiable"
import { z } from "zod" import { z } from "zod"
import { JsonifiableSchemableConfig } from "."
import { SchemableClass, SchemableConfig } from ".." import { SchemableClass, SchemableConfig } from ".."
import { parseZodTypeEffect } from "../util" import { StaticMembers, parseZodTypeEffect } from "../util"
export function makeJsonifiableSchemableClass< export function makeJsonifiableSchemableClass<
C extends SchemableClass<$Config>, C extends SchemableClass<$SchemableConfig>,
$Config extends SchemableConfig, $SchemableConfig extends SchemableConfig,
JsonifiedValues extends JsonifiableObject, JsonifiedValues extends JsonifiableObject,
@@ -18,28 +20,28 @@ export function makeJsonifiableSchemableClass<
DejsonifySchemaUnknownKeys extends z.UnknownKeysParam, DejsonifySchemaUnknownKeys extends z.UnknownKeysParam,
DejsonifySchemaCatchall extends z.ZodTypeAny, DejsonifySchemaCatchall extends z.ZodTypeAny,
>( >(
class_: C | SchemableClass<$Config>, class_: C | SchemableClass<$SchemableConfig>,
props: { props: {
jsonifySchema: (props: { jsonifySchema: (props: {
schema: $Config["schema"] schema: $SchemableConfig["schema"]
s: $Config["schema"]["shape"] s: $SchemableConfig["schema"]["shape"]
}) => z.ZodObject< }) => z.ZodObject<
JsonifySchemaT, JsonifySchemaT,
JsonifySchemaUnknownKeys, JsonifySchemaUnknownKeys,
JsonifySchemaCatchall, JsonifySchemaCatchall,
JsonifiedValues, JsonifiedValues,
$Config["values"] $SchemableConfig["values"]
> >
dejsonifySchema: (props: { dejsonifySchema: (props: {
schema: $Config["schema"] schema: $SchemableConfig["schema"]
s: $Config["schema"]["shape"] s: $SchemableConfig["schema"]["shape"]
}) => z.ZodObject< }) => z.ZodObject<
DejsonifySchemaT, DejsonifySchemaT,
DejsonifySchemaUnknownKeys, DejsonifySchemaUnknownKeys,
DejsonifySchemaCatchall, DejsonifySchemaCatchall,
$Config["values"], $SchemableConfig["values"],
JsonifiedValues JsonifiedValues
> >
}, },
@@ -55,13 +57,21 @@ export function makeJsonifiableSchemableClass<
s: class_.schema.shape, 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
return class JsonifiableSchemableObject extends class_ { const jsonifiableClass = class JsonifiableSchemableObject extends class_ {
static readonly jsonifySchema = jsonifySchema static readonly $jsonifiableSchemableConfig = $jsonifiableSchemableConfig
static readonly dejsonifySchema = dejsonifySchema static readonly jsonifySchema = jsonifySchema
static readonly dejsonifySchema = dejsonifySchema
readonly jsonifySchema = jsonifySchema readonly $jsonifiableSchemableConfig = $jsonifiableSchemableConfig
readonly dejsonifySchema = dejsonifySchema readonly jsonifySchema = jsonifySchema
readonly dejsonifySchema = dejsonifySchema
jsonify() { jsonify() {
return this.jsonifySchema.parse(this) return this.jsonifySchema.parse(this)
@@ -76,4 +86,13 @@ export function makeJsonifiableSchemableClass<
} }
} }
return jsonifiableClass as (
Class<
InstanceType<C> & InstanceType<typeof jsonifiableClass>,
ConstructorParameters<C>
> &
StaticMembers<C> &
StaticMembers<typeof jsonifiableClass>
)
} }

View File

@@ -26,10 +26,10 @@ export function makeSchemableClass<
const schema = zodObjectRemoveDefaults(schemaWithDefaultValues) const schema = zodObjectRemoveDefaults(schemaWithDefaultValues)
const $schemableConfig = { const $schemableConfig = {
values: {} as z.output<typeof schemaWithDefaultValues>, values: undefined as unknown as z.output<typeof schemaWithDefaultValues>,
input: {} as z.input<typeof schemaWithDefaultValues>, input: undefined as unknown as z.input<typeof schemaWithDefaultValues>,
schema, schema: undefined as unknown as typeof schema,
schemaWithDefaultValues, schemaWithDefaultValues: undefined as unknown as typeof schemaWithDefaultValues,
} as const satisfies SchemableConfig } as const satisfies SchemableConfig
return class SchemableObject { return class SchemableObject {

View File

@@ -1,5 +1,6 @@
import { z } from "zod" import { z } from "zod"
import { makeSchemableClass, newSchemable } from "." import { makeSchemableClass, newSchemable } from "."
import { dejsonifyBigIntSchema, jsonifyBigIntSchema, makeJsonifiableSchemableClass } from "./jsonifiable"
const UserSchema = z.object({ const UserSchema = z.object({
@@ -10,15 +11,17 @@ const UserSchema = z.object({
const UserSchemableObject = makeSchemableClass({ schema: UserSchema }) const UserSchemableObject = makeSchemableClass({ schema: UserSchema })
// const UserJsonifiableSchemableObject = makeJsonifiableSchemableClass(UserSchemableObject, { const UserJsonifiableSchemableObject = makeJsonifiableSchemableClass(UserSchemableObject, {
// jsonifySchema: ({ schema, s }) => schema.extend({ jsonifySchema: ({ schema, s }) => schema.extend({
// }), id: jsonifyBigIntSchema(s.id)
}),
// dejsonifySchema: ({ schema, s }) => schema.extend({ dejsonifySchema: ({ schema, s }) => schema.extend({
// }), id: dejsonifyBigIntSchema(s.id)
// }) }),
})
class User extends UserSchemableObject {} class User extends UserJsonifiableSchemableObject {}
const user1 = new User({ id: 1n }) const user1 = new User({ id: 1n })
const user2 = newSchemable(User, { id: 2n }) const user2 = newSchemable(User, { id: 2n })