Skip to content

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:

FlagDescription
--root <dir>Project root directory (default: current working directory)
--verbose, -vShow detailed output including timing and file-level information

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/).

Generate database schema files (SQL DDL and JSON metadata) from your TypeScript entity types.

Syntax

Terminal window
typokit generate:db

Flags

FlagDescription
--verbose, -vShow detailed output
--jsonOutput result metadata as JSON

What it does

  1. Reads all type files from the configured typeFiles globs
  2. Extracts entity interfaces annotated with @table JSDoc tags
  3. Calls diffSchemas() to compare current types against the last-known schema snapshot
  4. Emits SQL DDL statements and a JSON metadata file to the output directory

Example

Terminal window
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:

Terminal window
typokit generate:db --json
{
"success": true,
"filesWritten": [".typokit/db/schema.sql", ".typokit/db/schema.json"],
"tables": 6,
"duration": 312
}

Generate a type-safe API client from your route contracts.

Syntax

Terminal window
typokit generate:client

Flags

FlagDescription
--verbose, -vShow detailed output
--jsonOutput result metadata as JSON

What it does

  1. Reads all route files from the configured routeFiles globs
  2. Extracts route contracts with their typed parameters, query strings, request bodies, and responses
  3. Generates a TypeScript client module with a createClient() factory function
  4. Emits the client to the output directory

Example

Terminal window
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 response
const users = await api.getUsers({ query: { page: 1 } });
const user = await api.getUser({ params: { id: "abc" } });

Generate an OpenAPI 3.1 specification from your routes and types.

Syntax

Terminal window
typokit generate:openapi [--output <path>]

Flags

FlagDescription
--output <path>Custom output path (default: .typokit/openapi.json)
--verbose, -vShow detailed output
--jsonOutput result metadata as JSON

What it does

  1. Reads all route files and type files
  2. Builds a complete OpenAPI 3.1 specification including paths, schemas, parameters, and responses
  3. Writes the spec as a JSON file to the output location

Example

Terminal window
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:

Terminal window
typokit generate:openapi --output ./dist/openapi.json
✔ OpenAPI spec generated
dist/openapi.json (14.2kB)

Regenerate contract test stubs from your route contracts.

Syntax

Terminal window
typokit generate:tests

Flags

FlagDescription
--verbose, -vShow detailed output
--jsonOutput result metadata as JSON

What it does

  1. Reads all route contracts from configured routeFiles globs
  2. Generates contract test files that validate request/response shapes against the schema
  3. Writes test files to __generated__/tests/ in the output directory

Example

Terminal window
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)

Migration commands manage incremental database schema changes. Migrations are always generated as drafts for review — they never auto-apply.

Generate a migration draft from the diff between your current TypeScript types and the last-known schema snapshot.

Syntax

Terminal window
typokit migrate:generate --name <name>

Flags

FlagDescription
--name <name>Migration name (required)
--verbose, -vShow detailed output
--jsonOutput result metadata as JSON

What it does

  1. Compares the current entity types against the saved schema snapshot
  2. Generates a timestamped SQL migration file with the detected changes
  3. Generates a JSON metadata file describing each change
  4. Annotates destructive changes (column drops, type changes) with -- DESTRUCTIVE: requires review
  5. Updates the schema snapshot after generation

Example

Terminal window
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:

Terminal window
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)

Show pending schema changes without generating a migration file.

Syntax

Terminal window
typokit migrate:diff [--json]

Flags

FlagDescription
--jsonOutput as JSON instead of human-readable table
--verbose, -vShow detailed output

What it does

  1. Compares the current entity types against the saved schema snapshot
  2. Displays pending changes as a human-readable table or JSON
  3. Does not modify any files — this is a read-only inspection command

Example

Terminal window
typokit migrate:diff
Pending 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:

Terminal window
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
}

Apply pending migrations to the database.

Syntax

Terminal window
typokit migrate:apply [--force]

Flags

