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);
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"});
- 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
- Maps
.optional()
tovalidation.required: false
and.nullable()
tovalidation.notNull: false
.
import type {ModelDefinition} from "@orbit/records";
import type {AnyZodObject} from "zod";
export function zodToModelDefinition(zodSchema: AnyZodObject): ModelDefinition;
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;
ZodKey.definitionMeta: (definitionMeta: {[key: string]: unknown}) => ZodKey
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;
ZodAttribute.definitionMeta: (definitionMeta: {[key: string]: unknown}) => ZodAttribute
ZodAttribute.serialization: (serialization: {[key: string]: unknown}) => ZodAttribute
ZodAttribute.deserialization: (deserialization: {[key: string]: unknown}) => ZodAttribute
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;
ZodRelationship.definitionMeta: (definitionMeta: {[key: string]: unknown}) => ZodRelationship
ZodRelationship.inverse: (relationshipName: string) => ZodRelationship
ZodRelationship.dependentRemove: () => ZodRelationship
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
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