mcpField
D
drizzle-sqlite-scaffold

drizzle-sqlite-scaffold

github.com/pproencaデータ・データベース218140 回インストール11 週間前に更新
リポジトリ

drizzle-sqlite-scaffold について

Drizzle と SQLite の初期設定や、既存プロジェクトへのテーブル・CRUD リポジトリ追加に使うテンプレート型スキルです。設定やスキーマ、コードの規約を統一したい開発者向けです。

主な機能

  1. 01プロジェクト初期化テンプレート
  2. 02テーブル別スキーマ・CRUD テンプレート
  3. 03SQLite ドライバーの選択設定
  4. 04drizzle-zod バリデーターの任意生成
  5. 05マイグレーション手順の案内

活用シーン

  1. 01Drizzle SQLite プロジェクトの開始
  2. 02既存スキーマへのテーブル追加
  3. 03既存テーブル用 CRUD モジュールの作成
  4. 04手書き Drizzle 設定の統一

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/pproenca/dot-skills --skill drizzle-sqlite-scaffold

インストール後、Claude Code で/drizzle-sqlite-scaffoldを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

config.json
gotchas.md
metadata.json
assets/templates/
client.better-sqlite3.ts.template
client.bun-sqlite.ts.template
client.libsql.ts.template
drizzle.config.local.ts.template
drizzle.config.turso.ts.template
gitignore.template
repository.ts.template
schema-index.ts.template
table.ts.template
validators.ts.template
references/
conventions.md

詳細

Drizzle SQLite スキャフォールド

新規プロジェクトで Drizzle + SQLite を初期設定する場合や、既存プロジェクトに新しいテーブル/リポジトリを追加する場合に使える、パラメーター化されたテンプレートです。すべての出力には、references/conventions.md に記載されている規約が反映されます。明示的な主キー、インデックス付き外部キー、relations() 宣言、$inferSelect/$inferInsert のエクスポート、timestamp_ms の日付、ブールモードの真偽値、WAL + foreign_keys=ON + busy_timeout のプラグマ、HMR ガード付きのシングルトンクライアント、.returning() + inArray() + .onConflictDoUpdate() を使った CRUD ヘルパーなどが含まれます。

使用する場合

次のような場合に、これらのテンプレートを利用してください。

  • Drizzle と SQLite(任意のドライバー)を使う新規プロジェクトを開始するとき
  • 既存の Drizzle プロジェクトに新しいテーブルを追加するとき — テーブルファイルは既存のパターンに合わせてください
  • 既存のテーブル用に CRUD リポジトリモジュールを追加するとき
  • プラグマが不足している、relations() がない、または手書きの User 型がスキーマから乖離している、独自実装の Drizzle セットアップをリファクタリングするとき
  • 別の ORM(Prisma、Kysely)から Drizzle に移行し、最初から一貫した形にしたいとき

セットアップ

必須パラメーター(初回使用時に質問され、config.json に保存されます)
パラメーター必須デフォルト値
driverはい—better-sqlite3 | libsql | bun-sqlite(D1 はライフサイクルが異なります — 下記の「Cloudflare D1」を参照)
db_url_envいいえDATABASE_URL環境変数名
schema_dirいいえ./src/db/schemaテーブルごとのスキーマファイル
repository_dirいいえ./src/db/repositoryテーブルごとの CRUD モジュール
validators_dirいいえ./src/db/validatorsdrizzle-zod スキーマ(with_zod=true の場合)
client_pathいいえ./src/db/client.tsシングルトンクライアントモジュール
migrations_dirいいえ./drizzledrizzle-kit の出力先

config.json がすでに値を含んでいる場合、このスキルはその値を使用します。そうでない場合は、AskUserQuestion を通じて質問します。

テーブルごとのパラメーター(新しいテーブルをスキャフォールドするたびに質問されます)
パラメーター必須デフォルト説明
nameはい—ケバブケースの単数形:user、order-item。ファイル名と TS 識別子(name_camel、name_pascal を導出)に使用します。
table_nameいいえname のスネークケース複数形SQL テーブル名:users、order_items
pkいいえserial-intserial-int | uuid | cuid2 | text
timestampsいいえtruecreatedAt/updatedAt 列を追加します
soft_deleteいいえfalseNULL 許容の deletedAt + 部分インデックスを追加します
relationsいいえ[]関連するテーブル名のリスト — relations() の本体を展開します
with_zodいいえtruedrizzle-zod バリデーターのファイルを生成します

