jevstrudel.git / tools / dev / migrate.mjs
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}