63 lines
2.1 KiB
TypeScript
63 lines
2.1 KiB
TypeScript
#!/usr/bin/env bun
|
|
|
|
import { $ } from "bun"
|
|
import path from "path"
|
|
|
|
const root = path.resolve(import.meta.dirname, "../../..")
|
|
const sqlDir = path.join(root, "packages/core/migration")
|
|
const tsDir = path.join(root, "packages/core/src/database/migration")
|
|
const registry = path.join(root, "packages/core/src/database/migration.gen.ts")
|
|
|
|
await $`bun drizzle-kit generate`.cwd(path.join(root, "packages/core"))
|
|
|
|
const sqlMigrations = (await Array.fromAsync(new Bun.Glob("*/migration.sql").scan({ cwd: sqlDir })))
|
|
.map((file) => file.split("/")[0])
|
|
.filter((name) => name !== undefined)
|
|
.sort()
|
|
|
|
for (const name of sqlMigrations) {
|
|
if (await Bun.file(path.join(tsDir, `${name}.ts`)).exists()) continue
|
|
await Bun.write(path.join(tsDir, `${name}.ts`), renderMigration(name, await Bun.file(path.join(sqlDir, name, "migration.sql")).text()))
|
|
}
|
|
|
|
await Bun.write(registry, renderRegistry(sqlMigrations))
|
|
|
|
function renderMigration(name: string, sql: string) {
|
|
return `import { Effect } from "effect"
|
|
import type { DatabaseMigration } from "../migration"
|
|
|
|
export default {
|
|
id: ${JSON.stringify(name)},
|
|
up(tx) {
|
|
return Effect.gen(function* () {
|
|
${sql
|
|
.split("--> statement-breakpoint")
|
|
.map((statement) => statement.trim())
|
|
.filter((statement) => statement.length > 0)
|
|
.map(renderRun)
|
|
.join("\n")}
|
|
})
|
|
},
|
|
} satisfies DatabaseMigration.Migration
|
|
`
|
|
}
|
|
|
|
function renderRun(statement: string) {
|
|
const lines = statement.replaceAll("\t", " ").split("\n")
|
|
if (lines.length === 1) return ` yield* tx.run(\`${escapeTemplate(lines[0])}\`)`
|
|
return ` yield* tx.run(\`\n${lines.map((line) => ` ${escapeTemplate(line)}`).join("\n")}\n \`)`
|
|
}
|
|
|
|
function escapeTemplate(line: string) {
|
|
return line.replaceAll("\\", "\\\\").replaceAll("`", "\\`").replaceAll("${", "\\${")
|
|
}
|
|
|
|
function renderRegistry(names: string[]) {
|
|
return `import type { DatabaseMigration } from "./migration"
|
|
|
|
export const migrations = (await Promise.all([
|
|
${names.map((name) => ` import("./migration/${name}"),`).join("\n")}
|
|
])).map((module) => module.default) satisfies DatabaseMigration.Migration[]
|
|
`
|
|
}
|