Initial commit - Event Planner application

This commit is contained in:
mberlin
2026-03-18 14:55:56 -03:00
commit 86d779eb4d
7548 changed files with 1006324 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
import { Abstract, Type } from '@nestjs/common';
import { GetOrResolveOptions } from '@nestjs/common/interfaces';
import { Injector } from './injector';
import { InstanceLinksHost } from './instance-links-host';
import { ContextId } from './instance-wrapper';
import { Module } from './module';
export declare abstract class AbstractInstanceResolver {
protected abstract instanceLinksHost: InstanceLinksHost;
protected abstract injector: Injector;
protected abstract get<TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Function | string | symbol, options?: GetOrResolveOptions): TResult | Array<TResult>;
protected find<TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Abstract<TInput> | string | symbol, options: {
moduleId?: string;
each?: boolean;
}): TResult | Array<TResult>;
protected resolvePerContext<TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Abstract<TInput> | string | symbol, contextModule: Module, contextId: ContextId, options?: GetOrResolveOptions): Promise<TResult | Array<TResult>>;
}

View File

@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractInstanceResolver = void 0;
const common_1 = require("@nestjs/common");
const exceptions_1 = require("../errors/exceptions");
class AbstractInstanceResolver {
find(typeOrToken, options) {
const instanceLinkOrArray = this.instanceLinksHost.get(typeOrToken, options);
const pluckInstance = ({ wrapperRef }) => {
if (wrapperRef.scope === common_1.Scope.REQUEST ||
wrapperRef.scope === common_1.Scope.TRANSIENT ||
!wrapperRef.isDependencyTreeStatic()) {
throw new exceptions_1.InvalidClassScopeException(typeOrToken);
}
return wrapperRef.instance;
};
if (Array.isArray(instanceLinkOrArray)) {
return instanceLinkOrArray.map(pluckInstance);
}
return pluckInstance(instanceLinkOrArray);
}
async resolvePerContext(typeOrToken, contextModule, contextId, options) {
const instanceLinkOrArray = options?.strict
? this.instanceLinksHost.get(typeOrToken, {
moduleId: contextModule.id,
each: options.each,
})
: this.instanceLinksHost.get(typeOrToken, {
each: options?.each,
});
const pluckInstance = async (instanceLink) => {
const { wrapperRef, collection } = instanceLink;
if (wrapperRef.isDependencyTreeStatic() && !wrapperRef.isTransient) {
return wrapperRef.instance;
}
const ctorHost = wrapperRef.instance || { constructor: typeOrToken };
const instance = await this.injector.loadPerContext(ctorHost, wrapperRef.host, collection, contextId, wrapperRef);
if (!instance) {
throw new exceptions_1.UnknownElementException();
}
return instance;
};
if (Array.isArray(instanceLinkOrArray)) {
return Promise.all(instanceLinkOrArray.map(instanceLink => pluckInstance(instanceLink)));
}
return pluckInstance(instanceLinkOrArray);
}
}
exports.AbstractInstanceResolver = AbstractInstanceResolver;

18
node_modules/@nestjs/core/injector/compiler.d.ts generated vendored Normal file
View File

@@ -0,0 +1,18 @@
import { DynamicModule, ForwardReference, Type } from '@nestjs/common/interfaces';
import { ModuleOpaqueKeyFactory } from './opaque-key-factory/interfaces/module-opaque-key-factory.interface';
export interface ModuleFactory {
type: Type<any>;
token: string;
dynamicMetadata?: Partial<DynamicModule>;
}
export declare class ModuleCompiler {
private readonly _moduleOpaqueKeyFactory;
constructor(_moduleOpaqueKeyFactory: ModuleOpaqueKeyFactory);
get moduleOpaqueKeyFactory(): ModuleOpaqueKeyFactory;
compile(moduleClsOrDynamic: Type | DynamicModule | ForwardReference | Promise<DynamicModule>): Promise<ModuleFactory>;
extractMetadata(moduleClsOrDynamic: Type | ForwardReference | DynamicModule): {
type: Type;
dynamicMetadata: Omit<DynamicModule, 'module'> | undefined;
};
isDynamicModule(moduleClsOrDynamic: Type | DynamicModule | ForwardReference): moduleClsOrDynamic is DynamicModule;
}

35
node_modules/@nestjs/core/injector/compiler.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModuleCompiler = void 0;
class ModuleCompiler {
constructor(_moduleOpaqueKeyFactory) {
this._moduleOpaqueKeyFactory = _moduleOpaqueKeyFactory;
}
get moduleOpaqueKeyFactory() {
return this._moduleOpaqueKeyFactory;
}
async compile(moduleClsOrDynamic) {
moduleClsOrDynamic = await moduleClsOrDynamic;
const { type, dynamicMetadata } = this.extractMetadata(moduleClsOrDynamic);
const token = dynamicMetadata
? this._moduleOpaqueKeyFactory.createForDynamic(type, dynamicMetadata, moduleClsOrDynamic)
: this._moduleOpaqueKeyFactory.createForStatic(type, moduleClsOrDynamic);
return { type, dynamicMetadata, token };
}
extractMetadata(moduleClsOrDynamic) {
if (!this.isDynamicModule(moduleClsOrDynamic)) {
return {
type: moduleClsOrDynamic?.forwardRef
? moduleClsOrDynamic.forwardRef()
: moduleClsOrDynamic,
dynamicMetadata: undefined,
};
}
const { module: type, ...dynamicMetadata } = moduleClsOrDynamic;
return { type, dynamicMetadata };
}
isDynamicModule(moduleClsOrDynamic) {
return !!moduleClsOrDynamic.module;
}
}
exports.ModuleCompiler = ModuleCompiler;

3
node_modules/@nestjs/core/injector/constants.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import { ContextId } from './instance-wrapper';
export declare const CONTROLLER_ID_KEY = "CONTROLLER_ID";
export declare const STATIC_CONTEXT: ContextId;

8
node_modules/@nestjs/core/injector/constants.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.STATIC_CONTEXT = exports.CONTROLLER_ID_KEY = void 0;
exports.CONTROLLER_ID_KEY = 'CONTROLLER_ID';
const STATIC_CONTEXT_ID = 1;
exports.STATIC_CONTEXT = Object.freeze({
id: STATIC_CONTEXT_ID,
});

67
node_modules/@nestjs/core/injector/container.d.ts generated vendored Normal file
View File

@@ -0,0 +1,67 @@
import { DynamicModule, Provider } from '@nestjs/common';
import { EnhancerSubtype } from '@nestjs/common/constants';
import { Injectable, Type } from '@nestjs/common/interfaces';
import { NestApplicationContextOptions } from '@nestjs/common/interfaces/nest-application-context-options.interface';
import { ApplicationConfig } from '../application-config';
import { SerializedGraph } from '../inspector/serialized-graph';
import { ModuleCompiler } from './compiler';
import { ContextId } from './instance-wrapper';
import { Module } from './module';
import { ModulesContainer } from './modules-container';
import { ModuleOpaqueKeyFactory } from './opaque-key-factory/interfaces/module-opaque-key-factory.interface';
type ModuleMetatype = Type<any> | DynamicModule | Promise<DynamicModule>;
type ModuleScope = Type<any>[];
export declare class NestContainer {
private readonly _applicationConfig;
private readonly _contextOptions;
private readonly globalModules;
private readonly modules;
private readonly dynamicModulesMetadata;
private readonly internalProvidersStorage;
private readonly _serializedGraph;
private moduleCompiler;
private internalCoreModule;
constructor(_applicationConfig?: ApplicationConfig | undefined, _contextOptions?: NestApplicationContextOptions | undefined);
get serializedGraph(): SerializedGraph;
get applicationConfig(): ApplicationConfig | undefined;
get contextOptions(): NestApplicationContextOptions | undefined;
setHttpAdapter(httpAdapter: any): void;
getHttpAdapterRef(): import("..").AbstractHttpAdapter<any, any, any>;
getHttpAdapterHostRef(): import("..").HttpAdapterHost<import("..").AbstractHttpAdapter<any, any, any>>;
addModule(metatype: ModuleMetatype, scope: ModuleScope): Promise<{
moduleRef: Module;
inserted: boolean;
} | undefined>;
replaceModule(metatypeToReplace: ModuleMetatype, newMetatype: ModuleMetatype, scope: ModuleScope): Promise<{
moduleRef: Module;
inserted: boolean;
} | undefined>;
private setModule;
addDynamicMetadata(token: string, dynamicModuleMetadata: Partial<DynamicModule>, scope: Type<any>[]): Promise<void>;
addDynamicModules(modules: any[], scope: Type<any>[]): Promise<void>;
isGlobalModule(metatype: Type<any>, dynamicMetadata?: Partial<DynamicModule>): boolean;
addGlobalModule(module: Module): void;
getModules(): ModulesContainer;
getModuleCompiler(): ModuleCompiler;
getModuleByKey(moduleKey: string): Module | undefined;
getInternalCoreModuleRef(): Module | undefined;
addImport(relatedModule: Type<any> | DynamicModule, token: string): Promise<void>;
addProvider(provider: Provider, token: string, enhancerSubtype?: EnhancerSubtype): string | symbol | Function;
addInjectable(injectable: Provider, token: string, enhancerSubtype: EnhancerSubtype, host?: Type<Injectable>): string | symbol | Function | import("./instance-wrapper").InstanceWrapper<unknown>;
addExportedProviderOrModule(toExport: Type<any> | DynamicModule, token: string): void;
addController(controller: Type<any>, token: string): void;
clear(): void;
replace(toReplace: any, options: {
scope: any[] | null;
}): void;
bindGlobalScope(): void;
bindGlobalsToImports(moduleRef: Module): void;
bindGlobalModuleToModule(target: Module, globalModule: Module): void;
getDynamicMetadataByToken(token: string): Partial<DynamicModule>;
getDynamicMetadataByToken<K extends Exclude<keyof DynamicModule, 'global' | 'module'>>(token: string, metadataKey: K): DynamicModule[K];
registerCoreModuleRef(moduleRef: Module): void;
getModuleTokenFactory(): ModuleOpaqueKeyFactory;
registerRequestProvider<T = any>(request: T, contextId: ContextId): void;
private shouldInitOnPreview;
}
export {};

233
node_modules/@nestjs/core/injector/container.js generated vendored Normal file
View File

@@ -0,0 +1,233 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NestContainer = void 0;
const constants_1 = require("@nestjs/common/constants");
const discoverable_meta_host_collection_1 = require("../discovery/discoverable-meta-host-collection");
const exceptions_1 = require("../errors/exceptions");
const initialize_on_preview_allowlist_1 = require("../inspector/initialize-on-preview.allowlist");
const serialized_graph_1 = require("../inspector/serialized-graph");
const request_constants_1 = require("../router/request/request-constants");
const compiler_1 = require("./compiler");
const internal_core_module_1 = require("./internal-core-module/internal-core-module");
const internal_providers_storage_1 = require("./internal-providers-storage");
const module_1 = require("./module");
const modules_container_1 = require("./modules-container");
const by_reference_module_opaque_key_factory_1 = require("./opaque-key-factory/by-reference-module-opaque-key-factory");
const deep_hashed_module_opaque_key_factory_1 = require("./opaque-key-factory/deep-hashed-module-opaque-key-factory");
class NestContainer {
constructor(_applicationConfig = undefined, _contextOptions = undefined) {
this._applicationConfig = _applicationConfig;
this._contextOptions = _contextOptions;
this.globalModules = new Set();
this.modules = new modules_container_1.ModulesContainer();
this.dynamicModulesMetadata = new Map();
this.internalProvidersStorage = new internal_providers_storage_1.InternalProvidersStorage();
this._serializedGraph = new serialized_graph_1.SerializedGraph();
const moduleOpaqueKeyFactory = this._contextOptions?.moduleIdGeneratorAlgorithm === 'deep-hash'
? new deep_hashed_module_opaque_key_factory_1.DeepHashedModuleOpaqueKeyFactory()
: new by_reference_module_opaque_key_factory_1.ByReferenceModuleOpaqueKeyFactory({
keyGenerationStrategy: this._contextOptions?.snapshot
? 'shallow'
: 'random',
});
this.moduleCompiler = new compiler_1.ModuleCompiler(moduleOpaqueKeyFactory);
}
get serializedGraph() {
return this._serializedGraph;
}
get applicationConfig() {
return this._applicationConfig;
}
get contextOptions() {
return this._contextOptions;
}
setHttpAdapter(httpAdapter) {
this.internalProvidersStorage.httpAdapter = httpAdapter;
if (!this.internalProvidersStorage.httpAdapterHost) {
return;
}
const host = this.internalProvidersStorage.httpAdapterHost;
host.httpAdapter = httpAdapter;
}
getHttpAdapterRef() {
return this.internalProvidersStorage.httpAdapter;
}
getHttpAdapterHostRef() {
return this.internalProvidersStorage.httpAdapterHost;
}
async addModule(metatype, scope) {
// In DependenciesScanner#scanForModules we already check for undefined or invalid modules
// We still need to catch the edge-case of `forwardRef(() => undefined)`
if (!metatype) {
throw new exceptions_1.UndefinedForwardRefException(scope);
}
const { type, dynamicMetadata, token } = await this.moduleCompiler.compile(metatype);
if (this.modules.has(token)) {
return {
moduleRef: this.modules.get(token),
inserted: true,
};
}
return {
moduleRef: await this.setModule({
token,
type,
dynamicMetadata,
}, scope),
inserted: true,
};
}
async replaceModule(metatypeToReplace, newMetatype, scope) {
// In DependenciesScanner#scanForModules we already check for undefined or invalid modules
// We still need to catch the edge-case of `forwardRef(() => undefined)`
if (!metatypeToReplace || !newMetatype) {
throw new exceptions_1.UndefinedForwardRefException(scope);
}
const { token } = await this.moduleCompiler.compile(metatypeToReplace);
const { type, dynamicMetadata } = await this.moduleCompiler.compile(newMetatype);
return {
moduleRef: await this.setModule({
token,
type,
dynamicMetadata,
}, scope),
inserted: false,
};
}
async setModule({ token, dynamicMetadata, type }, scope) {
const moduleRef = new module_1.Module(type, this);
moduleRef.token = token;
moduleRef.initOnPreview = this.shouldInitOnPreview(type);
this.modules.set(token, moduleRef);
const updatedScope = [].concat(scope, type);
await this.addDynamicMetadata(token, dynamicMetadata, updatedScope);
if (this.isGlobalModule(type, dynamicMetadata)) {
moduleRef.isGlobal = true;
// Set global module distance to MAX_VALUE to ensure their lifecycle hooks
// are always executed first (when initializing the application)
moduleRef.distance = Number.MAX_VALUE;
this.addGlobalModule(moduleRef);
}
return moduleRef;
}
async addDynamicMetadata(token, dynamicModuleMetadata, scope) {
if (!dynamicModuleMetadata) {
return;
}
this.dynamicModulesMetadata.set(token, dynamicModuleMetadata);
const { imports } = dynamicModuleMetadata;
await this.addDynamicModules(imports, scope);
}
async addDynamicModules(modules, scope) {
if (!modules) {
return;
}
await Promise.all(modules.map(module => this.addModule(module, scope)));
}
isGlobalModule(metatype, dynamicMetadata) {
if (dynamicMetadata && dynamicMetadata.global) {
return true;
}
return !!Reflect.getMetadata(constants_1.GLOBAL_MODULE_METADATA, metatype);
}
addGlobalModule(module) {
this.globalModules.add(module);
}
getModules() {
return this.modules;
}
getModuleCompiler() {
return this.moduleCompiler;
}
getModuleByKey(moduleKey) {
return this.modules.get(moduleKey);
}
getInternalCoreModuleRef() {
return this.internalCoreModule;
}
async addImport(relatedModule, token) {
if (!this.modules.has(token)) {
return;
}
const moduleRef = this.modules.get(token);
const { token: relatedModuleToken } = await this.moduleCompiler.compile(relatedModule);
const related = this.modules.get(relatedModuleToken);
moduleRef.addImport(related);
}
addProvider(provider, token, enhancerSubtype) {
const moduleRef = this.modules.get(token);
if (!provider) {
throw new exceptions_1.CircularDependencyException(moduleRef?.metatype.name);
}
if (!moduleRef) {
throw new exceptions_1.UnknownModuleException();
}
const providerKey = moduleRef.addProvider(provider, enhancerSubtype);
const providerRef = moduleRef.getProviderByKey(providerKey);
discoverable_meta_host_collection_1.DiscoverableMetaHostCollection.inspectProvider(this.modules, providerRef);
return providerKey;
}
addInjectable(injectable, token, enhancerSubtype, host) {
if (!this.modules.has(token)) {
throw new exceptions_1.UnknownModuleException();
}
const moduleRef = this.modules.get(token);
return moduleRef.addInjectable(injectable, enhancerSubtype, host);
}
addExportedProviderOrModule(toExport, token) {
if (!this.modules.has(token)) {
throw new exceptions_1.UnknownModuleException();
}
const moduleRef = this.modules.get(token);
moduleRef.addExportedProviderOrModule(toExport);
}
addController(controller, token) {
if (!this.modules.has(token)) {
throw new exceptions_1.UnknownModuleException();
}
const moduleRef = this.modules.get(token);
moduleRef.addController(controller);
const controllerRef = moduleRef.controllers.get(controller);
discoverable_meta_host_collection_1.DiscoverableMetaHostCollection.inspectController(this.modules, controllerRef);
}
clear() {
this.modules.clear();
}
replace(toReplace, options) {
this.modules.forEach(moduleRef => moduleRef.replace(toReplace, options));
}
bindGlobalScope() {
this.modules.forEach(moduleRef => this.bindGlobalsToImports(moduleRef));
}
bindGlobalsToImports(moduleRef) {
this.globalModules.forEach(globalModule => this.bindGlobalModuleToModule(moduleRef, globalModule));
}
bindGlobalModuleToModule(target, globalModule) {
if (target === globalModule || target === this.internalCoreModule) {
return;
}
target.addImport(globalModule);
}
getDynamicMetadataByToken(token, metadataKey) {
const metadata = this.dynamicModulesMetadata.get(token);
return metadataKey ? (metadata?.[metadataKey] ?? []) : metadata;
}
registerCoreModuleRef(moduleRef) {
this.internalCoreModule = moduleRef;
this.modules[internal_core_module_1.InternalCoreModule.name] = moduleRef;
}
getModuleTokenFactory() {
return this.moduleCompiler.moduleOpaqueKeyFactory;
}
registerRequestProvider(request, contextId) {
const wrapper = this.internalCoreModule.getProviderByKey(request_constants_1.REQUEST);
wrapper.setInstanceByContextId(contextId, {
instance: request,
isResolved: true,
});
}
shouldInitOnPreview(type) {
return initialize_on_preview_allowlist_1.InitializeOnPreviewAllowlist.has(type);
}
}
exports.NestContainer = NestContainer;

