@medusajs/utils
Version:
Medusa utilities functions shared by Medusa core and Modules
169 lines • 7.21 kB
JavaScript
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _Migrations_instances, _Migrations_configOrConnection, _Migrations_getConnection;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Migrations = void 0;
const core_1 = require("@mikro-orm/core");
const postgresql_1 = require("@mikro-orm/postgresql");
const events_1 = require("events");
const promises_1 = require("fs/promises");
const path_1 = require("path");
const common_1 = require("../common");
/**
* Exposes the API to programmatically manage Mikro ORM migrations
*/
class Migrations extends events_1.EventEmitter {
constructor(configOrConnection) {
super();
_Migrations_instances.add(this);
_Migrations_configOrConnection.set(this, void 0);
__classPrivateFieldSet(this, _Migrations_configOrConnection, configOrConnection, "f");
}
/**
* Generates migrations for a collection of entities defined
* in the config
*/
async generate() {
const connection = await __classPrivateFieldGet(this, _Migrations_instances, "m", _Migrations_getConnection).call(this);
const migrator = connection.getMigrator();
try {
await this.migrateSnapshotFile(migrator["snapshotPath"]);
await this.ensureSnapshot(migrator["snapshotPath"]);
return await migrator.createMigration();
}
finally {
await connection.close(true);
}
}
/**
* Run migrations for the provided entities
*/
async run(options) {
const connection = await __classPrivateFieldGet(this, _Migrations_instances, "m", _Migrations_getConnection).call(this);
const migrator = connection.getMigrator();
migrator["umzug"].on("migrating", (event) => this.emit("migrating", event));
migrator["umzug"].on("migrated", (event) => {
this.emit("migrated", event);
});
try {
const res = await migrator.up(options);
return res;
}
finally {
migrator["umzug"].clearListeners();
await connection.close(true);
}
}
/**
* Run migrations for the provided entities
*/
async revert(options) {
const connection = await __classPrivateFieldGet(this, _Migrations_instances, "m", _Migrations_getConnection).call(this);
const migrator = connection.getMigrator();
migrator["umzug"].on("reverting", (event) => this.emit("reverting", event));
migrator["umzug"].on("reverted", (event) => {
this.emit("reverted", event);
});
try {
return await migrator.down(options);
}
catch (error) {
/**
* This is a very ugly hack to recover from an exception thrown by
* MikrORM when the `down` method is not implemented by the
* migration.
*
* We cannot check if "down" method exists on the migration, because it
* always exists (as inherited from the parent class). Also, throwing
* an exception is important, so that Mikro ORM does not consider the
* given migration as reverted.
*/
if (error?.migration &&
error?.cause?.message === "This migration cannot be reverted") {
this.emit("revert:skipped", {
...error.migration,
reason: "Missing down method",
});
return [];
}
throw error;
}
finally {
migrator["umzug"].clearListeners();
await connection.close(true);
}
}
/**
* Migrates the existing snapshot file of a module to follow to be
* named after the current snapshot file.
*
* If there are multiple snapshot files inside the directory, then
* the first one will be used.
*/
async migrateSnapshotFile(snapshotPath) {
const entries = await (0, common_1.readDir)((0, path_1.dirname)(snapshotPath), {
ignoreMissing: true,
});
/**
* We assume all JSON files are snapshot files in this directory
*/
const snapshotFile = entries.find((entry) => entry.isFile() && entry.name.endsWith(".json"));
if (snapshotFile) {
const absoluteName = (0, path_1.join)(snapshotFile.path, snapshotFile.name);
if (absoluteName !== snapshotPath) {
await (0, promises_1.rename)(absoluteName, snapshotPath);
}
}
}
/**
* Generate a default snapshot file if it does not already exists. This
* prevent from creating a database to manage the migrations and instead
* rely on the snapshot.
*
* @param snapshotPath
* @protected
*/
async ensureSnapshot(snapshotPath) {
await (0, promises_1.mkdir)((0, path_1.dirname)(snapshotPath), { recursive: true });
const doesFileExists = await (0, promises_1.access)(snapshotPath)
.then(() => true)
.catch(() => false);
if (doesFileExists) {
return;
}
const emptySnapshotContent = JSON.stringify({
tables: [],
namespaces: [],
}, null, 2);
await (0, promises_1.writeFile)(snapshotPath, emptySnapshotContent, "utf-8");
}
}
exports.Migrations = Migrations;
_Migrations_configOrConnection = new WeakMap(), _Migrations_instances = new WeakSet(), _Migrations_getConnection =
/**
* Returns an existing connection or instantiates a new
* one
*/
async function _Migrations_getConnection() {
if ("connect" in __classPrivateFieldGet(this, _Migrations_configOrConnection, "f")) {
return __classPrivateFieldGet(this, _Migrations_configOrConnection, "f");
}
return await core_1.MikroORM.init((0, postgresql_1.defineConfig)({
...__classPrivateFieldGet(this, _Migrations_configOrConnection, "f"),
migrations: {
...__classPrivateFieldGet(this, _Migrations_configOrConnection, "f").migrations,
silent: true,
},
}));
};
//# sourceMappingURL=index.js.map
;