UNPKG

graphile-migrate

Version:

Opinionated SQL-powered migration tool for PostgreSQL

100 lines 4.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const pgMinify = require("pg-minify"); const fs_1 = require("fs"); const current_1 = require("../current"); const hash_1 = require("../hash"); const instrumentation_1 = require("../instrumentation"); const migration_1 = require("../migration"); const settings_1 = require("../settings"); const sluggify_1 = require("../sluggify"); const _common_1 = require("./_common"); const migrate_1 = require("./migrate"); const reset_1 = require("./reset"); function omit(obj, keys) { const newObject = Object.assign({}, obj); for (const key of keys) { delete newObject[key]; } return newObject; } async function _commit(parsedSettings, messageOverride = undefined) { const { migrationsFolder } = parsedSettings; const currentLocation = await current_1.getCurrentMigrationLocation(parsedSettings); const contents = await current_1.readCurrentMigration(parsedSettings, currentLocation); const committedMigrationsFolder = `${migrationsFolder}/committed`; const allMigrations = await migration_1.getAllMigrations(parsedSettings); const lastMigration = allMigrations[allMigrations.length - 1]; const newMigrationNumber = lastMigration ? parseInt(lastMigration.filename, 10) + 1 : 1; if (Number.isNaN(newMigrationNumber)) { throw new Error("Could not determine next migration number"); } const { headers, body } = migration_1.parseMigrationText(currentLocation.path, contents, false); const messageFromComment = headers.Message; const message = messageOverride !== undefined ? messageOverride : messageFromComment; if (message && /[\r\n\0\b\v\f\cA-\cZ]/u.test(message)) { throw new Error("Invalid commit message: contains disallowed characters"); } if (message && message.length > 512) { throw new Error("Invalid commit message: message is too long (max: 512 chars)"); } const sluggifiedMessage = message ? sluggify_1.sluggify(message) : null; const newMigrationFilename = String(newMigrationNumber).padStart(6, "0") + (sluggifiedMessage ? `-${sluggifiedMessage}` : "") + ".sql"; if (!migration_1.isMigrationFilename(newMigrationFilename)) { throw Error("Could not construct migration filename"); } const minifiedBody = pgMinify(body); if (minifiedBody === "") { throw new Error("Current migration is blank."); } const hash = hash_1.calculateHash(body, lastMigration && lastMigration.hash); const finalBody = migration_1.serializeMigration(body, Object.assign({ Previous: lastMigration ? lastMigration.hash : "-", Hash: hash, Message: message ? message : undefined }, omit(headers, ["Previous", "Hash", "Message"]))); await reset_1._reset(parsedSettings, true); const newMigrationFilepath = `${committedMigrationsFolder}/${newMigrationFilename}`; await fs_1.promises.writeFile(newMigrationFilepath, finalBody); await fs_1.promises.chmod(newMigrationFilepath, "440"); parsedSettings.logger.info(`graphile-migrate: New migration '${newMigrationFilename}' created`); try { await migrate_1._migrate(parsedSettings, true); await migrate_1._migrate(parsedSettings); await current_1.writeCurrentMigration(parsedSettings, currentLocation, parsedSettings.blankMigrationContent.trim() + "\n"); } catch (e) { instrumentation_1.logDbError(parsedSettings, e); parsedSettings.logger.error("ABORTING..."); await current_1.writeCurrentMigration(parsedSettings, currentLocation, body); await fs_1.promises.unlink(newMigrationFilepath); parsedSettings.logger.error("ABORTED AND ROLLED BACK"); throw e; } } exports._commit = _commit; async function commit(settings, message) { const parsedSettings = await settings_1.parseSettings(settings, true); return _commit(parsedSettings, message); } exports.commit = commit; exports.commitCommand = { command: "commit", aliases: [], describe: "Commits the current migration into the `committed/` folder, resetting the current migration. Resets the shadow database.", builder: { message: { type: "string", alias: ["m"], description: "Optional commit message to label migration, must not contain newlines.", nargs: 1, }, }, handler: async (argv) => { if (argv.message !== undefined && !argv.message) { throw new Error("Missing or empty commit message after --message flag"); } await commit(await _common_1.getSettings({ configFile: argv.config }), argv.message); }, }; //# sourceMappingURL=commit.js.map