datocms-client
Version:
For new DatoCMS users, we recommend @datocms/cma-client-node
318 lines (242 loc) • 12.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = runPendingMigrations;
var _path = _interopRequireDefault(require("path"));
var _fs = _interopRequireDefault(require("fs"));
var _ora = _interopRequireDefault(require("ora"));
var _ApiException = _interopRequireDefault(require("../ApiException"));
var _SiteClient = _interopRequireDefault(require("../site/SiteClient"));
var _upsertMigrationModel = _interopRequireDefault(require("./upsertMigrationModel"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
var MIGRATION_FILE_REGEXP = /^[0-9]+.*\.js$/;
function catchPermissionErrors(_x, _x2) {
return _catchPermissionErrors.apply(this, arguments);
}
function _catchPermissionErrors() {
_catchPermissionErrors = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(operation, promise) {
var result;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.prev = 0;
_context.next = 3;
return promise;
case 3:
result = _context.sent;
return _context.abrupt("return", result);
case 7:
_context.prev = 7;
_context.t0 = _context["catch"](0);
if (_context.t0 instanceof _ApiException["default"] && _context.t0.statusCode === 401) {
process.stderr.write("\n\nFail: the API token has not enough permissions to perform the following operation: ".concat(operation, ". Please use another API token, or edit the permissions for the current one.\n"));
process.exit(1);
}
throw _context.t0;
case 11:
case "end":
return _context.stop();
}
}
}, _callee, null, [[0, 7]]);
}));
return _catchPermissionErrors.apply(this, arguments);
}
function runPendingMigrations(_x3) {
return _runPendingMigrations.apply(this, arguments);
}
function _runPendingMigrations() {
_runPendingMigrations = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(_ref) {
var sourceEnvId, rawDestinationEnvId, migrationModelApiKey, relativeMigrationsDir, inPlace, dryRun, jsonOutput, cmaBaseUrl, tokenByArg, jsonResult, migrationsDir, allMigrations, token, globalClient, allEnvironments, primaryEnv, sourceEnv, destinationEnvId, forkSpinner, existingEnvironment, client, migrationModel, alreadyRunMigrations, migrationsToRun, _iterator, _step, migrationFile, migrationSpinner, migrationAbsolutePath, migration;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
sourceEnvId = _ref.sourceEnvId, rawDestinationEnvId = _ref.destinationEnvId, migrationModelApiKey = _ref.migrationModelApiKey, relativeMigrationsDir = _ref.relativeMigrationsDir, inPlace = _ref.inPlace, dryRun = _ref.dryRun, jsonOutput = _ref.jsonOutput, cmaBaseUrl = _ref.cmaBaseUrl, tokenByArg = _ref.token;
jsonResult = {};
migrationsDir = _path["default"].resolve(relativeMigrationsDir);
if (_fs["default"].existsSync(migrationsDir)) {
_context2.next = 5;
break;
}
throw new Error("Error: ".concat(relativeMigrationsDir, " is not a directory!\n"));
case 5:
allMigrations = _fs["default"].readdirSync(migrationsDir).filter(function (file) {
return file.match(MIGRATION_FILE_REGEXP);
});
token = tokenByArg || process.env.DATO_MANAGEMENT_API_TOKEN;
globalClient = new _SiteClient["default"](token, {
baseUrl: cmaBaseUrl
});
_context2.next = 10;
return catchPermissionErrors('fetch the existing environments', globalClient.environments.all());
case 10:
allEnvironments = _context2.sent;
primaryEnv = allEnvironments.find(function (env) {
return env.meta.primary;
});
if (!sourceEnvId) {
_context2.next = 18;
break;
}
_context2.next = 15;
return catchPermissionErrors("fetch environment ".concat(sourceEnvId), globalClient.environments.find(sourceEnvId));
case 15:
_context2.t0 = _context2.sent;
_context2.next = 19;
break;
case 18:
_context2.t0 = primaryEnv;
case 19:
sourceEnv = _context2.t0;
if (sourceEnv) {
_context2.next = 22;
break;
}
throw new Error("You have no permissions to access the ".concat(sourceEnvId ? "\"".concat(sourceEnvId, "\"") : 'primary', " environment!"));
case 22:
destinationEnvId = inPlace ? sourceEnv.id : rawDestinationEnvId || "".concat(sourceEnv.id, "-post-migrations");
if (!inPlace) {
_context2.next = 28;
break;
}
if (!(primaryEnv && primaryEnv.id === destinationEnvId)) {
_context2.next = 26;
break;
}
throw new Error('Running migrations on primary environment is not allowed!');
case 26:
_context2.next = 40;
break;
case 28:
forkSpinner = (0, _ora["default"])("Creating a fork of `".concat(sourceEnv.id, "` called `").concat(destinationEnvId, "`...")).start();
existingEnvironment = allEnvironments.find(function (env) {
return env.id === destinationEnvId;
});
if (!existingEnvironment) {
_context2.next = 33;
break;
}
forkSpinner.fail();
throw new Error("Environment ".concat(destinationEnvId, " already exists! If you want to run the migrations inside this existing environment you can add the --inPlace flag."));
case 33:
if (!dryRun) {
_context2.next = 37;
break;
}
destinationEnvId = sourceEnv.id;
_context2.next = 39;
break;
case 37:
_context2.next = 39;
return catchPermissionErrors("fork environment ".concat(sourceEnv.id, " into ").concat(destinationEnvId), globalClient.environments.fork(sourceEnv.id, {
id: destinationEnvId
}));
case 39:
forkSpinner.succeed();
case 40:
jsonResult.destinationEnvId = destinationEnvId;
if (!jsonOutput) {
process.stdout.write("Migrations will be run in sandbox env `".concat(destinationEnvId, "`\n"));
}
client = new _SiteClient["default"](token, {
environment: destinationEnvId,
baseUrl: cmaBaseUrl
});
_context2.next = 45;
return (0, _upsertMigrationModel["default"])(client, migrationModelApiKey, catchPermissionErrors, dryRun);
case 45:
migrationModel = _context2.sent;
if (!migrationModel) {
_context2.next = 52;
break;
}
_context2.next = 49;
return client.items.all({
filter: {
type: migrationModel.id
}
}, {
allPages: true
});
case 49:
_context2.t1 = _context2.sent.map(function (m) {
return m.name;
});
_context2.next = 53;
break;
case 52:
_context2.t1 = [];
case 53:
alreadyRunMigrations = _context2.t1;
migrationsToRun = allMigrations.filter(function (file) {
return !alreadyRunMigrations.includes(file);
}).sort();
_iterator = _createForOfIteratorHelper(migrationsToRun);
_context2.prev = 56;
_iterator.s();
case 58:
if ((_step = _iterator.n()).done) {
_context2.next = 72;
break;
}
migrationFile = _step.value;
migrationSpinner = (0, _ora["default"])("Running ".concat(migrationFile, "...")).start();
if (dryRun) {
_context2.next = 66;
break;
}
migrationAbsolutePath = _path["default"].join(migrationsDir, migrationFile); // eslint-disable-next-line global-require, import/no-dynamic-require
migration = require(migrationAbsolutePath);
_context2.next = 66;
return migration(client);
case 66:
migrationSpinner.succeed();
if (dryRun) {
_context2.next = 70;
break;
}
_context2.next = 70;
return client.items.create({
itemType: migrationModel.id,
name: migrationFile
});
case 70:
_context2.next = 58;
break;
case 72:
_context2.next = 77;
break;
case 74:
_context2.prev = 74;
_context2.t2 = _context2["catch"](56);
_iterator.e(_context2.t2);
case 77:
_context2.prev = 77;
_iterator.f();
return _context2.finish(77);
case 80:
jsonResult.runMigrations = migrationsToRun;
jsonResult.runMigrationsCount = migrationsToRun.length;
if (!jsonOutput) {
process.stdout.write("Done! Successfully run ".concat(migrationsToRun.length, " migration files.\n"));
}
if (jsonOutput) {
process.stdout.write(JSON.stringify(jsonResult, null, 2));
}
case 84:
case "end":
return _context2.stop();
}
}
}, _callee2, null, [[56, 74, 77, 80]]);
}));
return _runPendingMigrations.apply(this, arguments);
}