UNPKG

dino-core

Version:

A dependency injection framework for NodeJS applications

98 lines 4.1 kB
"use strict"; // Copyright 2021 Quirino Brizi [quirino.brizi@gmail.com] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. Object.defineProperty(exports, "__esModule", { value: true }); exports.TransactionInterceptor = void 0; const Logger_1 = require("../../../Logger"); const promise_helper_1 = require("../../../helper/promise.helper"); const abstract_interceptors_1 = require("./abstract.interceptors"); class TransactionInterceptor extends abstract_interceptors_1.AbstractInterceptor { /** * Implement Proxy handler get method to provide transactional nature for repositories. * * The transaction environment is defined as: * * ```javascript * try { * obj.beginTransaction(); * const answer = Reflect.get(obj, prop); * obj.completeTransaction(); * return answer; * } catch(e) { * logger.error('unable to complete transaction, rolling-back', e); * obj.rollbackTransaction(); * } finally { * obj.cleanupTransactionResources(); * } * ``` * As such beginTransaction, completeTransaction, rollbackTransaction and eventually cleanupTransactionResources * should be implemented. * * * @param {Injectable} obj The target of this proxy * @param {String} prop the method or property name to access * @returns {Any} * * @public */ intercept(obj, prop) { return async (...args) => { return await new Promise((resolve, reject) => { try { Logger_1.Logger.info('starting transaction'); obj.beginTransaction(); const response = obj[prop].bind(obj)(...args); if (promise_helper_1.PromiseHelper.isAPromise(response)) { return response .then(async (response) => { await this.completeTransaction(resolve, obj, response); }) .catch(async (e) => { await this.rollbackTransaction(reject, obj, e); }) .finally(() => obj.cleanupTransactionResources()); } Logger_1.Logger.info('application logic executed, completing transaction'); return this.completeTransaction(resolve, obj, response); } catch (e) { Logger_1.Logger.error('unable to complete transaction, rolling-back', e); return this.rollbackTransaction(reject, obj, e); } finally { Logger_1.Logger.info('transaction completed cleaning-up transaction resources'); obj.cleanupTransactionResources(); } }); }; } isApplicable(obj, prop) { return Boolean(obj.transactional?.()) && obj.enableTransactionOn?.().includes(prop); } async completeTransaction(resolve, obj, response) { await obj.completeTransaction(); resolve(response); } async rollbackTransaction(reject, obj, e) { await obj.rollbackTransaction(); reject(e); } static create() { if (TransactionInterceptor._instance === undefined) { TransactionInterceptor._instance = new TransactionInterceptor(); } return TransactionInterceptor._instance; } } exports.TransactionInterceptor = TransactionInterceptor; //# sourceMappingURL=transaction.interceptor.js.map