migrating-to-zero-yaml について
`nango.yaml`を使うNangoプロジェクトをZero YAMLへ移行するためのスキルです。既存の動作を優先して設定やスクリプトを機械的に変換し、コンパイルと検証を行います。
主な機能
- 01YAML設定と参照スクリプトの棚卸し
- 02プロジェクトの土台とZodスキーマの作成
- 03同期、アクション、イベントハンドラーの変換
- 04エントリーのインポート生成と型インポートの修正
- 05コンパイル、dryrun、テストによる検証
活用シーン
- 01既存のNangoプロジェクトをZero YAMLへ移行
- 02スクリプトの配置と動作を保って移行
- 03移行後のコンパイルとdryrunの確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ nangohq/ skills --skill migrating-to-zero-yamlインストール後、Claude Code で/migrating-to-zero-yamlを入力して読み込まれたか確認します。
詳細
Zero YAML への移行
このスキルでは、従来の CLI 移行ツールを、LLM 主導の機械的な移行に置き換えます。既存の YAML プロジェクトの動作をできるだけ維持してから、検証して終了します。ユーザーから依頼がない限り、移行の範囲を広げてクリーンアップを行わないでください。
重要なルール
- ユーザーに
nango migrate-to-zero-yamlの実行を指示しないでください。 - コードを手作業で移行してください。
- まず既存の動作を維持してください。
- ユーザーから依頼された場合、またはコンパイル上どうしても必要な場合を除き、
lastSyncDate、syncType、trackDeletes、バリデーションパターンを機会に乗じて移行しないでください。 - リポジトリがすでに Zero YAML を使用している場合は、移行を無理に進めず、通常の Zero YAML リファクタリングのワークフローに切り替えて終了してください。
前提条件
- Nango プロジェクトのルートにいることと、
nango.yamlが存在することを確認します。 - 破壊的な編集を行う前に、ロールバック手段があることを確認します(Git ブランチ/コミット、または外部バックアップ)。
nango.yamlを読み、以下を一覧化します。- インテグレーション
- 同期
- アクション
- イベントハンドラー
- モデル
- YAML の各エントリーが参照している既存の TypeScript ファイルを調べます。
- 移行は機械的に行います。API の再設計、スクリプトの名前変更、ビジネスロジックの変更は避けてください。
目指す最終状態
移行後のプロジェクトには、以下が含まれている必要があります。
package.jsontsconfig.json- ルートの
models.ts - ルートの
index.ts createSync()、createAction()、またはcreateOnEvent()をエクスポートするインテグレーションファイルnangoから Nango ランタイム型をインポートするヘルパーファイル- 最終的な移行後の状態では
nango.yamlが存在しない
移行ワークフロー
nango.yamlを読み、移行項目の一覧を作成します。- Zero YAML の構成ファイルを作成または更新します。
package.jsontsconfig.json
- YAML のモデルから
models.tsを生成します。 - 各同期ファイルを
createSync(...)に書き換えます。 - 各アクションファイルを
createAction(...)に書き換えます。 - 各ライフサイクルハンドラーを
createOnEvent(...)に書き換えます。 - 移行した各スクリプトを対象とする、副作用インポートを
index.tsに生成します。 - ヘルパーファイルのインポートと、小規模な TypeScript の不具合を修正します。
- コンパイルして検証します。
- 置き換え後のプロジェクトが用意できており、ファイル外にロールバック手段が残っていることを確認してから、
nango.yamlを削除します。
構成ファイルのルール
package.json
プロジェクトにパッケージファイルがない場合は、作成します。すでに存在する場合は、既存のフィールドを維持しつつ、Zero YAML に必要な項目を追加します。
type: "module"engines.node: ">=20.0"- スクリプト:
compile: "nango compile"dev: "nango dev"
devDependencies.nangodevDependencies.zod
リポジトリで使用しているパッケージマネージャーと既存のワークスペース関連フィールドは、できるだけ維持してください。
tsconfig.json
標準的な Zero YAML の TypeScript 設定形式を使用します。
{
"$schema": "https://json.schemastore.org/tsconfig",
"include": ["index.ts", "**/*.ts"],
"exclude": ["node_modules", "dist", "build", ".nango"],
"compilerOptions": {
"module": "node16",
"target": "esnext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node16",
"exactOptionalPropertyTypes": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noPropertyAccessFromIndexSignature": true,
"noUncheckedIndexedAccess": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"sourceMap": true,
"noEmit": true
}
}
models.ts を生成する
YAML のモデル定義を、Zod スキーマとエクスポートする推論型に変換するルートの models.ts ファイルを作成します。
次のパターンを使用します。
import * as z from 'zod';
export const Ticket = z.object({
id: z.string(),
title: z.string()
});
export type Ticket = z.infer<typeof Ticket>;
export const models = {
Ticket
};
変換ルール:
string→z.string()number→z.number()boolean→z.boolean()Date→z.date()any→z.any()。より安全なフォールバックが必要な場合はz.unknown()- オプションのフィールド →
.optional() - 配列 →
z.array(...) - ネストされたオブジェクト → ネストされた
z.object(...) - ユニオン →
z.union([...]) - モデル参照 → 参照先のスキーマを再利用
- 動的なオブジェクトフィールド →
z.record(...)または.catchall(...)
実務上のルール:以前の YAML モデルを正確に表現するのが難しい場合は、プロジェクトをコンパイルできる範囲で、最も安全性の高い広範なスキーマを使って移行を進めます。必要な場合に限り、後から厳密化してください。
依存関係の順にモデルを定義します。循環参照が発生した場合は、z.lazy(() => ModelName) を使用します。
同期を変換する
各 YAML 同期について、可能な限り既存のファイルパスを維持し、既存のデフォルトエクスポート関数を createSync(...) でラップします。
YAML の設定を Zero YAML の設定に次のように対応させます。
description→descriptionversion→version(ない場合は0.0.1をデフォルト値にします)runs→frequencyauto_start→autoStartsync_type→syncTypetrack_deletes→trackDeletes- YAML の
endpoints→createSync(...)から省略します。Zero YAML のendpointsフィールドは非推奨です scopes→scopes- webhook のサブスクリプション →
webhookSubscriptions - YAML の
inputモデル →metadata - YAML の
outputモデル →models - 既存のデフォルトエクスポート関数の本体 →
exec
同期に YAML の input モデルがない場合は、移行時の同等性を保つため、metadata のデフォルト値として z.object({}) を指定します。
ファイルが onWebhookPayloadReceived をエクスポートしている場合は、その関数を createSync(...) の設定にある onWebhook に移します。
次の形を使用します。
import { createSync } from 'nango';
import * as z from 'zod';
import { Metadata, Ticket } from '../../models.js';
const sync = createSync({
description: 'Sync tickets',
version: '0.0.1',
frequency: 'every hour',
autoStart: true,
syncType: 'full',
trackDeletes: false,
metadata: Metadata,
models: { Ticket },
exec: async (nango) => {
// keep existing logic
}
});
export type NangoSyncLocal = Parameters<typeof sync['exec']>[0];
export default sync;
アクションを変換する
各 YAML アクションについて、既存のデフォルトエクスポート関数を createAction(...) でラップします。
YAML の設定を次のように対応させます。
description→descriptionversion→version(デフォルト値は0.0.1)- YAML の
endpoint→createAction(...)から省略します。Zero YAML のendpointフィールドは非推奨です input→inputoutput→outputscopes→scopes- 既存のデフォルトエクスポート関数の本体 →
exec
アクションに input または output のスキーマがない場合は、z.void() を使用します。
次の形を使用します。
import { createAction } from 'nango';
import * as z from 'zod';
import { CreateTicketInput, CreateTicketOutput } from '../../models.js';
const action = createAction({
description: 'Create ticket',
version: '0.0.1',
input: CreateTicketInput,
output: CreateTicketOutput,
exec: async (nango, input) => {
// keep existing logic
}
});
export type NangoActionLocal = Parameters<typeof action['exec']>[0];
export default action;
イベントハンドラーを変換する
各 YAML ライフサイクルハンドラーについて、既存のデフォルトエクスポートを createOnEvent(...) でラップします。
次のように対応させます。
- イベント名 →
event - description → 既存の description があればそのまま維持し、なければ
<event> event handlerを使用します - 既存のデフォルトエクスポート関数の本体 →
exec
次の形を使用します。
import { createOnEvent } from 'nango';
export default createOnEvent({
event: 'post-connection-creation',
description: 'post-connection-creation event handler',
exec: async (nango) => {
// keep existing logic
}
});
インポートと型の修正
旧マイグレーターではインポートも整理されていました。同様に手動で整理します。
- 古い
modelsインポートからNangoSync、NangoAction、ProxyConfiguration、ActionErrorのインポートを削除します。 - ランタイム型は
nangoからインポートします。 - 生成されたモデルのインポートは
../../models.jsまたは正しい相対パスを参照するようにします。 index.tsでは.jsを付けた副作用インポートを使用します。
重要な機械的修正:
- ファイルをラップした後、ローカルの
NangoSyncパラメーター注釈をNangoSyncLocalに置き換えます。 - ファイルをラップした後、ローカルの
NangoActionパラメーター注釈をNangoActionLocalに置き換えます。 - 次の型引数を削除します。
nango.batchSave<T>(...)nango.batchUpdate<T>(...)nango.batchDelete<T>(...)nango.getMetadata<T>()
これらのジェネリック引数は古い形式ではコンパイルできることが多いですが、移行後は冗長または不要になります。
index.ts を生成する
移行したすべてのスクリプトを副作用インポートするルート index.ts を作成します。.js 拡張子を含めてください。
例:
import './github/syncs/fetch-issues.js';
import './github/actions/create-issue.js';
import './github/on-events/post-connection-creation.js';
ここでは名前付きインポートやデフォルトインポートを使用しないでください。
ヘルパーファイルを整理する
移行したインテグレーションのエントリーポイント以外にある TypeScript ヘルパーファイルを、リポジトリ内で検索します。
古いモデルファイルから Nango のランタイム型をインポートしている場合は、そのインポートを nango に移し、実際のモデルスキーマや型に必要なモデルインポートだけを残します。
ヘルパーファイル内の無関係なビジネスロジックは書き換えないでください。
移行時の同等性を優先する
手動での移行は、旧 CLI マイグレーターと同じように動作させます。
- スクリプト名を維持する
- 可能な限りファイルの場所を維持する
- 関数本体を維持する
syncTypeを維持するtrackDeletesを維持する- 既存の
nango.lastSyncDateの使用箇所を維持する
ユーザーから明示的に依頼された場合に限り、2 回目のモダナイズを行ってください。
検証ループ
機械的な移行の後は、以下を実行します。
nango compileを実行します- 単純な TypeScript/インポート/スキーマの問題を修正します
nango dryrun <script-name> <connection-id> --validate -e dev --no-interactive --auto-confirmを実行します- アクションの場合は、
--input '{...}'または--input '{}'を追加します - 検証に合格したら、
nango dryrun <script-name> <connection-id> --save -e dev --no-interactive --auto-confirmを実行します nango generate:tests && npm testを実行します- 生成された
*.test.jsonを手動で編集してはいけません
移行された sync/action に、この時点でまだ実際の動作を変更するリファクタリングが必要な場合は、そこで作業を止め、別のタスクとして扱ってください。
参考ドキュメント
- Zero YAML 移行ドキュメント:https://www.nango.dev/docs/implementation-guides/platform/migrations/migrate-to-zero-yaml
- テスト:https://www.nango.dev/docs/implementation-guides/platform/functions/testing
- Functions SDK:https://www.nango.dev/docs/reference/functions
- チェックポイントの移行:https://www.nango.dev/docs/implementation-guides/platform/migrations/migrate-to-checkpoints
- 削除の検出:https://www.nango.dev/docs/implementation-guides/use-cases/syncs/deletion-detection