1// The local D1 databases, brought up to date before the Worker starts: every 2// database the chosen environment binds (worker/wrangler.json's 3// `d1_databases`) gets `wrangler d1 migrations apply <name> --local`, into the 4// same local state the Worker then runs on. So a fresh checkout's first 5// `//:dev` has its tables, and a pulled migration applies on the next start. 6// Applying is idempotent: wrangler records what it has run in the database's 7// d1_migrations table. 8// 9// stdin is not a terminal, so wrangler takes its "continue?" prompt's 10// non-interactive answer (yes) instead of waiting on it. 11import { execFileSync } from 'node:child_process'; 12import { readFileSync } from 'node:fs'; 13 14const CONFIG = 'worker/wrangler.json'; 15 16// `env` as passed to `wrangler --env` ('dev', or '' for production); 17// `persistTo` when the Worker runs with its own --persist-to. 18export function migrateLocal({ env, persistTo }) { 19 const config = JSON.parse(readFileSync(CONFIG, 'utf8')); 20 const bindings = (env ? config.env[env] : config).d1_databases ?? []; 21 for (const { database_name: name } of bindings) { 22 const args = ['d1', 'migrations', 'apply', name, '--local', '--config', CONFIG, '--env', env]; 23 if (persistTo) args.push('--persist-to', persistTo); 24 execFileSync('wrangler', args, { 25 stdio: ['ignore', 'inherit', 'inherit'], 26 env: { ...process.env, WRANGLER_SEND_METRICS: 'false' }, 27 }); 28 } 29}