@elsikora/nestjs-crud-automator
Version:
A library for automating the creation of CRUD operations in NestJS.
428 lines (424 loc) • 29.3 kB
JavaScript
import { ApiSubscriberExecutor } from '../../class/api/subscriber/executor.class.js';
import { CONTROLLER_API_DECORATOR_CONSTANT } from '../../constant/decorator/api/controller.constant.js';
import { FUNCTION_API_DECORATOR_CONSTANT } from '../../constant/decorator/api/function.constant.js';
import '../../enum/decorator/api/action.enum.js';
import '../../enum/decorator/api/authentication-type.enum.js';
import '../../enum/decorator/api/controller/load-relations-strategy.enum.js';
import '../../enum/decorator/api/controller/request-transformer-type.enum.js';
import { EApiDtoType } from '../../enum/decorator/api/dto-type.enum.js';
import '../../enum/decorator/api/function/type.enum.js';
import { EApiSubscriberOnType } from '../../enum/decorator/api/on-type.enum.js';
import '../../enum/decorator/api/property/data-type.enum.js';
import '../../enum/decorator/api/property/date/identifier.enum.js';
import '../../enum/decorator/api/property/date/type.enum.js';
import '../../enum/decorator/api/property/desribe-type.enum.js';
import '../../enum/decorator/api/property/number-type.enum.js';
import '../../enum/decorator/api/property/string-type.enum.js';
import { EApiRouteType } from '../../enum/decorator/api/route-type.enum.js';
import { Controller } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { ApiControllerApplyDecorators } from '../../utility/api/controller/apply-decorators.utility.js';
import { ApiControllerApplyMetadata } from '../../utility/api/controller/apply-metadata.utility.js';
import { ApiControllerGetListTransformFilter } from '../../utility/api/controller/get-list/transform-filter.utility.js';
import '../../enum/filter-operation.enum.js';
import 'typeorm/index';
import { ApiControllerGetPrimaryColumn } from '../../utility/api/controller/get-primary-column.utility.js';
import { ApiControllerHandleRequestRelations } from '../../utility/api/controller/handle-request-relations.utility.js';
import { ApiControllerTransformData } from '../../utility/api/controller/transform-data.utility.js';
import { ApiControllerValidateRequest } from '../../utility/api/controller/validate-request.utility.js';
import { ApiControllerWriteDtoSwagger } from '../../utility/api/controller/write-dto-swagger.utility.js';
import { ApiControllerWriteMethod } from '../../utility/api/controller/write-method.utility.js';
import 'typeorm';
import 'reflect-metadata';
import { analyzeEntityMetadata } from '../../utility/dto/analize.utility.js';
import '../../constant/utility/dto/constant.js';
import { ErrorException } from '../../utility/error-exception.utility.js';
import '../../external/tslib/tslib.es6.js';
import { plainToInstance } from 'class-transformer';
import 'class-validator';
import 'lodash/random';
import '../../validator/is-regular-expression.validator.js';
import 'node:crypto';
import '../../validator/must-match-one-of-schemas.validator.js';
import { DtoGenerate } from '../../utility/dto/generate.utility.js';
import '../../enum/filter-order-direction.enum.js';
import '../../validator/all-or-none-of-listed-properties.validator.js';
import { GenerateEntityInformation } from '../../utility/generate-entity-information.utility.js';
class ApiControllerFactory {
target;
properties;
get targetPrototype() {
return this.target.prototype;
}
ENTITY;
constructor(target, properties) {
this.target = target;
this.properties = properties;
this.ENTITY = GenerateEntityInformation(properties.entity);
analyzeEntityMetadata(this.properties.entity);
if (!this.ENTITY.primaryKey) {
throw ErrorException(`Primary key for entity ${this.properties.entity.name ?? "UnknownResource"} not found`);
}
Controller(this.properties.path ?? (this.properties.entity.name ? this.properties.entity.name.toLowerCase() : "UnknownResource"))(this.target);
ApiTags(this.properties.name ?? this.properties.entity.name ?? "UnknownResource")(this.target);
}
createMethod(method) {
if (!(method in this.properties.routes) || this.properties.routes[method]?.isEnabled !== false) {
const routeConfig = this.properties.routes[method] ?? {};
const routeDecorators = routeConfig.decorators ?? [];
const methodName = `${CONTROLLER_API_DECORATOR_CONSTANT.RESERVED_METHOD_PREFIX}${method}`;
ApiControllerWriteMethod(this, this.targetPrototype, method, this.properties, this.ENTITY);
const targetMethod = this.targetPrototype[methodName];
ApiControllerApplyMetadata(this.target, this.targetPrototype, this.ENTITY, this.properties, method, methodName, routeConfig);
if (this.properties.routes[method]?.shouldWriteToController !== false) {
ApiControllerApplyDecorators(targetMethod, this.ENTITY, this.properties, method, methodName, routeConfig, routeDecorators);
}
ApiControllerWriteDtoSwagger(this.target, this.ENTITY, this.properties, method, routeConfig, this.ENTITY);
// Reflect.defineMetadata(PARAMTYPES_METADATA, [routeConfig.dto.request], this.target, methodNameOnController);
// Reflect.defineMetadata(PATH_METADATA, `:${this.ENTITY.name}`, this.target, methodNameOnController);
/* const dtoProperties: Record<string, unknown> = (Reflect.getMetadata(DECORATORS.API_MODEL_PROPERTIES, routeConfig.dto.request) || {}) as Record<string, unknown>;
const dtoPropertiesArray: Array<unknown> = (Reflect.getMetadata(DECORATORS.API_MODEL_PROPERTIES_ARRAY, routeConfig.dto.request) || []) as Array<unknown>;
Reflect.defineMetadata(DECORATORS.API_MODEL_PROPERTIES, dtoProperties, routeConfig.dto.request);
Reflect.defineMetadata(DECORATORS.API_MODEL_PROPERTIES_ARRAY, dtoPropertiesArray, routeConfig.dto.request); */
}
}
init() {
for (const method of Object.values(EApiRouteType)) {
this.createMethod(method);
}
}
[EApiRouteType.CREATE](method, methodName, properties, entityMetadata) {
this.targetPrototype[methodName] = Object.defineProperty(async function (body, headers, ip, authenticationRequest) {
const entityInstance = new properties.entity();
const beforeExecutionContext = {
DATA: { entityMetadata, method, methodName, properties },
ENTITY: entityInstance,
result: { authenticationRequest, body, headers, ip },
ROUTE_TYPE: EApiRouteType.CREATE,
};
const beforeResult = await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.CREATE, EApiSubscriberOnType.BEFORE, beforeExecutionContext);
if (beforeResult) {
body = beforeResult.body;
headers = beforeResult.headers;
ip = beforeResult.ip;
authenticationRequest = beforeResult.authenticationRequest;
}
try {
const primaryKey = ApiControllerGetPrimaryColumn(body, entityMetadata);
if (!primaryKey) {
await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.CREATE, EApiSubscriberOnType.BEFORE_ERROR, { ...beforeExecutionContext, result: undefined }, new Error("Primary key not found in entity columns"));
throw ErrorException("Primary key not found in entity columns");
}
ApiControllerTransformData(properties.routes[method]?.request?.transformers, properties, { body }, { authenticationRequest, headers, ip });
await ApiControllerValidateRequest(properties.routes[method]?.request?.validators, properties, body);
await ApiControllerHandleRequestRelations(this, properties, properties.routes[method]?.request?.relations, body);
const createResponse = await this.service.create(body);
const dto = DtoGenerate(properties.entity, entityMetadata, method, EApiDtoType.RESPONSE, properties.routes[method]?.autoDto?.[EApiDtoType.RESPONSE], properties.routes[method]?.authentication?.guard);
const requestProperties = {
relations: properties.routes[method]?.response?.relations,
where: { [primaryKey.key]: createResponse[primaryKey.key] },
};
const response = await this.service.get(requestProperties);
ApiControllerTransformData(properties.routes[method]?.response?.transformers, properties, { response }, { authenticationRequest, headers, ip });
const afterExecutionContext = {
DATA: { ...beforeExecutionContext.DATA, authenticationRequest, body, headers, ip },
ENTITY: response,
result: response,
ROUTE_TYPE: EApiRouteType.CREATE,
};
const afterResult = await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, response, EApiRouteType.CREATE, EApiSubscriberOnType.AFTER, afterExecutionContext);
const finalResponse = afterResult ?? response;
return plainToInstance(dto, finalResponse, {
/* eslint-disable-next-line @elsikora/typescript/naming-convention */
excludeExtraneousValues: true,
strategy: "excludeAll",
});
}
catch (error) {
const errorExecutionContext = {
DATA: { ...beforeExecutionContext.DATA, authenticationRequest, body, headers, ip },
ENTITY: entityInstance,
ROUTE_TYPE: EApiRouteType.CREATE,
};
await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.CREATE, EApiSubscriberOnType.AFTER_ERROR, errorExecutionContext, error);
throw error;
}
}, "name", { value: methodName });
}
[EApiRouteType.DELETE](method, methodName, properties, entityMetadata) {
this.targetPrototype[methodName] = Object.defineProperty(async function (parameters, headers, ip, authenticationRequest) {
const entityInstance = new properties.entity();
const beforeExecutionContext = {
DATA: { entityMetadata, method, methodName, properties },
ENTITY: entityInstance,
result: { authenticationRequest, headers, ip, parameters },
ROUTE_TYPE: EApiRouteType.DELETE,
};
const beforeResult = await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.DELETE, EApiSubscriberOnType.BEFORE, beforeExecutionContext);
if (beforeResult) {
parameters = beforeResult.parameters;
headers = beforeResult.headers;
ip = beforeResult.ip;
authenticationRequest = beforeResult.authenticationRequest;
}
try {
const primaryKey = ApiControllerGetPrimaryColumn(parameters, entityMetadata);
if (!primaryKey) {
await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.DELETE, EApiSubscriberOnType.BEFORE_ERROR, { ...beforeExecutionContext, result: undefined }, new Error("Primary key not found in entity columns"));
throw ErrorException("Primary key not found in entity columns");
}
ApiControllerTransformData(properties.routes[method]?.request?.transformers, properties, { parameters }, { authenticationRequest, headers, ip });
await ApiControllerValidateRequest(properties.routes[method]?.request?.validators, properties, parameters);
await ApiControllerHandleRequestRelations(this, properties, properties.routes[method]?.request?.relations, parameters);
const requestCriteria = {
[primaryKey.key]: primaryKey.value,
};
await this.service.delete(requestCriteria);
const afterExecutionContext = {
DATA: { ...beforeExecutionContext.DATA, authenticationRequest, headers, ip, parameters },
ENTITY: entityInstance,
result: parameters,
ROUTE_TYPE: EApiRouteType.DELETE,
};
await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.DELETE, EApiSubscriberOnType.AFTER, afterExecutionContext);
}
catch (error) {
const errorExecutionContext = {
DATA: { ...beforeExecutionContext.DATA, authenticationRequest, headers, ip, parameters },
ENTITY: entityInstance,
ROUTE_TYPE: EApiRouteType.DELETE,
};
await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.DELETE, EApiSubscriberOnType.AFTER_ERROR, errorExecutionContext, error);
throw error;
}
}, "name", { value: methodName });
}
[EApiRouteType.GET](method, methodName, properties, entityMetadata) {
this.targetPrototype[methodName] = Object.defineProperty(async function (parameters, headers, ip, authenticationRequest) {
const entityInstance = new properties.entity();
const beforeExecutionContext = {
DATA: { entityMetadata, method, methodName, properties },
ENTITY: entityInstance,
result: { authenticationRequest, headers, ip, parameters },
ROUTE_TYPE: EApiRouteType.GET,
};
const beforeResult = await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.GET, EApiSubscriberOnType.BEFORE, beforeExecutionContext);
if (beforeResult) {
parameters = beforeResult.parameters;
headers = beforeResult.headers;
ip = beforeResult.ip;
authenticationRequest = beforeResult.authenticationRequest;
}
try {
const primaryKey = ApiControllerGetPrimaryColumn(parameters, entityMetadata);
if (!primaryKey) {
await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.GET, EApiSubscriberOnType.BEFORE_ERROR, { ...beforeExecutionContext, result: undefined }, new Error("Primary key not found in entity columns"));
throw ErrorException("Primary key not found in entity columns");
}
ApiControllerTransformData(properties.routes[method]?.request?.transformers, properties, { parameters }, { authenticationRequest, headers, ip });
await ApiControllerValidateRequest(properties.routes[method]?.request?.validators, properties, parameters);
await ApiControllerHandleRequestRelations(this, properties, properties.routes[method]?.request?.relations, parameters);
const requestProperties = {
relations: properties.routes[method]?.response?.relations,
where: { [primaryKey.key]: primaryKey.value },
};
const response = await this.service.get(requestProperties);
ApiControllerTransformData(properties.routes[method]?.response?.transformers, properties, { response }, { authenticationRequest, headers, ip });
const afterExecutionContext = {
DATA: { ...beforeExecutionContext.DATA, authenticationRequest, headers, ip, parameters },
ENTITY: response,
result: response,
ROUTE_TYPE: EApiRouteType.GET,
};
const afterResult = await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, response, EApiRouteType.GET, EApiSubscriberOnType.AFTER, afterExecutionContext);
const finalResponse = afterResult ?? response;
const dto = DtoGenerate(properties.entity, entityMetadata, method, EApiDtoType.RESPONSE, properties.routes[method]?.autoDto?.[EApiDtoType.RESPONSE], properties.routes[method]?.authentication?.guard);
return plainToInstance(dto, finalResponse, {
/* eslint-disable-next-line @elsikora/typescript/naming-convention */
excludeExtraneousValues: true,
});
}
catch (error) {
const errorExecutionContext = {
DATA: { ...beforeExecutionContext.DATA, authenticationRequest, headers, ip, parameters },
ENTITY: entityInstance,
ROUTE_TYPE: EApiRouteType.GET,
};
await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.GET, EApiSubscriberOnType.AFTER_ERROR, errorExecutionContext, error);
throw error;
}
}, "name", { value: methodName });
}
[EApiRouteType.GET_LIST](method, methodName, properties, entityMetadata) {
this.targetPrototype[methodName] = Object.defineProperty(async function (query, headers, ip, authenticationRequest) {
const entityInstance = new properties.entity();
const beforeExecutionContext = {
DATA: { entityMetadata, method, methodName, properties },
ENTITY: entityInstance,
result: { authenticationRequest, headers, ip, query },
ROUTE_TYPE: EApiRouteType.GET_LIST,
};
const beforeResult = await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.GET_LIST, EApiSubscriberOnType.BEFORE, beforeExecutionContext);
if (beforeResult) {
query = beforeResult.query;
headers = beforeResult.headers;
ip = beforeResult.ip;
authenticationRequest = beforeResult.authenticationRequest;
}
try {
ApiControllerTransformData(properties.routes[method]?.request?.transformers, properties, { query }, { authenticationRequest, headers, ip });
await ApiControllerValidateRequest(properties.routes[method]?.request?.validators, properties, query);
await ApiControllerHandleRequestRelations(this, properties, properties.routes[method]?.request?.relations, query);
const { limit, orderBy, orderDirection, page, ...getListQuery } = query;
const filter = ApiControllerGetListTransformFilter(getListQuery, entityMetadata);
const requestProperties = {
relations: properties.routes[method]?.response?.relations,
skip: query.limit * (query.page - 1),
take: query.limit,
where: filter,
};
if (orderBy) {
requestProperties.order = { [orderBy]: orderDirection ?? FUNCTION_API_DECORATOR_CONSTANT.DEFAULT_FILTER_ORDER_BY_DIRECTION };
}
const response = await this.service.getList(requestProperties);
ApiControllerTransformData(properties.routes[method]?.request?.transformers, properties, { response }, { authenticationRequest, headers, ip });
const afterExecutionContext = {
DATA: { ...beforeExecutionContext.DATA, authenticationRequest, headers, ip, query },
ENTITY: entityInstance,
result: response,
ROUTE_TYPE: EApiRouteType.GET_LIST,
};
const afterResult = await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.GET_LIST, EApiSubscriberOnType.AFTER, afterExecutionContext);
const finalResponse = afterResult ?? response;
const dto = DtoGenerate(properties.entity, entityMetadata, method, EApiDtoType.RESPONSE, properties.routes[method]?.autoDto?.[EApiDtoType.RESPONSE], properties.routes[method]?.authentication?.guard);
return plainToInstance(dto, finalResponse, {
// eslint-disable-next-line @elsikora/typescript/naming-convention
excludeExtraneousValues: true,
});
}
catch (error) {
const errorExecutionContext = {
DATA: { ...beforeExecutionContext.DATA, authenticationRequest, headers, ip, query },
ENTITY: entityInstance,
ROUTE_TYPE: EApiRouteType.GET_LIST,
};
await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.GET_LIST, EApiSubscriberOnType.AFTER_ERROR, errorExecutionContext, error);
throw error;
}
}, "name", { value: methodName });
}
[EApiRouteType.PARTIAL_UPDATE](method, methodName, properties, entityMetadata) {
this.targetPrototype[methodName] = Object.defineProperty(async function (parameters, body, headers, ip, authenticationRequest) {
const entityInstance = new properties.entity();
const beforeExecutionContext = {
DATA: { entityMetadata, method, methodName, properties },
ENTITY: entityInstance,
result: { authenticationRequest, body, headers, ip, parameters },
ROUTE_TYPE: EApiRouteType.PARTIAL_UPDATE,
};
const beforeResult = await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.PARTIAL_UPDATE, EApiSubscriberOnType.BEFORE, beforeExecutionContext);
if (beforeResult) {
parameters = beforeResult.parameters;
body = beforeResult.body;
headers = beforeResult.headers;
ip = beforeResult.ip;
authenticationRequest = beforeResult.authenticationRequest;
}
try {
const primaryKey = ApiControllerGetPrimaryColumn(parameters, entityMetadata);
if (!primaryKey) {
await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.PARTIAL_UPDATE, EApiSubscriberOnType.BEFORE_ERROR, { ...beforeExecutionContext, result: undefined }, new Error("Primary key not found in entity columns"));
throw ErrorException("Primary key not found in entity columns");
}
ApiControllerTransformData(properties.routes[method]?.request?.transformers, properties, { body, parameters }, { authenticationRequest, headers, ip });
await ApiControllerValidateRequest(properties.routes[method]?.request?.validators, properties, parameters);
await ApiControllerHandleRequestRelations(this, properties, properties.routes[method]?.request?.relations, parameters);
const requestCriteria = {
[primaryKey.key]: primaryKey.value,
};
const response = await this.service.update(requestCriteria, body);
ApiControllerTransformData(properties.routes[method]?.response?.transformers, properties, { response }, { authenticationRequest, headers, ip });
const afterExecutionContext = {
DATA: { ...beforeExecutionContext.DATA, authenticationRequest, body, headers, ip, parameters },
ENTITY: response,
result: response,
ROUTE_TYPE: EApiRouteType.PARTIAL_UPDATE,
};
const afterResult = await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, response, EApiRouteType.PARTIAL_UPDATE, EApiSubscriberOnType.AFTER, afterExecutionContext);
const finalResponse = afterResult ?? response;
const dto = DtoGenerate(properties.entity, entityMetadata, method, EApiDtoType.RESPONSE, properties.routes[method]?.autoDto?.[EApiDtoType.RESPONSE], properties.routes[method]?.authentication?.guard);
return plainToInstance(dto, finalResponse, {
// eslint-disable-next-line @elsikora/typescript/naming-convention
excludeExtraneousValues: true,
});
}
catch (error) {
const errorExecutionContext = {
DATA: { ...beforeExecutionContext.DATA, authenticationRequest, body, headers, ip, parameters },
ENTITY: entityInstance,
ROUTE_TYPE: EApiRouteType.PARTIAL_UPDATE,
};
await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.PARTIAL_UPDATE, EApiSubscriberOnType.AFTER_ERROR, errorExecutionContext, error);
throw error;
}
}, "name", { value: methodName });
}
[EApiRouteType.UPDATE](method, methodName, properties, entityMetadata) {
this.targetPrototype[methodName] = Object.defineProperty(async function (parameters, body, headers, ip, authenticationRequest) {
const entityInstance = new properties.entity();
const beforeExecutionContext = {
DATA: { entityMetadata, method, methodName, properties },
ENTITY: entityInstance,
result: { authenticationRequest, body, headers, ip, parameters },
ROUTE_TYPE: EApiRouteType.UPDATE,
};
const beforeResult = await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.UPDATE, EApiSubscriberOnType.BEFORE, beforeExecutionContext);
if (beforeResult) {
parameters = beforeResult.parameters;
body = beforeResult.body;
headers = beforeResult.headers;
ip = beforeResult.ip;
authenticationRequest = beforeResult.authenticationRequest;
}
try {
const primaryKey = ApiControllerGetPrimaryColumn(parameters, entityMetadata);
if (!primaryKey) {
await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.UPDATE, EApiSubscriberOnType.BEFORE_ERROR, { ...beforeExecutionContext, result: undefined }, new Error("Primary key not found in entity columns"));
throw ErrorException("Primary key not found in entity columns");
}
ApiControllerTransformData(properties.routes[method]?.request?.transformers, properties, { body, parameters }, { authenticationRequest, headers, ip });
await ApiControllerValidateRequest(properties.routes[method]?.request?.validators, properties, parameters);
await ApiControllerHandleRequestRelations(this, properties, properties.routes[method]?.request?.relations, parameters);
const requestCriteria = {
[primaryKey.key]: primaryKey.value,
};
const response = await this.service.update(requestCriteria, body);
ApiControllerTransformData(properties.routes[method]?.response?.transformers, properties, { response }, { authenticationRequest, headers, ip });
const afterExecutionContext = {
DATA: { ...beforeExecutionContext.DATA, authenticationRequest, body, headers, ip, parameters },
ENTITY: response,
result: response,
ROUTE_TYPE: EApiRouteType.UPDATE,
};
const afterResult = await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, response, EApiRouteType.UPDATE, EApiSubscriberOnType.AFTER, afterExecutionContext);
const finalResponse = afterResult ?? response;
const dto = DtoGenerate(properties.entity, entityMetadata, method, EApiDtoType.RESPONSE, properties.routes[method]?.autoDto?.[EApiDtoType.RESPONSE], properties.routes[method]?.authentication?.guard);
return plainToInstance(dto, finalResponse, {
// eslint-disable-next-line @elsikora/typescript/naming-convention
excludeExtraneousValues: true,
});
}
catch (error) {
const errorExecutionContext = {
DATA: { ...beforeExecutionContext.DATA, authenticationRequest, body, headers, ip, parameters },
ENTITY: entityInstance,
ROUTE_TYPE: EApiRouteType.UPDATE,
};
await ApiSubscriberExecutor.executeRouteSubscribers(this.constructor, entityInstance, EApiRouteType.UPDATE, EApiSubscriberOnType.AFTER_ERROR, errorExecutionContext, error);
throw error;
}
}, "name", { value: methodName });
}
}
export { ApiControllerFactory };
//# sourceMappingURL=controller.factory.js.map