View File

@@ -0,0 +1,4 @@
import { ClassProvider, FactoryProvider, Provider, ValueProvider } from '@nestjs/common';
export declare function isClassProvider<T = any>(provider: Provider): provider is ClassProvider<T>;
export declare function isValueProvider<T = any>(provider: Provider): provider is ValueProvider<T>;
export declare function isFactoryProvider<T = any>(provider: Provider): provider is FactoryProvider<T>;

View File

@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isClassProvider = isClassProvider;
exports.isValueProvider = isValueProvider;
exports.isFactoryProvider = isFactoryProvider;
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
function isClassProvider(provider) {
return Boolean(provider?.useClass);
}
function isValueProvider(provider) {
const providerValue = provider?.useValue;
return !(0, shared_utils_1.isUndefined)(providerValue);
}
function isFactoryProvider(provider) {
return Boolean(provider.useFactory);
}

View File

@@ -0,0 +1,10 @@
import { Logger } from '@nestjs/common';
export declare class SilentLogger extends Logger {
log: () => void;
error: () => void;
warn: () => void;
debug: () => void;
verbose: () => void;
fatal: () => void;
setLogLevels: () => void;
}

View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SilentLogger = void 0;
const common_1 = require("@nestjs/common");
const noop = () => { };
class SilentLogger extends common_1.Logger {
constructor() {
super(...arguments);
this.log = noop;
this.error = noop;
this.warn = noop;
this.debug = noop;
this.verbose = noop;
this.fatal = noop;
this.setLogLevels = noop;
}
}
exports.SilentLogger = SilentLogger;

View File

@@ -0,0 +1,12 @@
import { InjectionToken } from '@nestjs/common';
import { InstanceWrapper } from '../instance-wrapper';
/**
* Returns the instances which are transient
* @param instances The instances which should be checked whether they are transient
*/
export declare function getTransientInstances(instances: [InjectionToken, InstanceWrapper][]): InstanceWrapper[];
/**
* Returns the instances which are not transient
* @param instances The instances which should be checked whether they are transient
*/
export declare function getNonTransientInstances(instances: [InjectionToken, InstanceWrapper][]): InstanceWrapper[];

View File

@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTransientInstances = getTransientInstances;
exports.getNonTransientInstances = getNonTransientInstances;
const iterare_1 = require("iterare");
/**
* Returns the instances which are transient
* @param instances The instances which should be checked whether they are transient
*/
function getTransientInstances(instances) {
return (0, iterare_1.iterate)(instances)
.filter(([_, wrapper]) => wrapper.isDependencyTreeStatic())
.map(([_, wrapper]) => wrapper.getStaticTransientInstances())
.flatten()
.filter(item => !!item)
.map(({ instance }) => instance)
.toArray();
}
/**
* Returns the instances which are not transient
* @param instances The instances which should be checked whether they are transient
*/
function getNonTransientInstances(instances) {
return (0, iterare_1.iterate)(instances)
.filter(([key, wrapper]) => wrapper.isDependencyTreeStatic() && !wrapper.isTransient)
.map(([key, { instance }]) => instance)
.toArray();
}

6
node_modules/@nestjs/core/injector/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,6 @@
export * from './container';
export * from './inquirer';
export { ContextId, HostComponentInfo } from './instance-wrapper';
export * from './lazy-module-loader/lazy-module-loader';
export * from './module-ref';
export * from './modules-container';

8
node_modules/@nestjs/core/injector/index.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./container"), exports);
tslib_1.__exportStar(require("./inquirer"), exports);
tslib_1.__exportStar(require("./lazy-module-loader/lazy-module-loader"), exports);
tslib_1.__exportStar(require("./module-ref"), exports);
tslib_1.__exportStar(require("./modules-container"), exports);

104
node_modules/@nestjs/core/injector/injector.d.ts generated vendored Normal file
View File

@@ -0,0 +1,104 @@
import { InjectionToken } from '@nestjs/common';
import { Controller, ForwardReference, Injectable, Type } from '@nestjs/common/interfaces';
import { ContextId, InstancePerContext, InstanceWrapper, PropertyMetadata } from './instance-wrapper';
import { Module } from './module';
import { SettlementSignal } from './settlement-signal';
/**
* The type of an injectable dependency
*/
export type InjectorDependency = InjectionToken;
/**
* The property-based dependency
*/
export interface PropertyDependency {
key: symbol | string;
name: InjectorDependency;
isOptional?: boolean;
instance?: any;
}
/**
* Context of a dependency which gets injected by
* the injector
*/
export interface InjectorDependencyContext {
/**
* The name of the property key (property-based injection)
*/
key?: string | symbol;
/**
* The function itself, the name of the function, or injection token.
*/
name?: Function | string | symbol;
/**
* The index of the dependency which gets injected
* from the dependencies array
*/
index?: number;
/**
* The dependency array which gets injected
*/
dependencies?: InjectorDependency[];
}
export declare class Injector {
private readonly options?;
private logger;
private readonly instanceDecorator;
constructor(options?: {
/**
* Whether to enable preview mode.
*/
preview: boolean;
/**
* Function to decorate a freshly created instance.
*/
instanceDecorator?: (target: unknown) => unknown;
} | undefined);
loadPrototype<T>({ token }: InstanceWrapper<T>, collection: Map<InjectionToken, InstanceWrapper<T>>, contextId?: ContextId): void;
loadInstance<T>(wrapper: InstanceWrapper<T>, collection: Map<InjectionToken, InstanceWrapper>, moduleRef: Module, contextId?: ContextId, inquirer?: InstanceWrapper): Promise<void>;
loadMiddleware(wrapper: InstanceWrapper, collection: Map<InjectionToken, InstanceWrapper>, moduleRef: Module, contextId?: ContextId, inquirer?: InstanceWrapper): Promise<void>;
loadController(wrapper: InstanceWrapper<Controller>, moduleRef: Module, contextId?: ContextId): Promise<void>;
loadInjectable<T = any>(wrapper: InstanceWrapper<T>, moduleRef: Module, contextId?: ContextId, inquirer?: InstanceWrapper): Promise<void>;
loadProvider(wrapper: InstanceWrapper<Injectable>, moduleRef: Module, contextId?: ContextId, inquirer?: InstanceWrapper): Promise<void>;
applySettlementSignal<T>(instancePerContext: InstancePerContext<T>, host: InstanceWrapper<T>): SettlementSignal;
resolveConstructorParams<T>(wrapper: InstanceWrapper<T>, moduleRef: Module, inject: InjectorDependency[] | undefined, callback: (args: unknown[]) => void | Promise<void>, contextId?: ContextId, inquirer?: InstanceWrapper, parentInquirer?: InstanceWrapper): Promise<void>;
getClassDependencies<T>(wrapper: InstanceWrapper<T>): [InjectorDependency[], number[]];
getFactoryProviderDependencies<T>(wrapper: InstanceWrapper<T>): [InjectorDependency[], number[]];
reflectConstructorParams<T>(type: Type<T>): any[];
reflectOptionalParams<T>(type: Type<T>): any[];
reflectSelfParams<T>(type: Type<T>): any[];
resolveSingleParam<T>(wrapper: InstanceWrapper<T>, param: Type<any> | string | symbol, dependencyContext: InjectorDependencyContext, moduleRef: Module, contextId?: ContextId, inquirer?: InstanceWrapper, keyOrIndex?: symbol | string | number): Promise<InstanceWrapper<any>>;
resolveParamToken<T>(wrapper: InstanceWrapper<T>, param: Type<any> | string | symbol | ForwardReference): any;
resolveComponentWrapper<T>(moduleRef: Module, token: InjectionToken, dependencyContext: InjectorDependencyContext, wrapper: InstanceWrapper<T>, contextId?: ContextId, inquirer?: InstanceWrapper, keyOrIndex?: symbol | string | number): Promise<InstanceWrapper>;
resolveComponentHost<T>(moduleRef: Module, instanceWrapper: InstanceWrapper<T | Promise<T>>, contextId?: ContextId, inquirer?: InstanceWrapper): Promise<InstanceWrapper>;
lookupComponent<T = any>(providers: Map<Function | string | symbol, InstanceWrapper>, moduleRef: Module, dependencyContext: InjectorDependencyContext, wrapper: InstanceWrapper<T>, contextId?: ContextId, inquirer?: InstanceWrapper, keyOrIndex?: symbol | string | number): Promise<InstanceWrapper<T>>;
lookupComponentInParentModules<T = any>(dependencyContext: InjectorDependencyContext, moduleRef: Module, wrapper: InstanceWrapper<T>, contextId?: ContextId, inquirer?: InstanceWrapper, keyOrIndex?: symbol | string | number): Promise<any>;
lookupComponentInImports(moduleRef: Module, name: InjectionToken, wrapper: InstanceWrapper, moduleRegistry?: Set<string>, contextId?: ContextId, inquirer?: InstanceWrapper, keyOrIndex?: symbol | string | number, isTraversing?: boolean): Promise<any>;
resolveProperties<T>(wrapper: InstanceWrapper<T>, moduleRef: Module, inject?: InjectorDependency[], contextId?: ContextId, inquirer?: InstanceWrapper, parentInquirer?: InstanceWrapper): Promise<PropertyDependency[]>;
reflectProperties<T>(type: Type<T>): PropertyDependency[];
applyProperties<T = any>(instance: T, properties: PropertyDependency[]): void;
instantiateClass<T = any>(instances: any[], wrapper: InstanceWrapper, targetMetatype: InstanceWrapper, contextId?: ContextId, inquirer?: InstanceWrapper): Promise<T>;
loadPerContext<T = any>(instance: T, moduleRef: Module, collection: Map<InjectionToken, InstanceWrapper>, ctx: ContextId, wrapper?: InstanceWrapper): Promise<T>;
loadEnhancersPerContext(wrapper: InstanceWrapper, ctx: ContextId, inquirer?: InstanceWrapper): Promise<void>;
loadCtorMetadata(metadata: InstanceWrapper<any>[], contextId: ContextId, inquirer?: InstanceWrapper, parentInquirer?: InstanceWrapper): Promise<any[]>;
loadPropertiesMetadata(metadata: PropertyMetadata[], contextId: ContextId, inquirer?: InstanceWrapper): Promise<PropertyDependency[]>;
private getInquirerId;
/**
* For nested TRANSIENT dependencies (TRANSIENT -> TRANSIENT) in non-static contexts,
* returns parentInquirer to ensure each parent TRANSIENT gets its own instance.
* This is necessary because in REQUEST/DURABLE scopes, the same TRANSIENT wrapper
* can be used by multiple parents, causing nested TRANSIENTs to be shared incorrectly.
* For non-TRANSIENT -> TRANSIENT, returns inquirer (current wrapper being created).
*/
private getEffectiveInquirer;
private resolveScopedComponentHost;
private isInquirerRequest;
private isInquirer;
protected addDependencyMetadata(keyOrIndex: symbol | string | number, hostWrapper: InstanceWrapper, instanceWrapper: InstanceWrapper): void;
private getTokenName;
private printResolvingDependenciesLog;
private printLookingForProviderLog;
private printFoundInModuleLog;
private isDebugMode;
private getContextId;
private getNowTimestamp;
}

554
node_modules/@nestjs/core/injector/injector.js generated vendored Normal file
View File