FlagDescription
--forceApply destructive migrations without interactive review
--verbose, -vShow detailed output
--jsonOutput result metadata as JSON

What it does

  1. Reads all migration files from the migrations directory
  2. Checks which migrations have already been applied (tracked in .applied log)
  3. Applies pending migrations in chronological order
  4. Blocks on destructive migrations unless --force is passed
  5. Records applied migrations in the .applied log

Example

Terminal window
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:

Terminal window
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.
Terminal window
typokit migrate:apply --force
● Checking pending migrations... 1 pending
● Applying 20260302_130000_remove-legacy-fields.sql... ✔ (destructive)
✔ 1 migration applied (92ms)

With --json:

Terminal window
typokit migrate:apply --json
{
"success": true,
"applied": [
{
"file": "20260302_120000_add-user-avatar.sql",
"duration": 84,
"destructive": false
}
],
"total": 1,
"duration": 148
}

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:

PriorityRunnerConfig files checked
1Jestjest.config.{js,ts,mjs,cjs}
2Vitestvitest.config.{js,ts,mjs,cjs}
3Rstestrstest.config.{js,ts,mjs,cjs}
fallbackVitest(used when no config found)

Run all tests (contract tests + integration tests) using the detected test runner.

Syntax

Terminal window
typokit test [--runner <runner>]

Flags

FlagDescription
--runner <runner>Override test runner detection (jest, vitest, or rstest)
--verbose, -vShow verbose test output
--jsonOutput result metadata as JSON

What it does

  1. Auto-detects the test runner (or uses the --runner override)
  2. Checks if contract test stubs are stale — regenerates them if the schema has changed since the last build
  3. Spawns the test runner as a subprocess with the full test suite

Example

Terminal window
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 passed

With --runner override:

Terminal window
typokit test --runner jest
● Using runner: jest
● Checking contract tests... regenerated (schema changed)
● Running tests...
PASS __generated__/tests/getUsers.contract.test.ts
PASS __generated__/tests/createUser.contract.test.ts
PASS tests/integration/users.test.ts
PASS tests/integration/auth.test.ts
Tests: 14 passed, 14 total
Time: 2.1s
✔ All tests passed

With --json:

Terminal window
typokit test --json
{
"success": true,
"runner": "vitest",
"passed": 14,
"failed": 0,
"duration": 1200,
"contractsRegenerated": false
}

Run only the generated contract tests.

Syntax

Terminal window
typokit test:contracts [--runner <runner>]

Flags

FlagDescription
--runner <runner>Override test runner detection (jest, vitest, or rstest)
--verbose, -vShow verbose test output
--jsonOutput result metadata as JSON

What it does

  1. Auto-detects the test runner (or uses the --runner override)
  2. Regenerates contract tests if schemas have changed
  3. Runs only the tests in __generated__/tests/ using runner-specific path patterns

Runner-specific patterns:

RunnerPattern
Jest--testPathPattern __generated__/.*\.contract\.test
Vitestrun __generated__/
Rstestrun --testPathPattern __generated__/.*\.contract\.test

Example

Terminal window
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 passed

Run integration tests with real services (database, external APIs).

Syntax

Terminal window
typokit test:integration [--runner <runner>]

Flags

FlagDescription
--runner <runner>Override test runner detection (jest, vitest, or rstest)
--verbose, -vShow verbose test output
--jsonOutput result metadata as JSON

What it does

  1. Auto-detects the test runner (or uses the --runner override)
  2. Runs only the tests in the integration test directory using runner-specific path patterns

Runner-specific patterns:

RunnerPattern
Jest--testPathPattern integration
Vitestrun --dir tests/integration
Rstestrun --testPathPattern integration

Example

Terminal window
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 passed

With --runner override:

Terminal window
typokit test:integration --runner jest
● Using runner: jest
● Running integration tests...
PASS tests/integration/users.test.ts
PASS tests/integration/auth.test.ts
PASS tests/integration/posts.test.ts
Tests: 15 passed, 15 total
Time: 4.2s
✔ Integration tests passed