利用可能なテンプレート

プロジェクト初期化テンプレート(一度だけ出力)
テンプレート出力ファイル使用条件
drizzle.config.local.ts.templatedrizzle.config.tsdriver が better-sqlite3、bun-sqlite、または file: URL を使う libsql の場合
drizzle.config.turso.ts.templatedrizzle.config.tsTurso に接続する libsql の場合(リモートの libsql: URL)
client.better-sqlite3.ts.template{{client_path}}driver が better-sqlite3 の場合
client.libsql.ts.template{{client_path}}driver が libsql の場合
client.bun-sqlite.ts.template{{client_path}}driver が bun-sqlite の場合
schema-index.ts.template{{schema_dir}}/index.ts常に(初期状態では空で、テーブルの追加に合わせてエクスポートを追記します)
gitignore.template.gitignore(追記)常に
テーブルごとのテンプレート(テーブルごとに一度出力)
テンプレート出力ファイルタイミング
table.ts.template{{schema_dir}}/{{name}}.tsテーブルごと
repository.ts.template{{repository_dir}}/{{name}}.tsテーブルごと
validators.ts.template{{validators_dir}}/{{name}}.tswith_zod=true の場合、テーブルごと

使用方法

フロー A — 新しいプロジェクトを初期化する(一度だけ実行)
  1. プロジェクトのパラメーターを解決します。 config.json を読み込みます。必須フィールドが空の場合は、AskUserQuestion を通じてユーザーに質問します(厳密に必須なのは driver のみで、他の項目には妥当なデフォルト値があります)。

  2. 最初にランタイムとツールをインストールします。これにより、生成されたファイルがすぐに型チェックできるようになります:

    # Pick the driver-specific runtime package:
    npm install drizzle-orm @libsql/client      # for libsql
    npm install drizzle-orm better-sqlite3      # for better-sqlite3
    npm install drizzle-orm                     # bun:sqlite is built into Bun
    
    # Dev tools (all drivers):
    npm install -D drizzle-kit
    npm install -D @types/better-sqlite3        # better-sqlite3 only
    npm install -D drizzle-zod zod              # if with_zod=true
    
  3. 解決した driver に応じて、設定とクライアントのバリアントを選択します:

    • better-sqlite3 → drizzle.config.local.ts.template + client.better-sqlite3.ts.template
    • file: URL を使用する libsql → drizzle.config.local.ts.template + client.libsql.ts.template
    • リモートの Turso URL を使用する libsql → drizzle.config.turso.ts.template + client.libsql.ts.template
    • bun-sqlite → drizzle.config.local.ts.template + client.bun-sqlite.ts.template
  4. プロジェクト初期化用ファイルを生成して書き込みます:

    • drizzle.config.ts
    • {{client_path}}(通常は src/db/client.ts)
    • {{schema_dir}}/index.ts(空のバレルファイル)
    • gitignore.template のブロックをプロジェクトの .gitignore に追加します
  5. libsql の場合: クライアントテンプレートではトップレベルの await migrate(...) を使用しています。トップレベルの await をサポートするため、tsconfig.json で "module": "ESNext"(または "NodeNext")と "target": "ES2022"+ が設定されていることを確認します。ランタイムが CommonJS の場合は、トップレベルの await を、アプリの起動時に呼び出すエクスポート済みの async function init() に置き換えます。

  6. 解決した値を config.json に保存し、以降のテーブル追加時に再度質問されないようにします。

