UNPKG

@elsikora/nestjs-crud-automator

Version:

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

121 lines (117 loc) 6.72 kB
'use strict'; var node_async_hooks = require('node:async_hooks'); var scopeWhereContract_class = require('./scope-where-contract.class.js'); var securitySnapshot_class = require('./security-snapshot.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/pagination-mode.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'); 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'); var type_enum = 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 scopeMergeWhere_utility = require('../../../../utility/authorization/scope-merge-where.utility.js'); var exception_utility = require('../../../../utility/error/exception.utility.js'); /** * Carries the final generated-route read predicate to exactly one decorated service call. * This is intentionally internal: direct service calls retain their ordinary subscriber contract. */ class ApiControllerGeneratedReadScopeStorage { static STORAGE = new node_async_hooks.AsyncLocalStorage(); static claim(functionType, input) { const entry = this.STORAGE.getStore(); if (entry?.functionType !== functionType || entry.input !== input) { return undefined; } if (entry.isClaimed) { throw exception_utility.ErrorException("Generated mandatory scope must be claimed exactly once"); } entry.isClaimed = true; return entry.where; } static isWriteHydration(functionType, input) { const entry = this.STORAGE.getStore(); return Boolean(entry?.isWriteHydration && entry.functionType === functionType && entry.input === input && entry.isClaimed); } static protect(properties, mandatoryWhere) { const whereDescriptor = Object.getOwnPropertyDescriptor(properties, "where"); if (whereDescriptor && (!whereDescriptor.enumerable || !("value" in whereDescriptor))) { throw exception_utility.ErrorException("Generated read function subscriber WHERE must be an enumerable data property"); } const protectedProperties = Object.create(Object.getPrototypeOf(properties)); for (const key of Reflect.ownKeys(properties)) { if (key === "cache" || key === "where") { continue; } const descriptor = Object.getOwnPropertyDescriptor(properties, key); if (descriptor) { Object.defineProperty(protectedProperties, key, descriptor); } } Object.defineProperty(protectedProperties, "cache", { // eslint-disable-next-line @elsikora/typescript/naming-convention configurable: true, // eslint-disable-next-line @elsikora/typescript/naming-convention enumerable: true, // eslint-disable-next-line @elsikora/typescript/naming-convention value: false, // eslint-disable-next-line @elsikora/typescript/naming-convention writable: true, }); Object.defineProperty(protectedProperties, "where", { // eslint-disable-next-line @elsikora/typescript/naming-convention configurable: true, // eslint-disable-next-line @elsikora/typescript/naming-convention enumerable: true, value: scopeWhereContract_class.ApiControllerGeneratedScopeWhereContract.merge(whereDescriptor && "value" in whereDescriptor ? whereDescriptor.value : undefined, mandatoryWhere), // eslint-disable-next-line @elsikora/typescript/naming-convention writable: true, }); return protectedProperties; } static run(functionType, input, where, callback) { return this.runWithEntry(functionType, input, where, callback, false); } static runWriteHydration(input, where, callback) { return this.runWithEntry(type_enum.EApiFunctionType.GET, input, where, callback, true); } static runWithEntry(functionType, input, where, callback, isWriteHydration) { const normalizedWhere = scopeMergeWhere_utility.AuthorizationScopeMergeWhere(undefined, securitySnapshot_class.ApiControllerGeneratedSecuritySnapshot.detach(where)); const entry = { functionType, input, isClaimed: false, isWriteHydration, where: normalizedWhere, }; return this.STORAGE.run(entry, async () => { const result = await callback(); if (!entry.isClaimed) { throw exception_utility.ErrorException("Generated service function did not claim its mandatory scope"); } return result; }); } } exports.ApiControllerGeneratedReadScopeStorage = ApiControllerGeneratedReadScopeStorage; //# sourceMappingURL=read-scope-storage.class.js.map