mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-21 04:10:47 +02:00
40 lines
1.5 KiB
JavaScript
40 lines
1.5 KiB
JavaScript
import path from "node:path";
|
|
import { atomicWriteJson, readJson, withLock } from "./storage.js";
|
|
import { resolveRuntimePaths } from "./paths.js";
|
|
|
|
export const RUNTIME_SCHEMA_VERSION = 2;
|
|
export const RUNTIME_MIGRATION_ID = "2.0.0-host-neutral-runtime";
|
|
|
|
export async function ensureMigrations(home, options = {}) {
|
|
const paths = resolveRuntimePaths({ home });
|
|
return withLock(path.join(paths.locks, "migration.lock"), async () => {
|
|
const existing = await readJson(paths.migrations, null);
|
|
if (existing?.schemaVersion > RUNTIME_SCHEMA_VERSION) {
|
|
const error = new Error(
|
|
`State schema ${existing.schemaVersion} is newer than this runtime supports (${RUNTIME_SCHEMA_VERSION})`,
|
|
);
|
|
error.code = "MIGRATION_NEWER_THAN_RUNTIME";
|
|
throw error;
|
|
}
|
|
|
|
if (existing?.schemaVersion === RUNTIME_SCHEMA_VERSION &&
|
|
existing.applied?.some((entry) => entry.id === RUNTIME_MIGRATION_ID)) {
|
|
return existing;
|
|
}
|
|
|
|
const now = (options.now ?? (() => new Date()))().toISOString();
|
|
const marker = {
|
|
format: "gstack-forward-migrations",
|
|
schemaVersion: RUNTIME_SCHEMA_VERSION,
|
|
direction: "forward-only",
|
|
applied: [
|
|
...(Array.isArray(existing?.applied) ? existing.applied : []),
|
|
{ id: RUNTIME_MIGRATION_ID, appliedAt: now },
|
|
].filter((entry, index, all) => all.findIndex((other) => other.id === entry.id) === index),
|
|
updatedAt: now,
|
|
};
|
|
await atomicWriteJson(paths.migrations, marker, { mode: 0o600 });
|
|
return marker;
|
|
});
|
|
}
|