Skip to content

Schemas

Mondel uses a functional schema API. One definition drives types, validation, and (via CLI) indexes/validators.

defineSchema

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

export const userSchema = defineSchema("users", {
  collection: "app_users", // MongoDB collection (defaults to name)
  timestamps: true, // or { createdAt: "created_at", updatedAt: "updated_at" }
  softDelete: { field: "deletedAt" }, // optional; field stamped by `{ soft: true }` deletes
  fields: {
    email: s.string().required().email().unique(),
    name: s.string(),
    role: s.enum(["ADMIN", "USER"]).default("USER"),
    age: s.number().min(0).max(150),
    meta: s.object({
      source: s.string(),
    }),
    tags: s.array(s.string()),
  },
  indexes: [
    {
      fields: { role: 1, createdAt: -1 },
      options: { name: "idx_role_created" },
    },
  ],
});

schema is an alias of defineSchema.

Implicit _id

Do not define _id in fields. MongoDB generates it; Mondel types documents with _id: ObjectId.

Field builders (s)

BuilderDescription
s.string()String (+ min/max/email/url/pattern)
s.number()Number (+ min/max)
s.boolean()Boolean
s.date()Date
s.objectId()ObjectId (refs) — accepts an ObjectId or a 24-char hex string
s.array(item)Array of a field builder
s.object(props)Nested object
s.json()Arbitrary JSON
s.literal(value)Literal (e.g. GeoJSON "Point")
s.enum([...])String enum

Common modifiers

typescript
s.string()
  .required() // mandatory on create (runtime)
  .unique() // unique index (via push)
  .default("guest") // applied on create in strict/loose (never on update; not when validation is "off")
  .index() // single-field index
  .index({ name: "idx", unique: true, type: "text" })
  .min(1)
  .max(100)
  .email()
  .url()
  .pattern(/^[A-Z]+$/);

Full tables: Field Types.

Indexes

Field-level:

typescript
email: s.string().index({ unique: true, name: "idx_email" });
location: s.object({ ... }).index({ type: "2dsphere" });
expiresAt: s.date().index({ expireAfterSeconds: 3600 });

Compound / partial / text weights — schema indexes array (see Advanced).

Apply with CLI (recommended):

bash
npx mondel push --uri "$MONGODB_URI" --schema ./dist/schemas.js --apply-validators

Type inference

typescript
import type { InferSchemaType, CreateInput, UpdateInput } from "mondel";

type User = InferSchemaType<typeof userSchema>;
// { _id: ObjectId; email?: string; ...; createdAt?: Date; updatedAt?: Date }

type UserCreate = CreateInput<typeof userSchema>;
type UserUpdate = UpdateInput<typeof userSchema>;

Exporting for the client

Always use as const so collection names become literal types:

typescript
export const schemas = [userSchema, orderSchema] as const;

Pull from an existing database

bash
npx mondel pull --uri mongodb://localhost:27017/app --out ./src/db/schemas.ts

Pull samples one document per collection — treat output as a bootstrap, then tighten types/required/defaults manually. See CLI.

Released under the MIT License. · llms.txt