damat-orm is migrations-only: src/cli/commands/index.ts registers only
migrate. Public type generation runs through damat codegen <module> in
an app or damat module codegen in a module package. Those commands use
@damatjs/module-generator, which owns discovery, output, registries,
scaffolds, and barrels.
The unregistered src/cli/commands/generate/types.ts handler is narrower: it
uses @damatjs/schema-codegen directly for a pure file map, augments links, and
writes only generated types. It is internal source, not a callable
damat-orm or damat command.
generate:types (unregistered) → discoverModels → toModuleSchema
→ generateFilesMap → augmentWithLinks → write
The public damat codegen command follows the @damatjs/module-generator
pipeline described above, including registry generation, scaffold-once CRUD,
and workflow barrel rebuilding.
generate:types <module> — src/cli/commands/generate/types.ts
Generate TypeScript type files from a module's ORM model definitions. Requires
the module name as ctx.args[0] (error if missing). No database connection.
Pipeline:
- Load modules:
loadModules("damat.config.ts", ctx.cwd); error if empty; look upmodules[moduleName](error if absent). - Link short-circuit: if
moduleConfig.kind === "link"(alink:<owner>module discovered fromconfig.links), log a notice that link modules don't emit their own types and return0. Link relationships surface as fields on the linked modules' types instead (step 6). - Verify models dir:
resolvedModelsDir = resolveModelsPath( moduleConfig.resolve)(=<resolve>/models); error if it does not exist. - Discover models:
models = await discoverModels(moduleConfig.resolve)(from@damatjs/orm-migration). - Build schema:
schema = toModuleSchema(moduleName, models)(from@damatjs/orm-model). - Generate files:
filesMap = generateFilesMap(schema, {}, ctx.logger)(from@damatjs/schema-codegen) — aMap<fileName, content>that includes anindex.tsplus one file per table. - Weave link augmentations:
augmentWithLinks(...)inspects everylink:<owner>module in the container, and for each link this module participates in adds the linked entity as an optional field on its interface via a sibling<table>.links.ts(declaration merging), re-exported fromindex.ts. No-op when no link modules exist — the output stays model-only. - Write output:
outputDir = resolveTypesPath(moduleConfig.resolve)(=<resolve>/types);mkdir -pif missing; write each[fileName, content]tooutputDir/fileName. - Log the output dir and the generated file names;
logger.success.
Any thrown error → logger.error("Failed to generate types: …"), return 1.
Success → 0.
internal generate:types handler for "user"
# Output: <project>/src/modules/user/types
# Files: index.ts, <table>.ts, ...
Inputs and outputs
| Concern | Source / target | Resolver |
|---|---|---|
| Models read from | <module.resolve>/models | resolveModelsPath |
| Types written to | <module.resolve>/types | resolveTypesPath |
| Schema name | the CLI <module> arg | passed straight to toModuleSchema |
| Link defs read from | each link:<owner> module's index.ts (links export) | loadModules (via config.links) |
| Link fields rendered by | renderLinkAugmentations | @damatjs/link |
Gotchas
- The models directory must already exist —
generate:typesvalidates it up front and errors rather than creating it. (Contrast with the outputtypes/dir, which is created on demand.) generateFilesMapis given an empty options object ({}) and the command'sctx.logger; per-codegen options are not surfaced through the CLI yet.- Files are written verbatim from the map keys — codegen owns the file naming
(e.g.
index.ts+ per-table files). The CLI does not post-process them. - Like the migrate commands,
@damatjs/schema-codegen,@damatjs/orm-model,@damatjs/orm-migration, and@damatjs/linkare loaded viaawait import(...)inside the handler. - Link modules don't generate types —
generate:types link:<owner>is a no-op that prints a notice and exits 0. To pick up linked fields, rungenerate:typesfor the linked modules themselves. - Link augmentation is best-effort: if a link directory fails to import or a
referenced table can't be resolved,
augmentWithLinkslogs awarnand skips that augmentation rather than failing the command. The base model types are always written. - The
<table>.links.tsfiles declaration-merge onto the base interfaces and carry an "auto-generated" banner; they are overwritten on every run, so don't hand-edit them.