UNPKG

@elsikora/nestjs-crud-automator

Version:

A library for automating the creation of CRUD operations in NestJS.

117 lines (113 loc) 5.91 kB
'use strict'; var node_crypto = require('node:crypto'); var contextStorage_class = require('../context-storage.class.js'); var lifecycle_class = require('./lifecycle.class.js'); var registry_class = require('./registry.class.js'); require('../../../../enum/decorator/api/action.enum.js'); require('../../../../enum/decorator/api/authentication-type.enum.js'); require('../../../../enum/decorator/api/controller/get-list/query/filter/missing-behavior.enum.js'); require('../../../../enum/decorator/api/controller/get-list/query/unlisted-fields.enum.js'); require('../../../../enum/decorator/api/controller/relation-reference-shape.enum.js'); require('../../../../enum/decorator/api/controller/request/target.enum.js'); require('../../../../enum/decorator/api/controller/request/transformer-type.enum.js'); require('../../../../enum/decorator/api/controller/response-target.enum.js'); require('../../../../enum/decorator/api/dto-type.enum.js'); require('../../../../enum/decorator/api/function/context-storage-kind.enum.js'); require('../../../../enum/decorator/api/function/subscriber-transaction-expectation.enum.js'); require('../../../../enum/decorator/api/function/transaction/event-status.enum.js'); var failureStage_enum = require('../../../../enum/decorator/api/function/transaction/failure-stage.enum.js'); require('../../../../enum/decorator/api/function/transaction/mode.enum.js'); require('../../../../enum/decorator/api/function/transaction/outcome.enum.js'); require('../../../../enum/decorator/api/function/transaction/owner-kind.enum.js'); require('../../../../enum/decorator/api/function/transaction/trace-type.enum.js'); require('../../../../enum/decorator/api/function/type.enum.js'); require('../../../../enum/decorator/api/on-type.enum.js'); require('../../../../enum/decorator/api/property/data-type.enum.js'); require('../../../../enum/decorator/api/property/date/identifier.enum.js'); require('../../../../enum/decorator/api/property/date/type.enum.js'); require('../../../../enum/decorator/api/property/desribe-type.enum.js'); require('../../../../enum/decorator/api/property/number-type.enum.js'); require('../../../../enum/decorator/api/property/string-type.enum.js'); require('../../../../enum/decorator/api/route/subscriber-authorization-expectation.enum.js'); require('../../../../enum/decorator/api/route/type.enum.js'); var exception_utility = require('../../../../utility/error/exception.utility.js'); var logger_utility = require('../../../../utility/logger.utility.js'); const transactionLogger = logger_utility.LoggerUtility.getLogger("ApiFunctionTransactionRuntime"); class ApiFunctionTransactionRuntime { static async execute(options) { if (contextStorage_class.ApiFunctionContextStorage.getTransactionRegistry()) { throw exception_utility.ErrorException("Cannot open an owning transaction inside an active Automator transaction"); } const queryRunner = options.dataSource.createQueryRunner(); try { await queryRunner.connect(); await queryRunner.startTransaction(); } catch (error) { await ApiFunctionTransactionRuntime.releaseBestEffort(queryRunner); throw error; } const registry = new registry_class.ApiFunctionTransactionRegistry(node_crypto.randomUUID(), options.owner); const result = {}; let commitCleanupFailure; let commitError; let hasCommitError = false; let hasOperationError = false; let operationError; let rollbackFailure; await contextStorage_class.ApiFunctionContextStorage.runTransaction(queryRunner.manager, queryRunner, registry, async () => { try { result.value = await options.callback(queryRunner.manager); } catch (error) { hasOperationError = true; operationError = error; rollbackFailure = await ApiFunctionTransactionRuntime.rollbackBestEffort(queryRunner); await ApiFunctionTransactionRuntime.releaseBestEffort(queryRunner); return; } try { await queryRunner.commitTransaction(); } catch (error) { commitError = error; hasCommitError = true; commitCleanupFailure = await ApiFunctionTransactionRuntime.rollbackBestEffort(queryRunner); } await ApiFunctionTransactionRuntime.releaseBestEffort(queryRunner); }); if (hasOperationError) { return await lifecycle_class.ApiFunctionTransactionLifecycle.executeAfterRollback(registry, operationError, rollbackFailure); } if (hasCommitError) { return await lifecycle_class.ApiFunctionTransactionLifecycle.executeCommitUnknown(registry, commitError, commitCleanupFailure); } if (!("value" in result)) { throw exception_utility.ErrorException("Automator transaction completed without a committed result"); } await lifecycle_class.ApiFunctionTransactionLifecycle.executeAfterCommit(registry); return result.value; } static async releaseBestEffort(queryRunner) { try { await queryRunner.release(); } catch (error) { transactionLogger.error("Failed to release transaction query runner", error); } } static async rollbackBestEffort(queryRunner) { try { await queryRunner.rollbackTransaction(); return undefined; } catch (error) { return Object.freeze({ error, stage: failureStage_enum.EApiFunctionTransactionFailureStage.ROLLBACK, }); } } } exports.ApiFunctionTransactionRuntime = ApiFunctionTransactionRuntime; //# sourceMappingURL=runtime.class.js.map