UNPKG

@decaf-ts/core

Version:

Core persistence module for the decaf framework

109 lines 4.08 kB
"use strict"; 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