UNPKG

@elsikora/nestjs-crud-automator

Version:

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

89 lines (85 loc) 4.08 kB
'use strict'; var contextualManual_constant = require('../../../constant/dto/contextual-manual.constant.js'); var camelCaseString_utility = require('../../camel-case-string.utility.js'); var pop_utility = require('../auto/context/pop.utility.js'); var push_utility = require('../auto/context/push.utility.js'); var get_utility = require('../manual/property-metadata/get.utility.js'); const contextualManualDtoCache = new WeakMap(); /** * Generates a path-aware DTO wrapper for a nested manual DTO inside an auto-generated CRUD DTO. * The wrapper replays all original `ApiProperty*` decorators so Swagger, validation, and * class-transformer semantics remain intact while the schema name becomes context-specific. * @param {Type<unknown>} sourceDto - Source manual DTO class. * @param {EApiRouteType} method - Current auto DTO route method. * @param {EApiDtoType} dtoType - Current auto DTO type. * @param {string} parentDtoName - Parent generated DTO class name. * @param {string} propertyPathSegment - Current nested path segment to append. * @returns {Type<unknown>} Context-specific wrapper or the original class when replay metadata is unavailable. */ function DtoGenerateContextualManualDto(sourceDto, method, dtoType, parentDtoName, propertyPathSegment) { if (sourceDto === Object || IsContextualManualDto(sourceDto)) { return sourceDto; } const sourcePrototype = sourceDto.prototype; const propertyMetadata = get_utility.GetManualDtoPropertyMetadata(sourcePrototype); if (propertyMetadata.size === 0) { return sourceDto; } // eslint-disable-next-line @elsikora/typescript/no-magic-numbers const parentDtoNameBase = parentDtoName.endsWith("DTO") ? parentDtoName.slice(0, -3) : parentDtoName; const className = `${parentDtoNameBase}${camelCaseString_utility.CamelCaseString(propertyPathSegment)}DTO`; const cached = contextualManualDtoCache.get(sourceDto)?.get(className); if (cached) { return cached; } class GeneratedDTO { constructor() { for (const propertyKey of propertyMetadata.keys()) { Object.defineProperty(this, propertyKey, { // eslint-disable-next-line @elsikora/typescript/naming-convention configurable: true, // eslint-disable-next-line @elsikora/typescript/naming-convention enumerable: true, value: undefined, // eslint-disable-next-line @elsikora/typescript/naming-convention writable: true, }); } } } Object.defineProperty(GeneratedDTO, "name", { value: className, }); Reflect.defineMetadata?.(contextualManual_constant.CONTEXTUAL_MANUAL_DTO_CONSTANT.METADATA_KEY, { dtoType, method, source: sourceDto, }, GeneratedDTO); let dtoCache = contextualManualDtoCache.get(sourceDto); if (!dtoCache) { dtoCache = new Map(); contextualManualDtoCache.set(sourceDto, dtoCache); } dtoCache.set(className, GeneratedDTO); push_utility.DtoAutoContextPush(GeneratedDTO.prototype, method, dtoType); try { for (const [propertyKey, metadata] of propertyMetadata.entries()) { metadata.apply(GeneratedDTO.prototype, propertyKey); } } finally { pop_utility.DtoAutoContextPop(GeneratedDTO.prototype); } return GeneratedDTO; } /** * Returns whether a class was materialized as a context-specific wrapper around a manual DTO. * @param {unknown} value - Constructor candidate. * @returns {boolean} Whether the candidate is a generated contextual manual DTO. */ function IsContextualManualDto(value) { return typeof value === "function" && Boolean(Reflect.getMetadata?.(contextualManual_constant.CONTEXTUAL_MANUAL_DTO_CONSTANT.METADATA_KEY, value)); } exports.DtoGenerateContextualManualDto = DtoGenerateContextualManualDto; exports.IsContextualManualDto = IsContextualManualDto; //# sourceMappingURL=manual-child.utility.js.map