@@ -0,0 +1,554 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Injector = void 0;
const common_1 = require("@nestjs/common");
const constants_1 = require("@nestjs/common/constants");
const cli_colors_util_1 = require("@nestjs/common/utils/cli-colors.util");
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
const iterare_1 = require("iterare");
const perf_hooks_1 = require("perf_hooks");
const exceptions_1 = require("../errors/exceptions");
const runtime_exception_1 = require("../errors/exceptions/runtime.exception");
const undefined_dependency_exception_1 = require("../errors/exceptions/undefined-dependency.exception");
const unknown_dependencies_exception_1 = require("../errors/exceptions/unknown-dependencies.exception");
const barrier_1 = require("../helpers/barrier");
const constants_2 = require("./constants");
const inquirer_1 = require("./inquirer");
const instance_wrapper_1 = require("./instance-wrapper");
const settlement_signal_1 = require("./settlement-signal");
class Injector {
constructor(options) {
this.options = options;
this.logger = new common_1.Logger('InjectorLogger');
this.instanceDecorator = (target) => target;
if (options?.instanceDecorator) {
this.instanceDecorator = options.instanceDecorator;
}
}
loadPrototype({ token }, collection, contextId = constants_2.STATIC_CONTEXT) {
if (!collection) {
return;
}
const target = collection.get(token);
const instance = target.createPrototype(contextId);
if (instance) {
const wrapper = new instance_wrapper_1.InstanceWrapper({
...target,
instance,
});
collection.set(token, wrapper);
}
}
async loadInstance(wrapper, collection, moduleRef, contextId = constants_2.STATIC_CONTEXT, inquirer) {
const inquirerId = this.getInquirerId(inquirer);
const instanceHost = wrapper.getInstanceByContextId(this.getContextId(contextId, wrapper), inquirerId);
if (instanceHost.isPending) {
const settlementSignal = wrapper.settlementSignal;
if (inquirer && settlementSignal?.isCycle(inquirer.id)) {
throw new exceptions_1.CircularDependencyException(`"${wrapper.name}"`);
}
return instanceHost.donePromise.then((err) => {
if (err) {
throw err;
}
});
}
const settlementSignal = this.applySettlementSignal(instanceHost, wrapper);
const token = wrapper.token || wrapper.name;
const { inject } = wrapper;
const targetWrapper = collection.get(token);
if ((0, shared_utils_1.isUndefined)(targetWrapper)) {
throw new runtime_exception_1.RuntimeException();
}
if (instanceHost.isResolved) {
return settlementSignal.complete();
}
try {
const t0 = this.getNowTimestamp();
const callback = async (instances) => {
const properties = await this.resolveProperties(wrapper, moduleRef, inject, contextId, wrapper, inquirer);
const instance = await this.instantiateClass(instances, wrapper, targetWrapper, contextId, inquirer);
this.applyProperties(instance, properties);
wrapper.initTime = this.getNowTimestamp() - t0;
settlementSignal.complete();
};
await this.resolveConstructorParams(wrapper, moduleRef, inject, callback, contextId, wrapper, inquirer);
}
catch (err) {
wrapper.removeInstanceByContextId(this.getContextId(contextId, wrapper), inquirerId);
settlementSignal.error(err);
throw err;
}
}
async loadMiddleware(wrapper, collection, moduleRef, contextId = constants_2.STATIC_CONTEXT, inquirer) {
const { metatype, token } = wrapper;
const targetWrapper = collection.get(token);
if (!(0, shared_utils_1.isUndefined)(targetWrapper.instance)) {
return;
}
targetWrapper.instance = Object.create(metatype.prototype);
await this.loadInstance(wrapper, collection, moduleRef, contextId, inquirer || wrapper);
}
async loadController(wrapper, moduleRef, contextId = constants_2.STATIC_CONTEXT) {
const controllers = moduleRef.controllers;
await this.loadInstance(wrapper, controllers, moduleRef, contextId, wrapper);
await this.loadEnhancersPerContext(wrapper, contextId, wrapper);
}
async loadInjectable(wrapper, moduleRef, contextId = constants_2.STATIC_CONTEXT, inquirer) {
const injectables = moduleRef.injectables;
await this.loadInstance(wrapper, injectables, moduleRef, contextId, inquirer);
}
async loadProvider(wrapper, moduleRef, contextId = constants_2.STATIC_CONTEXT, inquirer) {
const providers = moduleRef.providers;
await this.loadInstance(wrapper, providers, moduleRef, contextId, inquirer);
await this.loadEnhancersPerContext(wrapper, contextId, wrapper);
}
applySettlementSignal(instancePerContext, host) {
const settlementSignal = new settlement_signal_1.SettlementSignal();
instancePerContext.donePromise = settlementSignal.asPromise();
instancePerContext.isPending = true;
host.settlementSignal = settlementSignal;
return settlementSignal;
}
async resolveConstructorParams(wrapper, moduleRef, inject, callback, contextId = constants_2.STATIC_CONTEXT, inquirer, parentInquirer) {
const metadata = wrapper.getCtorMetadata();
if (metadata && contextId !== constants_2.STATIC_CONTEXT) {
const deps = await this.loadCtorMetadata(metadata, contextId, inquirer, parentInquirer);
return callback(deps);
}
const isFactoryProvider = !(0, shared_utils_1.isNil)(inject);
const [dependencies, optionalDependenciesIds] = isFactoryProvider
? this.getFactoryProviderDependencies(wrapper)
: this.getClassDependencies(wrapper);
const paramBarrier = new barrier_1.Barrier(dependencies.length);
let isResolved = true;
const resolveParam = async (param, index) => {
try {
if (this.isInquirer(param, parentInquirer)) {
/*
* Signal the barrier to make sure other dependencies do not get stuck waiting forever.
*/
paramBarrier.signal();
return parentInquirer && parentInquirer.instance;
}
if (inquirer?.isTransient && parentInquirer) {
// When `inquirer` is transient too, inherit the parent inquirer
// This is required to ensure that transient providers are only resolved
// when requested
inquirer.attachRootInquirer(parentInquirer);
}
const paramWrapper = await this.resolveSingleParam(wrapper, param, { index, dependencies }, moduleRef, contextId, inquirer, index);
/*
* Ensure that all instance wrappers are resolved at this point before we continue.
* Otherwise the staticity of `wrapper`'s dependency tree may be evaluated incorrectly
* and result in undefined / null injection.
*/
await paramBarrier.signalAndWait();
const effectiveInquirer = this.getEffectiveInquirer(paramWrapper, inquirer, parentInquirer, contextId);
const paramWrapperWithInstance = await this.resolveComponentHost(moduleRef, paramWrapper, contextId, effectiveInquirer);
const instanceHost = paramWrapperWithInstance.getInstanceByContextId(this.getContextId(contextId, paramWrapperWithInstance), this.getInquirerId(effectiveInquirer));
if (!instanceHost.isResolved && !paramWrapperWithInstance.forwardRef) {
isResolved = false;
}
return instanceHost?.instance;
}
catch (err) {
/*
* Signal the barrier to make sure other dependencies do not get stuck waiting forever. We
* do not care if this occurs after `Barrier.signalAndWait()` is called in the `try` block
* because the barrier will always have been resolved by then.
*/
paramBarrier.signal();
const isOptional = optionalDependenciesIds.includes(index);
if (!isOptional) {
throw err;
}
return undefined;
}
};
const instances = await Promise.all(dependencies.map(resolveParam));
isResolved && (await callback(instances));
}
getClassDependencies(wrapper) {
const ctorRef = wrapper.metatype;
return [
this.reflectConstructorParams(ctorRef),
this.reflectOptionalParams(ctorRef),
];
}
getFactoryProviderDependencies(wrapper) {
const optionalDependenciesIds = [];
/**
* Same as the internal utility function `isOptionalFactoryDependency` from `@nestjs/common`.
* We are duplicating it here because that one is not supposed to be exported.
*/
function isOptionalFactoryDependency(value) {
return (!(0, shared_utils_1.isUndefined)(value.token) &&
!(0, shared_utils_1.isUndefined)(value.optional) &&
!value.prototype);
}
const mapFactoryProviderInjectArray = (item, index) => {
if (typeof item !== 'object') {
return item;
}
if (isOptionalFactoryDependency(item)) {
if (item.optional) {
optionalDependenciesIds.push(index);
}
return item?.token;
}
return item;
};
return [
wrapper.inject?.map?.(mapFactoryProviderInjectArray),
optionalDependenciesIds,
];
}
reflectConstructorParams(type) {
const paramtypes = [
...(Reflect.getMetadata(constants_1.PARAMTYPES_METADATA, type) || []),
];
const selfParams = this.reflectSelfParams(type);
selfParams.forEach(({ index, param }) => (paramtypes[index] = param));
return paramtypes;
}
reflectOptionalParams(type) {
return Reflect.getMetadata(constants_1.OPTIONAL_DEPS_METADATA, type) || [];
}
reflectSelfParams(type) {
return Reflect.getMetadata(constants_1.SELF_DECLARED_DEPS_METADATA, type) || [];
}
async resolveSingleParam(wrapper, param, dependencyContext, moduleRef, contextId = constants_2.STATIC_CONTEXT, inquirer, keyOrIndex) {
if ((0, shared_utils_1.isUndefined)(param)) {
this.logger.log('Nest encountered an undefined dependency. This may be due to a circular import or a missing dependency declaration.');
throw new undefined_dependency_exception_1.UndefinedDependencyException(wrapper.name, dependencyContext, moduleRef);
}
const token = this.resolveParamToken(wrapper, param);
return this.resolveComponentWrapper(moduleRef, token, dependencyContext, wrapper, contextId, inquirer, keyOrIndex);
}
resolveParamToken(wrapper, param) {
if (typeof param === 'object' && 'forwardRef' in param) {
wrapper.forwardRef = true;
return param.forwardRef();
}
return param;
}
async resolveComponentWrapper(moduleRef, token, dependencyContext, wrapper, contextId = constants_2.STATIC_CONTEXT, inquirer, keyOrIndex) {
this.printResolvingDependenciesLog(token, inquirer);
this.printLookingForProviderLog(token, moduleRef);
const providers = moduleRef.providers;
return this.lookupComponent(providers, moduleRef, { ...dependencyContext, name: token }, wrapper, contextId, inquirer, keyOrIndex);
}
async resolveComponentHost(moduleRef, instanceWrapper, contextId = constants_2.STATIC_CONTEXT, inquirer) {
const inquirerId = this.getInquirerId(inquirer);
const instanceHost = instanceWrapper.getInstanceByContextId(this.getContextId(contextId, instanceWrapper), inquirerId);
if (!instanceHost.isResolved && !instanceWrapper.forwardRef) {
inquirer?.settlementSignal?.insertRef(instanceWrapper.id);
await this.loadProvider(instanceWrapper, instanceWrapper.host ?? moduleRef, contextId, inquirer);
}
else if (!instanceHost.isResolved &&
instanceWrapper.forwardRef &&
(contextId !== constants_2.STATIC_CONTEXT || !!inquirerId)) {
/**
* When circular dependency has been detected between
* either request/transient providers, we have to asynchronously
* resolve instance host for a specific contextId or inquirer, to ensure
* that eventual lazily created instance will be merged with the prototype
* instantiated beforehand.
*/
instanceHost.donePromise &&
void instanceHost.donePromise
.then(() => this.loadProvider(instanceWrapper, moduleRef, contextId, inquirer))
.catch(err => {
instanceWrapper.settlementSignal?.error(err);
});
}
if (instanceWrapper.async) {
const host = instanceWrapper.getInstanceByContextId(this.getContextId(contextId, instanceWrapper), inquirerId);
host.instance = await host.instance;
instanceWrapper.setInstanceByContextId(contextId, host, inquirerId);
}
return instanceWrapper;
}
async lookupComponent(providers, moduleRef, dependencyContext, wrapper, contextId = constants_2.STATIC_CONTEXT, inquirer, keyOrIndex) {
const token = wrapper.token || wrapper.name;
const { name } = dependencyContext;
if (wrapper && token === name) {
throw new unknown_dependencies_exception_1.UnknownDependenciesException(wrapper.name, dependencyContext, moduleRef, { id: wrapper.id });
}
if (name && providers.has(name)) {
const instanceWrapper = providers.get(name);
this.printFoundInModuleLog(name, moduleRef);
this.addDependencyMetadata(keyOrIndex, wrapper, instanceWrapper);
return instanceWrapper;
}
return this.lookupComponentInParentModules(dependencyContext, moduleRef, wrapper, contextId, inquirer, keyOrIndex);
}
async lookupComponentInParentModules(dependencyContext, moduleRef, wrapper, contextId = constants_2.STATIC_CONTEXT, inquirer, keyOrIndex) {
const instanceWrapper = await this.lookupComponentInImports(moduleRef, dependencyContext.name, wrapper, new Set(), contextId, inquirer, keyOrIndex);
if ((0, shared_utils_1.isNil)(instanceWrapper)) {
throw new unknown_dependencies_exception_1.UnknownDependenciesException(wrapper.name, dependencyContext, moduleRef, { id: wrapper.id });
}
return instanceWrapper;
}
async lookupComponentInImports(moduleRef, name, wrapper, moduleRegistry = new Set(), contextId = constants_2.STATIC_CONTEXT, inquirer, keyOrIndex, isTraversing) {
let instanceWrapperRef = null;
const imports = moduleRef.imports || new Set();
const identity = (item) => item;
let children = [...imports.values()].filter(identity);
if (isTraversing) {
const contextModuleExports = moduleRef.exports;
children = children.filter(child => contextModuleExports.has(child.metatype));
}
for (const relatedModule of children) {
if (moduleRegistry.has(relatedModule.id)) {
continue;
}
this.printLookingForProviderLog(name, relatedModule);
moduleRegistry.add(relatedModule.id);
const { providers, exports } = relatedModule;
if (!exports.has(name) || !providers.has(name)) {
const instanceRef = await this.lookupComponentInImports(relatedModule, name, wrapper, moduleRegistry, contextId, inquirer, keyOrIndex, true);
if (instanceRef) {
this.addDependencyMetadata(keyOrIndex, wrapper, instanceRef);
return instanceRef;
}
continue;
}
this.printFoundInModuleLog(name, relatedModule);
instanceWrapperRef = providers.get(name);
this.addDependencyMetadata(keyOrIndex, wrapper, instanceWrapperRef);
const inquirerId = this.getInquirerId(inquirer);
const instanceHost = instanceWrapperRef.getInstanceByContextId(this.getContextId(contextId, instanceWrapperRef), inquirerId);
if (!instanceHost.isResolved && !instanceWrapperRef.forwardRef) {
/*
* Provider will be loaded shortly in resolveComponentHost() once we pass the current
* Barrier. We cannot load it here because doing so could incorrectly evaluate the
* staticity of the dependency tree and lead to undefined / null injection.
*/
break;
}
}
return instanceWrapperRef;
}
async resolveProperties(wrapper, moduleRef, inject, contextId = constants_2.STATIC_CONTEXT, inquirer, parentInquirer) {
if (!(0, shared_utils_1.isNil)(inject)) {
return [];
}
const metadata = wrapper.getPropertiesMetadata();
if (metadata && contextId !== constants_2.STATIC_CONTEXT) {
return this.loadPropertiesMetadata(metadata, contextId, inquirer);
}
const properties = this.reflectProperties(wrapper.metatype);
const propertyBarrier = new barrier_1.Barrier(properties.length);
const instances = await Promise.all(properties.map(async (item) => {
try {
const dependencyContext = {
key: item.key,
name: item.name,
};
if (this.isInquirer(item.name, parentInquirer)) {
/*
* Signal the barrier to make sure other dependencies do not get stuck waiting forever.
*/
propertyBarrier.signal();
return parentInquirer && parentInquirer.instance;
}
const paramWrapper = await this.resolveSingleParam(wrapper, item.name, dependencyContext, moduleRef, contextId, inquirer, item.key);
/*
* Ensure that all instance wrappers are resolved at this point before we continue.
* Otherwise the staticity of `wrapper`'s dependency tree may be evaluated incorrectly
* and result in undefined / null injection.
*/
await propertyBarrier.signalAndWait();
const effectivePropertyInquirer = this.getEffectiveInquirer(paramWrapper, inquirer, parentInquirer, contextId);
const paramWrapperWithInstance = await this.resolveComponentHost(moduleRef, paramWrapper, contextId, effectivePropertyInquirer);
if (!paramWrapperWithInstance) {
return undefined;
}
const instanceHost = paramWrapperWithInstance.getInstanceByContextId(this.getContextId(contextId, paramWrapperWithInstance), this.getInquirerId(effectivePropertyInquirer));
return instanceHost.instance;
}
catch (err) {
/*
* Signal the barrier to make sure other dependencies do not get stuck waiting forever. We
* do not care if this occurs after `Barrier.signalAndWait()` is called in the `try` block
* because the barrier will always have been resolved by then.
*/
propertyBarrier.signal();
if (!item.isOptional) {
throw err;
}
return undefined;
}
}));
return properties.map((item, index) => ({
...item,
instance: instances[index],
}));
}
reflectProperties(type) {
const properties = Reflect.getMetadata(constants_1.PROPERTY_DEPS_METADATA, type) || [];
const optionalKeys = Reflect.getMetadata(constants_1.OPTIONAL_PROPERTY_DEPS_METADATA, type) || [];
return properties.map((item) => ({
...item,
name: item.type,
isOptional: optionalKeys.includes(item.key),
}));
}
applyProperties(instance, properties) {
if (!(0, shared_utils_1.isObject)(instance)) {
return undefined;
}
(0, iterare_1.iterate)(properties)
.filter(item => !(0, shared_utils_1.isNil)(item.instance))
.forEach(item => (instance[item.key] = item.instance));
}
async instantiateClass(instances, wrapper, targetMetatype, contextId = constants_2.STATIC_CONTEXT, inquirer) {
const { metatype, inject } = wrapper;
const inquirerId = this.getInquirerId(inquirer);
const instanceHost = targetMetatype.getInstanceByContextId(this.getContextId(contextId, targetMetatype), inquirerId);
const isInContext = wrapper.isStatic(contextId, inquirer) ||
wrapper.isInRequestScope(contextId, inquirer) ||
wrapper.isLazyTransient(contextId, inquirer) ||
wrapper.isExplicitlyRequested(contextId, inquirer);
if (this.options?.preview && !wrapper.host?.initOnPreview) {
instanceHost.isResolved = true;
return instanceHost.instance;
}
if ((0, shared_utils_1.isNil)(inject) && isInContext) {
instanceHost.instance = wrapper.forwardRef
? Object.assign(instanceHost.instance, new metatype(...instances))
: new metatype(...instances);
instanceHost.instance = this.instanceDecorator(instanceHost.instance);
instanceHost.isConstructorCalled = true;
}
else if (isInContext) {
const factoryReturnValue = targetMetatype.metatype(...instances);
instanceHost.instance = await factoryReturnValue;
instanceHost.instance = this.instanceDecorator(instanceHost.instance);
instanceHost.isConstructorCalled = true;
}
instanceHost.isResolved = true;
return instanceHost.instance;
}
async loadPerContext(instance, moduleRef, collection, ctx, wrapper) {
if (!wrapper) {
const injectionToken = instance.constructor;
wrapper = collection.get(injectionToken);
}
await this.loadInstance(wrapper, collection, moduleRef, ctx, wrapper);
await this.loadEnhancersPerContext(wrapper, ctx, wrapper);
const host = wrapper.getInstanceByContextId(this.getContextId(ctx, wrapper), wrapper.id);
return host && host.instance;
}
async loadEnhancersPerContext(wrapper, ctx, inquirer) {
const enhancers = wrapper.getEnhancersMetadata() || [];
const loadEnhancer = (item) => {
const hostModule = item.host;
return this.loadInstance(item, hostModule.injectables, hostModule, ctx, inquirer);
};
await Promise.all(enhancers.map(loadEnhancer));
}
async loadCtorMetadata(metadata, contextId, inquirer, parentInquirer) {
const hosts = await Promise.all(metadata.map(async (item) => this.resolveScopedComponentHost(item, contextId, inquirer, parentInquirer)));
return hosts.map((item, index) => {
const dependency = metadata[index];
const effectiveInquirer = this.getEffectiveInquirer(dependency, inquirer, parentInquirer, contextId);
return item?.getInstanceByContextId(this.getContextId(contextId, item), this.getInquirerId(effectiveInquirer)).instance;
});
}
async loadPropertiesMetadata(metadata, contextId, inquirer) {
const dependenciesHosts = await Promise.all(metadata.map(async ({ wrapper: item, key }) => ({
key,
host: await this.resolveComponentHost(item.host, item, contextId, inquirer),
})));
const inquirerId = this.getInquirerId(inquirer);
return dependenciesHosts.map(({ key, host }) => ({
key,
name: key,
instance: host.getInstanceByContextId(this.getContextId(contextId, host), inquirerId).instance,
}));
}
getInquirerId(inquirer) {
return inquirer ? inquirer.id : undefined;
}
/**
* For nested TRANSIENT dependencies (TRANSIENT -> TRANSIENT) in non-static contexts,
* returns parentInquirer to ensure each parent TRANSIENT gets its own instance.
* This is necessary because in REQUEST/DURABLE scopes, the same TRANSIENT wrapper
* can be used by multiple parents, causing nested TRANSIENTs to be shared incorrectly.
* For non-TRANSIENT -> TRANSIENT, returns inquirer (current wrapper being created).
*/
getEffectiveInquirer(dependency, inquirer, parentInquirer, contextId) {
return dependency?.isTransient &&
inquirer?.isTransient &&
parentInquirer &&
contextId !== constants_2.STATIC_CONTEXT
? parentInquirer
: inquirer;
}
resolveScopedComponentHost(item, contextId, inquirer, parentInquirer) {
return this.isInquirerRequest(item, parentInquirer)
? parentInquirer
: this.resolveComponentHost(item.host, item, contextId, this.getEffectiveInquirer(item, inquirer, parentInquirer, contextId));
}
isInquirerRequest(item, parentInquirer) {
return item.isTransient && item.name === inquirer_1.INQUIRER && parentInquirer;
}
isInquirer(param, parentInquirer) {
return param === inquirer_1.INQUIRER && parentInquirer;
}
addDependencyMetadata(keyOrIndex, hostWrapper, instanceWrapper) {
if ((0, shared_utils_1.isSymbol)(keyOrIndex) || (0, shared_utils_1.isString)(keyOrIndex)) {
hostWrapper.addPropertiesMetadata(keyOrIndex, instanceWrapper);
}
else {
hostWrapper.addCtorMetadata(keyOrIndex, instanceWrapper);
}
}
getTokenName(token) {
return (0, shared_utils_1.isFunction)(token) ? token.name : token.toString();
}
printResolvingDependenciesLog(token, inquirer) {
if (!this.isDebugMode()) {
return;
}
const tokenName = this.getTokenName(token);
const dependentName = (inquirer?.name && inquirer.name.toString?.()) ?? 'unknown';
const isAlias = dependentName === tokenName;
const messageToPrint = `Resolving dependency ${cli_colors_util_1.clc.cyanBright(tokenName)}${cli_colors_util_1.clc.green(' in the ')}${cli_colors_util_1.clc.yellow(dependentName)}${cli_colors_util_1.clc.green(` provider ${isAlias ? '(alias)' : ''}`)}`;
this.logger.log(messageToPrint);
}
printLookingForProviderLog(token, moduleRef) {
if (!this.isDebugMode()) {
return;
}
const tokenName = this.getTokenName(token);
const moduleRefName = moduleRef?.metatype?.name ?? 'unknown';
this.logger.log(`Looking for ${cli_colors_util_1.clc.cyanBright(tokenName)}${cli_colors_util_1.clc.green(' in ')}${cli_colors_util_1.clc.magentaBright(moduleRefName)}`);
}
printFoundInModuleLog(token, moduleRef) {
if (!this.isDebugMode()) {
return;
}
const tokenName = this.getTokenName(token);
const moduleRefName = moduleRef?.metatype?.name ?? 'unknown';
this.logger.log(`Found ${cli_colors_util_1.clc.cyanBright(tokenName)}${cli_colors_util_1.clc.green(' in ')}${cli_colors_util_1.clc.magentaBright(moduleRefName)}`);
}
isDebugMode() {
return !!process.env.NEST_DEBUG;
}
getContextId(contextId, instanceWrapper) {
return contextId.getParent
? contextId.getParent({
token: instanceWrapper.token,
isTreeDurable: instanceWrapper.isDependencyTreeDurable(),
})
: contextId;
}
getNowTimestamp() {
return perf_hooks_1.performance.now();
}
}
exports.Injector = Injector;

