#!/usr/bin/env node /** * cli:efcore-squash — Consolidate branch-only migrations into one. * * The reference (base) branch is chosen by branch TYPE — the GOLDEN RULE: * feature/* → develop · release/hotfix/develop → main · main/master → BLOCKED. * Migrations already present in the reference branch are NEVER deleted. * * Steps (per assembly of the target context): * 1. Backup branch-only migrations + snapshot to .efcore-squash-backup/ * 2. Delete branch-only migration files (+ .Designer.cs) — inherited ones untouched * 3. Restore the reference-branch migrations + ModelSnapshot.cs verbatim * 4. Run `dotnet ef migrations add ` to regenerate * * Refuses to run on main/master, or when the reference branch can't be resolved. * * Usage: * npx --prefer-offline tsx skills/efcore/cli/squash/index.ts --spec '{ * "cwd": "...", * "contextName": "CoreDbContext", * "description": "FeatureXYZConsolidated" * }' */ import { parseArgs } from 'node:util'; import { existsSync, readFileSync } from 'node:fs'; import { validate } from './validate.js'; import { execute } from './execute.js'; async function main(): Promise { const { values } = parseArgs({ options: { spec: { type: 'string' }, help: { type: 'boolean', short: 'h' }, }, }); if (values.help || !values.spec) { console.log(`Usage: npx --prefer-offline tsx skills/efcore/cli/squash/index.ts --spec '{"cwd":"...","contextName":"CoreDbContext","description":"FooConsolidated"}'`); process.exit(values.help ? 0 : 1); } let raw: unknown; try { raw = existsSync(values.spec!) ? JSON.parse(readFileSync(values.spec!, 'utf-8')) : JSON.parse(values.spec!); } catch (err) { console.log(JSON.stringify({ success: false, errors: [`Invalid JSON: ${(err as Error).message}`], warnings: [] }, null, 2)); process.exit(1); } const validation = validate(raw); if (!validation.valid || !validation.data) { console.log(JSON.stringify({ success: false, errors: validation.blockers, warnings: validation.warnings }, null, 2)); process.exit(1); } const result = await execute(validation.data); console.log(JSON.stringify(result, null, 2)); process.exit(result.success ? 0 : 1); } void main();