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,
format: "esm",
},
{
file: pkg.exports["."].require.default,
format: "cjs",
},
{
file: pkg.exports["./jsonifiable"].import.default,
format: "esm",
},
{
file: pkg.exports["./jsonifiable"].require.default,
format: "cjs",
},
],
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 "./schema"

View File

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

View File

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