View File

@@ -0,0 +1 @@
export * from './inquirer-constants';

4
node_modules/@nestjs/core/injector/inquirer/index.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./inquirer-constants"), exports);

View File

@@ -0,0 +1 @@
export declare const INQUIRER = "INQUIRER";

View File

@@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.INQUIRER = void 0;
exports.INQUIRER = 'INQUIRER';

View File

@@ -0,0 +1,2 @@
import { Provider } from '@nestjs/common';
export declare const inquirerProvider: Provider;

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.inquirerProvider = void 0;
const common_1 = require("@nestjs/common");
const inquirer_constants_1 = require("./inquirer-constants");
const noop = () => { };
exports.inquirerProvider = {
provide: inquirer_constants_1.INQUIRER,
scope: common_1.Scope.TRANSIENT,
useFactory: noop,
};

View File

@@ -0,0 +1,22 @@
import { InjectionToken } from '@nestjs/common';
import { NestContainer } from './container';
import { InstanceWrapper } from './instance-wrapper';
export interface InstanceLink<T = any> {
token: InjectionToken;
wrapperRef: InstanceWrapper<T>;
collection: Map<any, InstanceWrapper>;
moduleId: string;
}
export declare class InstanceLinksHost {
private readonly container;
private readonly instanceLinks;
constructor(container: NestContainer);
get<T = any>(token: InjectionToken): InstanceLink<T>;
get<T = any>(token: InjectionToken, options?: {
moduleId?: string;
each?: boolean;
}): InstanceLink<T> | Array<InstanceLink<T>>;
private initialize;
private addLink;
private getInstanceNameByToken;
}

View File

@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InstanceLinksHost = void 0;
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
const unknown_element_exception_1 = require("../errors/exceptions/unknown-element.exception");
class InstanceLinksHost {
constructor(container) {
this.container = container;
this.instanceLinks = new Map();
this.initialize();
}
get(token, options = {}) {
const instanceLinksForGivenToken = this.instanceLinks.get(token);
if (!instanceLinksForGivenToken) {
throw new unknown_element_exception_1.UnknownElementException(this.getInstanceNameByToken(token));
}
if (options.each) {
return instanceLinksForGivenToken;
}
const instanceLink = options.moduleId
? instanceLinksForGivenToken.find(item => item.moduleId === options.moduleId)
: instanceLinksForGivenToken[instanceLinksForGivenToken.length - 1];
if (!instanceLink) {
throw new unknown_element_exception_1.UnknownElementException(this.getInstanceNameByToken(token));
}
return instanceLink;
}
initialize() {
const modules = this.container.getModules();
modules.forEach(moduleRef => {
const { providers, injectables, controllers } = moduleRef;
providers.forEach((wrapper, token) => this.addLink(wrapper, token, moduleRef, 'providers'));
injectables.forEach((wrapper, token) => this.addLink(wrapper, token, moduleRef, 'injectables'));
controllers.forEach((wrapper, token) => this.addLink(wrapper, token, moduleRef, 'controllers'));
});
}
addLink(wrapper, token, moduleRef, collectionName) {
const instanceLink = {
moduleId: moduleRef.id,
wrapperRef: wrapper,
collection: moduleRef[collectionName],
token,
};
const existingLinks = this.instanceLinks.get(token);
if (!existingLinks) {
this.instanceLinks.set(token, [instanceLink]);
}
else {
existingLinks.push(instanceLink);
}
}
getInstanceNameByToken(token) {
return (0, shared_utils_1.isFunction)(token) ? token?.name : token;
}
}
exports.InstanceLinksHost = InstanceLinksHost;

View File

@@ -0,0 +1,23 @@
import { Logger, LoggerService } from '@nestjs/common';
import { GraphInspector } from '../inspector/graph-inspector';
import { NestContainer } from './container';
import { Injector } from './injector';
import { Module } from './module';
export declare class InstanceLoader<TInjector extends Injector = Injector> {
protected readonly container: NestContainer;
protected readonly injector: TInjector;
protected readonly graphInspector: GraphInspector;
private logger;
constructor(container: NestContainer, injector: TInjector, graphInspector: GraphInspector, logger?: LoggerService);
setLogger(logger: Logger): void;
createInstancesOfDependencies(modules?: Map<string, Module>): Promise<void>;
private createPrototypes;
private createInstances;
private createPrototypesOfProviders;
private createInstancesOfProviders;
private createPrototypesOfControllers;
private createInstancesOfControllers;
private createPrototypesOfInjectables;
private createInstancesOfInjectables;
private isModuleWhitelisted;
}

88
node_modules/@nestjs/core/injector/instance-loader.js generated vendored Normal file
View File

@@ -0,0 +1,88 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InstanceLoader = void 0;
const common_1 = require("@nestjs/common");
const messages_1 = require("../helpers/messages");
const internal_core_module_1 = require("./internal-core-module/internal-core-module");
class InstanceLoader {
constructor(container, injector, graphInspector, logger = new common_1.Logger(InstanceLoader.name, {
timestamp: true,
})) {
this.container = container;
this.injector = injector;
this.graphInspector = graphInspector;
this.logger = logger;
}
setLogger(logger) {
this.logger = logger;
}
async createInstancesOfDependencies(modules = this.container.getModules()) {
this.createPrototypes(modules);
try {
await this.createInstances(modules);
}
catch (err) {
this.graphInspector.inspectModules(modules);
this.graphInspector.registerPartial(err);
throw err;
}
this.graphInspector.inspectModules(modules);
}
createPrototypes(modules) {
modules.forEach(moduleRef => {
this.createPrototypesOfProviders(moduleRef);
this.createPrototypesOfInjectables(moduleRef);
this.createPrototypesOfControllers(moduleRef);
});
}
async createInstances(modules) {
await Promise.all([...modules.values()].map(async (moduleRef) => {
await this.createInstancesOfProviders(moduleRef);
await this.createInstancesOfInjectables(moduleRef);
await this.createInstancesOfControllers(moduleRef);
const { name } = moduleRef;
this.isModuleWhitelisted(name) &&
this.logger.log((0, messages_1.MODULE_INIT_MESSAGE) `${name}`);
}));
}
createPrototypesOfProviders(moduleRef) {
const { providers } = moduleRef;
providers.forEach(wrapper => this.injector.loadPrototype(wrapper, providers));
}
async createInstancesOfProviders(moduleRef) {
const { providers } = moduleRef;
const wrappers = [...providers.values()];
await Promise.all(wrappers.map(async (item) => {
await this.injector.loadProvider(item, moduleRef);
this.graphInspector.inspectInstanceWrapper(item, moduleRef);
}));
}
createPrototypesOfControllers(moduleRef) {
const { controllers } = moduleRef;
controllers.forEach(wrapper => this.injector.loadPrototype(wrapper, controllers));
}
async createInstancesOfControllers(moduleRef) {
const { controllers } = moduleRef;
const wrappers = [...controllers.values()];
await Promise.all(wrappers.map(async (item) => {
await this.injector.loadController(item, moduleRef);
this.graphInspector.inspectInstanceWrapper(item, moduleRef);
}));
}
createPrototypesOfInjectables(moduleRef) {
const { injectables } = moduleRef;
injectables.forEach(wrapper => this.injector.loadPrototype(wrapper, injectables));
}
async createInstancesOfInjectables(moduleRef) {
const { injectables } = moduleRef;
const wrappers = [...injectables.values()];
await Promise.all(wrappers.map(async (item) => {
await this.injector.loadInjectable(item, moduleRef);
this.graphInspector.inspectInstanceWrapper(item, moduleRef);
}));
}
isModuleWhitelisted(name) {
return name !== internal_core_module_1.InternalCoreModule.name;
}
}
exports.InstanceLoader = InstanceLoader;

View File

