@damatjs/orm-cli
v1.0.6
Published
Damatjs ORM CLI - database migration commands
Readme
@damatjs/orm-cli
damat-orm— the standalone CLI for Damat ORM migrations.
@damatjs/orm-cli ships the damat-orm binary: a small, config-driven command
line tool that runs system and module migrations. It reads damat.config.ts to discover
modules, the cross-module links under links, and the database URL, then
delegates the real work to the @damatjs/orm-* packages. It is built on the
shared @damatjs/cli runner, so commands, options, banner, and help formatting
come from the same framework as the rest of the Damat CLIs.
Part of the Damat monorepo · Full guide · Internals
Install
The binary is damat-orm.
# inside the monorepo (workspace protocol)
bun add -d @damatjs/orm-cli@*
# globally, to get `damat-orm` on your PATH
bun add -g @damatjs/orm-cli# typical invocation from a project root that has damat.config.ts
bun damat-orm <command> [args] [options]
# or, if installed globally
damat-orm <command> [args] [options]Commands
| Command | Description | Example |
| ------------------------- | ------------------------------------------------------- | ------------------------------- |
| database:setup | Create the configured database and apply migrations | damat-orm database:setup |
| migrate:up | Run all pending migrations across every module | damat-orm migrate:up |
| migrate:status [module] | Show applied/pending counts (optionally for one module) | damat-orm migrate:status user |
| migrate:list | List modules that have migrations, with counts | damat-orm migrate:list |
| migrate:create <module> | Create an initial or diff migration for a module | damat-orm migrate:create user |
| migrate:adopt <module> <migration> | Audit an already committed non-transactional migration | damat-orm migrate:adopt user Migration1_Index --checksum ... --actor ... --reason ... |
migrate:statusalso accepts--module <name>/-m <name>as an alternative to the positional argument.Type generation lives elsewhere.
damat-ormis migrations-only — generate row types/zod/registry withdamat codegen <module>(in an app) ordamat module codegen(in a module package). Both commands use@damatjs/module-generator, which consumes@damatjs/schema-codegen.
All migration commands honor a resolved module's declared migration directory,
including immutable packages whose SQL lives below src/migrations.
When durable events are enabled, migrate:up applies the shared durability
catalog followed by the events catalog before module migrations. Enabling jobs
selects shared durability followed by jobs. Enabling pipelines selects shared
durability, jobs, then pipelines because pipeline action/workflow nodes use the
durable job runtime. With every capability enabled the stable owner order is
shared durability, jobs, events, then pipelines. The all-module
migrate:status view includes each enabled system owner. A module-scoped
status request remains limited to that module.
database:setup first connects to the configured target. PostgreSQL error
3D000 triggers a server-level check through the standard postgres database;
the command safely creates the requested database when absent and then delegates
to migrate:up. Existing databases and repeated migration runs are idempotent.
The configured user needs CREATEDB only when the target does not exist.
Every command propagates its handler result to the process exit status, so
configuration, connection, and migration failures are nonzero in CI and scripts.
Configuration imports are cache-busted through the operating-system temporary
directory rather than beside the source, so migration jobs can keep the
application filesystem read-only. Config bundling also leaves pg-cloudflare
external. It remains an optional transport of pg; applications do not need to
declare it merely to run migrations or application codegen.
Cross-module links
When damat.config.ts declares links (a path, or list of paths, e.g.
"./src/links"), each owner directory underneath it — src/links/<owner>/ with
its own models/, index.ts, and migrations/ — is discovered as a link
migration module with id link:<owner>. Link modules carry the junction
tables that join models living in different modules.
migrate:list/migrate:status/migrate:create/migrate:uptreat eachlink:<owner>like any other module, so its junction tables migrate through the same pipeline:bun damat-orm migrate:create link:user # initial/diff migration for the junction tables bun damat-orm migrate:up # applies module + link migrations togetherdamat codegendoes not emit standalone types for a link module. Passing alink:<owner>id prints a notice and exits 0. Instead, runningdamat codegenfor a linked module weaves the relationship in: for every link the module participates in, the linked entity is added as an optional field on the module's generated interface via a sibling<table>.links.tsdeclaration-merge file that is re-exported from the module's types index.# user and organization are linked → regenerate the linked modules bun damat codegen user # Users gains e.g. organizations?: Organizations[] bun damat codegen organization # Organizations gains the reverse field
When to use
- Use
damat-ormwhen you want to drive migrations directly — in CI, scripts, or a non-Damat-app project that still uses the Damat ORM and adamat.config.ts. - Inside a full Damat backend, the
damatCLI (@damatjs/damat-cli) is the day-to-day entry point; it shells out tobun damat-orm migrate:upafter installing a module. Both read the samedamat.config.ts. - For authoring a single standalone module package, prefer
damat module migration:create/damat module codegen(from@damatjs/damat-cli), which operate on the module package directly.
Quick start
Given a project with a damat.config.ts like:
export default {
projectConfig: {
databaseUrl: process.env.DATABASE_URL,
},
modules: {
user: { id: "user", resolve: "./src/modules/user" },
},
// optional: cross-module link directories (each owner becomes link:<owner>)
links: "./src/links",
};# 1. create the first migration for the user module (diffs models vs snapshot)
bun damat-orm migrate:create user
# 2. apply pending migrations for all modules
bun damat-orm migrate:up
# 3. check what is applied vs pending
bun damat-orm migrate:status
bun damat-orm migrate:status user # or: --module user
# 4. list modules that have migrations
bun damat-orm migrate:list
# 5. generate TypeScript types from the user module's models
bun damat codegen userNotes grounded in the source:
- The config file name is fixed to
damat.config.ts. Source paths resolve relative to it; Node and Damat descriptors resolve immutable artifact roots and their manifest-declared migrations. - The database URL is read from
projectConfig.databaseUrl, falling back toservices.database(connectionString, or host/port/user/password/database fields used to build one). migrate:createwrites an initial migration the first time (no snapshot yet) and a diff migration thereafter; a diff with no changes is reported as "No changes detected." and exits 0.damat codegen(notdamat-orm) writes a file-per-table map plus anindex.tsinto the module'stypes/directory; when the module participates in cross-module links it also emits<table>.links.tsaugmentation files and re-exports them fromindex.ts.- Link migration modules are discovered from
linksindamat.config.ts: eachsrc/links/<owner>becomes alink:<owner>module whose junction tables migrate throughmigrate:create/migrate:up.
How it fits
Depends on:
@damatjs/cli— command runner, option parsing, banner, help, config loader.@damatjs/orm-migration— discovery, executor, generator, tracker (runMigrations,createInitialMigration,createDiffMigration,getMigrationStatus,discoverModels,discoverAllMigrations).@damatjs/orm-processor—snapshotExist(initial-vs-diff decision).@damatjs/orm-model— schema construction used by the unregistered internal type-generation handler.@damatjs/schema-codegen— pure file-map generation used by that handler.@damatjs/link—resolveLinkMigrationModules(discoverslink:<owner>migration modules) andrenderLinkAugmentations(the<table>.links.tsfiles woven into linked modules' generated types).@damatjs/orm-type—OrmModule/OrmModuleContainershapes.@damatjs/deps— bundledpg(Pool).@damatjs/logger—ILoggerused by command output.
Consumed by: invoked directly by developers/CI, and shelled out to by
@damatjs/damat-cli (damat module add suggests bun damat-orm migrate:up).
Documentation
- Internals — module map, command dispatch, config/path resolution, and per-command behaviour.
- Full guide — the Damat monorepo guide.
License
MIT
