Compare commits

..

4 Commits

Author SHA1 Message Date
e8d92f58dc Merge pull request 'chore: untrack .claude/settings.local.json (machine-specific)' (#4) from chore/gitignore-claude-settings-local into main
All checks were successful
ci / test (push) Successful in 12s
2026-05-14 03:33:10 +00:00
9c19d0f7d1 chore: untrack .claude/settings.local.json (machine-specific)
All checks were successful
ci / test (pull_request) Successful in 15s
2026-05-13 20:31:45 -07:00
7dbce6637c Merge pull request 'feat: v0.1.0 — sqlite-migrate package extraction from authd' (#1) from feat/initial-package into main
All checks were successful
ci / test (push) Successful in 11s
2026-05-12 09:30:50 +00:00
93f5d63f26 refactor: dedupe INSERT SQL and DDL exec in migrate.ts
All checks were successful
ci / test (pull_request) Successful in 12s
- Extract INSERT_MIGRATION_SQL constant; was repeated three times.
- Hoist db.exec(SCHEMA_MIGRATIONS_DDL) above the genesis-stamp branch
  so it is no longer duplicated in both arms of the if/else.
- Prepare insertRow once and reuse it for both genesis-stamping and
  the per-file insert in the apply loop.
- Simplify existence probe in stampMigration to SELECT 1 and drop the
  misleading MigrationRow cast (only existence was checked).
2026-05-12 02:24:33 -07:00
4 changed files with 26 additions and 88 deletions

View File

@@ -1,57 +0,0 @@
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(npm *)",
"Bash(npm:*)",
"Bash(npx *)",
"Bash(node *)",
"Bash(tsx *)",
"Bash(esbuild *)",
"Bash(vitest *)",
"Bash(tsc *)",
"Bash(. ~/.nvm/nvm.sh*)",
"Bash(source ~/.nvm/nvm.sh*)",
"Bash(git *)",
"Bash(tea *)",
"Bash(tea:*)",
"Bash(gh *)",
"Bash(claude *)",
"Bash(curl *)",
"Bash(xargs -r kill)"
],
"deny": [
"Bash(npm publish*)",
"Bash(sudo *)"
],
"defaultMode": "acceptEdits"
},
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": true,
"network": {
"allowedDomains": [
"registry.npmjs.org",
"*.npmjs.org",
"nodejs.org",
"*.nodejs.org",
"raw.githubusercontent.com",
"objects.githubusercontent.com",
"codeload.github.com",
"github.com",
"api.github.com",
"*.bchen.dev"
],
"allowLocalBinding": true
},
"filesystem": {
"allowWrite": [
"/home/brendan/sqlite-migrate",
"/home/brendan/sqlite-migrate/.git",
"/home/brendan/.npm",
"/home/brendan/.config/tea"
],
"denyWrite": []
}
}
}

2
.gitignore vendored
View File

@@ -139,3 +139,5 @@ dist
# package: ship pre-compiled dist/
!/dist/
.claude/settings.local.json

19
dist/migrate.js vendored
View File