@@ -0,0 +1,99 @@
import { Provider, Scope, Type } from '@nestjs/common';
import { EnhancerSubtype } from '@nestjs/common/constants';
import { FactoryProvider, InjectionToken } from '@nestjs/common/interfaces';
import { Module } from './module';
import { SettlementSignal } from './settlement-signal';
export declare const INSTANCE_METADATA_SYMBOL: unique symbol;
export declare const INSTANCE_ID_SYMBOL: unique symbol;
export interface HostComponentInfo {
/**
* Injection token (or class reference)
*/
token: InjectionToken;
/**
* Flag that indicates whether DI subtree is durable
*/
isTreeDurable: boolean;
}
export interface ContextId {
readonly id: number;
payload?: unknown;
getParent?(info: HostComponentInfo): ContextId;
}
export interface InstancePerContext<T> {
instance: T;
isResolved?: boolean;
isPending?: boolean;
donePromise?: Promise<unknown>;
isConstructorCalled?: boolean;
}
export interface PropertyMetadata {
key: symbol | string;
wrapper: InstanceWrapper;
}
export declare class InstanceWrapper<T = any> {
readonly name: any;
readonly token: InjectionToken;
readonly async?: boolean;
readonly host?: Module;
readonly isAlias: boolean;
readonly subtype?: EnhancerSubtype;
scope?: Scope;
metatype: Type<T> | Function | null;
inject?: FactoryProvider['inject'] | null;
forwardRef?: boolean;
durable?: boolean;
initTime?: number;
settlementSignal?: SettlementSignal;
private static logger;
private readonly values;
private readonly [INSTANCE_METADATA_SYMBOL];
private readonly [INSTANCE_ID_SYMBOL];
private transientMap?;
private isTreeStatic;
private isTreeDurable;
/**
* The root inquirer reference. Present only if child instance wrapper
* is transient and has a parent inquirer.
*/
private rootInquirer;
constructor(metadata?: Partial<InstanceWrapper<T>> & Partial<InstancePerContext<T>>);
get id(): string;
set instance(value: T);
get instance(): T;
get isNotMetatype(): boolean;
get isFactory(): boolean;
get isTransient(): boolean;
getInstanceByContextId(contextId: ContextId, inquirerId?: string): InstancePerContext<T>;
getInstanceByInquirerId(contextId: ContextId, inquirerId: string): InstancePerContext<T>;
setInstanceByContextId(contextId: ContextId, value: InstancePerContext<T>, inquirerId?: string): void;
setInstanceByInquirerId(contextId: ContextId, inquirerId: string, value: InstancePerContext<T>): void;
removeInstanceByContextId(contextId: ContextId, inquirerId?: string): void;
removeInstanceByInquirerId(contextId: ContextId, inquirerId: string): void;
addCtorMetadata(index: number, wrapper: InstanceWrapper): void;
getCtorMetadata(): InstanceWrapper[];
addPropertiesMetadata(key: symbol | string, wrapper: InstanceWrapper): void;
getPropertiesMetadata(): PropertyMetadata[];
addEnhancerMetadata(wrapper: InstanceWrapper): void;
getEnhancersMetadata(): InstanceWrapper[];
isDependencyTreeDurable(lookupRegistry?: string[]): boolean;
introspectDepsAttribute(callback: (collection: InstanceWrapper[], lookupRegistry: string[]) => boolean, lookupRegistry?: string[]): boolean;
isDependencyTreeStatic(lookupRegistry?: string[]): boolean;
cloneStaticInstance(contextId: ContextId): InstancePerContext<T>;
cloneTransientInstance(contextId: ContextId, inquirerId: string): InstancePerContext<T>;
createPrototype(contextId: ContextId): any;
isInRequestScope(contextId: ContextId, inquirer?: InstanceWrapper): boolean;
isLazyTransient(contextId: ContextId, inquirer: InstanceWrapper | undefined): boolean;
isExplicitlyRequested(contextId: ContextId, inquirer?: InstanceWrapper): boolean;
isStatic(contextId: ContextId, inquirer: InstanceWrapper | undefined): boolean;
attachRootInquirer(inquirer: InstanceWrapper): void;
getRootInquirer(): InstanceWrapper | undefined;
getStaticTransientInstances(): (InstancePerContext<T> | undefined)[];
mergeWith(provider: Provider): void;
private isNewable;
private initialize;
private printIntrospectedAsRequestScoped;
private printIntrospectedAsDurable;
private isDebugMode;
private generateUuid;
}

350
node_modules/@nestjs/core/injector/instance-wrapper.js generated vendored Normal file
View File

@@ -0,0 +1,350 @@
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.InstanceWrapper = exports.INSTANCE_ID_SYMBOL = exports.INSTANCE_METADATA_SYMBOL = void 0;
const common_1 = require("@nestjs/common");
const cli_colors_util_1 = require("@nestjs/common/utils/cli-colors.util");
const random_string_generator_util_1 = require("@nestjs/common/utils/random-string-generator.util");
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
const iterare_1 = require("iterare");
const uuid_factory_1 = require("../inspector/uuid-factory");
const constants_1 = require("./constants");
const provider_classifier_1 = require("./helpers/provider-classifier");
exports.INSTANCE_METADATA_SYMBOL = Symbol.for('instance_metadata:cache');
exports.INSTANCE_ID_SYMBOL = Symbol.for('instance_metadata:id');
class InstanceWrapper {
constructor(metadata = {}) {
this.isAlias = false;
this.scope = common_1.Scope.DEFAULT;
this.values = new WeakMap();
this[_a] = {};
this.initialize(metadata);
this[exports.INSTANCE_ID_SYMBOL] =
metadata[exports.INSTANCE_ID_SYMBOL] ?? this.generateUuid();
}
get id() {
return this[exports.INSTANCE_ID_SYMBOL];
}
set instance(value) {
this.values.set(constants_1.STATIC_CONTEXT, { instance: value });
}
get instance() {
const instancePerContext = this.getInstanceByContextId(constants_1.STATIC_CONTEXT);
return instancePerContext.instance;
}
get isNotMetatype() {
return !this.metatype || this.isFactory;
}
get isFactory() {
return !!this.metatype && !(0, shared_utils_1.isNil)(this.inject);
}
get isTransient() {
return this.scope === common_1.Scope.TRANSIENT;
}
getInstanceByContextId(contextId, inquirerId) {
if (this.scope === common_1.Scope.TRANSIENT && inquirerId) {
return this.getInstanceByInquirerId(contextId, inquirerId);
}
const instancePerContext = this.values.get(contextId);
return instancePerContext
? instancePerContext
: contextId !== constants_1.STATIC_CONTEXT
? this.cloneStaticInstance(contextId)
: {
instance: null,
isResolved: true,
isPending: false,
};
}
getInstanceByInquirerId(contextId, inquirerId) {
let collectionPerContext = this.transientMap.get(inquirerId);
if (!collectionPerContext) {
collectionPerContext = new WeakMap();
this.transientMap.set(inquirerId, collectionPerContext);
}
const instancePerContext = collectionPerContext.get(contextId);
return instancePerContext
? instancePerContext
: this.cloneTransientInstance(contextId, inquirerId);
}
setInstanceByContextId(contextId, value, inquirerId) {
if (this.scope === common_1.Scope.TRANSIENT && inquirerId) {
return this.setInstanceByInquirerId(contextId, inquirerId, value);
}
this.values.set(contextId, value);
}
setInstanceByInquirerId(contextId, inquirerId, value) {
let collection = this.transientMap.get(inquirerId);
if (!collection) {
collection = new WeakMap();
this.transientMap.set(inquirerId, collection);
}
collection.set(contextId, value);
}
removeInstanceByContextId(contextId, inquirerId) {
if (this.scope === common_1.Scope.TRANSIENT && inquirerId) {
return this.removeInstanceByInquirerId(contextId, inquirerId);
}
this.values.delete(contextId);
}
removeInstanceByInquirerId(contextId, inquirerId) {
const collection = this.transientMap.get(inquirerId);
if (!collection) {
return;
}
collection.delete(contextId);
}
addCtorMetadata(index, wrapper) {
if (!this[exports.INSTANCE_METADATA_SYMBOL].dependencies) {
this[exports.INSTANCE_METADATA_SYMBOL].dependencies = [];
}
this[exports.INSTANCE_METADATA_SYMBOL].dependencies[index] = wrapper;
}
getCtorMetadata() {
return this[exports.INSTANCE_METADATA_SYMBOL].dependencies;
}
addPropertiesMetadata(key, wrapper) {
if (!this[exports.INSTANCE_METADATA_SYMBOL].properties) {
this[exports.INSTANCE_METADATA_SYMBOL].properties = [];
}
this[exports.INSTANCE_METADATA_SYMBOL].properties.push({
key,
wrapper,
});
}
getPropertiesMetadata() {
return this[exports.INSTANCE_METADATA_SYMBOL].properties;
}
addEnhancerMetadata(wrapper) {
if (!this[exports.INSTANCE_METADATA_SYMBOL].enhancers) {
this[exports.INSTANCE_METADATA_SYMBOL].enhancers = [];
}
this[exports.INSTANCE_METADATA_SYMBOL].enhancers.push(wrapper);
}
getEnhancersMetadata() {
return this[exports.INSTANCE_METADATA_SYMBOL].enhancers;
}
isDependencyTreeDurable(lookupRegistry = []) {
if (!(0, shared_utils_1.isUndefined)(this.isTreeDurable)) {
return this.isTreeDurable;
}
if (this.scope === common_1.Scope.REQUEST) {
this.isTreeDurable = this.durable === undefined ? false : this.durable;
if (this.isTreeDurable) {
this.printIntrospectedAsDurable();
}
return this.isTreeDurable;
}
const isStatic = this.isDependencyTreeStatic();
if (isStatic) {
return false;
}
const isTreeNonDurable = this.introspectDepsAttribute((collection, registry) => collection.some((item) => !item.isDependencyTreeStatic() &&
!item.isDependencyTreeDurable(registry)), lookupRegistry);
this.isTreeDurable = !isTreeNonDurable;
if (this.isTreeDurable) {
this.printIntrospectedAsDurable();
}
return this.isTreeDurable;
}
introspectDepsAttribute(callback, lookupRegistry = []) {
if (lookupRegistry.includes(this[exports.INSTANCE_ID_SYMBOL])) {
return false;
}
lookupRegistry = lookupRegistry.concat(this[exports.INSTANCE_ID_SYMBOL]);
const { dependencies, properties, enhancers } = this[exports.INSTANCE_METADATA_SYMBOL];
let introspectionResult = dependencies
? callback(dependencies, lookupRegistry)
: false;
if (introspectionResult || !(properties || enhancers)) {
return introspectionResult;
}
introspectionResult = properties
? callback(properties.map(item => item.wrapper), lookupRegistry)
: false;
if (introspectionResult || !enhancers) {
return introspectionResult;
}
return enhancers ? callback(enhancers, lookupRegistry) : false;
}
isDependencyTreeStatic(lookupRegistry = []) {
if (!(0, shared_utils_1.isUndefined)(this.isTreeStatic)) {
return this.isTreeStatic;
}
if (this.scope === common_1.Scope.REQUEST) {
this.isTreeStatic = false;
this.printIntrospectedAsRequestScoped();
return this.isTreeStatic;
}
this.isTreeStatic = !this.introspectDepsAttribute((collection, registry) => collection.some((item) => !item.isDependencyTreeStatic(registry)), lookupRegistry);
if (!this.isTreeStatic) {
this.printIntrospectedAsRequestScoped();
}
return this.isTreeStatic;
}
cloneStaticInstance(contextId) {
const staticInstance = this.getInstanceByContextId(constants_1.STATIC_CONTEXT);
if (this.isDependencyTreeStatic()) {
return staticInstance;
}
const instancePerContext = {
...staticInstance,
instance: undefined,
isResolved: false,
isPending: false,
};
if (this.isNewable()) {
instancePerContext.instance = Object.create(this.metatype.prototype);
}
this.setInstanceByContextId(contextId, instancePerContext);
return instancePerContext;
}
cloneTransientInstance(contextId, inquirerId) {
const staticInstance = this.getInstanceByContextId(constants_1.STATIC_CONTEXT);
const instancePerContext = {
...staticInstance,
instance: undefined,
isResolved: false,
isPending: false,
};
if (this.isNewable()) {
instancePerContext.instance = Object.create(this.metatype.prototype);
}
this.setInstanceByInquirerId(contextId, inquirerId, instancePerContext);
return instancePerContext;
}
createPrototype(contextId) {
const host = this.getInstanceByContextId(contextId);
if (!this.isNewable() || host.isResolved) {
return;
}
return Object.create(this.metatype.prototype);
}
isInRequestScope(contextId, inquirer) {
const isDependencyTreeStatic = this.isDependencyTreeStatic();
return (!isDependencyTreeStatic &&
contextId !== constants_1.STATIC_CONTEXT &&
(!this.isTransient || (this.isTransient && !!inquirer)));
}
isLazyTransient(contextId, inquirer) {
const isInquirerRequestScoped = !!(inquirer && !inquirer.isDependencyTreeStatic());
return (this.isDependencyTreeStatic() &&
contextId !== constants_1.STATIC_CONTEXT &&
this.isTransient &&
isInquirerRequestScoped);
}
isExplicitlyRequested(contextId, inquirer) {
const isSelfRequested = inquirer === this;
return (this.isDependencyTreeStatic() &&
contextId !== constants_1.STATIC_CONTEXT &&
(isSelfRequested || !!(inquirer && inquirer.scope === common_1.Scope.TRANSIENT)));
}
isStatic(contextId, inquirer) {
if (!this.isDependencyTreeStatic() || contextId !== constants_1.STATIC_CONTEXT) {
return false;
}
// Non-transient provider in static context
if (!this.isTransient) {
return true;
}
const isInquirerRequestScoped = inquirer && !inquirer.isDependencyTreeStatic();
const isStaticTransient = this.isTransient && !isInquirerRequestScoped;
const rootInquirer = inquirer?.getRootInquirer();
// Transient provider inquired by non-transient (e.g., DEFAULT -> TRANSIENT)
if (isStaticTransient && inquirer && !inquirer.isTransient) {
return true;
}
// Nested transient with non-transient root (e.g., DEFAULT -> TRANSIENT -> TRANSIENT)
if (isStaticTransient && rootInquirer && !rootInquirer.isTransient) {
return true;
}
// Nested transient during initial instantiation (rootInquirer not yet set)
if (isStaticTransient && inquirer?.isTransient && !rootInquirer) {
return true;
}
return false;
}
attachRootInquirer(inquirer) {
if (!this.isTransient) {
// Only attach root inquirer if the instance wrapper is transient
return;
}
this.rootInquirer = inquirer.getRootInquirer() ?? inquirer;
}
getRootInquirer() {
return this.rootInquirer;
}
getStaticTransientInstances() {
if (!this.transientMap) {
return [];
}
const instances = [...this.transientMap.values()];
return (0, iterare_1.iterate)(instances)
.map(item => item.get(constants_1.STATIC_CONTEXT))
.filter(item => {
// Only return items where constructor has been actually called
// This prevents calling lifecycle hooks on non-instantiated transient services
return !!(item && item.isConstructorCalled);
})
.toArray();
}
mergeWith(provider) {
if ((0, provider_classifier_1.isValueProvider)(provider)) {
this.metatype = null;
this.inject = null;
this.scope = common_1.Scope.DEFAULT;
this.setInstanceByContextId(constants_1.STATIC_CONTEXT, {
instance: provider.useValue,
isResolved: true,
isPending: false,
});
}
else if ((0, provider_classifier_1.isClassProvider)(provider)) {
this.inject = null;
this.metatype = provider.useClass;
}
else if ((0, provider_classifier_1.isFactoryProvider)(provider)) {
this.metatype = provider.useFactory;
this.inject = provider.inject || [];
}
}
isNewable() {
return (0, shared_utils_1.isNil)(this.inject) && this.metatype && this.metatype.prototype;
}
initialize(metadata) {
const { instance, isResolved, ...wrapperPartial } = metadata;
Object.assign(this, wrapperPartial);
this.setInstanceByContextId(constants_1.STATIC_CONTEXT, {
instance: instance,
isResolved,
});
this.scope === common_1.Scope.TRANSIENT && (this.transientMap = new Map());
}
printIntrospectedAsRequestScoped() {
if (!this.isDebugMode() || this.name === 'REQUEST') {
return;
}
if ((0, shared_utils_1.isString)(this.name)) {
InstanceWrapper.logger.log(`${cli_colors_util_1.clc.cyanBright(this.name)}${cli_colors_util_1.clc.green(' introspected as ')}${cli_colors_util_1.clc.magentaBright('request-scoped')}`);
}
}
printIntrospectedAsDurable() {
if (!this.isDebugMode()) {
return;
}
if ((0, shared_utils_1.isString)(this.name)) {
InstanceWrapper.logger.log(`${cli_colors_util_1.clc.cyanBright(this.name)}${cli_colors_util_1.clc.green(' introspected as ')}${cli_colors_util_1.clc.magentaBright('durable')}`);
}
}
isDebugMode() {
return !!process.env.NEST_DEBUG;
}
generateUuid() {
let key = this.name?.toString() ?? this.token?.toString();
key += this.host?.name ?? '';
return key ? uuid_factory_1.UuidFactory.get(key) : (0, random_string_generator_util_1.randomStringGenerator)();
}
}
exports.InstanceWrapper = InstanceWrapper;
_a = exports.INSTANCE_METADATA_SYMBOL;
InstanceWrapper.logger = new common_1.Logger(InstanceWrapper.name);

View File

@@ -0,0 +1 @@
export * from './internal-core-module';

