@decaf-ts/core
Version:
Core persistence module for the decaf framework
109 lines • 4.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbsMigration = void 0;
exports.prefixMethod = prefixMethod;
exports.migration = migration;
const Adapter_1 = require("./Adapter.cjs");
const db_decorators_1 = require("@decaf-ts/db-decorators");
const logging_1 = require("@decaf-ts/logging");
const constants_1 = require("./constants.cjs");
const decoration_1 = require("@decaf-ts/decoration");
const errors_1 = require("./errors.cjs");
const decorator_validation_1 = require("@decaf-ts/decorator-validation");
const Context_1 = require("./Context.cjs");
function prefixMethod(obj, after, prefix, afterName) {
async function wrapper(...args) {
let results;
try {
results = await Promise.resolve(prefix.call(this, ...args));
}
catch (e) {
if (e instanceof errors_1.MigrationRuleError)
return;
throw e;
}
return Promise.resolve(after.apply(this, results));
}
const wrapped = wrapper.bind(obj);
const name = afterName ? afterName : after.name;
Object.defineProperty(wrapped, "name", {
enumerable: true,
configurable: true,
writable: false,
value: name,
});
obj[name] = wrapped;
}
class AbsMigration extends logging_1.LoggedClass {
constructor() {
super();
this.transaction = true;
[this.up, this.down].forEach((m) => {
const name = m.name;
prefixMethod(this, m, this.prefix(name));
});
}
get adapter() {
const meta = decoration_1.Metadata.get(this.constructor, constants_1.PersistenceKeys.MIGRATION);
if (!meta)
throw new db_decorators_1.InternalError(`No migration metadata for ${this.constructor.name}`);
const flavour = meta.flavour;
return Adapter_1.Adapter.get(flavour);
}
async enforceRules(qr, adapter, ctx) {
const rules = decoration_1.Metadata.get(this.constructor, constants_1.PersistenceKeys.MIGRATION)?.rules;
if (!rules || !rules.length)
return true;
for (const rule of rules) {
const result = await rule(qr, adapter, ctx);
if (!result)
return false;
}
return true;
}
prefix(name) {
return async function preffix(qrOrAdapter) {
let qr;
if (qrOrAdapter instanceof Adapter_1.Adapter) {
qr = this.getQueryRunner(qrOrAdapter.client);
}
else {
qr = qrOrAdapter;
qrOrAdapter = this.adapter;
}
const ctx = await Context_1.Context.args("migration", decorator_validation_1.Model, [name], qrOrAdapter);
const allowed = await this.enforceRules(qr, qrOrAdapter, ctx.context);
if (!allowed) {
ctx.context.logger.verbose(`Skipping migration ${this.constructor.name} due to rules`);
throw new errors_1.MigrationRuleError("Migration skipped for rule enforcement");
}
return [qr, qrOrAdapter, ctx.context];
}.bind(this);
}
}
exports.AbsMigration = AbsMigration;
function migration(flavour, rules) {
function innerMigration(flavour, rules) {
return function (original) {
const current = decoration_1.Metadata["innerGet"](Symbol.for(constants_1.PersistenceKeys.MIGRATION), flavour) ||
[];
decoration_1.Metadata.set(constants_1.PersistenceKeys.MIGRATION, flavour, [
...current,
{
class: original,
},
]);
return (0, decoration_1.metadata)(constants_1.PersistenceKeys.MIGRATION, {
flavour: flavour,
rules: rules,
})(original);
};
}
return decoration_1.Decoration.for(constants_1.PersistenceKeys.MIGRATION)
.define({
decorator: innerMigration,
args: [flavour, rules],
})
.apply();
}
//# sourceMappingURL=migrations.js.map