@elsikora/nestjs-crud-automator
Version:
A library for automating the creation of CRUD operations in NestJS.
112 lines (109 loc) • 6.42 kB
JavaScript
import { createHash } from 'node:crypto';
import '../../../constant/decorator/api/function.constant.js';
import { PROPERTY_DESCRIBE_DECORATOR_API_CONSTANT } from '../../../constant/decorator/api/property-describe.constant.js';
import '../../../enum/decorator/api/action.enum.js';
import '../../../enum/decorator/api/authentication-type.enum.js';
import '../../../enum/decorator/api/controller/get-list/query/filter/missing-behavior.enum.js';
import '../../../enum/decorator/api/controller/get-list/query/pagination-mode.enum.js';
import '../../../enum/decorator/api/controller/get-list/query/unlisted-fields.enum.js';
import '../../../enum/decorator/api/controller/relation-reference-shape.enum.js';
import '../../../enum/decorator/api/controller/request/target.enum.js';
import '../../../enum/decorator/api/controller/request/transformer-type.enum.js';
import '../../../enum/decorator/api/controller/response-target.enum.js';
import { EApiDtoType } from '../../../enum/decorator/api/dto-type.enum.js';
import '../../../enum/decorator/api/function/context-storage-kind.enum.js';
import '../../../enum/decorator/api/function/subscriber-transaction-expectation.enum.js';
import '../../../enum/decorator/api/function/transaction/event-status.enum.js';
import '../../../enum/decorator/api/function/transaction/failure-stage.enum.js';
import '../../../enum/decorator/api/function/transaction/mode.enum.js';
import '../../../enum/decorator/api/function/transaction/outcome.enum.js';
import '../../../enum/decorator/api/function/transaction/owner-kind.enum.js';
import '../../../enum/decorator/api/function/transaction/trace-type.enum.js';
import '../../../enum/decorator/api/function/type.enum.js';
import '../../../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 '../../../enum/decorator/api/route/subscriber-authorization-expectation.enum.js';
import { EApiRouteType } from '../../../enum/decorator/api/route/type.enum.js';
import { DtoBuildDecorator } from '../build-decorator.utility.js';
import { ErrorException } from '../../error/exception.utility.js';
import { Validate } from 'class-validator';
const NO_READ_PLAN = Object.freeze({});
const identityParametersDtoCache = new WeakMap();
/**
* Generates a PARAMETERS DTO for a GET identity alias and optional inherited read scope.
* @param {IApiEntity<E>} entityMetadata - Entity metadata supplying field decorators.
* @param {IApiControllerIdentityPlan} identityPlan - Compiled identity alias plan.
* @param {IApiControllerReadPlan} [readPlan] - Optional compiled owner-scope plan.
* @param {IApiControllerPropertiesRouteAutoDtoConfig} [dtoConfig] - Auto DTO validators.
* @param {Type<IAuthGuard>} [currentGuard] - Route authentication guard.
* @returns {Type<unknown>} Generated PARAMETERS DTO.
* @template E - Entity type.
*/
function DtoGenerateIdentityReadParameters(entityMetadata, identityPlan, readPlan, dtoConfig, currentGuard) {
let readPlanCache = identityParametersDtoCache.get(identityPlan);
if (!readPlanCache) {
readPlanCache = new WeakMap();
identityParametersDtoCache.set(identityPlan, readPlanCache);
}
const readPlanKey = readPlan ?? NO_READ_PLAN;
let guardCache = readPlanCache.get(readPlanKey);
if (!guardCache) {
guardCache = new Map();
readPlanCache.set(readPlanKey, guardCache);
}
let dtoConfigCache = guardCache.get(currentGuard);
if (!dtoConfigCache) {
dtoConfigCache = new Map();
guardCache.set(currentGuard, dtoConfigCache);
}
const cached = dtoConfigCache.get(dtoConfig);
if (cached) {
return cached;
}
const parameters = [{ field: identityPlan.field, parameter: identityPlan.parameter }, ...(readPlan?.parameters ?? [])];
class GeneratedIdentityReadParametersDTO {
constructor() {
for (const parameter of parameters) {
Object.defineProperty(this, parameter.parameter, {
// 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,
});
}
}
}
const combinedSignature = readPlan ? createHash("sha256").update(identityPlan.signature).update(":").update(readPlan.signature).digest("hex") : undefined;
const schemaName = readPlan ? `${identityPlan.controllerName}${entityMetadata.name ?? "UnknownResource"}GetParameters${combinedSignature}DTO` : identityPlan.schemaName;
Object.defineProperty(GeneratedIdentityReadParametersDTO, "name", { value: schemaName });
for (const parameter of parameters) {
const column = entityMetadata.columns.find((candidate) => String(candidate.name) === parameter.field);
const metadata = column?.metadata?.[PROPERTY_DESCRIBE_DECORATOR_API_CONSTANT.METADATA_KEY];
if (!column || !metadata) {
throw ErrorException(`Metadata for generated identity/read field ${parameter.field} not found`);
}
const decorators = DtoBuildDecorator(EApiRouteType.GET, metadata, entityMetadata, EApiDtoType.PARAMETERS, parameter.parameter, currentGuard);
if (decorators) {
for (const decorator of decorators) {
decorator(GeneratedIdentityReadParametersDTO.prototype, parameter.parameter);
}
}
}
if (dtoConfig?.validators) {
for (const validator of dtoConfig.validators) {
Validate(validator.constraintClass, validator.options)(GeneratedIdentityReadParametersDTO.prototype, "object");
}
}
dtoConfigCache.set(dtoConfig, GeneratedIdentityReadParametersDTO);
return GeneratedIdentityReadParametersDTO;
}
export { DtoGenerateIdentityReadParameters };
//# sourceMappingURL=identity-read-parameters.utility.js.map