View File

@@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./internal-core-module"), exports);

View File

@@ -0,0 +1,9 @@
import { HttpAdapterHost } from '../../helpers/http-adapter-host';
import { GraphInspector } from '../../inspector/graph-inspector';
import { ModuleOverride } from '../../interfaces/module-override.interface';
import { DependenciesScanner } from '../../scanner';
import { ModuleCompiler } from '../compiler';
import { NestContainer } from '../container';
export declare class InternalCoreModuleFactory {
static create(container: NestContainer, scanner: DependenciesScanner, moduleCompiler: ModuleCompiler, httpAdapterHost: HttpAdapterHost, graphInspector: GraphInspector, moduleOverrides?: ModuleOverride[]): import("@nestjs/common").DynamicModule;
}

View File

@@ -0,0 +1,52 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InternalCoreModuleFactory = void 0;
const common_1 = require("@nestjs/common");
const external_context_creator_1 = require("../../helpers/external-context-creator");
const http_adapter_host_1 = require("../../helpers/http-adapter-host");
const initialize_on_preview_allowlist_1 = require("../../inspector/initialize-on-preview.allowlist");
const serialized_graph_1 = require("../../inspector/serialized-graph");
const injector_1 = require("../injector");
const instance_loader_1 = require("../instance-loader");
const lazy_module_loader_1 = require("../lazy-module-loader/lazy-module-loader");
const modules_container_1 = require("../modules-container");
const internal_core_module_1 = require("./internal-core-module");
class InternalCoreModuleFactory {
static create(container, scanner, moduleCompiler, httpAdapterHost, graphInspector, moduleOverrides) {
const lazyModuleLoaderFactory = () => {
const logger = new common_1.Logger(lazy_module_loader_1.LazyModuleLoader.name, {
timestamp: false,
});
const injector = new injector_1.Injector({
preview: container.contextOptions?.preview,
instanceDecorator: container.contextOptions?.instrument?.instanceDecorator,
});
const instanceLoader = new instance_loader_1.InstanceLoader(container, injector, graphInspector, logger);
return new lazy_module_loader_1.LazyModuleLoader(scanner, instanceLoader, moduleCompiler, container.getModules(), moduleOverrides);
};
initialize_on_preview_allowlist_1.InitializeOnPreviewAllowlist.add(internal_core_module_1.InternalCoreModule);
return internal_core_module_1.InternalCoreModule.register([
{
provide: external_context_creator_1.ExternalContextCreator,
useFactory: () => external_context_creator_1.ExternalContextCreator.fromContainer(container),
},
{
provide: modules_container_1.ModulesContainer,
useFactory: () => container.getModules(),
},
{
provide: http_adapter_host_1.HttpAdapterHost,
useFactory: () => httpAdapterHost,
},
{
provide: lazy_module_loader_1.LazyModuleLoader,
useFactory: lazyModuleLoaderFactory,
},
{
provide: serialized_graph_1.SerializedGraph,
useFactory: () => container.serializedGraph,
},
]);
}
}
exports.InternalCoreModuleFactory = InternalCoreModuleFactory;

View File

@@ -0,0 +1,5 @@
import { DynamicModule } from '@nestjs/common';
import { ExistingProvider, FactoryProvider, ValueProvider } from '@nestjs/common/interfaces';
export declare class InternalCoreModule {
static register(providers: Array<ValueProvider | FactoryProvider | ExistingProvider>): DynamicModule;
}

View File

@@ -0,0 +1,40 @@
"use strict";
var InternalCoreModule_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.InternalCoreModule = void 0;
const tslib_1 = require("tslib");
const common_1 = require("@nestjs/common");
const request_providers_1 = require("../../router/request/request-providers");
const services_1 = require("../../services");
const inquirer_providers_1 = require("../inquirer/inquirer-providers");
const ReflectorAliasProvider = {
provide: services_1.Reflector.name,
useExisting: services_1.Reflector,
};
let InternalCoreModule = InternalCoreModule_1 = class InternalCoreModule {
static register(providers) {
return {
module: InternalCoreModule_1,
providers: [...providers],
exports: [...providers.map(item => item.provide)],
};
}
};
exports.InternalCoreModule = InternalCoreModule;
exports.InternalCoreModule = InternalCoreModule = InternalCoreModule_1 = tslib_1.__decorate([
(0, common_1.Global)(),
(0, common_1.Module)({
providers: [
services_1.Reflector,
ReflectorAliasProvider,
request_providers_1.requestProvider,
inquirer_providers_1.inquirerProvider,
],
exports: [
services_1.Reflector,
ReflectorAliasProvider,
request_providers_1.requestProvider,
inquirer_providers_1.inquirerProvider,
],
})
], InternalCoreModule);

View File

@@ -0,0 +1,9 @@
import { AbstractHttpAdapter } from '../adapters';
import { HttpAdapterHost } from '../helpers/http-adapter-host';
export declare class InternalProvidersStorage {
private readonly _httpAdapterHost;
private _httpAdapter;
get httpAdapterHost(): HttpAdapterHost;
get httpAdapter(): AbstractHttpAdapter;
set httpAdapter(httpAdapter: AbstractHttpAdapter);
}

View File

@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InternalProvidersStorage = void 0;
const http_adapter_host_1 = require("../helpers/http-adapter-host");
class InternalProvidersStorage {
constructor() {
this._httpAdapterHost = new http_adapter_host_1.HttpAdapterHost();
}
get httpAdapterHost() {
return this._httpAdapterHost;
}
get httpAdapter() {
return this._httpAdapter;
}
set httpAdapter(httpAdapter) {
this._httpAdapter = httpAdapter;
}
}
exports.InternalProvidersStorage = InternalProvidersStorage;

View File

@@ -0,0 +1,6 @@
export interface LazyModuleLoaderLoadOptions {
/**
* If `false`, no logs will be generated when loading some module lazily.
*/
logger?: boolean;
}

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,20 @@
import { DynamicModule, Type } from '@nestjs/common';
import { ModuleOverride } from '../../interfaces/module-override.interface';
import { DependenciesScanner } from '../../scanner';
import { ModuleCompiler } from '../compiler';
import { InstanceLoader } from '../instance-loader';
import { ModuleRef } from '../module-ref';
import { ModulesContainer } from '../modules-container';
import { LazyModuleLoaderLoadOptions } from './lazy-module-loader-options.interface';
export declare class LazyModuleLoader {
private readonly dependenciesScanner;
private readonly instanceLoader;
private readonly moduleCompiler;
private readonly modulesContainer;
private readonly moduleOverrides?;
constructor(dependenciesScanner: DependenciesScanner, instanceLoader: InstanceLoader, moduleCompiler: ModuleCompiler, modulesContainer: ModulesContainer, moduleOverrides?: ModuleOverride[] | undefined);
load(loaderFn: () => Promise<Type<unknown> | DynamicModule> | Type<unknown> | DynamicModule, loadOpts?: LazyModuleLoaderLoadOptions): Promise<ModuleRef>;
private registerLoggerConfiguration;
private createLazyModulesContainer;
private getTargetModuleRef;
}

View File

@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LazyModuleLoader = void 0;
const silent_logger_1 = require("../helpers/silent-logger");
const module_ref_1 = require("../module-ref");
class LazyModuleLoader {
constructor(dependenciesScanner, instanceLoader, moduleCompiler, modulesContainer, moduleOverrides) {
this.dependenciesScanner = dependenciesScanner;
this.instanceLoader = instanceLoader;
this.moduleCompiler = moduleCompiler;
this.modulesContainer = modulesContainer;
this.moduleOverrides = moduleOverrides;
}
async load(loaderFn, loadOpts) {
this.registerLoggerConfiguration(loadOpts);
const moduleClassOrDynamicDefinition = await loaderFn();
const moduleInstances = await this.dependenciesScanner.scanForModules({
moduleDefinition: moduleClassOrDynamicDefinition,
overrides: this.moduleOverrides,
lazy: true,
});
if (moduleInstances.length === 0) {
// The module has been loaded already. In this case, we must
// retrieve a module reference from the existing container.
const { token } = await this.moduleCompiler.compile(moduleClassOrDynamicDefinition);
const moduleInstance = this.modulesContainer.get(token);
return moduleInstance && this.getTargetModuleRef(moduleInstance);
}
const lazyModulesContainer = this.createLazyModulesContainer(moduleInstances);
await this.dependenciesScanner.scanModulesForDependencies(lazyModulesContainer);
await this.instanceLoader.createInstancesOfDependencies(lazyModulesContainer);
const [targetModule] = moduleInstances;
return this.getTargetModuleRef(targetModule);
}
registerLoggerConfiguration(loadOpts) {
if (loadOpts?.logger === false) {
this.instanceLoader.setLogger(new silent_logger_1.SilentLogger());
}
}
createLazyModulesContainer(moduleInstances) {
moduleInstances = Array.from(new Set(moduleInstances));
return new Map(moduleInstances.map(ref => [ref.token, ref]));
}
getTargetModuleRef(moduleInstance) {
const moduleRefInstanceWrapper = moduleInstance.getProviderByKey(module_ref_1.ModuleRef);
return moduleRefInstanceWrapper.instance;
}
}
exports.LazyModuleLoader = LazyModuleLoader;

106
node_modules/@nestjs/core/injector/module-ref.d.ts generated vendored Normal file
View File

@@ -0,0 +1,106 @@
import { IntrospectionResult, Type } from '@nestjs/common';
import { AbstractInstanceResolver } from './abstract-instance-resolver';
import { NestContainer } from './container';
import { Injector } from './injector';
import { InstanceLinksHost } from './instance-links-host';
import { ContextId } from './instance-wrapper';
import { Module } from './module';
export interface ModuleRefGetOrResolveOpts {
/**
* If enabled, lookup will only be performed in the host module.
* @default true
*/
strict?: boolean;
/**
* If enabled, instead of returning a first instance registered under a given token,
* a list of instances will be returned.
* @default false
*/
each?: boolean;
}
export declare abstract class ModuleRef extends AbstractInstanceResolver {
protected readonly container: NestContainer;
protected readonly injector: Injector;
private _instanceLinksHost;
protected get instanceLinksHost(): InstanceLinksHost;
constructor(container: NestContainer);
/**
* Retrieves an instance of either injectable or controller, otherwise, throws exception.
* @returns {TResult}
*/
abstract get<TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Function | string | symbol): TResult;
/**
* Retrieves an instance of either injectable or controller, otherwise, throws exception.
* @returns {TResult}
*/
abstract get<TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Function | string | symbol, options: {
/**
* If enabled, lookup will only be performed in the host module.
* @default true
*/
strict?: boolean;
/** This indicates that only the first instance registered will be returned. */
each?: undefined | false;
}): TResult;
/**
* Retrieves a list of instances of either injectables or controllers, otherwise, throws exception.
* @returns {Array<TResult>}
*/
abstract get<TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Function | string | symbol, options: {
/**
* If enabled, lookup will only be performed in the host module.
* @default true
*/
strict?: boolean;
/** This indicates that a list of instances will be returned. */
each: true;
}): Array<TResult>;
/**
* Retrieves an instance (or a list of instances) of either injectable or controller, otherwise, throws exception.
* @returns {TResult | Array<TResult>}
*/
abstract get<TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Function | string | symbol, options?: ModuleRefGetOrResolveOpts): TResult | Array<TResult>;
/**
* Resolves transient or request-scoped instance of either injectable or controller, otherwise, throws exception.
* @returns {Array<TResult>}
*/
abstract resolve<TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Function | string | symbol): Promise<TResult>;
/**
* Resolves transient or request-scoped instance of either injectable or controller, otherwise, throws exception.
* @returns {Array<TResult>}
*/
abstract resolve<TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Function | string | symbol, contextId?: {
id: number;
}): Promise<TResult>;
/**
* Resolves transient or request-scoped instance of either injectable or controller, otherwise, throws exception.
* @returns {Array<TResult>}
*/
abstract resolve<TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Function | string | symbol, contextId?: {
id: number;
}, options?: {
strict?: boolean;
each?: undefined | false;
}): Promise<TResult>;
/**
* Resolves transient or request-scoped instances of either injectables or controllers, otherwise, throws exception.
* @returns {Array<TResult>}
*/
abstract resolve<TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Function | string | symbol, contextId?: {
id: number;
}, options?: {
strict?: boolean;
each: true;
}): Promise<Array<TResult>>;
/**
* Resolves transient or request-scoped instance (or a list of instances) of either injectable or controller, otherwise, throws exception.
* @returns {Promise<TResult | Array<TResult>>}
*/
abstract resolve<TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Function | string | symbol, contextId?: {
id: number;
}, options?: ModuleRefGetOrResolveOpts): Promise<TResult | Array<TResult>>;
abstract create<T = any>(type: Type<T>, contextId?: ContextId): Promise<T>;
introspect<T = any>(token: Type<T> | string | symbol): IntrospectionResult;
registerRequestByContextId<T = any>(request: T, contextId: ContextId): void;
protected instantiateClass<T = any>(type: Type<T>, moduleRef: Module, contextId?: ContextId): Promise<T>;
}

66
node_modules/@nestjs/core/injector/module-ref.js generated vendored Normal file
View File

@@ -0,0 +1,66 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModuleRef = void 0;
const common_1 = require("@nestjs/common");
const get_class_scope_1 = require("../helpers/get-class-scope");
const is_durable_1 = require("../helpers/is-durable");
const abstract_instance_resolver_1 = require("./abstract-instance-resolver");
const injector_1 = require("./injector");
const instance_links_host_1 = require("./instance-links-host");
const instance_wrapper_1 = require("./instance-wrapper");
class ModuleRef extends abstract_instance_resolver_1.AbstractInstanceResolver {
get instanceLinksHost() {
if (!this._instanceLinksHost) {
this._instanceLinksHost = new instance_links_host_1.InstanceLinksHost(this.container);
}
return this._instanceLinksHost;
}
constructor(container) {
super();
this.container = container;
this.injector = new injector_1.Injector({
preview: container.contextOptions?.preview,
instanceDecorator: container.contextOptions?.instrument?.instanceDecorator,
});
}
introspect(token) {
const { wrapperRef } = this.instanceLinksHost.get(token);
let scope = common_1.Scope.DEFAULT;
if (!wrapperRef.isDependencyTreeStatic()) {
scope = common_1.Scope.REQUEST;
}
else if (wrapperRef.isTransient) {
scope = common_1.Scope.TRANSIENT;
}
return { scope };
}
registerRequestByContextId(request, contextId) {
this.container.registerRequestProvider(request, contextId);
}
async instantiateClass(type, moduleRef, contextId) {
const wrapper = new instance_wrapper_1.InstanceWrapper({
name: type && type.name,
metatype: type,
isResolved: false,
scope: (0, get_class_scope_1.getClassScope)(type),
durable: (0, is_durable_1.isDurable)(type),
host: moduleRef,
});
/* eslint-disable-next-line no-async-promise-executor */
return new Promise(async (resolve, reject) => {
try {
const callback = async (instances) => {
const properties = await this.injector.resolveProperties(wrapper, moduleRef, undefined, contextId);
const instance = new type(...instances);
this.injector.applyProperties(instance, properties);
resolve(instance);
};
await this.injector.resolveConstructorParams(wrapper, moduleRef, undefined, callback, contextId);
}
catch (err) {
reject(err);
}
});
}
}
exports.ModuleRef = ModuleRef;

82
node_modules/@nestjs/core/injector/module.d.ts generated vendored Normal file
View File

