mcpField
O
orm-preflight

orm-preflight

ローカル
sikandar100.github.io開発ツール02 週間前に更新

orm-preflight について

orm-preflightは、TypeORMのマイグレーションを検査し、マージ前にデータ損失、テーブルロック、デプロイ上のリスクを検出するコマンドラインツールです。データベース接続は不要で、問題の説明、安全な代替案、CI向けの出力を提供します。

主な機能

  1. 01マイグレーションのデータ損失リスクを検査
  2. 02ブロックにつながる可能性のある操作を検出
  3. 03ローリングデプロイの問題を検出
  4. 04検出内容と安全な代替案を説明
  5. 05JSON、GitHub注釈、SARIFで出力

活用シーン

  1. 01マージ前にTypeORMのマイグレーションを確認
  2. 02プルリクエスト内の追加・変更分を検査
  3. 03GitHub Actionsにマイグレーション検査を追加
  4. 04データ書き換えやテーブルロックの可能性を調査

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"sikandar100-orm-preflight": {
"command": "npx",
"args": [
"-y",
"orm-preflight"
]
}
}
}
起動コマンドnpx -y orm-preflight

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmorm-preflight1.2.0

ツール

3

掲載時のツール一覧 · 2 週間前に更新

パラメーター型必須説明
filesarrayいいえprojectDir からの相対パスで指定するマイグレーションファイルまたは glob です。例:["src/migrations/1727200000000-AddEmail.ts"]。
dialectenumいいえデータベースです。デフォルト:設定値、または postgres。postgres | mysql
projectDirstringいいえpackage.json があるプロジェクトルートの絶対パスです。デフォルト:サーバーの起動時のディレクトリ。
changedSincestringいいえorigin/main などの Git 参照です。ブランチがその参照から分岐した後に追加または変更されたマイグレーションのみを確認します。
postgresVersionintegerいいえPostgreSQL のメジャーバージョンです。デフォルト:設定値、または 16。

詳細

orm-preflight

npm CI OpenSSF Scorecard License: MIT

TypeORM のマイグレーションを安全に事前チェックします。データ損失やロックをマージ前に検出します。

ドキュメント:https://sikandar100.github.io/orm-preflight/