フロー B — 新しいテーブルを追加する(テーブルごとに実行)
  1. テーブルごとのパラメーターを解決します。 name をユーザーに尋ねてから、table_name(snake_case の複数形)、pk、timestamps、soft_delete、relations、with_zod のデフォルト値を提示します。ユーザーがデフォルト以外を希望する項目については、AskUserQuestion を使用します。

  2. 派生する識別子を計算します:

    • name_camel — name の camelCase 形式(user、orderItem)
    • name_pascal — name の PascalCase 形式(User、OrderItem)
    • pk_field — PK カラム名(4 つの pk モードすべてで id)
    • pk_ts_type — PK の TS 型(serial-int では number、uuid/cuid2/text では string)
    • pk_definition — 実際の行。例:id: integer().primaryKey({ autoIncrement: true }),(以下の PK バリアント表を参照)
  3. テーブルテンプレートを生成します: table.ts.template を読み込み、{{name}}、{{name_camel}}、{{name_pascal}}、{{table_name}}、{{pk_definition}}、{{pk_extra_imports}} などを置換します。パラメーターに応じて {{timestamps_block}} と {{soft_delete_block}} を展開します(以下の「ブロックの展開」を参照)。{{schema_dir}}/{{name}}.ts に書き込みます。

  4. 同じパラメーターでリポジトリテンプレートを生成します。{{repository_dir}}/{{name}}.ts に書き込みます。

  5. with_zod=true の場合は、バリデーターのテンプレートを生成します。{{validators_dir}}/{{name}}.ts に書き込みます。

  6. スキーマのバレルファイルに追加します:{{schema_dir}}/index.ts に export * from './{{name}}'; を追加します。

  7. マイグレーションを生成します: SQL ファイルを生成するために npx drizzle-kit generate を実行するようユーザーに伝えます。このスキャフォールドで、名前の異なる既存のテーブルを置き換える場合は、名前変更の確認プロンプトに明示的に回答するよう念を押します。

  8. マイグレーションを適用します: 開発用データベースに対して npx drizzle-kit migrate を実行します。クライアントテンプレートも起動時に migrate(...) を呼び出しますが、開発ループで一度適用しておけば、次回のプロセス再起動前に SQL が機能することを確認できます。

フロー C — 既存のテーブルに CRUD モジュールを追加する(スキーマ変更なし)

フロー B の手順 1~2 と同じですが、table.ts.template のレンダリングはスキップし、リポジトリモジュール(および任意でバリデーターモジュール)のみを出力します。

PK のバリエーション

pk の値pk_definitionpk_ts_type追加のインポート
serial-int(デフォルト)id: integer().primaryKey({ autoIncrement: true }),number—
uuidid: text().primaryKey().$defaultFn(() => crypto.randomUUID()),string—(Web Crypto を使用)
cuid2id: text().primaryKey().$defaultFn(() => createId()),stringimport { createId } from '@paralleldrive/cuid2';
textid: text().primaryKey(),string—(呼び出し元が ID を指定)

プレースホルダーの参照

テンプレートで使用するすべての {{placeholder}} と、その導出ルールです。simple sub の項目は検索して置換し、block の項目は次のセクションのルールに従ってエージェントが展開する必要があります。

プレースホルダー種類ソース/導出方法
{{driver}}simple subconfig.json:driver
{{db_url_env}}simple subconfig.json:db_url_env
{{schema_dir}}simple subconfig.json:schema_dir
{{repository_dir}}simple subconfig.json:repository_dir
{{validators_dir}}simple subconfig.json:validators_dir
{{client_path}}simple subconfig.json:client_path
{{migrations_dir}}simple subconfig.json:migrations_dir
{{schema_index_import}}simple sub導出:client_path から {{schema_dir}}/index.ts への相対パス(通常は './schema')
{{client_import}}simple sub導出:リポジトリ内のファイルから client_path への相対パス(通常は '../client')
{{schema_import}}simple sub導出:リポジトリまたはバリデーターのファイルから該当するテーブルファイルへの相対パス(通常は '../schema/{{name}}')
{{name}}simple subテーブルごとのパラメーター — ケバブケースの単数形(user)
{{name_camel}}simple subname から導出(user、orderItem)
{{name_pascal}}simple subname から導出(User、OrderItem)
{{table_name}}simple subテーブルごとのパラメーター。デフォルトは name のスネークケース複数形(users、order_items)
{{pk}}metadataテーブルごとのパラメーター — serial-int | uuid | cuid2 | text(以下の行を決定します)
{{pk_definition}}block実際の PK カラム行 — 「PK バリアント」表を参照
{{pk_field}}simple subこのスキルで提供される4つの PK バリアントでは常に id
{{pk_ts_type}}simple subserial-int の場合は number、uuid/cuid2/text の場合は string
{{pk_extra_imports}}blockserial-int/uuid/text の場合は空。cuid2 の場合は import { createId } from '@paralleldrive/cuid2';
{{relation_imports}}blockrelations[] 内の各テーブルについて、import { {{relatedCamel}} } from './{{related-kebab}}'; を出力
{{domain_columns}}blockエンティティの実際の、PK でもタイムスタンプでもないカラムに置き換えます。ユーザーから情報が提供されていない場合は、TODO コメントのままにします。
{{timestamps_block}}block下記の展開方法を参照 — timestamps=true の場合に出力し、false の場合は行全体を削除
{{soft_delete_block}}block下記の展開方法を参照 — soft_delete=true の場合にカラムブロック内へ出力
{{indexes}}block外部キーのカラムごとに1行の index(...) を出力(およびユーザーが指定した (authorId, publishedAt) 形式の複合インデックス)
{{soft_delete_index}}blockdeletedAt に対する部分インデックス(下記の展開方法を参照)。soft_delete=true の場合のみ出力
{{relations_body}}block関連テーブルごとに1行の one(...)/many(...) を出力。下記の展開方法を参照
{{insert_refinements}}blockINSERT 形式の drizzle-zod リファインメントコールバック。指定がない場合はサンプルコメントを残す
{{update_refinements}}block部分 UPDATE 形式について同様に処理
{{exports}}blockschema-index.ts.template 内で、テーブルごとに export * from './{{name}}'; の行を出力。新しいテーブルを追加するたびに追記