@@ -0,0 +1,82 @@
import { EnhancerSubtype } from '@nestjs/common/constants';
import { ClassProvider, Controller, DynamicModule, ExistingProvider, FactoryProvider, Injectable, InjectionToken, NestModule, Provider, Type, ValueProvider } from '@nestjs/common/interfaces';
import { NestContainer } from './container';
import { InstanceWrapper } from './instance-wrapper';
import { ModuleRef } from './module-ref';
export declare class Module {
private readonly _metatype;
private readonly container;
private readonly _id;
private readonly _imports;
private readonly _providers;
private readonly _injectables;
private readonly _middlewares;
private readonly _controllers;
private readonly _entryProviderKeys;
private readonly _exports;
private _distance;
private _initOnPreview;
private _isGlobal;
private _token;
constructor(_metatype: Type<any>, container: NestContainer);
get id(): string;
get token(): string;
set token(token: string);
get name(): string;
get isGlobal(): boolean;
set isGlobal(global: boolean);
get initOnPreview(): boolean;
set initOnPreview(initOnPreview: boolean);
get providers(): Map<InjectionToken, InstanceWrapper<Injectable>>;
get middlewares(): Map<InjectionToken, InstanceWrapper<Injectable>>;
get imports(): Set<Module>;
get injectables(): Map<InjectionToken, InstanceWrapper<Injectable>>;
get controllers(): Map<InjectionToken, InstanceWrapper<Controller>>;
get entryProviders(): Array<InstanceWrapper<Injectable>>;
get exports(): Set<InjectionToken>;
get instance(): NestModule;
get metatype(): Type<any>;
get distance(): number;
set distance(value: number);
addCoreProviders(): void;
addModuleRef(): void;
addModuleAsProvider(): void;
addApplicationConfig(): void;
addInjectable<T extends Injectable>(injectable: Provider, enhancerSubtype: EnhancerSubtype, host?: Type<T>): string | symbol | Function | InstanceWrapper<unknown>;
addProvider(provider: Provider): InjectionToken;
addProvider(provider: Provider, enhancerSubtype: EnhancerSubtype): InjectionToken;
isCustomProvider(provider: Provider): provider is ClassProvider | FactoryProvider | ValueProvider | ExistingProvider;
addCustomProvider(provider: ClassProvider | FactoryProvider | ValueProvider | ExistingProvider, collection: Map<Function | string | symbol, any>, enhancerSubtype?: EnhancerSubtype): InjectionToken;
isCustomClass(provider: any): provider is ClassProvider;
isCustomValue(provider: any): provider is ValueProvider;
isCustomFactory(provider: any): provider is FactoryProvider;
isCustomUseExisting(provider: any): provider is ExistingProvider;
isDynamicModule(exported: any): exported is DynamicModule;
addCustomClass(provider: ClassProvider, collection: Map<InjectionToken, InstanceWrapper>, enhancerSubtype?: EnhancerSubtype): void;
addCustomValue(provider: ValueProvider, collection: Map<Function | string | symbol, InstanceWrapper>, enhancerSubtype?: EnhancerSubtype): void;
addCustomFactory(provider: FactoryProvider, collection: Map<Function | string | symbol, InstanceWrapper>, enhancerSubtype?: EnhancerSubtype): void;
addCustomUseExisting(provider: ExistingProvider, collection: Map<Function | string | symbol, InstanceWrapper>, enhancerSubtype?: EnhancerSubtype): void;
addExportedProviderOrModule(toExport: Provider | string | symbol | DynamicModule): Set<InjectionToken> | undefined;
addCustomExportedProvider(provider: FactoryProvider | ValueProvider | ClassProvider | ExistingProvider): Set<InjectionToken> | undefined;
validateExportedProvider(token: InjectionToken): InjectionToken;
addController(controller: Type<Controller>): void;
assignControllerUniqueId(controller: Type<Controller>): void;
addImport(moduleRef: Module): void;
replace(toReplace: InjectionToken, options: any): void;
hasProvider(token: InjectionToken): boolean;
hasInjectable(token: InjectionToken): boolean;
getProviderByKey<T = any>(name: InjectionToken<T>): InstanceWrapper<T>;
getProviderById<T = any>(id: string): InstanceWrapper<T> | undefined;
getControllerById<T = any>(id: string): InstanceWrapper<T> | undefined;
getInjectableById<T = any>(id: string): InstanceWrapper<T> | undefined;
getMiddlewareById<T = any>(id: string): InstanceWrapper<T> | undefined;
getNonAliasProviders(): Array<[
InjectionToken,
InstanceWrapper<Injectable>
]>;
createModuleReferenceType(): Type<ModuleRef>;
private isEntryProvider;
private generateUuid;
private isTransientProvider;
private isRequestScopeProvider;
}

432
node_modules/@nestjs/core/injector/module.js generated vendored Normal file
View File

@@ -0,0 +1,432 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Module = void 0;
const constants_1 = require("@nestjs/common/constants");
const interfaces_1 = require("@nestjs/common/interfaces");
const random_string_generator_util_1 = require("@nestjs/common/utils/random-string-generator.util");
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
const iterare_1 = require("iterare");
const application_config_1 = require("../application-config");
const exceptions_1 = require("../errors/exceptions");
const context_id_factory_1 = require("../helpers/context-id-factory");
const get_class_scope_1 = require("../helpers/get-class-scope");
const is_durable_1 = require("../helpers/is-durable");
const uuid_factory_1 = require("../inspector/uuid-factory");
const constants_2 = require("./constants");
const instance_wrapper_1 = require("./instance-wrapper");
const module_ref_1 = require("./module-ref");
class Module {
constructor(_metatype, container) {
this._metatype = _metatype;
this.container = container;
this._imports = new Set();
this._providers = new Map();
this._injectables = new Map();
this._middlewares = new Map();
this._controllers = new Map();
this._entryProviderKeys = new Set();
this._exports = new Set();
this._distance = 0;
this._initOnPreview = false;
this._isGlobal = false;
this.addCoreProviders();
this._id = this.generateUuid();
}
get id() {
return this._id;
}
get token() {
return this._token;
}
set token(token) {
this._token = token;
}
get name() {
return this.metatype.name;
}
get isGlobal() {
return this._isGlobal;
}
set isGlobal(global) {
this._isGlobal = global;
}
get initOnPreview() {
return this._initOnPreview;
}
set initOnPreview(initOnPreview) {
this._initOnPreview = initOnPreview;
}
get providers() {
return this._providers;
}
get middlewares() {
return this._middlewares;
}
get imports() {
return this._imports;
}
get injectables() {
return this._injectables;
}
get controllers() {
return this._controllers;
}
get entryProviders() {
return Array.from(this._entryProviderKeys).map(token => this.providers.get(token));
}
get exports() {
return this._exports;
}
get instance() {
if (!this._providers.has(this._metatype)) {
throw new exceptions_1.RuntimeException();
}
const moduleRef = this._providers.get(this._metatype);
return moduleRef.instance;
}
get metatype() {
return this._metatype;
}
get distance() {
return this._distance;
}
set distance(value) {
this._distance = value;
}
addCoreProviders() {
this.addModuleAsProvider();
this.addModuleRef();
this.addApplicationConfig();
}
addModuleRef() {
const moduleRef = this.createModuleReferenceType();
this._providers.set(module_ref_1.ModuleRef, new instance_wrapper_1.InstanceWrapper({
token: module_ref_1.ModuleRef,
name: module_ref_1.ModuleRef.name,
metatype: module_ref_1.ModuleRef,
isResolved: true,
instance: new moduleRef(),
host: this,
}));
}
addModuleAsProvider() {
this._providers.set(this._metatype, new instance_wrapper_1.InstanceWrapper({
token: this._metatype,
name: this._metatype.name,
metatype: this._metatype,
isResolved: false,
instance: null,
host: this,
}));
}
addApplicationConfig() {
this._providers.set(application_config_1.ApplicationConfig, new instance_wrapper_1.InstanceWrapper({
token: application_config_1.ApplicationConfig,
name: application_config_1.ApplicationConfig.name,
isResolved: true,
instance: this.container.applicationConfig,
host: this,
}));
}
addInjectable(injectable, enhancerSubtype, host) {
if (this.isCustomProvider(injectable)) {
return this.addCustomProvider(injectable, this._injectables, enhancerSubtype);
}
let instanceWrapper = this.injectables.get(injectable);
if (!instanceWrapper) {
instanceWrapper = new instance_wrapper_1.InstanceWrapper({
token: injectable,
name: injectable.name,
metatype: injectable,
instance: null,
isResolved: false,
scope: (0, get_class_scope_1.getClassScope)(injectable),
durable: (0, is_durable_1.isDurable)(injectable),
subtype: enhancerSubtype,
host: this,
});
this._injectables.set(injectable, instanceWrapper);
}
if (host) {
const hostWrapper = this._controllers.get(host) || this._providers.get(host);
hostWrapper && hostWrapper.addEnhancerMetadata(instanceWrapper);
}
return instanceWrapper;
}
addProvider(provider, enhancerSubtype) {
if (this.isCustomProvider(provider)) {
if (this.isEntryProvider(provider.provide)) {
this._entryProviderKeys.add(provider.provide);
}
return this.addCustomProvider(provider, this._providers, enhancerSubtype);
}
const isAlreadyDeclared = this._providers.has(provider);
if ((this.isTransientProvider(provider) ||
this.isRequestScopeProvider(provider)) &&
isAlreadyDeclared) {
return provider;
}
this._providers.set(provider, new instance_wrapper_1.InstanceWrapper({
token: provider,
name: provider.name,
metatype: provider,
instance: null,
isResolved: false,
scope: (0, get_class_scope_1.getClassScope)(provider),
durable: (0, is_durable_1.isDurable)(provider),
host: this,
}));
if (this.isEntryProvider(provider)) {
this._entryProviderKeys.add(provider);
}
return provider;
}
isCustomProvider(provider) {
return !(0, shared_utils_1.isNil)(provider.provide);
}
addCustomProvider(provider, collection, enhancerSubtype) {
if (this.isCustomClass(provider)) {
this.addCustomClass(provider, collection, enhancerSubtype);
}
else if (this.isCustomValue(provider)) {
this.addCustomValue(provider, collection, enhancerSubtype);
}
else if (this.isCustomFactory(provider)) {
this.addCustomFactory(provider, collection, enhancerSubtype);
}
else if (this.isCustomUseExisting(provider)) {
this.addCustomUseExisting(provider, collection, enhancerSubtype);
}
return provider.provide;
}
isCustomClass(provider) {
return !(0, shared_utils_1.isUndefined)(provider.useClass);
}
isCustomValue(provider) {
return ((0, shared_utils_1.isObject)(provider) &&
Object.prototype.hasOwnProperty.call(provider, 'useValue'));
}
isCustomFactory(provider) {
return !(0, shared_utils_1.isUndefined)(provider.useFactory);
}
isCustomUseExisting(provider) {
return !(0, shared_utils_1.isUndefined)(provider.useExisting);
}
isDynamicModule(exported) {
return exported && exported.module;
}
addCustomClass(provider, collection, enhancerSubtype) {
let { scope, durable } = provider;
const { useClass } = provider;
if ((0, shared_utils_1.isUndefined)(scope)) {
scope = (0, get_class_scope_1.getClassScope)(useClass);
}
if ((0, shared_utils_1.isUndefined)(durable)) {
durable = (0, is_durable_1.isDurable)(useClass);
}
const token = provider.provide;
collection.set(token, new instance_wrapper_1.InstanceWrapper({
token,
name: useClass?.name || useClass,
metatype: useClass,
instance: null,
isResolved: false,
scope,
durable,
host: this,
subtype: enhancerSubtype,
}));
}
addCustomValue(provider, collection, enhancerSubtype) {
const { useValue: value, provide: providerToken } = provider;
const instanceDecorator = this.container.contextOptions?.instrument?.instanceDecorator;
collection.set(providerToken, new instance_wrapper_1.InstanceWrapper({
token: providerToken,
name: providerToken?.name || providerToken,
metatype: null,
instance: instanceDecorator ? instanceDecorator(value) : value,
isResolved: true,
async: value instanceof Promise,
host: this,
subtype: enhancerSubtype,
}));
}
addCustomFactory(provider, collection, enhancerSubtype) {
const { useFactory: factory, inject, scope, durable, provide: providerToken, } = provider;
collection.set(providerToken, new instance_wrapper_1.InstanceWrapper({
token: providerToken,
name: providerToken?.name || providerToken,
metatype: factory,
instance: null,
isResolved: false,
inject: inject || [],
scope,
durable,
host: this,
subtype: enhancerSubtype,
}));
}
addCustomUseExisting(provider, collection, enhancerSubtype) {
const { useExisting, provide: providerToken } = provider;
collection.set(providerToken, new instance_wrapper_1.InstanceWrapper({
token: providerToken,
name: providerToken?.name || providerToken,
metatype: (instance => instance),
instance: null,
isResolved: false,
inject: [useExisting],
host: this,
isAlias: true,
subtype: enhancerSubtype,
}));
}
addExportedProviderOrModule(toExport) {
const addExportedUnit = (token) => this._exports.add(this.validateExportedProvider(token));
if (this.isCustomProvider(toExport)) {
return this.addCustomExportedProvider(toExport);
}
else if ((0, shared_utils_1.isString)(toExport) || (0, shared_utils_1.isSymbol)(toExport)) {
return addExportedUnit(toExport);
}
else if (this.isDynamicModule(toExport)) {
const { module: moduleClassRef } = toExport;
return addExportedUnit(moduleClassRef);
}
addExportedUnit(toExport);
}
addCustomExportedProvider(provider) {
const provide = provider.provide;
if ((0, shared_utils_1.isString)(provide) || (0, shared_utils_1.isSymbol)(provide)) {
return this._exports.add(this.validateExportedProvider(provide));
}
this._exports.add(this.validateExportedProvider(provide));
}
validateExportedProvider(token) {
if (this._providers.has(token)) {
return token;
}
const imports = (0, iterare_1.iterate)(this._imports.values())
.filter(item => !!item)
.map(({ metatype }) => metatype)
.filter(metatype => !!metatype)
.toArray();
if (!imports.includes(token)) {
const { name } = this.metatype;
const providerName = (0, shared_utils_1.isFunction)(token) ? token.name : token;
throw new exceptions_1.UnknownExportException(providerName, name);
}
return token;
}
addController(controller) {
this._controllers.set(controller, new instance_wrapper_1.InstanceWrapper({
token: controller,
name: controller.name,
metatype: controller,
instance: null,
isResolved: false,
scope: (0, get_class_scope_1.getClassScope)(controller),
durable: (0, is_durable_1.isDurable)(controller),
host: this,
}));
this.assignControllerUniqueId(controller);
}
assignControllerUniqueId(controller) {
Object.defineProperty(controller, constants_2.CONTROLLER_ID_KEY, {
enumerable: false,
writable: false,
configurable: true,
value: (0, random_string_generator_util_1.randomStringGenerator)(),
});
}
addImport(moduleRef) {
this._imports.add(moduleRef);
}
replace(toReplace, options) {
if (options.isProvider && this.hasProvider(toReplace)) {
const originalProvider = this._providers.get(toReplace);
return originalProvider.mergeWith({ provide: toReplace, ...options });
}
else if (!options.isProvider && this.hasInjectable(toReplace)) {
const originalInjectable = this._injectables.get(toReplace);
return originalInjectable.mergeWith({
provide: toReplace,
...options,
});
}
}
hasProvider(token) {
return this._providers.has(token);
}
hasInjectable(token) {
return this._injectables.has(token);
}
getProviderByKey(name) {
return this._providers.get(name);
}
getProviderById(id) {
return Array.from(this._providers.values()).find(item => item.id === id);
}
getControllerById(id) {
return Array.from(this._controllers.values()).find(item => item.id === id);
}
getInjectableById(id) {
return Array.from(this._injectables.values()).find(item => item.id === id);
}
getMiddlewareById(id) {
return Array.from(this._middlewares.values()).find(item => item.id === id);
}
getNonAliasProviders() {
return [...this._providers].filter(([_, wrapper]) => !wrapper.isAlias);
}
createModuleReferenceType() {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;
return class extends module_ref_1.ModuleRef {
constructor() {
super(self.container);
}
get(typeOrToken, options = {}) {
options.strict ??= true;
options.each ??= false;
return this.find(typeOrToken, options.strict
? {
moduleId: self.id,
each: options.each,
}
: options);
}
resolve(typeOrToken, contextId = (0, context_id_factory_1.createContextId)(), options = {}) {
options.strict ??= true;
options.each ??= false;
return this.resolvePerContext(typeOrToken, self, contextId, options);
}
async create(type, contextId) {
if (!(type && (0, shared_utils_1.isFunction)(type) && type.prototype)) {
throw new exceptions_1.InvalidClassException(type);
}
return this.instantiateClass(type, self, contextId);
}
};
}
isEntryProvider(metatype) {
return typeof metatype === 'function'
? !!Reflect.getMetadata(constants_1.ENTRY_PROVIDER_WATERMARK, metatype)
: false;
}
generateUuid() {
const prefix = 'M_';
const key = this.token
? this.token.includes(':')
? this.token.split(':')[1]
: this.token
: this.name;
return key ? uuid_factory_1.UuidFactory.get(`${prefix}_${key}`) : (0, random_string_generator_util_1.randomStringGenerator)();
}
isTransientProvider(provider) {
return (0, get_class_scope_1.getClassScope)(provider) === interfaces_1.Scope.TRANSIENT;
}
isRequestScopeProvider(provider) {
return (0, get_class_scope_1.getClassScope)(provider) === interfaces_1.Scope.REQUEST;
}
}
exports.Module = Module;