@@ -11,6 +11,7 @@ const SCHEMA_MIGRATIONS_DDL = `
applied_at INTEGER NOT NULL
);
`;
const INSERT_MIGRATION_SQL = `INSERT INTO schema_migrations (version, name, checksum, applied_at) VALUES (?, ?, ?, ?)`;
function sha256Hex(body) {
return createHash('sha256').update(body).digest('hex');
}
@@ -54,28 +55,24 @@ export function applyMigrations(db, migrationsDir, opts = {}) {
return { applied: 0, pending: 0, alreadyApplied: 0, stamped: [] };
}
const schemaMigrationsExists = tableExists(db, 'schema_migrations');
const stamped = [];
const genesisFile = files.find((f) => f.version === GENESIS_VERSION);
const shouldStampGenesis = !schemaMigrationsExists &&
genesisFile !== undefined &&
(opts.stampGenesis === true || tableExists(db, probeTable));
db.exec(SCHEMA_MIGRATIONS_DDL);
const insertRow = db.prepare(INSERT_MIGRATION_SQL);
const stamped = [];
if (shouldStampGenesis && genesisFile) {
db.exec(SCHEMA_MIGRATIONS_DDL);
const reason = opts.stampGenesis
? 'stampGenesis option set'
: `detected pre-existing '${probeTable}' table`;
log(`WARN genesis-stamp: marked ${genesisFile.name} as applied without executing (${reason})`);
db.prepare(`INSERT INTO schema_migrations (version, name, checksum, applied_at) VALUES (?, ?, ?, ?)`).run(genesisFile.version, genesisFile.name, genesisFile.checksum, Date.now());
insertRow.run(genesisFile.version, genesisFile.name, genesisFile.checksum, Date.now());
stamped.push(genesisFile.version);
}
else {
db.exec(SCHEMA_MIGRATIONS_DDL);
}
const appliedRows = readAppliedRows(db);
const appliedByVersion = new Map(appliedRows.map((r) => [r.version, r]));
const appliedByVersion = new Map(readAppliedRows(db).map((r) => [r.version, r]));
let applied = 0;
let alreadyApplied = 0;
const insertRow = db.prepare(`INSERT INTO schema_migrations (version, name, checksum, applied_at) VALUES (?, ?, ?, ?)`);
for (const file of files) {
const existing = appliedByVersion.get(file.version);
if (existing) {
@@ -103,11 +100,11 @@ export function stampMigration(db, migrationsDir, version) {
}
db.exec(SCHEMA_MIGRATIONS_DDL);
const existing = db
.prepare(`SELECT version, name, checksum, applied_at FROM schema_migrations WHERE version = ?`)
.prepare(`SELECT 1 FROM schema_migrations WHERE version = ?`)
.get(file.version);
if (existing) {
throw new Error(`migration already applied: ${file.name}`);
}
db.prepare(`INSERT INTO schema_migrations (version, name, checksum, applied_at) VALUES (?, ?, ?, ?)`).run(file.version, file.name, file.checksum, Date.now());
db.prepare(INSERT_MIGRATION_SQL).run(file.version, file.name, file.checksum, Date.now());
return file;
}

View File

@@ -43,6 +43,8 @@ const SCHEMA_MIGRATIONS_DDL = `
);
`;
const INSERT_MIGRATION_SQL = `INSERT INTO schema_migrations (version, name, checksum, applied_at) VALUES (?, ?, ?, ?)`;
function sha256Hex(body: string): string {
return createHash('sha256').update(body).digest('hex');
}
@@ -97,38 +99,31 @@ export function applyMigrations(
}
const schemaMigrationsExists = tableExists(db, 'schema_migrations');
const stamped: string[] = [];
const genesisFile = files.find((f) => f.version === GENESIS_VERSION);
const shouldStampGenesis =
!schemaMigrationsExists &&
genesisFile !== undefined &&
(opts.stampGenesis === true || tableExists(db, probeTable));
db.exec(SCHEMA_MIGRATIONS_DDL);
const insertRow = db.prepare(INSERT_MIGRATION_SQL);
const stamped: string[] = [];
if (shouldStampGenesis && genesisFile) {
db.exec(SCHEMA_MIGRATIONS_DDL);
const reason = opts.stampGenesis
? 'stampGenesis option set'
: `detected pre-existing '${probeTable}' table`;
log(
`WARN genesis-stamp: marked ${genesisFile.name} as applied without executing (${reason})`,
);
db.prepare(
`INSERT INTO schema_migrations (version, name, checksum, applied_at) VALUES (?, ?, ?, ?)`,
).run(genesisFile.version, genesisFile.name, genesisFile.checksum, Date.now());
insertRow.run(genesisFile.version, genesisFile.name, genesisFile.checksum, Date.now());
stamped.push(genesisFile.version);
} else {
db.exec(SCHEMA_MIGRATIONS_DDL);
}
const appliedRows = readAppliedRows(db);
const appliedByVersion = new Map(appliedRows.map((r) => [r.version, r]));
const appliedByVersion = new Map(readAppliedRows(db).map((r) => [r.version, r]));
let applied = 0;
let alreadyApplied = 0;
const insertRow = db.prepare(
`INSERT INTO schema_migrations (version, name, checksum, applied_at) VALUES (?, ?, ?, ?)`,
);
for (const file of files) {
const existing = appliedByVersion.get(file.version);
@@ -166,15 +161,16 @@ export function stampMigration(
}
db.exec(SCHEMA_MIGRATIONS_DDL);
const existing = db
.prepare(
`SELECT version, name, checksum, applied_at FROM schema_migrations WHERE version = ?`,
)
.get(file.version) as MigrationRow | undefined;
.prepare(`SELECT 1 FROM schema_migrations WHERE version = ?`)
.get(file.version);
if (existing) {
throw new Error(`migration already applied: ${file.name}`);
}
db.prepare(
`INSERT INTO schema_migrations (version, name, checksum, applied_at) VALUES (?, ?, ?, ?)`,
).run(file.version, file.name, file.checksum, Date.now());
db.prepare(INSERT_MIGRATION_SQL).run(
file.version,
file.name,
file.checksum,
Date.now(),
);
return file;
}