テンプレートがこの表にない {{placeholder}} を出力する場合はバグです。gotchas.md に報告してください。

ブロックの展開

table.ts.template では、形状が可変のセクションにプレースホルダーのブロックを使用します。エージェントは単にテキスト置換するのではなく、パラメーターに従って展開する必要があります。

{{timestamps_block}}(timestamps=true の場合)
createdAt: integer({ mode: 'timestamp_ms' })
  .notNull()
  .$defaultFn(() => new Date()),
updatedAt: integer({ mode: 'timestamp_ms' })
  .notNull()
  .$defaultFn(() => new Date())
  .$onUpdateFn(() => new Date()),

timestamps=false の場合は、行全体を削除します(コメントマーカーを残さないでください)。

{{soft_delete_block}}(soft_delete=true の場合)

カラムブロック内:

deletedAt: integer({ mode: 'timestamp_ms' }),

インデックスブロック内:

index('{{table_name}}_active_idx').on(table.deletedAt).where(sql`deleted_at IS NULL`),

それに応じて sql のインポートを調整してください。

{{relations_body}}(relations が空でない場合)

relations[] の関連テーブルごとに、エージェントは、FK が現在のテーブルにある場合は one、関連テーブルにある場合は many と判断します。

// FK on current table — `one`:
parent: one(parents, { fields: [users.parentId], references: [parents.id] }),

// FK on related table — `many`:
posts: many(posts),

ユーザーが簡単に判断できない場合は、それぞれの例を 1 つずつ使用し、コメントを残してください。

{{indexes}} ブロック

各 FK カラムについて、次を出力します。

index('{{table_name}}_{{column}}_idx').on(table.{{columnCamel}}),

Cloudflare D1 に関する注意

D1 のライフサイクルは異なります。クライアントはモジュールレベルのシングルトンとしてではなく、env.DB(バインディング)からリクエストごとに構築されます。このスキルには D1 クライアントのテンプレートは含まれていません。配線については、公式の D1 + Drizzle ガイドに従ってください。table.ts.template、repository.ts.template、validators.ts.template は D1 でも引き続き使用できます。異なるのはクライアントモジュールのみです。

参照ファイル

ファイル説明
references/conventions.md適用される 11 の規約と、その理由およびルールへの相互参照
gotchas.md時間をかけて明らかになったエッジケース
metadata.jsonバージョンとドライバーの参照情報
config.jsonプロジェクトレベルのパラメーターストア

関連スキル

  • drizzle-sqlite — これらのテンプレートに反映されているライブラリ参照ルールです。規約ドキュメントでは、このスキル内の特定のルールファイルを参照しています。十分な情報に基づいて例外を設ける場合、生成されたファイルをデバッグする場合、またはテンプレートの対象範囲外のもの(カスタムマイグレーション、複雑なクエリ、パフォーマンス関連の作業)をスキャフォールドする場合に参照してください。
  • better-auth-scaffold — Drizzle DB 上に Better Auth をスキャフォールドします。このスキルがクライアントを提供した後に実行できます。

コメント