@elsikora/nestjs-crud-automator
Version:
A library for automating the creation of CRUD operations in NestJS.
210 lines (206 loc) • 11.4 kB
JavaScript
'use strict';
var transformerValue_constant = require('../../../constant/dto/transformer-value.constant.js');
require('../../../enum/decorator/api/action.enum.js');
require('../../../enum/decorator/api/authentication-type.enum.js');
require('../../../enum/decorator/api/controller/load-relations-strategy.enum.js');
var requestTransformerType_enum = require('../../../enum/decorator/api/controller/request-transformer-type.enum.js');
var dtoType_enum = require('../../../enum/decorator/api/dto-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-type.enum.js');
var action_enum = require('../../../enum/utility/error-string/action.enum.js');
require('../../../enum/utility/error-string/composite-action.enum.js');
var common = require('@nestjs/common');
var errorString_utility = require('../../error-string.utility.js');
/**
* Transforms data between request/response objects and entity objects.
* Handles both static and dynamic transformations for body, query, request, and response data.
* @param {TApiControllerPropertiesRouteBaseRequestTransformers<E, R> | TApiControllerPropertiesRouteBaseResponseTransformers<E, R> | undefined} transformers - Configuration for data transformations
* @param {IApiControllerProperties<E>} properties - Controller configuration properties
* @param {TApiControllerTransformDataObjectToTransform<E>} objectToTransform - The object to apply transformations to
* @param {TApiControllerTransformDataData} data - Data sources to use for transformations including headers, IP address, and authentication
* @returns {void}
* @template E - The entity type
* @template R - The route type
*/
function ApiControllerTransformData(transformers, properties, objectToTransform, data) {
if (!transformers)
return;
if (dtoType_enum.EApiDtoType.BODY in transformers && transformers[dtoType_enum.EApiDtoType.BODY]) {
for (const transformer of transformers[dtoType_enum.EApiDtoType.BODY]) {
if (objectToTransform.body)
processTransformer(transformer, objectToTransform.body, properties, data);
}
}
if (dtoType_enum.EApiDtoType.QUERY in transformers && transformers[dtoType_enum.EApiDtoType.QUERY]) {
for (const transformer of transformers[dtoType_enum.EApiDtoType.QUERY]) {
if (objectToTransform.query)
processTransformer(transformer, objectToTransform.query, properties, data);
}
}
if (dtoType_enum.EApiDtoType.REQUEST in transformers && transformers[dtoType_enum.EApiDtoType.REQUEST]) {
for (const transformer of transformers[dtoType_enum.EApiDtoType.REQUEST]) {
if (objectToTransform.parameters)
processTransformer(transformer, objectToTransform.parameters, properties, data);
}
}
if (dtoType_enum.EApiDtoType.RESPONSE in transformers && transformers[dtoType_enum.EApiDtoType.RESPONSE]) {
for (const transformer of transformers[dtoType_enum.EApiDtoType.RESPONSE]) {
if (objectToTransform.response)
processTransformer(transformer, objectToTransform.response, properties, data);
}
}
}
/**
* Handles transformation of object properties, setting values with appropriate type handling.
* @param {TApiTransformDataIsValidationProperties<E>} object - The object to transform
* @param {keyof E | keyof IApiGetListResponseResult<E> | keyof TApiControllerGetListQuery<E>} key - The property key
* @param {unknown} value - The value to set
* @param {IApiBaseEntity} entity - The entity metadata
* @param {boolean} [shouldSetValueEvenIfMissing] - Whether to set the value even if the key is missing
* @returns {void}
* @throws {InternalServerErrorException} When key not found in object and not forced
* @private
*/
function handleTransformation(object, key, value, entity, shouldSetValueEvenIfMissing = false) {
if (isApiGetListResponseResult(object)) {
if (key in object) {
object[key] = value;
}
}
else if (isApiFunctionGetListProperties(object)) {
if (key in object) {
object[key] = value;
}
}
else if (isPartialE(object) && key in object) {
object[key] = value;
}
else if (shouldSetValueEvenIfMissing) {
object[key] = value;
}
else {
throw new common.InternalServerErrorException(errorString_utility.ErrorString({
entity,
type: action_enum.EErrorStringAction.KEY_FOR_TRANSFORM_NOT_IN_OBJECT,
}));
}
}
/**
* Checks if an object is a get list query properties instance.
* @param {TApiTransformDataIsValidationProperties<E>} object - The object to check
* @returns {boolean} True if the object is a get list query object
* @private
*/
function isApiFunctionGetListProperties(object) {
return "limit" in object && "page" in object;
}
/**
* Checks if an object is a get list response result instance.
* @param {TApiTransformDataIsValidationProperties<E>} object - The object to check
* @returns {boolean} True if the object is a get list response result
* @private
*/
function isApiGetListResponseResult(object) {
return "items" in object && "totalCount" in object;
}
/**
* Checks if an object is a partial entity instance.
* @param {TApiTransformDataIsValidationProperties<E>} object - The object to check
* @returns {boolean} True if the object is a partial entity
* @private
*/
function isPartialE(object) {
return !isApiGetListResponseResult(object) && !isApiFunctionGetListProperties(object);
}
/**
* Processes a single transformer, applying the transformation to the object.
* Handles both static and dynamic transformations including special values like user, IP, and headers.
* @param {TApiRequestTransformer<E>} transformer - The transformer configuration
* @param {TApiTransformDataIsValidationProperties<E>} objectToTransform - The object to transform
* @param {IApiControllerProperties<E>} properties - Controller configuration properties
* @param {TApiControllerTransformDataData} data - The data sources for transformation
* @returns {void}
* @throws {InternalServerErrorException} When required data for transformation is missing
* @private
*/
function processTransformer(transformer, objectToTransform, properties, data) {
switch (transformer.type) {
case requestTransformerType_enum.EApiControllerRequestTransformerType.DYNAMIC: {
if (Object.values(transformerValue_constant.TRANSFORMER_VALUE_DTO_CONSTANT).includes(transformer.value)) {
switch (transformer.value) {
case transformerValue_constant.TRANSFORMER_VALUE_DTO_CONSTANT.AUTHORIZED_ENTITY: {
if (!data.authenticationRequest) {
throw new common.InternalServerErrorException(errorString_utility.ErrorString({
entity: properties.entity,
type: action_enum.EErrorStringAction.AUTHORIZED_ENTITY_NOT_FOUND,
}));
}
handleTransformation(objectToTransform, transformer.key, data.authenticationRequest.user, properties.entity, transformer.shouldSetValueEvenIfMissing);
break;
}
case transformerValue_constant.TRANSFORMER_VALUE_DTO_CONSTANT.REQUEST_IP: {
handleTransformation(objectToTransform, transformer.key, data.ip, properties.entity, transformer.shouldSetValueEvenIfMissing);
break;
}
case transformerValue_constant.TRANSFORMER_VALUE_DTO_CONSTANT.REQUEST_SIGNATURE: {
if (!data.headers["x-signature"]) {
throw new common.InternalServerErrorException(errorString_utility.ErrorString({
entity: properties.entity,
type: action_enum.EErrorStringAction.REQUEST_SIGNATURE_NOT_FOUND,
}));
}
handleTransformation(objectToTransform, transformer.key, data.headers["x-signature"], properties.entity, transformer.shouldSetValueEvenIfMissing);
break;
}
case transformerValue_constant.TRANSFORMER_VALUE_DTO_CONSTANT.REQUEST_TIMESTAMP: {
if (!data.headers["x-timestamp"]) {
throw new common.InternalServerErrorException(errorString_utility.ErrorString({
entity: properties.entity,
type: action_enum.EErrorStringAction.REQUEST_TIMESTAMP_NOT_FOUND,
}));
}
handleTransformation(objectToTransform, transformer.key, data.headers["x-timestamp"], properties.entity, transformer.shouldSetValueEvenIfMissing);
break;
}
case transformerValue_constant.TRANSFORMER_VALUE_DTO_CONSTANT.REQUEST_USER_AGENT: {
if (!data.headers["user-agent"]) {
throw new common.InternalServerErrorException(errorString_utility.ErrorString({
entity: properties.entity,
type: action_enum.EErrorStringAction.REQUEST_USER_AGENT_NOT_FOUND,
}));
}
handleTransformation(objectToTransform, transformer.key, data.headers["user-agent"], properties.entity, transformer.shouldSetValueEvenIfMissing);
break;
}
default: {
throw new common.InternalServerErrorException(errorString_utility.ErrorString({
entity: properties.entity,
type: action_enum.EErrorStringAction.INVALID_DYNAMIC_VALUE_SPECIFIED,
}));
}
}
}
else {
throw new common.InternalServerErrorException(errorString_utility.ErrorString({
entity: properties.entity,
type: action_enum.EErrorStringAction.INVALID_DYNAMIC_VALUE_SPECIFIED,
}));
}
break;
}
case requestTransformerType_enum.EApiControllerRequestTransformerType.STATIC: {
const staticValue = transformer.value;
handleTransformation(objectToTransform, transformer.key, staticValue, properties.entity, transformer.shouldSetValueEvenIfMissing);
break;
}
}
}
exports.ApiControllerTransformData = ApiControllerTransformData;
//# sourceMappingURL=transform-data.utility.js.map