TypeORM でカラムの長さを変更すると、そのカラムのデータがすべて削除されることがあります。カラムの型や長さが変更されると、TypeORM のマイグレーションジェネレーターはカラムを削除して再度追加します (typeorm/typeorm#3357)。このマイグレーションはレビューでは問題がないように見え、空のデータベースではすべてのテストに合格します。orm-preflight は、こうしたマイグレーションや、データ損失を引き起こす、稼働中のテーブルをロックする、またはローリングデプロイを妨げるほかのマイグレーションを、マージ前に検出します。

src/migrations/1727100000000-WidenUserName.ts
  7:30  error  no-drop-and-recreate-column
        "users"."name" is dropped and re-added in the same migration. Every existing value in this column will be lost.
        Why:  TypeORM drops and re-adds a column when its type or length changes, instead of changing it in place. The new column starts empty.
        Safe: Change the type in place: ALTER TABLE "users" ALTER COLUMN "name" TYPE varchar(255). Widening a varchar, or changing varchar to text, does not rewrite the table. ...
        Docs: https://github.com/sikandar100/orm-preflight/blob/main/docs/rules/no-drop-and-recreate-column.md

  8:30  error  no-add-not-null-without-default
        "users"."name" is added as NOT NULL without a default. The migration fails as soon as "users" has any rows.
        ...

2 errors, 0 warnings in 1 migration

インストールと実行

npm install --save-dev orm-preflight
npx orm-preflight "src/migrations/*.ts"

Node.js 20 以降が必要です。引数を指定しない場合、orm-preflight は設定内の migrations グロブ、またはプロジェクト内のすべての migrations フォルダーをチェックします。

既存プロジェクトで履歴を修正せずに使い始めるには、まず npx orm-preflight init を実行してください (既存プロジェクトへの導入を参照)。

検出できる問題

ルール検出内容
データ損失
no-drop-and-recreate-column1つのマイグレーション内で削除後に再追加されたカラム
possible-rename-data-lossデータがコピーされずに、あるカラムが削除され、別のカラムが追加されている(警告)
no-drop-column削除されたカラム
no-drop-table削除されたテーブル
no-truncateTRUNCATE または clearTable()
no-truncating-type-changeleft() など、USING が各値の一部だけを保持する型変更(警告)
no-delete-rows既存のテーブルに対する DELETE(警告)
no-null-out-columnカラムを NULL に設定するだけの UPDATE(警告)
rewrites-existing-rows既存のテーブルに対するすべての UPDATE、upsert、または INSERT ... SELECT(レビュー用、情報)
typeorm/no-changecolumn-recreateカラムを削除して再追加する changeColumn()
デプロイの安全性
no-rename-column名前が変更されたカラム
no-rename-table名前が変更されたテーブル
ロック(PostgreSQL)
require-concurrent-indexCONCURRENTLY を指定しない CREATE INDEX
concurrent-index-transactionトランザクション内で実行される CONCURRENTLY
no-add-not-null-without-defaultデフォルト値なしで追加された NOT NULL カラム
no-volatile-default揮発性のデフォルト値を指定して追加されたカラム、またはシリアル、identity、generated として追加されたカラム
no-unsafe-column-type-changeテーブルを書き換えるカラムの型変更
require-not-valid-foreign-keyNOT VALID を指定せずに追加された外部キー
no-set-not-null既存のカラムに対する SET NOT NULL
require-not-valid-checkNOT VALID を指定せずに追加された CHECK 制約
validate-in-same-transactionNOT VALID で追加した同じトランザクション内での VALIDATE CONSTRAINT(効果がない場合、警告)
require-concurrent-uniqueインプレースで追加された一意制約または主キー
require-concurrent-index-dropCONCURRENTLY を指定しない DROP INDEX(警告)
no-blocking-maintenanceCONCURRENTLY を指定しない VACUUM FULL、CLUSTER、または REINDEX
enum-value-used-in-same-transaction追加するトランザクションがコミットされる前に使用された新しい enum 値
require-lock-timeoutlock_timeout を指定しない既存テーブルへの変更(オフ、オプトイン)
typeorm/no-enum-recreate型を再作成する TypeORM 0.3 の enum 変更(警告)
正確性
typeorm/transaction-override-forbiddenトランザクションモードが "all" のときにマイグレーションに設定された transaction
typeorm/invalid-migration-name13 桁のタイムスタンプを含まないマイグレーション名
unanalyzable-statementorm-preflight が解析できなかったステートメント(警告)
invalid-suppression理由がない、または不明なルールを指定した抑制コメント
no-edit-applied-migration--changed-since の使用時:ベースブランチにすでに存在するマイグレーションの編集
require-down空または未定義の down()(警告)
各指摘では、何が起こるのか、その理由、安全に変更する方法を説明します。各ルールのページでは、主張の根拠となる PostgreSQL、MySQL、または TypeORM のソースを引用しています。npx orm-preflight explain <rule> を実行するとターミナルで内容を確認できます。一覧を見るには npx orm-preflight rules を実行してください。

同じマイグレーション内で作成されたテーブルへの変更は報告されません。まだ行が存在しないためです。

コマンドライン

orm-preflight [files or globs...] [options]

  -c, --config <path>         Config file (default: orm-preflight.config.json, then the
                              "ormPreflight" key in package.json)
  --dialect <postgres|mysql>  Database dialect (default: postgres)
  --postgres-version <n>      PostgreSQL major version the migrations run on (default: 16)
  --orm <typeorm>             ORM adapter (default: typeorm)
  --changed-since <git-ref>   Check only migrations added or changed since the merge base
                              with <git-ref>, such as origin/main
  --format <format>           pretty, json, github (annotations), or sarif. Default:
                              github in GitHub Actions, pretty elsewhere
  --max-warnings <n>          Fail when there are more than n warnings (default: no limit)
  --execute                   Run each migration's up() to see SQL built at run time. This
                              runs your code: only use it on code you trust
  --allow-untrusted-execute   Allow --execute under GitHub's pull_request_target event
  --no-color                  Print without colors

orm-preflight rules                      List every rule
orm-preflight explain <rule>             Print a rule's documentation
orm-preflight init [files or globs...]   Write a starter config
orm-preflight mcp                        Run as an MCP server for AI coding agents
終了コード意味
0エラーがなく、警告数が --max-warnings 以下
1エラーがある、または警告数が --max-warnings を超過
2使用方法、設定、または内部エラー
形式出力
prettyファイルごとにグループ化した、人が読みやすい指摘。抑制された指摘は件数のみ表示されます。
json抑制されたものも含む、すべての指摘。形式は公開 API であり、docs/json-output.md に記載されています。
githubプルリクエストの該当行に対する GitHub Actions の注釈と、その後に表示されるサマリー行。
sarifGitHub コードスキャンやその他の SARIF ビューアー向けの SARIF 2.1.0。抑制された指摘も理由とともに保持されます。

設定

設定は orm-preflight.config.json に記述するか、package.json の "ormPreflight" キーの下に記述してください。JSON のみをサポートしているため、プルリクエストから設定を通じてコードを実行することはできません。

{
  "$schema": "./node_modules/orm-preflight/schema.json",
  "orm": "typeorm",
  "dialect": "postgres",
  "postgresVersion": 16,
  "migrations": ["src/migrations/*.ts"],
  "startAfter": 1727000000000,
  "typeorm": { "transactionMode": "each" },
  "rules": { "no-rename-column": "warn" }
}
キー意味
migrationsマイグレーションファイルの glob パターン。デフォルト:すべての migrations フォルダー。
startAfterマイグレーションのタイムスタンプ。このタイムスタンプ以前のマイグレーションはチェックされません。
postgresVersion実行する PostgreSQL のメジャーバージョン。12 以降を指定してください。安全な代替策の一部はバージョンに依存します。デフォルト:16。
defaultSchemaスキーマが修飾されていないテーブル名に適用するスキーマ。PostgreSQL でのデフォルト:public。
typeorm.transactionModeDataSource の migrationsTransactionMode と一致させる必要があります。all(TypeORM のデフォルト)、each、または none。
rulesルールごとの重大度:error、warn、info、または off。

コマンドラインフラグは設定を上書きします。

各重大度の動作:

重大度意味
error実際の問題です。実行は失敗します(終了コード 1)。
warn問題の可能性があります。--max-warnings を超えた場合にのみ実行が失敗します。
info既存の行を書き換えるステートメントなど、把握しておくとよい情報です。実行が失敗することはありません。
offこのルールは実行されません。

既存のプロジェクトに導入する

npx orm-preflight init

init は startAfter に最新のマイグレーションを設定した orm-preflight.config.json を書き込みます。そのため、これ以降に追加したマイグレーションだけがチェックされます。マイグレーションファイルは読み取りますが、実行することはありません。

プルリクエストでは、ブランチで追加または変更したマイグレーションだけをチェックすることもできます。

npx orm-preflight --changed-since origin/main

origin/main とのマージベースを比較し、未コミットファイルと未追跡ファイルも含めます。変更されたマイグレーションのいずれかが作成するテーブルは、それらすべてのマイグレーションに対して新規として扱われます。origin/main にすでに存在するマイグレーションの編集は、no-edit-applied-migration によって報告されます。GitHub Actions では、マージベースを利用できるように fetch-depth: 0 を指定してチェックアウトしてください。

継続的インテグレーション

orm-preflight はデータベースもシークレットも必要としないため、フォークからのプルリクエストでも安全に実行できます。

GitHub Action

検出結果は、プルリクエストの該当行に注釈として表示されます。

name: Migrations
on: pull_request

permissions:
  contents: read

jobs:
  orm-preflight:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0 # for changed-since
          persist-credentials: false
      - uses: sikandar100/orm-preflight@v1
        with:
          changed-since: origin/${{ github.base_ref }}

使用するバージョンは次のとおりです。

  • @v1 はすべての 1.x リリースに追従するため、変更を加えずに修正を取得できます。
  • 固定する必要がある場合は、@v1.0.0 またはコミット SHA を指定すると、そのバージョンに固定されます。

このアクションはタグに対応するバージョンの orm-preflight を npm でインストールして実行するため、GitHub ホストランナーではほかに何も必要ありません。セルフホストランナーでは、事前に Node.js 20 以降をセットアップしてください。

入力意味
changed-sinceこの git ref とのマージベース以降に追加または変更されたマイグレーションだけをチェックします。
filesチェックするファイルまたは glob。スペース区切りです。デフォルトは設定ファイル、またはすべての migrations フォルダーです。
config設定ファイルのパス。
working-directoryリポジトリのルートからの相対パスで指定する、実行ディレクトリ。デフォルトは . です。
max-warnings警告がこの数を超えた場合に失敗します。
mysqlマイグレーションが MySQL を対象とする場合は true にして、MySQL パーサーをインストールします。
sarif検出結果も GitHub コードスキャンにアップロードする場合は true にします。以下を参照してください。
version実行する orm-preflight のバージョン。デフォルトはアクションのタグのバージョンです。

pull_request トリガーを使用してください。この用途では pull_request_target を絶対に使用しないでください。フォークからのプルリクエストに書き込み権限のあるトークンとシークレットを与えることになりますが、orm-preflight はどちらも必要としません。

GitHub では、各ステップで各レベルの注釈は最大 10 件まで表示されます。ログの最終行には、すべての検出結果が常に表示されます。

リポジトリのコードスキャンアラートにも検出結果を表示するには、sarif: true を設定し、security-events: write を付与します。GitHub はフォークからのプルリクエストにはこの権限を付与しないため、その場合、アクションはアップロードをスキップし、注釈は引き続き表示します。

permissions:
  contents: read
  security-events: write
その他の CI システム

CLI を実行します。エラーがある場合、終了コードは 1 です。

npx orm-preflight --changed-since origin/main

マージベースを取得できるだけの履歴をチェックアウトしてください(GitHub Actions では fetch-depth: 0)。

AI コーディングエージェントで使用する

AI コーディングエージェントはマイグレーションをすばやく作成できますが、危険なマイグレーションを作成することもあります。orm-preflight に接続すると、エージェントは作成した各マイグレーションをチェックし、検出した問題を修正してから、あなたが内容をレビューできます。

Claude Code プラグイン

このプラグインを使うと、多くの作業を自動化できます。Claude Code 内で一度インストールするだけです。

/plugin marketplace add sikandar100/orm-preflight
/plugin install orm-preflight@orm-preflight

次の3つの機能が追加されます。

  • 自動チェック。 Claude がマイグレーションを作成または編集するたびに、orm-preflight がチェックし、その結果を Claude に直接返します。Claude はマイグレーションを修正するか、安全である理由を説明します。警告を自分で読む必要はありません。それ以外のファイルは即座にスキップされます。
  • スキーマを安全に変更する方法を Claude に教えるスキル。たとえば、カラムを削除せずにその場で変更する方法を教えます。
  • 以下で説明する MCP ツール。

プラグインは、リリース時に同梱された正確なバージョンの orm-preflight を、初回使用時に npm からダウンロードして実行します。プロジェクトの orm-preflight.config.json は引き続き適用されます。たとえば MySQL パーサーを使用するために、自動チェックでプロジェクトにインストールされている orm-preflight を実行するには、/config でプラグイン設定の Use the project's own orm-preflight をオンにします。

MCP を使って任意のエージェントで利用する

orm-preflight mcp は orm-preflight を MCP サーバーとして実行します。MCP はエージェントに新しいツールを提供する標準的な方法です。一度追加するだけです。

プラグインを使わずに Claude Code で設定する場合:

claude mcp add orm-preflight -- npx -y orm-preflight mcp

Cursor、VS Code、Codex、Gemini CLI などのほかのエージェントでは、このコマンドを実行するサーバーを MCP 設定に追加します。各アプリにはそれぞれ設定ファイルがありますが、コマンドは常に同じです。

npx -y orm-preflight mcp

各エージェントの具体的な設定方法と、AGENTS.md 用の指示スニペットは、AI エージェントでの使用をご覧ください。

エージェントは次の3つのツールを利用できます。

ツールエージェントが得られる情報
check_migrations一部のファイル、プロジェクト全体、または origin/main などの git ref 以降に変更されたマイグレーションの検出結果。各検出結果には、何が起きるか、なぜ問題なのか、安全な実施方法が含まれます。
explain_ruleルールのドキュメント全文。
list_rulesカテゴリとデフォルトの重要度を含む、すべてのルール。

知っておくと便利なこと:

  • ツールはファイルを読み取るだけです。マイグレーションを実行したり、データベースに接続したりすることはありません。また、MCP 経由では --execute を使用できません。
  • サーバーは、起動したディレクトリのプロジェクトをチェックします。別の場所で起動したエージェントは projectDir を渡すことができます。
  • mcp の後に指定したフラグはデフォルト値になります。たとえば npx -y orm-preflight mcp --dialect mysql です。MySQL の場合は、プロジェクトに orm-preflight と node-sql-parser をインストールし、パーサーが見つかるように -y を付けずに npx orm-preflight mcp を使用してください。
  • サーバーは、事前に確認せず抑制コメントを追加しないようエージェントに指示します。
  • エージェントから、ツールの使用許可を一度求められることがあります。

検出結果の抑制

検出結果が想定どおりの場合は、その理由をステートメントの上のコメントに記載します。

// preflight safety-assured no-drop-column -- bio removed from the entity in 2.3, deployed everywhere
await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "bio"`)

抑制には理由が必須です。これにより、抑制の監査証跡が作成されます。ファイル全体を対象にする場合は、/* preflight safety-assured-file <rule> -- <reason> */ をファイル内の任意の場所に記述します。理由がない抑制や未知のルールを指定した抑制は、それ自体がエラーになります。

仕組み

orm-preflight は各マイグレーションファイルを Babel で解析し、queryRunner.query() に渡される SQL 文字列と、addColumn() や createIndex() などのビルダー呼び出しを読み取ります。また、同じファイル内で値が分かる場合は、SQL 内の ${...} も展開します。たとえば、定数、固定引数で呼び出されるローカル関数、既知の配列に対する .join() が対象です。既知の配列を対象とするループも、項目ごとに一度ずつ読み取ります。SQL は PostgreSQL パーサー(libpg-query)または MySQL パーサーで解析し、その結果にルールを適用します。

マイグレーションをインポートしたり実行したりすることはなく、データベースにも接続せず、TypeORM も読み込みません。実行時に構築される SQL など、読み取れないものは黙ってスキップされず、unanalyzable-statement として報告されます。

--execute を使ったマイグレーションの実行

データベースから読み取った名前や、別ファイルからインポートしたヘルパーなど、実行時にならないと分からない値から SQL を構築するマイグレーションがあります。静的解析ではその SQL を読み取れません。--execute を使うと可能になります。

npx orm-preflight --execute

各マイグレーションファイルを読み込み、TypeORM のクエリランナーの代役を使って up() を実行します。この代役は、データベースに送信する代わりにすべてのステートメントを記録します。そのため、次のようになります。

  • データベースは不要で、データベースにアクセスすることもありません。
  • typeorm のインポートには簡易的な代役が使われ、実際の TypeORM が読み込まれることはありません。
  • up() が getTable() などでデータベースを読み取る場合、空の結果が返されます。そのため、実際のデータベースでは異なるステートメントになる可能性があると orm-preflight が報告します。
  • up() が失敗した場合、または 10 秒を超えて実行された場合は報告され、リンティングは続行されます。

--execute はコードを実行します。 信頼できるコードにのみ使用してください。

  • pull_request_target トリガーが設定されたフォークからのプルリクエストでは、シークレットが渡されるため、絶対に使用しないでください。--allow-untrusted-execute を追加しない限り、orm-preflight は実行を拒否します。
  • GitHub Action は --execute を使用しません。フォークに対しても静的解析を行い、安全性を保ちます。

クリーンな実行が意味すること

クリーンな実行とは、文書化された危険性が見つからなかったことを意味します。マイグレーションの安全性を保証するものではありません。orm-preflight はテーブルの規模やトラフィックを把握できないため、既存のテーブルはすべて大規模で、頻繁に利用されているものと仮定します。

制限事項:

  • TypeORM のみが対象です。コアは ORM に依存しないため、他の ORM 用のアダプターも開発できます。
  • PostgreSQL と MySQL に対応しています。MySQL では、データ損失、デプロイの安全性、正確性に関するルールが適用されます。MySQL のロック解析(ALGORITHM=INSTANT、INPLACE、COPY)は 1.0 以降に予定されています。MySQL を使うには npm install --save-dev node-sql-parser が必要です。
  • 解析対象は up() のみです。down() は空であることのみ確認します(require-down)。
  • 実行時に構築される SQL は、--execute を使用しない限り、解析されずに報告されます。

プログラムからの使用

import { formatJson, lint } from 'orm-preflight'

const result = await lint({ cwd: process.cwd(), patterns: ['src/migrations/*.ts'] })
process.stdout.write(formatJson(result))
if (result.summary.errors > 0) process.exitCode = 1

貢献

CONTRIBUTING.md をご覧ください。セキュリティ上の問題を報告する場合は、SECURITY.md をご覧ください。

プライバシー

orm-preflight は何も収集せず、何も送信しません。テレメトリ、分析、アカウントはありません。お使いのマシンまたは CI ランナー上で実行され、データベースに接続することはありません。詳細はプライバシーポリシーをご覧ください。

謝辞

orm-preflight は、Rails 向けの strong_migrations と PostgreSQL 向けの squawk に着想を得ています。

ライセンス

MIT

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。