Skip to content

Models & fields

dorm.model(name, schema, options?) returns a Model whose .objects manager is your query/write surface. The schema is the single source of truth: it drives type inference and runtime validation.

ts
const User = dorm.model(
  "users",
  {
    email: f.string({ required: true, validate: (v) => {
      if (!v.includes("@")) throw new Error("Enter a valid email.");
    } }),
    salary: f.number({ default: 0 }),
    active: f.boolean({ default: true }),
    supervisor: f.ref("users"),
  },
  { timestamps: true },
);

Models are declared synchronously and can be defined at module top-level, before dorm.connect().

Field builders

Every f.* builder accepts { required?, default?, validate?, unique?, index? }:

BuilderStored asNotes
f.string(opts?)string
f.number(opts?)numberrejects NaN
f.boolean(opts?)boolean
f.date(opts?)DateISO strings / timestamps are coerced
f.objectId(opts?)ObjectIdhex strings are coerced
f.ref(collection, opts?)ObjectIdsupplies $lookup.from for __ traversal
f.array(element, opts?)T[]each element validated against element
f.embedded(schema, opts?)objectvalidated against the sub-schema (typed)
f.enum(values, opts?)unionvalue must be one of values

See Data modeling for array / embedded / enum in depth.

Options

  • default — a value or a factory (() => new Date()) evaluated per create.
  • validate — throw an Error to reject; the message surfaces on the validation error (code DORM_ERROR_3).
  • unique / index — declare indexes, created by ensureIndexes().
  • options.timestamps: true — manages createdAt / updatedAt automatically.

Typed input & output

The schema types every operation:

ts
const u = await User.objects.create({ email: "a@b.com" });
u._id;       // ObjectId
u.createdAt; // Date  (present because timestamps: true)
u.salary;    // number

// @ts-expect-error — `email` is required
await User.objects.create({ salary: 10 });
  • InferDoc — the stored/returned document shape (_id + fields + timestamps).
  • CreateInput — required-without-default fields are mandatory; the rest optional.
  • UpdateInput — every field optional (a partial patch).

Released under the MIT License.