Skip to content

Schema Definition

Mondel utilizes a functional approach to schema definition that is entirely type-safe.

Philosophy

You define your schema in TypeScript using defineSchema, and Mondel derives everything from it:

  • Runtime validation (Zod)
  • TypeScript interfaces
  • Database collection names
  • Default values & constraints

The defineSchema API

The schema definition is split into two parts: the schema name (for internal debugging/logging) and the configuration object.

typescript
import { defineSchema, s } from "mondel";

export const userSchema = defineSchema("users", {
  collection: "app_users", // actual MongoDB collection name (defaults to schema name)
  timestamps: true, // adds createdAt/updatedAt automatically
  fields: {
    // _id is implicit - auto-generated by MongoDB and typed as ObjectId
    // only define your custom fields here
  },
  indexes: [
    // compound indexes go here
  ],
});

Implicit _id

You don't need to define _id in your schema. MongoDB automatically generates it, and Mondel automatically includes it in your TypeScript types as _id: ObjectId.

Field Builders

Use the s helper to construct fields.

Common Types

  • s.string()
  • s.number()
  • s.boolean()
  • s.date()
  • s.objectId()
  • s.array(s.string()) // array of strings
  • s.object({ ... }) // nested object
  • s.litearl("foo") // literal value "foo"
  • s.enum(["A", "B"]) // union of string literals

Constraints & Modifiers

Chain modifiers to add constraints. These are enforced both by TypeScript (where possible) and at runtime.

typescript
s.string()
  .required() // makes field mandatory
  .unique() // adds unique index
  .default("guest") // sets default value if undefined
  .min(3) // minimum string length
  .max(50) // maximum string length
  .email(); // validates email format

Indexes

You can define single-field indexes directly on the field definition for convenience.

typescript
email: s.string().index();
// or with options
email: s.string().index({ unique: true, name: "email_idx" });

For compound indexes involving multiple fields, use the indexes array at the schema root.

typescript
indexes: [
  {
    fields: { role: 1, email: -1 },
    options: { unique: true },
  },
];

Type Inference

You can extract the full TypeScript type of your schema using InferSchemaType.

typescript
import type { InferSchemaType } from "mondel";

type User = InferSchemaType<typeof userSchema>;
// { _id: ObjectId, email: string, role: "ADMIN" | "USER", ... }

Released under the MIT License.