@elsikora/nestjs-crud-automator
Version:
A library for automating the creation of CRUD operations in NestJS.
117 lines (113 loc) • 5.91 kB
JavaScript
;
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