@orbit-utils/zod-to-model-definition
v0.1.0
Published
Define your RecordSchema using Zod.
Downloads
1
Maintainers
Readme
@orbit-utils/zod-to-model-definition
Define your RecordSchema
using Zod.
Before:
const planetModelDefinition = {
attributes: {
name: {type: "string"},
classification: {type: "string"},
atmosphere: {type: "boolean"},
mass: {type: "number"},
},
relationships: {
solarSystem: {kind: "hasOne", type: "solarSystem", inverse: "planets"},
moons: {kind: "hasMany", type: "moon", inverse: "planet"},
},
};
After:
import {m, zodToModelDefinition} from "@orbit-utils/zod-to-model-definition";
import {z} from "zod";
const planetZodSchema = z.object({
type: z.literal("planet"),
id: z.string().optional(),
attributes: z.object({
name: z.string(),
classification: z.enum(["terrestrial", "gaseous"]),
atmosphere: z.boolean(),
mass: z.number().positive().finite(),
}),
relationships: z.object({
solarSystem: m.relationship("hasOne", "solarSystem").inverse("planets"),
moons: m.relationship("hasMany", "moon").inverse("planet"),
}),
});
const planetModelDefinition = zodToModelDefinition(planetZodSchema);
Usage
Install using your preferred Node.js package manager. For example:
pnpm add @orbit-utils/zod-to-model-definition
Import and enjoy!
import {zodToModelDefinition} from "@orbit-utils/zod-to-model-definition";
For facilitating special model definition attributes (such as inverse
, dependent: "delete"
and meta
) in your Zod schema, the library provides custom ZodType
s through m
:
import {m} from "@orbit-utils/zod-to-model-definition";
m.relationship("hasOne", "solarSystem").inverse("planets");
m.relationship("hasMany", "moon").inverse("planet");
m.attribute(z.number().positive().finite()).definitionMeta({unit: "kg"});
Advantages of using Zod to define your RecordSchema
- You can infer TypeScript types from your Zod schema.
type Planet = z.infer<typeof planetZodSchema>; // same as… interface Planet extends UninitializedRecord { type: "planet"; ... } // …except you don't have to maintain separate interface definitions
- Zod allows for a more granular schema definition (more granular types, more granular validation).
classification: { type: "string"; } vs.z.enum(["terrestrial", "gaseous"]); mass: { type: "number"; } vs.z.number().positive().finite();
- You can configure Orbit to use Zod's validation instead of its own with
validateFor
.
- You can configure Orbit to use Zod's validation instead of its own with
Additional features
- Maps
.optional()
tovalidation.required: false
and.nullable()
tovalidation.notNull: false
.
API reference
zodToModelDefinition
import type {ModelDefinition} from "@orbit/records";
import type {AnyZodObject} from "zod";
export function zodToModelDefinition(zodSchema: AnyZodObject): ModelDefinition;
ZodKey
Extends ZodType
.
Zod schema counterpart for KeyDefinition
.
Can be created by calling m.key
.
import type {ZodType} from "zod";
export function key(zodType?: ZodType<string>): ZodKey;
.definitionMeta
ZodKey.definitionMeta: (definitionMeta: {[key: string]: unknown}) => ZodKey
ZodAttribute
Extends ZodType
.
Zod schema counterpart for AttributeDefinition
.
Can be created by calling m.attribute
.
import type {ZodTypeAny} from "zod";
export function attribute(zodType?: ZodTypeAny): ZodAttribute;
.definitionMeta
ZodAttribute.definitionMeta: (definitionMeta: {[key: string]: unknown}) => ZodAttribute
.serialization
ZodAttribute.serialization: (serialization: {[key: string]: unknown}) => ZodAttribute
.deserialization
ZodAttribute.deserialization: (deserialization: {[key: string]: unknown}) => ZodAttribute
ZodRelationship
Extends ZodType
.
Zod schema counterpart for RelationshipDefinition
.
Can be created by calling m.relationship
.
import type {ZodTypeAny} from "zod";
export function relationship(
kind: "hasOne" | "hasMany",
type?: string | string[],
): ZodRelationship;
.definitionMeta
ZodRelationship.definitionMeta: (definitionMeta: {[key: string]: unknown}) => ZodRelationship
.inverse
ZodRelationship.inverse: (relationshipName: string) => ZodRelationship
.dependentRemove
ZodRelationship.dependentRemove: () => ZodRelationship
.links
Schema for the links
object that can appear on your record. (See RecordRelationship
.)
import type {Link} from "@orbit/records";
import type {ZodType} from "zod";
ZodRelationship.links: (schema: ZodType<{[key: string]: Link} | undefined>) => ZodRelationship
.meta
Schema for the meta
object that can appear on your record. (See RecordRelationship
.)
import type {ZodType} from "zod";
ZodRelationship.meta: (schema: ZodType<{[key: string]: unknown} | undefined>) => ZodRelationship