sendou.ink/scripts/create-migration.ts

67 lines
1.6 KiB
TypeScript

import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
const MIGRATION_FOLDER = fileURLToPath(
new URL("../migrations", import.meta.url),
);
const TEMPLATE = `import type { Kysely } from "kysely";
export async function up(db: Kysely<any>): Promise<void> {
await db.transaction().execute(async (trx) => {
await trx.schema.alterTable("TODO").addColumn("TODO", "text").execute();
});
}
`;
function main() {
const description = toKebabCase(process.argv.slice(2).join(" "));
if (!description) {
throw new Error(
'Missing migration description e.g. pnpm run migrate:new "add user pronouns"',
);
}
const fileName = `${timestamp(new Date())}-${description}.ts`;
const filePath = path.join(MIGRATION_FOLDER, fileName);
if (fs.existsSync(filePath)) {
throw new Error(`${fileName} already exists`);
}
fs.writeFileSync(filePath, TEMPLATE);
// biome-ignore lint/suspicious/noConsole: CLI script output
console.log(`Created migrations/${fileName}`);
}
/** Sortable UTC stamp, so two branches can never claim the same slot. */
function timestamp(date: Date) {
const pad = (value: number) => String(value).padStart(2, "0");
return [
date.getUTCFullYear(),
pad(date.getUTCMonth() + 1),
pad(date.getUTCDate()),
pad(date.getUTCHours()),
pad(date.getUTCMinutes()),
pad(date.getUTCSeconds()),
].join("");
}
function toKebabCase(input: string) {
return input
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, "");
}
try {
main();
} catch (error) {
// biome-ignore lint/suspicious/noConsole: CLI script output
console.error((error as Error).message);
process.exit(1);
}