67 lines
2.1 KiB
TypeScript
67 lines
2.1 KiB
TypeScript
import process from "process";
|
|
import { existsSync } from "fs";
|
|
import { exec } from "child_process";
|
|
import type { IAppConfig } from "config";
|
|
|
|
/**
|
|
* We use graphile-migrate for managing database migrations.
|
|
*
|
|
* However we also use convict as the sole source of truth for our app's configuration. We do not want to have to configure
|
|
* separate env files or config files for graphile-migrate and yet again others for convict.
|
|
*
|
|
* So we wrap the graphile-migrate cli tool here. We parse our convict config, set necessary env vars, and then shell out to
|
|
* graphile-migrate.
|
|
*
|
|
* Commander eats all args starting with --, so you must use the -- escape to indicate the arguments have finished
|
|
*
|
|
* Example:
|
|
* ./cli db -- --help // will show graphile migrate help
|
|
* ./cli db -- watch // will watch the current sql for changes
|
|
* ./cli db -- watch --once // will apply the current sql once
|
|
*/
|
|
export const migrateWrapper = async (
|
|
commands: string[],
|
|
config: IAppConfig,
|
|
silent = false
|
|
): Promise<void> => {
|
|
const env = {
|
|
DATABASE_URL: config.db.connection,
|
|
SHADOW_DATABASE_URL: config.dev.shadowConnection,
|
|
ROOT_DATABASE_URL: config.dev.rootConnection,
|
|
DATABASE_NAME: config.db.name,
|
|
DATABASE_OWNER: config.db.owner,
|
|
DATABASE_AUTHENTICATOR: config.postgraphile.auth,
|
|
DATABASE_VISITOR: config.postgraphile.visitor,
|
|
};
|
|
const cmd = `npx --no-install graphile-migrate ${commands.join(" ")}`;
|
|
const dbDir = `../../db`;
|
|
const gmrc = `${dbDir}/.gmrc`;
|
|
if (!existsSync(gmrc)) {
|
|
throw new Error(`graphile migrate config not found at ${gmrc}`);
|
|
}
|
|
|
|
if (!silent) console.log("executing:", cmd);
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const proc = exec(cmd, {
|
|
env: { ...process.env, ...env },
|
|
cwd: dbDir,
|
|
});
|
|
|
|
proc.stdout.on("data", (data) => {
|
|
if (!silent) console.log("MIGRATE:", data);
|
|
});
|
|
|
|
proc.stderr.on("data", (data) => {
|
|
console.error("MIGRATE", data);
|
|
});
|
|
proc.on("close", (code) => {
|
|
if (code !== 0) {
|
|
reject(new Error(`graphile-migrate exited with code ${code}`));
|
|
return;
|
|
}
|
|
|
|
resolve();
|
|
});
|
|
});
|
|
};
|