Generators
Generator commands scaffold boilerplate files so you can focus on implementation rather than file structure. All generators are prefixed with make:.
make:migration
Generate a new migration file with up() and down() stubs.
bunx d1-eloquent make:migration <name> [--factory] [--seeder] [--all]Output: src/database/migrations/<timestamp>_<name>.ts
| Option | Description |
|---|---|
--factory | Also scaffold a matching factory. The model name is guessed from <name> with the leading create_/alter_/update_/drop_ verb stripped (e.g. create_posts → PostsFactory). |
--seeder | Also scaffold a matching seeder (e.g. create_posts → PostsSeeder). |
--all | Scaffold both a factory and a seeder alongside the migration. |
Example:
bunx d1-eloquent make:migration create_posts_tableGenerated file (src/database/migrations/20240115_000000_create_posts_table.ts):
import type { TMigration } from '@orphnet/d1-eloquent/cli'
import { Schema } from '@orphnet/d1-eloquent/cli'
const migration: TMigration = {
name: '20240115_000000_create_posts_table',
// description: 'Purpose of this migration',
up: (schema: Schema) => {
// schema.createTable('posts', (t) => {
// t.id()
// t.timestamps()
// })
},
down: (schema: Schema) => {
// schema.dropTable('posts')
},
}
export default migrationmake:model
Generate a model class that extends BaseModel with a typed attributes interface.
bunx d1-eloquent make:model <Name> [--soft-deletes]Output: src/app/models/<Name>.ts
Pass --soft-deletes to add a deleted_at?: string | null field to the attributes type and set static softDeletes = true.
Example:
bunx d1-eloquent make:model PostGenerated file (src/app/models/Post.ts):
import { BaseModel } from '@orphnet/d1-eloquent'
export type TPostAttrs = {
id: string
// add fields
created_at: string
updated_at: string
}
export class Post extends BaseModel<TPostAttrs> {
public static table = 'posts'
public static primaryKey = 'id'
public static softDeletes = false
// public static revisions = { enabled: true, mode: 'diff+after', includeRequestId: true }
// public static eagerLoaders = { ... }
}make:seeder
Generate a seeder class with a run(db) method stub.
bunx d1-eloquent make:seeder <Name>Output: src/database/seeders/<Name>.ts
Example:
bunx d1-eloquent make:seeder PostSeederGenerated file (src/database/seeders/PostSeeder.ts):
import type { TSeeder, TSeederOpts } from '@orphnet/d1-eloquent/cli'
import { fake, output } from '@orphnet/d1-eloquent/cli'
// import { YourFactory } from '../factories/YourFactory'
const seeder: TSeeder = {
name: 'PostSeeder',
// description: 'Purpose of this seeder',
run: async (opts: TSeederOpts): Promise<void> => {
// const factory = new YourFactory()
// const rows = await factory.createMany(opts, 50)
//
// output.log(`Seeded ${rows.length} records`, { tag: 'post' })
},
}
export default seederThe stub imports the fake (data generation) and output (formatted logging) helpers ready for use.
For usage patterns — including combining seeders with factories — see Seeders & Factories.
make:factory
Generate a factory class with a definition() method that returns partial model attributes.
bunx d1-eloquent make:factory <Name>Output: src/database/factories/<Name>.ts
Example:
bunx d1-eloquent make:factory PostFactoryGenerated file (src/database/factories/PostFactory.ts):
import { Factory } from '@orphnet/d1-eloquent'
export type TPostAttrs = {
id: string
// add fields
created_at: string
updated_at: string
}
export class PostFactory extends Factory<TPostAttrs> {
public readonly table = 'posts'
public definition(): TPostAttrs {
const ts = new Date().toISOString()
return {
id: crypto.randomUUID(),
// define defaults
created_at: ts,
updated_at: ts,
}
}
}For usage patterns — including overrides and bulk creation — see Seeders & Factories.
make:resource
Generate a model, migration, factory, and seeder in a single command.
bunx d1-eloquent make:resource <Name> [--soft-deletes]Pass --soft-deletes to generate the model with soft-delete support (only the model is affected — the migration and factory are unchanged).
Example:
bunx d1-eloquent make:resource PostExample output:
Generating resource: Post
Created model: src/app/models/Post.ts
Created migration: src/database/migrations/20240115_000000_create_posts.ts
Created factory: src/database/factories/PostFactory.ts
Created seeder: src/database/seeders/PostSeeder.ts
Resource Post created (model + migration + factory + seeder)This is equivalent to running make:model Post, make:migration create_posts, make:factory PostFactory, and make:seeder PostSeeder separately. The table name is derived by pluralizing the model name (Post → posts).
make:pivot
Generate a pivot table migration for a many-to-many relationship. No model or seeder is created — pivot tables are typically managed directly through the join table.
bunx d1-eloquent make:pivot <pivot_table>Output: src/database/migrations/<timestamp>_create_<pivot_table>.ts
The table name is used to derive two foreign key column names: the last underscore-separated segment is singularized for one FK, and everything before it forms the other. For example, user_roles produces user_id and role_id. The table name must contain at least two segments (an underscore) or the command errors out.
Example:
bunx d1-eloquent make:pivot user_rolesGenerated file (src/database/migrations/20240115_000000_create_user_roles.ts):
import type { TMigration } from '@orphnet/d1-eloquent/cli'
import { Schema } from '@orphnet/d1-eloquent/cli'
const migration: TMigration = {
name: '20240115_000000_create_user_roles',
up: (schema: Schema) => {
schema.createTable('user_roles', (t) => {
t.text('user_id', { nullable: false })
t.text('role_id', { nullable: false })
t.primary('user_id, role_id')
t.index('user_id')
t.index('role_id')
})
},
down: (schema: Schema) => {
schema.dropTable('user_roles')
},
}
export default migrationFor usage patterns after generating, see the Seeders & Factories guide.
make:dto
Generate a typed attributes interface for a single model. Reads the model source and its corresponding migration to produce TModelAttrs (all fields) and TModelCreateAttrs (omitting auto-generated fields like id, created_at, updated_at, deleted_at).
bunx d1-eloquent make:dto <model> [--out-dir=path] [--force]Output: src/types/generated/<Model>Attrs.ts (default, override with --out-dir)
| Option | Description |
|---|---|
--out-dir=path | Output directory (default: src/types/generated) |
--force | Overwrite without prompting |
Example:
bunx d1-eloquent make:dto UserGenerated file (src/types/generated/UserAttrs.ts):
// Auto-generated by d1-eloquent make:dto
// Source model: User
export type TUserAttrs = {
id: string;
name: string;
email: string;
created_at: string;
updated_at: string;
};
export type TUserCreateAttrs = {
name: string;
email: string;
};If the file already exists, the CLI will prompt for confirmation before overwriting. Pass --force to skip the prompt.
make:types
Generate typed attributes for all models in the project, plus a barrel index.ts that re-exports everything.
bunx d1-eloquent make:types [--out-dir=path] [--force] [--json]Output: Individual <Model>Attrs.ts files + index.ts barrel in src/types/generated/ (default)
| Option | Description |
|---|---|
--out-dir=path | Output directory (default: src/types/generated) |
--force | Overwrite all without prompting |
--json | Machine-readable output |
Example:
bunx d1-eloquent make:typesExample output:
Generating types for 3 model(s)...
Created DTO: src/types/generated/UserAttrs.ts
Created DTO: src/types/generated/PostAttrs.ts
Created DTO: src/types/generated/CommentAttrs.ts
Created barrel: src/types/generated/index.ts
Done: 3 generated, 0 skippedModels that cannot be parsed are skipped with a warning. Use --json for CI integration.
generate (schema-diff migrations)
generate is a different kind of generator — instead of scaffolding a stub, it diffs each model's desired schema against the migrations already on disk and emits a reconciling migration (createTable for a new table, add*/dropColumn alters for a changed one). It never opens a database — the emitted file is the review gate.
bunx d1-eloquent generate # dry run — print the diff for every model
bunx d1-eloquent generate Post --write # emit the migration file
bunx d1-eloquent generate Post --write --name=add_pinned_to_posts # custom name| Option | Description |
|---|---|
--write | Emit the migration file(s). Without it, generate is a dry run that only prints the diff. |
--name=<name> | Custom migration name. Replaces the derived create_<table> / update_<table> segment after the timestamp prefix. Only applied when exactly one migration file is emitted - a multi-table run keeps the derived per-table names. |
See the Migrations guide → generate for the full walkthrough, destructive-drop annotations, and multi-table caveats.