View File

@@ -0,0 +1,27 @@
import { Observable } from 'rxjs';
import { Module } from './module';
export declare class ModulesContainer extends Map<string, Module> {
private readonly _applicationId;
private readonly _rpcTargetRegistry$;
/**
* Unique identifier of the application instance.
*/
get applicationId(): string;
/**
* Retrieves a module by its identifier.
* @param id The identifier of the module to retrieve.
* @returns The module instance if found, otherwise undefined.
*/
getById(id: string): Module | undefined;
/**
* Returns the RPC target registry as an observable.
* This registry contains all RPC targets registered in the application.
* @returns An observable that emits the RPC target registry.
*/
getRpcTargetRegistry<T>(): Observable<T>;
/**
* Adds an RPC target to the registry.
* @param target The RPC target to add.
*/
addRpcTarget<T>(target: T): void;
}

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModulesContainer = void 0;
const rxjs_1 = require("rxjs");
const uid_1 = require("uid");
class ModulesContainer extends Map {
constructor() {
super(...arguments);
this._applicationId = (0, uid_1.uid)(21);
this._rpcTargetRegistry$ = new rxjs_1.ReplaySubject();
}
/**
* Unique identifier of the application instance.
*/
get applicationId() {
return this._applicationId;
}
/**
* Retrieves a module by its identifier.
* @param id The identifier of the module to retrieve.
* @returns The module instance if found, otherwise undefined.
*/
getById(id) {
return Array.from(this.values()).find(moduleRef => moduleRef.id === id);
}
/**
* Returns the RPC target registry as an observable.
* This registry contains all RPC targets registered in the application.
* @returns An observable that emits the RPC target registry.
*/
getRpcTargetRegistry() {
return this._rpcTargetRegistry$.asObservable();
}
/**
* Adds an RPC target to the registry.
* @param target The RPC target to add.
*/
addRpcTarget(target) {
this._rpcTargetRegistry$.next(target);
}
}
exports.ModulesContainer = ModulesContainer;

View File

@@ -0,0 +1,15 @@
import { DynamicModule } from '@nestjs/common/interfaces/modules/dynamic-module.interface';
import { ForwardReference } from '@nestjs/common/interfaces/modules/forward-reference.interface';
import { Type } from '@nestjs/common/interfaces/type.interface';
import { ModuleOpaqueKeyFactory } from './interfaces/module-opaque-key-factory.interface';
export declare class ByReferenceModuleOpaqueKeyFactory implements ModuleOpaqueKeyFactory {
private readonly keyGenerationStrategy;
constructor(options?: {
keyGenerationStrategy: 'random' | 'shallow';
});
createForStatic(moduleCls: Type, originalRef?: Type | ForwardReference): string;
createForDynamic(moduleCls: Type<unknown>, dynamicMetadata: Omit<DynamicModule, 'module'>, originalRef: DynamicModule | ForwardReference): string;
private getOrCreateModuleId;
private hashString;
private generateRandomString;
}

View File

@@ -0,0 +1,41 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ByReferenceModuleOpaqueKeyFactory = void 0;
const random_string_generator_util_1 = require("@nestjs/common/utils/random-string-generator.util");
const crypto_1 = require("crypto");
const K_MODULE_ID = Symbol('K_MODULE_ID');
class ByReferenceModuleOpaqueKeyFactory {
constructor(options) {
this.keyGenerationStrategy = options?.keyGenerationStrategy ?? 'random';
}
createForStatic(moduleCls, originalRef = moduleCls) {
return this.getOrCreateModuleId(moduleCls, undefined, originalRef);
}
createForDynamic(moduleCls, dynamicMetadata, originalRef) {
return this.getOrCreateModuleId(moduleCls, dynamicMetadata, originalRef);
}
getOrCreateModuleId(moduleCls, dynamicMetadata, originalRef) {
if (originalRef[K_MODULE_ID]) {
return originalRef[K_MODULE_ID];
}
let moduleId;
if (this.keyGenerationStrategy === 'random') {
moduleId = this.generateRandomString();
}
else {
const delimiter = ':';
moduleId = dynamicMetadata
? `${this.generateRandomString()}${delimiter}${this.hashString(moduleCls.name + JSON.stringify(dynamicMetadata))}`
: `${this.generateRandomString()}${delimiter}${this.hashString(moduleCls.toString())}`;
}
originalRef[K_MODULE_ID] = moduleId;
return moduleId;
}
hashString(value) {
return (0, crypto_1.createHash)('sha256').update(value).digest('hex');
}
generateRandomString() {
return (0, random_string_generator_util_1.randomStringGenerator)();
}
}
exports.ByReferenceModuleOpaqueKeyFactory = ByReferenceModuleOpaqueKeyFactory;

View File

@@ -0,0 +1,15 @@
import { DynamicModule } from '@nestjs/common/interfaces/modules/dynamic-module.interface';
import { Type } from '@nestjs/common/interfaces/type.interface';
import { ModuleOpaqueKeyFactory } from './interfaces/module-opaque-key-factory.interface';
export declare class DeepHashedModuleOpaqueKeyFactory implements ModuleOpaqueKeyFactory {
private readonly moduleIdsCache;
private readonly moduleTokenCache;
private readonly logger;
createForStatic(moduleCls: Type): string;
createForDynamic(moduleCls: Type<unknown>, dynamicMetadata: Omit<DynamicModule, 'module'>): string;
getStringifiedOpaqueToken(opaqueToken: object | undefined): string;
getModuleId(metatype: Type<unknown>): string;
getModuleName(metatype: Type<any>): string;
private hashString;
private replacer;
}

View File

@@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeepHashedModuleOpaqueKeyFactory = void 0;
const logger_service_1 = require("@nestjs/common/services/logger.service");
const random_string_generator_util_1 = require("@nestjs/common/utils/random-string-generator.util");
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
const crypto_1 = require("crypto");
const fast_safe_stringify_1 = require("fast-safe-stringify");
const CLASS_STR = 'class ';
const CLASS_STR_LEN = CLASS_STR.length;
class DeepHashedModuleOpaqueKeyFactory {
constructor() {
this.moduleIdsCache = new WeakMap();
this.moduleTokenCache = new Map();
this.logger = new logger_service_1.Logger(DeepHashedModuleOpaqueKeyFactory.name, {
timestamp: true,
});
}
createForStatic(moduleCls) {
const moduleId = this.getModuleId(moduleCls);
const moduleName = this.getModuleName(moduleCls);
const key = `${moduleId}_${moduleName}`;
if (this.moduleTokenCache.has(key)) {
return this.moduleTokenCache.get(key);
}
const hash = this.hashString(key);
this.moduleTokenCache.set(key, hash);
return hash;
}
createForDynamic(moduleCls, dynamicMetadata) {
const moduleId = this.getModuleId(moduleCls);
const moduleName = this.getModuleName(moduleCls);
const opaqueToken = {
id: moduleId,
module: moduleName,
dynamic: dynamicMetadata,
};
const start = performance.now();
const opaqueTokenString = this.getStringifiedOpaqueToken(opaqueToken);
const timeSpentInMs = performance.now() - start;
if (timeSpentInMs > 10) {
const formattedTimeSpent = timeSpentInMs.toFixed(2);
this.logger.warn(`The module "${opaqueToken.module}" is taking ${formattedTimeSpent}ms to serialize, this may be caused by larger objects statically assigned to the module. Consider changing the "moduleIdGeneratorAlgorithm" option to "reference" to improve the performance.`);
}
return this.hashString(opaqueTokenString);
}
getStringifiedOpaqueToken(opaqueToken) {
// Uses safeStringify instead of JSON.stringify to support circular dynamic modules
// The replacer function is also required in order to obtain real class names
// instead of the unified "Function" key
return opaqueToken ? (0, fast_safe_stringify_1.default)(opaqueToken, this.replacer) : '';
}
getModuleId(metatype) {
let moduleId = this.moduleIdsCache.get(metatype);
if (moduleId) {
return moduleId;
}
moduleId = (0, random_string_generator_util_1.randomStringGenerator)();
this.moduleIdsCache.set(metatype, moduleId);
return moduleId;
}
getModuleName(metatype) {
return metatype.name;
}
hashString(value) {
return (0, crypto_1.createHash)('sha256').update(value).digest('hex');
}
replacer(key, value) {
if ((0, shared_utils_1.isFunction)(value)) {
const funcAsString = value.toString();
const isClass = funcAsString.slice(0, CLASS_STR_LEN) === CLASS_STR;
if (isClass) {
return value.name;
}
return funcAsString;
}
if ((0, shared_utils_1.isSymbol)(value)) {
return value.toString();
}
return value;
}
}
exports.DeepHashedModuleOpaqueKeyFactory = DeepHashedModuleOpaqueKeyFactory;

View File

@@ -0,0 +1,18 @@
import { DynamicModule } from '@nestjs/common/interfaces/modules/dynamic-module.interface';
import { ForwardReference } from '@nestjs/common/interfaces/modules/forward-reference.interface';
import { Type } from '@nestjs/common/interfaces/type.interface';
export interface ModuleOpaqueKeyFactory {
/**
* Creates a unique opaque key for the given static module.
* @param moduleCls A static module class.
* @param originalRef Original object reference. In most cases, it's the same as `moduleCls`.
*/
createForStatic(moduleCls: Type, originalRef: Type | ForwardReference): string;
/**
* Creates a unique opaque key for the given dynamic module.
* @param moduleCls A dynamic module class reference.
* @param dynamicMetadata Dynamic module metadata.
* @param originalRef Original object reference.
*/
createForDynamic(moduleCls: Type<unknown>, dynamicMetadata: Omit<DynamicModule, 'module'>, originalRef: DynamicModule | ForwardReference): string;
}

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,37 @@
/**
* SettlementSignal is used to signal the resolution of a provider/instance.
* Calling `complete` or `error` will resolve the promise returned by `asPromise`.
* Can be used to detect circular dependencies.
*/
export declare class SettlementSignal {
private readonly _refs;
private readonly settledPromise;
private settleFn;
private completed;
constructor();
/**
* Resolves the promise returned by `asPromise`.
*/
complete(): void;
/**
* Rejects the promise returned by `asPromise` with the given error.
* @param err Error to reject the promise returned by `asPromise` with.
*/
error(err: unknown): void;
/**
* Returns a promise that will be resolved when `complete` or `error` is called.
* @returns Promise that will be resolved when `complete` or `error` is called.
*/
asPromise(): Promise<unknown>;
/**
* Inserts a wrapper id that the host of this signal depends on.
* @param wrapperId Wrapper id to insert.
*/
insertRef(wrapperId: string): void;
/**
* Check if relationship is circular.
* @param wrapperId Wrapper id to check.
* @returns True if relationship is circular, false otherwise.
*/
isCycle(wrapperId: string): boolean;
}

View File

@@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SettlementSignal = void 0;
/**
* SettlementSignal is used to signal the resolution of a provider/instance.
* Calling `complete` or `error` will resolve the promise returned by `asPromise`.
* Can be used to detect circular dependencies.
*/
class SettlementSignal {
constructor() {
this._refs = new Set();
this.completed = false;
this.settledPromise = new Promise(resolve => {
this.settleFn = resolve;
});
}
/**
* Resolves the promise returned by `asPromise`.
*/
complete() {
this.completed = true;
this.settleFn();
}
/**
* Rejects the promise returned by `asPromise` with the given error.
* @param err Error to reject the promise returned by `asPromise` with.
*/
error(err) {
this.completed = true;
this.settleFn(err);
}
/**
* Returns a promise that will be resolved when `complete` or `error` is called.
* @returns Promise that will be resolved when `complete` or `error` is called.
*/
asPromise() {
return this.settledPromise;
}
/**
* Inserts a wrapper id that the host of this signal depends on.
* @param wrapperId Wrapper id to insert.
*/
insertRef(wrapperId) {
this._refs.add(wrapperId);
}
/**
* Check if relationship is circular.
* @param wrapperId Wrapper id to check.
* @returns True if relationship is circular, false otherwise.
*/
isCycle(wrapperId) {
return !this.completed && this._refs.has(wrapperId);
}
}
exports.SettlementSignal = SettlementSignal;

View File

@@ -0,0 +1,8 @@
import { Module } from '../module';
export declare class TopologyTree {
private root;
private links;
constructor(moduleRef: Module);
walk(callback: (value: Module, depth: number) => void): void;
private traverseAndMapToTree;
}

View File

@@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TopologyTree = void 0;
const tree_node_1 = require("./tree-node");
class TopologyTree {
constructor(moduleRef) {
this.links = new Map();
this.root = new tree_node_1.TreeNode({
value: moduleRef,
parent: null,
});
this.links.set(moduleRef, this.root);
this.traverseAndMapToTree(this.root);
}
walk(callback) {
function walkNode(node, depth = 1) {
callback(node.value, depth);
node.children.forEach(child => walkNode(child, depth + 1));
}
walkNode(this.root);
}
traverseAndMapToTree(node, depth = 1) {
if (!node.value.imports) {
return;
}
node.value.imports.forEach(child => {
if (!child) {
return;
}
if (this.links.has(child)) {
const existingSubtree = this.links.get(child);
if (node.hasCycleWith(child)) {
return;
}
const existingDepth = existingSubtree.getDepth();
if (existingDepth < depth) {
existingSubtree.relink(node);
}
return;
}
const childNode = new tree_node_1.TreeNode({
value: child,
parent: node,
});
node.addChild(childNode);
this.links.set(child, childNode);
this.traverseAndMapToTree(childNode, depth + 1);
});
}
}
exports.TopologyTree = TopologyTree;

View File

@@ -0,0 +1,14 @@
export declare class TreeNode<T> {
readonly value: T;
readonly children: Set<TreeNode<T>>;
private parent;
constructor({ value, parent }: {
value: T;
parent: TreeNode<T> | null;
});
addChild(child: TreeNode<T>): void;
removeChild(child: TreeNode<T>): void;
relink(parent: TreeNode<T>): void;
getDepth(): number;
hasCycleWith(target: T): boolean;
}

View File

@@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TreeNode = void 0;
class TreeNode {
constructor({ value, parent }) {
this.children = new Set();
this.value = value;
this.parent = parent;
}
addChild(child) {
this.children.add(child);
}
removeChild(child) {
this.children.delete(child);
}
relink(parent) {
this.parent?.removeChild(this);
this.parent = parent;
this.parent.addChild(this);
}
getDepth() {
const visited = new Set();
let depth = 0;
// eslint-disable-next-line @typescript-eslint/no-this-alias
let current = this;
while (current) {
depth++;
current = current.parent;
// Stop on cycle
if (visited.has(current)) {
return -1;
}
visited.add(current);
}
return depth;
}
hasCycleWith(target) {
const visited = new Set();
// eslint-disable-next-line @typescript-eslint/no-this-alias
let current = this;
while (current) {
if (current.value === target) {
return true;
}
current = current.parent;
if (visited.has(current)) {
return false;
}
visited.add(current);
}
return false;
}
}
exports.TreeNode = TreeNode;