Generate, Migrate, and Test
Reference for TypoKit CLI commands that generate code from your schema, manage database migrations, and run tests.
Every command accepts these global flags:
| Flag | Description |
|---|---|
--root <dir> | Project root directory (default: current working directory) |
--verbose, -v | Show detailed output including timing and file-level information |
Generate Commands
Section titled “Generate Commands”All generate commands read your TypeScript type files (configured via typeFiles in typokit.config.ts) and route files, then emit derived artifacts to the output directory (default: .typokit/).
typokit generate:db
Section titled “typokit generate:db”Generate database schema files (SQL DDL and JSON metadata) from your TypeScript entity types.
Syntax
typokit generate:dbFlags
| Flag | Description |
|---|---|
--verbose, -v | Show detailed output |
--json | Output result metadata as JSON |
What it does
- Reads all type files from the configured
typeFilesglobs - Extracts entity interfaces annotated with
@tableJSDoc tags - Calls
diffSchemas()to compare current types against the last-known schema snapshot - Emits SQL DDL statements and a JSON metadata file to the output directory
Example
typokit generate:db● Reading type files... 12 files● Extracting entities... 6 tables● Generating DDL... done
✔ Database schema generated (6 tables) .typokit/db/schema.sql (2.4kB) .typokit/db/schema.json (1.1kB)With --json:
typokit generate:db --json{ "success": true, "filesWritten": [".typokit/db/schema.sql", ".typokit/db/schema.json"], "tables": 6, "duration": 312}typokit generate:client
Section titled “typokit generate:client”Generate a type-safe API client from your route contracts.
Syntax
typokit generate:clientFlags
| Flag | Description |
|---|---|
--verbose, -v | Show detailed output |
--json | Output result metadata as JSON |
What it does
- Reads all route files from the configured
routeFilesglobs - Extracts route contracts with their typed parameters, query strings, request bodies, and responses
- Generates a TypeScript client module with a
createClient()factory function - Emits the client to the output directory
Example
typokit generate:client● Reading route files... 8 modules● Extracting contracts... 24 operations● Generating client... done
✔ Client generated (24 operations) .typokit/client/index.ts (6.8kB)Generated client usage:
import { createClient } from ".typokit/client";
const api = createClient({ baseUrl: "http://localhost:3000" });
// Fully typed — params, query, body, and responseconst users = await api.getUsers({ query: { page: 1 } });const user = await api.getUser({ params: { id: "abc" } });typokit generate:openapi
Section titled “typokit generate:openapi”Generate an OpenAPI 3.1 specification from your routes and types.
Syntax
typokit generate:openapi [--output <path>]Flags
| Flag | Description |
|---|---|
--output <path> | Custom output path (default: .typokit/openapi.json) |
--verbose, -v | Show detailed output |
--json | Output result metadata as JSON |
What it does
- Reads all route files and type files
- Builds a complete OpenAPI 3.1 specification including paths, schemas, parameters, and responses
- Writes the spec as a JSON file to the output location
Example
typokit generate:openapi● Reading routes and types... 8 modules, 12 type files● Building OpenAPI spec... 24 operations, 18 schemas● Writing spec... done
✔ OpenAPI spec generated .typokit/openapi.json (14.2kB)With a custom output path:
typokit generate:openapi --output ./dist/openapi.json✔ OpenAPI spec generated dist/openapi.json (14.2kB)typokit generate:tests
Section titled “typokit generate:tests”Regenerate contract test stubs from your route contracts.
Syntax
typokit generate:testsFlags
| Flag | Description |
|---|---|
--verbose, -v | Show detailed output |
--json | Output result metadata as JSON |
What it does
- Reads all route contracts from configured
routeFilesglobs - Generates contract test files that validate request/response shapes against the schema
- Writes test files to
__generated__/tests/in the output directory
Example
typokit generate:tests● Reading route contracts... 24 operations● Generating contract tests... done
✔ Contract tests generated (24 test files) __generated__/tests/getUsers.contract.test.ts __generated__/tests/createUser.contract.test.ts __generated__/tests/getUser.contract.test.ts ... (24 files)Migrate Commands
Section titled “Migrate Commands”Migration commands manage incremental database schema changes. Migrations are always generated as drafts for review — they never auto-apply.
typokit migrate:generate
Section titled “typokit migrate:generate”Generate a migration draft from the diff between your current TypeScript types and the last-known schema snapshot.
Syntax
typokit migrate:generate --name <name>Flags
| Flag | Description |
|---|---|
--name <name> | Migration name (required) |
--verbose, -v | Show detailed output |
--json | Output result metadata as JSON |
What it does
- Compares the current entity types against the saved schema snapshot
- Generates a timestamped SQL migration file with the detected changes
- Generates a JSON metadata file describing each change
- Annotates destructive changes (column drops, type changes) with
-- DESTRUCTIVE: requires review - Updates the schema snapshot after generation
Example
typokit migrate:generate --name add-user-avatar● Comparing schemas... 2 changes detected● Generating migration... done
✔ Migration generated .typokit/migrations/20260302_120000_add-user-avatar.sql .typokit/migrations/20260302_120000_add-user-avatar.json
Changes: + users.avatar_url VARCHAR(255) (add column) + users.avatar_updated TIMESTAMP (add column)When destructive changes are detected:
typokit migrate:generate --name remove-legacy-fields● Comparing schemas... 3 changes detected (1 destructive)● Generating migration... done
✔ Migration generated .typokit/migrations/20260302_130000_remove-legacy-fields.sql .typokit/migrations/20260302_130000_remove-legacy-fields.json
Changes: - users.legacy_role VARCHAR(50) (drop column) ⚠ DESTRUCTIVE ~ posts.status ENUM → VARCHAR (type change) + posts.published_at TIMESTAMP (add column)typokit migrate:diff
Section titled “typokit migrate:diff”Show pending schema changes without generating a migration file.
Syntax
typokit migrate:diff [--json]Flags
| Flag | Description |
|---|---|
--json | Output as JSON instead of human-readable table |
--verbose, -v | Show detailed output |
What it does
- Compares the current entity types against the saved schema snapshot
- Displays pending changes as a human-readable table or JSON
- Does not modify any files — this is a read-only inspection command
Example
typokit migrate:diffPending schema changes:
Table Column Change Type ───── ────── ────── ──── users avatar_url add column VARCHAR(255) users avatar_updated add column TIMESTAMP posts published_at add column TIMESTAMP
3 changes pending (0 destructive)With --json:
typokit migrate:diff --json{ "changes": [ { "table": "users", "column": "avatar_url", "change": "add_column", "type": "VARCHAR(255)", "destructive": false }, { "table": "users", "column": "avatar_updated", "change": "add_column", "type": "TIMESTAMP", "destructive": false }, { "table": "posts", "column": "published_at", "change": "add_column", "type": "TIMESTAMP", "destructive": false } ], "sql": "ALTER TABLE users ADD COLUMN avatar_url VARCHAR(255);\nALTER TABLE users ADD COLUMN avatar_updated TIMESTAMP;\nALTER TABLE posts ADD COLUMN published_at TIMESTAMP;", "total": 3, "destructive": 0}typokit migrate:apply
Section titled “typokit migrate:apply”Apply pending migrations to the database.
Syntax
typokit migrate:apply [--force]Flags
| Flag | Description |
|---|---|
--force | Apply destructive migrations without interactive review |
--verbose, -v | Show detailed output |
--json | Output result metadata as JSON |
What it does
- Reads all migration files from the migrations directory
- Checks which migrations have already been applied (tracked in
.appliedlog) - Applies pending migrations in chronological order
- Blocks on destructive migrations unless
--forceis passed - Records applied migrations in the
.appliedlog
Example
typokit migrate:apply● Checking pending migrations... 2 pending● Applying 20260302_120000_add-user-avatar.sql... ✔● Applying 20260302_130000_add-indexes.sql... ✔
✔ 2 migrations applied (148ms)When destructive migrations are pending:
typokit migrate:apply● Checking pending migrations... 1 pending
⚠ Migration 20260302_130000_remove-legacy-fields.sql contains destructive changes: - users.legacy_role (drop column)
Blocked. Use --force to apply destructive migrations.typokit migrate:apply --force● Checking pending migrations... 1 pending● Applying 20260302_130000_remove-legacy-fields.sql... ✔ (destructive)
✔ 1 migration applied (92ms)With --json:
typokit migrate:apply --json{ "success": true, "applied": [ { "file": "20260302_120000_add-user-avatar.sql", "duration": 84, "destructive": false } ], "total": 1, "duration": 148}Test Commands
Section titled “Test Commands”Test commands run your project’s tests using auto-detected or explicitly specified test runners.
TypoKit detects the test runner by checking for config files in this priority order:
| Priority | Runner | Config files checked |
|---|---|---|
| 1 | Jest | jest.config.{js,ts,mjs,cjs} |
| 2 | Vitest | vitest.config.{js,ts,mjs,cjs} |
| 3 | Rstest | rstest.config.{js,ts,mjs,cjs} |
| fallback | Vitest | (used when no config found) |
typokit test
Section titled “typokit test”Run all tests (contract tests + integration tests) using the detected test runner.
Syntax
typokit test [--runner <runner>]Flags
| Flag | Description |
|---|---|
--runner <runner> | Override test runner detection (jest, vitest, or rstest) |
--verbose, -v | Show verbose test output |
--json | Output result metadata as JSON |
What it does
- Auto-detects the test runner (or uses the
--runneroverride) - Checks if contract test stubs are stale — regenerates them if the schema has changed since the last build
- Spawns the test runner as a subprocess with the full test suite
Example
typokit test● Detected runner: vitest● Checking contract tests... up to date● Running tests...
✓ __generated__/tests/getUsers.contract.test.ts (3 tests) ✓ __generated__/tests/createUser.contract.test.ts (2 tests) ✓ tests/integration/users.test.ts (5 tests) ✓ tests/integration/auth.test.ts (4 tests)
Tests 14 passed (4 files) Time 1.2s
✔ All tests passedWith --runner override:
typokit test --runner jest● Using runner: jest● Checking contract tests... regenerated (schema changed)● Running tests...
PASS __generated__/tests/getUsers.contract.test.tsPASS __generated__/tests/createUser.contract.test.tsPASS tests/integration/users.test.tsPASS tests/integration/auth.test.ts
Tests: 14 passed, 14 totalTime: 2.1s
✔ All tests passedWith --json:
typokit test --json{ "success": true, "runner": "vitest", "passed": 14, "failed": 0, "duration": 1200, "contractsRegenerated": false}typokit test:contracts
Section titled “typokit test:contracts”Run only the generated contract tests.
Syntax
typokit test:contracts [--runner <runner>]Flags
| Flag | Description |
|---|---|
--runner <runner> | Override test runner detection (jest, vitest, or rstest) |
--verbose, -v | Show verbose test output |
--json | Output result metadata as JSON |
What it does
- Auto-detects the test runner (or uses the
--runneroverride) - Regenerates contract tests if schemas have changed
- Runs only the tests in
__generated__/tests/using runner-specific path patterns
Runner-specific patterns:
| Runner | Pattern |
|---|---|
| Jest | --testPathPattern __generated__/.*\.contract\.test |
| Vitest | run __generated__/ |
| Rstest | run --testPathPattern __generated__/.*\.contract\.test |
Example
typokit test:contracts● Detected runner: vitest● Checking contract tests... up to date● Running contract tests...
✓ __generated__/tests/getUsers.contract.test.ts (3 tests) ✓ __generated__/tests/createUser.contract.test.ts (2 tests) ✓ __generated__/tests/getUser.contract.test.ts (2 tests) ✓ __generated__/tests/updateUser.contract.test.ts (2 tests) ✓ __generated__/tests/deleteUser.contract.test.ts (1 test)
Tests 10 passed (5 files) Time 0.8s
✔ Contract tests passedtypokit test:integration
Section titled “typokit test:integration”Run integration tests with real services (database, external APIs).
Syntax
typokit test:integration [--runner <runner>]Flags
| Flag | Description |
|---|---|
--runner <runner> | Override test runner detection (jest, vitest, or rstest) |
--verbose, -v | Show verbose test output |
--json | Output result metadata as JSON |
What it does
- Auto-detects the test runner (or uses the
--runneroverride) - Runs only the tests in the integration test directory using runner-specific path patterns
Runner-specific patterns:
| Runner | Pattern |
|---|---|
| Jest | --testPathPattern integration |
| Vitest | run --dir tests/integration |
| Rstest | run --testPathPattern integration |
Example
typokit test:integration● Detected runner: vitest● Running integration tests...
✓ tests/integration/users.test.ts (5 tests) ✓ tests/integration/auth.test.ts (4 tests) ✓ tests/integration/posts.test.ts (6 tests)
Tests 15 passed (3 files) Time 3.4s
✔ Integration tests passedWith --runner override:
typokit test:integration --runner jest● Using runner: jest● Running integration tests...
PASS tests/integration/users.test.tsPASS tests/integration/auth.test.tsPASS tests/integration/posts.test.ts
Tests: 15 passed, 15 totalTime: 4.2s
✔ Integration tests passedSee Also
Section titled “See Also”- Scaffolding and Development — Project scaffolding and development server commands
- Inspect Commands — Query framework state from the CLI
- Building Your First API — Step-by-step tutorial using generate and test commands
- Database Adapters — How TypoKit interacts with your database