diff --git a/bun.lockb b/bun.lockb index 692b0f6..c02ea2e 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/src/index.ts b/src/index.ts index e69de29..8038132 100644 --- a/src/index.ts +++ b/src/index.ts @@ -0,0 +1 @@ +export * from "./makeSchemaClass" diff --git a/src/makeSchemaClass.ts b/src/makeSchemaClass.ts new file mode 100644 index 0000000..caf104a --- /dev/null +++ b/src/makeSchemaClass.ts @@ -0,0 +1,48 @@ +import { Class } from "type-fest" +import { z } from "zod" +import { StaticMembers, zodObjectRemoveDefaults } from "./util" + + +export function makeSchemaClass< + 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) + + class SchemaObject { + static readonly schema = schema + static readonly schemaWithDefaultValues = schemaWithDefaultValues + + readonly schema = schema + readonly schemaWithDefaultValues = schemaWithDefaultValues + + constructor(data: z.output) { + Object.assign(this, data) + } + } + + return SchemaObject as ( + Class< + SchemaObject & z.output, + ConstructorParameters + > & + StaticMembers + ) + +} diff --git a/src/tests.ts b/src/tests.ts new file mode 100644 index 0000000..1c2b569 --- /dev/null +++ b/src/tests.ts @@ -0,0 +1,14 @@ +import { z } from "zod" +import { makeSchemaClass } from "./makeSchemaClass" + + +const UserSchema = z.object({ + /** User ID */ + id: z.bigint().default(-1n) +}) + + +const UserSchemaObject = makeSchemaClass({ schema: UserSchema }) + +const user = new UserSchemaObject({ id: 1n }) +user.id diff --git a/src/util.ts b/src/util.ts index 7ab75c7..2cf7b08 100644 --- a/src/util.ts +++ b/src/util.ts @@ -3,6 +3,15 @@ import { mapValues } from "lodash-es" import { z } from "zod" +/** + * Represents the static members of a class. + * @template C - The class type. + */ +export type StaticMembers = { + [Key in keyof C as Key extends "prototype" ? never : Key]: C[Key] +} + + /** * Removes default values from a ZodObject schema and returns a new schema. *