mirror of
https://github.com/nestjs/nest.git
synced 2026-02-22 23:41:40 +00:00
feat(core): use class refs as keys (container)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { CanActivate } from '@nestjs/common';
|
||||
import { GUARDS_METADATA } from '@nestjs/common/constants';
|
||||
import { Controller } from '@nestjs/common/interfaces';
|
||||
import { Controller, Type } from '@nestjs/common/interfaces';
|
||||
import { isEmpty, isFunction } from '@nestjs/common/utils/shared.utils';
|
||||
import { iterate } from 'iterare';
|
||||
import { ApplicationConfig } from '../application-config';
|
||||
@@ -54,15 +54,17 @@ export class GuardsContextCreator extends ContextCreator {
|
||||
}
|
||||
|
||||
public getGuardInstance(
|
||||
guard: Function | CanActivate,
|
||||
metatype: Function | CanActivate,
|
||||
contextId = STATIC_CONTEXT,
|
||||
inquirerId?: string,
|
||||
): CanActivate | null {
|
||||
const isObject = (guard as CanActivate).canActivate;
|
||||
const isObject = (metatype as CanActivate).canActivate;
|
||||
if (isObject) {
|
||||
return guard as CanActivate;
|
||||
return metatype as CanActivate;
|
||||
}
|
||||
const instanceWrapper = this.getInstanceByMetatype(guard);
|
||||
const instanceWrapper = this.getInstanceByMetatype(
|
||||
metatype as Type<unknown>,
|
||||
);
|
||||
if (!instanceWrapper) {
|
||||
return null;
|
||||
}
|
||||
@@ -73,8 +75,8 @@ export class GuardsContextCreator extends ContextCreator {
|
||||
return instanceHost && instanceHost.instance;
|
||||
}
|
||||
|
||||
public getInstanceByMetatype<T extends Record<string, any> | Function>(
|
||||
guard: T,
|
||||
public getInstanceByMetatype(
|
||||
metatype: Type<unknown>,
|
||||
): InstanceWrapper | undefined {
|
||||
if (!this.moduleContext) {
|
||||
return;
|
||||
@@ -85,7 +87,7 @@ export class GuardsContextCreator extends ContextCreator {
|
||||
return;
|
||||
}
|
||||
const injectables = moduleRef.injectables;
|
||||
return injectables.get(guard.name as string);
|
||||
return injectables.get(metatype);
|
||||
}
|
||||
|
||||
public getGlobalMetadata<T extends unknown[]>(
|
||||
|
||||
@@ -13,7 +13,6 @@ import { GuardsContextCreator } from '../guards/guards-context-creator';
|
||||
import { STATIC_CONTEXT } from '../injector/constants';
|
||||
import { NestContainer } from '../injector/container';
|
||||
import { ContextId } from '../injector/instance-wrapper';
|
||||
import { Module } from '../injector/module';
|
||||
import { ModulesContainer } from '../injector/modules-container';
|
||||
import { InterceptorsConsumer } from '../interceptors/interceptors-consumer';
|
||||
import { InterceptorsContextCreator } from '../interceptors/interceptors-context-creator';
|
||||
@@ -38,9 +37,7 @@ export interface ExternalContextOptions {
|
||||
export class ExternalContextCreator {
|
||||
private readonly contextUtils = new ContextUtils();
|
||||
private readonly externalErrorProxy = new ExternalErrorProxy();
|
||||
private readonly handlerMetadataStorage = new HandlerMetadataStorage<
|
||||
ExternalHandlerMetadata
|
||||
>();
|
||||
private readonly handlerMetadataStorage = new HandlerMetadataStorage<ExternalHandlerMetadata>();
|
||||
private container: NestContainer;
|
||||
|
||||
constructor(
|
||||
@@ -107,7 +104,7 @@ export class ExternalContextCreator {
|
||||
},
|
||||
contextType: TContext = 'http' as TContext,
|
||||
) {
|
||||
const module = this.getContextModuleName(instance.constructor);
|
||||
const module = this.getContextModuleKey(instance.constructor);
|
||||
const { argsLength, paramtypes, getParamsMetadata } = this.getMetadata<
|
||||
TParamsMetadata,
|
||||
TContext
|
||||
@@ -240,26 +237,18 @@ export class ExternalContextCreator {
|
||||
return handlerMetadata;
|
||||
}
|
||||
|
||||
public getContextModuleName(constructor: Function): string {
|
||||
const defaultModuleName = '';
|
||||
const className = constructor.name;
|
||||
if (!className) {
|
||||
return defaultModuleName;
|
||||
public getContextModuleKey(moduleCtor: Function | undefined): string {
|
||||
const emptyModuleKey = '';
|
||||
if (!moduleCtor) {
|
||||
return emptyModuleKey;
|
||||
}
|
||||
for (const [key, module] of [...this.modulesContainer.entries()]) {
|
||||
if (this.getProviderByClassName(module, className)) {
|
||||
const moduleContainerEntries = this.modulesContainer.entries();
|
||||
for (const [key, moduleRef] of moduleContainerEntries) {
|
||||
if (moduleRef.hasProvider(moduleCtor)) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return defaultModuleName;
|
||||
}
|
||||
|
||||
public getProviderByClassName(module: Module, className: string): boolean {
|
||||
const { providers } = module;
|
||||
const hasProvider = [...providers.keys()].some(
|
||||
provider => provider === className,
|
||||
);
|
||||
return hasProvider;
|
||||
return emptyModuleKey;
|
||||
}
|
||||
|
||||
public exchangeKeysForValues<TMetadata = any>(
|
||||
|
||||
@@ -143,7 +143,10 @@ export class NestContainer {
|
||||
moduleRef.addRelatedModule(related);
|
||||
}
|
||||
|
||||
public addProvider(provider: Provider, token: string): string {
|
||||
public addProvider(
|
||||
provider: Provider,
|
||||
token: string,
|
||||
): string | symbol | Function {
|
||||
if (!provider) {
|
||||
throw new CircularDependencyException();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { iterate } from 'iterare';
|
||||
import { InstanceWrapper } from '../instance-wrapper';
|
||||
import { InstanceToken } from '../module';
|
||||
|
||||
/**
|
||||
* Returns the instances which are transient
|
||||
* @param instances The instances which should be checked whether they are transcient
|
||||
*/
|
||||
export function getTransientInstances(
|
||||
instances: [string, InstanceWrapper][],
|
||||
instances: [InstanceToken, InstanceWrapper][],
|
||||
): InstanceWrapper[] {
|
||||
return iterate(instances)
|
||||
.filter(([_, wrapper]) => wrapper.isDependencyTreeStatic())
|
||||
@@ -22,7 +23,7 @@ export function getTransientInstances(
|
||||
* @param instances The instances which should be checked whether they are transcient
|
||||
*/
|
||||
export function getNonTransientInstances(
|
||||
instances: [string, InstanceWrapper][],
|
||||
instances: [InstanceToken, InstanceWrapper][],
|
||||
): InstanceWrapper[] {
|
||||
return iterate(instances)
|
||||
.filter(
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
InstanceWrapper,
|
||||
PropertyMetadata,
|
||||
} from './instance-wrapper';
|
||||
import { Module } from './module';
|
||||
import { InstanceToken, Module } from './module';
|
||||
|
||||
/**
|
||||
* The type of an injectable dependency
|
||||
@@ -69,27 +69,27 @@ export interface InjectorDependencyContext {
|
||||
|
||||
export class Injector {
|
||||
public loadPrototype<T>(
|
||||
{ name }: InstanceWrapper<T>,
|
||||
collection: Map<string, InstanceWrapper<T>>,
|
||||
{ token }: InstanceWrapper<T>,
|
||||
collection: Map<InstanceToken, InstanceWrapper<T>>,
|
||||
contextId = STATIC_CONTEXT,
|
||||
) {
|
||||
if (!collection) {
|
||||
return;
|
||||
}
|
||||
const target = collection.get(name);
|
||||
const target = collection.get(token);
|
||||
const instance = target.createPrototype(contextId);
|
||||
if (instance) {
|
||||
const wrapper = new InstanceWrapper({
|
||||
...target,
|
||||
instance,
|
||||
});
|
||||
collection.set(name, wrapper);
|
||||
collection.set(token, wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
public async loadInstance<T>(
|
||||
wrapper: InstanceWrapper<T>,
|
||||
collection: Map<string, InstanceWrapper>,
|
||||
collection: Map<InstanceToken, InstanceWrapper>,
|
||||
moduleRef: Module,
|
||||
contextId = STATIC_CONTEXT,
|
||||
inquirer?: InstanceWrapper,
|
||||
@@ -100,9 +100,10 @@ export class Injector {
|
||||
return instanceHost.donePromise;
|
||||
}
|
||||
const done = this.applyDoneHook(instanceHost);
|
||||
const { name, inject } = wrapper;
|
||||
const token = wrapper.token || wrapper.name;
|
||||
|
||||
const targetWrapper = collection.get(name);
|
||||
const { inject } = wrapper;
|
||||
const targetWrapper = collection.get(token);
|
||||
if (isUndefined(targetWrapper)) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
@@ -141,13 +142,13 @@ export class Injector {
|
||||
|
||||
public async loadMiddleware(
|
||||
wrapper: InstanceWrapper,
|
||||
collection: Map<string, InstanceWrapper>,
|
||||
collection: Map<InstanceToken, InstanceWrapper>,
|
||||
moduleRef: Module,
|
||||
contextId = STATIC_CONTEXT,
|
||||
inquirer?: InstanceWrapper,
|
||||
) {
|
||||
const { metatype } = wrapper;
|
||||
const targetWrapper = collection.get(metatype.name);
|
||||
const { metatype, token } = wrapper;
|
||||
const targetWrapper = collection.get(token);
|
||||
if (!isUndefined(targetWrapper.instance)) {
|
||||
return;
|
||||
}
|
||||
@@ -338,7 +339,7 @@ export class Injector {
|
||||
|
||||
public async resolveComponentInstance<T>(
|
||||
moduleRef: Module,
|
||||
name: any,
|
||||
token: InstanceToken,
|
||||
dependencyContext: InjectorDependencyContext,
|
||||
wrapper: InstanceWrapper<T>,
|
||||
contextId = STATIC_CONTEXT,
|
||||
@@ -349,7 +350,7 @@ export class Injector {
|
||||
const instanceWrapper = await this.lookupComponent(
|
||||
providers,
|
||||
moduleRef,
|
||||
{ ...dependencyContext, name },
|
||||
{ ...dependencyContext, name: token },
|
||||
wrapper,
|
||||
contextId,
|
||||
inquirer,
|
||||
@@ -466,7 +467,7 @@ export class Injector {
|
||||
|
||||
public async lookupComponentInImports(
|
||||
moduleRef: Module,
|
||||
name: any,
|
||||
name: InstanceToken,
|
||||
wrapper: InstanceWrapper,
|
||||
moduleRegistry: any[] = [],
|
||||
contextId = STATIC_CONTEXT,
|
||||
@@ -483,7 +484,7 @@ export class Injector {
|
||||
if (isTraversing) {
|
||||
const contextModuleExports = moduleRef.exports;
|
||||
children = children.filter(child =>
|
||||
contextModuleExports.has(child.metatype && child.metatype.name),
|
||||
contextModuleExports.has(child.metatype),
|
||||
);
|
||||
}
|
||||
for (const relatedModule of children) {
|
||||
@@ -655,15 +656,12 @@ export class Injector {
|
||||
public async loadPerContext<T = any>(
|
||||
instance: T,
|
||||
moduleRef: Module,
|
||||
collection: Map<string, InstanceWrapper>,
|
||||
collection: Map<InstanceToken, InstanceWrapper>,
|
||||
ctx: ContextId,
|
||||
wrapper?: InstanceWrapper,
|
||||
): Promise<T> {
|
||||
if (!wrapper) {
|
||||
const providerCtor = instance.constructor;
|
||||
const injectionToken =
|
||||
(providerCtor && providerCtor.name) ||
|
||||
((providerCtor as unknown) as string);
|
||||
const injectionToken = instance.constructor;
|
||||
wrapper = collection.get(injectionToken);
|
||||
}
|
||||
await this.loadInstance(wrapper, collection, moduleRef, ctx, wrapper);
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { Abstract, Type } from '@nestjs/common';
|
||||
import { isFunction } from '@nestjs/common/utils/shared.utils';
|
||||
import { UnknownElementException } from '../errors/exceptions/unknown-element.exception';
|
||||
import { NestContainer } from './container';
|
||||
import { InstanceWrapper } from './instance-wrapper';
|
||||
import { Module } from './module';
|
||||
import { InstanceToken, Module } from './module';
|
||||
|
||||
type InstanceToken = string | symbol | Type<any> | Abstract<any> | Function;
|
||||
type HostCollection = 'providers' | 'controllers' | 'injectables';
|
||||
|
||||
export interface InstanceLink<T = any> {
|
||||
@@ -23,20 +21,17 @@ export class InstanceLinksHost {
|
||||
}
|
||||
|
||||
get<T = any>(token: InstanceToken, moduleId?: string): InstanceLink<T> {
|
||||
const name = isFunction(token)
|
||||
? (token as Function).name
|
||||
: (token as string | symbol);
|
||||
const modulesMap = this.instanceLinks.get(name);
|
||||
const modulesMap = this.instanceLinks.get(token);
|
||||
|
||||
if (!modulesMap) {
|
||||
throw new UnknownElementException(name);
|
||||
throw new UnknownElementException(this.getInstanceNameByToken(token));
|
||||
}
|
||||
const instanceLink = moduleId
|
||||
? modulesMap.find(item => item.moduleId === moduleId)
|
||||
: modulesMap[modulesMap.length - 1];
|
||||
|
||||
if (!instanceLink) {
|
||||
throw new UnknownElementException(name);
|
||||
throw new UnknownElementException(this.getInstanceNameByToken(token));
|
||||
}
|
||||
return instanceLink;
|
||||
}
|
||||
@@ -76,4 +71,8 @@ export class InstanceLinksHost {
|
||||
existingLinks.push(instanceLink);
|
||||
}
|
||||
}
|
||||
|
||||
private getInstanceNameByToken(token: InstanceToken): string {
|
||||
return isFunction(token) ? (token as Function)?.name : (token as string);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,69 +21,69 @@ export class InstanceLoader {
|
||||
}
|
||||
|
||||
private createPrototypes(modules: Map<string, Module>) {
|
||||
modules.forEach(module => {
|
||||
this.createPrototypesOfProviders(module);
|
||||
this.createPrototypesOfInjectables(module);
|
||||
this.createPrototypesOfControllers(module);
|
||||
modules.forEach(moduleRef => {
|
||||
this.createPrototypesOfProviders(moduleRef);
|
||||
this.createPrototypesOfInjectables(moduleRef);
|
||||
this.createPrototypesOfControllers(moduleRef);
|
||||
});
|
||||
}
|
||||
|
||||
private async createInstances(modules: Map<string, Module>) {
|
||||
await Promise.all(
|
||||
[...modules.values()].map(async module => {
|
||||
await this.createInstancesOfProviders(module);
|
||||
await this.createInstancesOfInjectables(module);
|
||||
await this.createInstancesOfControllers(module);
|
||||
[...modules.values()].map(async moduleRef => {
|
||||
await this.createInstancesOfProviders(moduleRef);
|
||||
await this.createInstancesOfInjectables(moduleRef);
|
||||
await this.createInstancesOfControllers(moduleRef);
|
||||
|
||||
const { name } = module.metatype;
|
||||
const { name } = moduleRef.metatype;
|
||||
this.isModuleWhitelisted(name) &&
|
||||
this.logger.log(MODULE_INIT_MESSAGE`${name}`);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
private createPrototypesOfProviders(module: Module) {
|
||||
const { providers } = module;
|
||||
private createPrototypesOfProviders(moduleRef: Module) {
|
||||
const { providers } = moduleRef;
|
||||
providers.forEach(wrapper =>
|
||||
this.injector.loadPrototype<Injectable>(wrapper, providers),
|
||||
);
|
||||
}
|
||||
|
||||
private async createInstancesOfProviders(module: Module) {
|
||||
const { providers } = module;
|
||||
private async createInstancesOfProviders(moduleRef: Module) {
|
||||
const { providers } = moduleRef;
|
||||
const wrappers = [...providers.values()];
|
||||
await Promise.all(
|
||||
wrappers.map(item => this.injector.loadProvider(item, module)),
|
||||
wrappers.map(item => this.injector.loadProvider(item, moduleRef)),
|
||||
);
|
||||
}
|
||||
|
||||
private createPrototypesOfControllers(module: Module) {
|
||||
const { controllers } = module;
|
||||
private createPrototypesOfControllers(moduleRef: Module) {
|
||||
const { controllers } = moduleRef;
|
||||
controllers.forEach(wrapper =>
|
||||
this.injector.loadPrototype<Controller>(wrapper, controllers),
|
||||
);
|
||||
}
|
||||
|
||||
private async createInstancesOfControllers(module: Module) {
|
||||
const { controllers } = module;
|
||||
private async createInstancesOfControllers(moduleRef: Module) {
|
||||
const { controllers } = moduleRef;
|
||||
const wrappers = [...controllers.values()];
|
||||
await Promise.all(
|
||||
wrappers.map(item => this.injector.loadController(item, module)),
|
||||
wrappers.map(item => this.injector.loadController(item, moduleRef)),
|
||||
);
|
||||
}
|
||||
|
||||
private createPrototypesOfInjectables(module: Module) {
|
||||
const { injectables } = module;
|
||||
private createPrototypesOfInjectables(moduleRef: Module) {
|
||||
const { injectables } = moduleRef;
|
||||
injectables.forEach(wrapper =>
|
||||
this.injector.loadPrototype(wrapper, injectables),
|
||||
);
|
||||
}
|
||||
|
||||
private async createInstancesOfInjectables(module: Module) {
|
||||
const { injectables } = module;
|
||||
private async createInstancesOfInjectables(moduleRef: Module) {
|
||||
const { injectables } = moduleRef;
|
||||
const wrappers = [...injectables.values()];
|
||||
await Promise.all(
|
||||
wrappers.map(item => this.injector.loadInjectable(item, module)),
|
||||
wrappers.map(item => this.injector.loadInjectable(item, moduleRef)),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { randomStringGenerator } from '@nestjs/common/utils/random-string-genera
|
||||
import { isNil, isUndefined } from '@nestjs/common/utils/shared.utils';
|
||||
import { iterate } from 'iterare';
|
||||
import { STATIC_CONTEXT } from './constants';
|
||||
import { Module } from './module';
|
||||
import { InstanceToken, Module } from './module';
|
||||
|
||||
export const INSTANCE_METADATA_SYMBOL = Symbol.for('instance_metadata:cache');
|
||||
export const INSTANCE_ID_SYMBOL = Symbol.for('instance_metadata:id');
|
||||
@@ -36,6 +36,7 @@ interface InstanceMetadataStore {
|
||||
|
||||
export class InstanceWrapper<T = any> {
|
||||
public readonly name: any;
|
||||
public readonly token: InstanceToken;
|
||||
public readonly async?: boolean;
|
||||
public readonly host?: Module;
|
||||
public readonly isAlias: boolean = false;
|
||||
|
||||
@@ -31,21 +31,33 @@ import { NestContainer } from './container';
|
||||
import { InstanceWrapper } from './instance-wrapper';
|
||||
import { ModuleRef } from './module-ref';
|
||||
|
||||
interface ProviderName {
|
||||
name?: string | symbol;
|
||||
}
|
||||
export type InstanceToken =
|
||||
| string
|
||||
| symbol
|
||||
| Type<any>
|
||||
| Abstract<any>
|
||||
| Function;
|
||||
|
||||
export class Module {
|
||||
private readonly _id: string;
|
||||
private readonly _imports = new Set<Module>();
|
||||
private readonly _providers = new Map<any, InstanceWrapper<Injectable>>();
|
||||
private readonly _injectables = new Map<any, InstanceWrapper<Injectable>>();
|
||||
private readonly _middlewares = new Map<any, InstanceWrapper<Injectable>>();
|
||||
private readonly _providers = new Map<
|
||||
InstanceToken,
|
||||
InstanceWrapper<Injectable>
|
||||
>();
|
||||
private readonly _injectables = new Map<
|
||||
InstanceToken,
|
||||
InstanceWrapper<Injectable>
|
||||
>();
|
||||
private readonly _middlewares = new Map<
|
||||
InstanceToken,
|
||||
InstanceWrapper<Injectable>
|
||||
>();
|
||||
private readonly _controllers = new Map<
|
||||
string,
|
||||
InstanceToken,
|
||||
InstanceWrapper<Controller>
|
||||
>();
|
||||
private readonly _exports = new Set<string | symbol>();
|
||||
private readonly _exports = new Set<InstanceToken>();
|
||||
private _distance = 0;
|
||||
|
||||
constructor(
|
||||
@@ -60,11 +72,11 @@ export class Module {
|
||||
return this._id;
|
||||
}
|
||||
|
||||
get providers(): Map<any, InstanceWrapper<Injectable>> {
|
||||
get providers(): Map<InstanceToken, InstanceWrapper<Injectable>> {
|
||||
return this._providers;
|
||||
}
|
||||
|
||||
get middlewares(): Map<any, InstanceWrapper<Injectable>> {
|
||||
get middlewares(): Map<InstanceToken, InstanceWrapper<Injectable>> {
|
||||
return this._middlewares;
|
||||
}
|
||||
|
||||
@@ -82,34 +94,34 @@ export class Module {
|
||||
/**
|
||||
* Left for backward-compatibility reasons
|
||||
*/
|
||||
get components(): Map<string, InstanceWrapper<Injectable>> {
|
||||
get components(): Map<InstanceToken, InstanceWrapper<Injectable>> {
|
||||
return this._providers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Left for backward-compatibility reasons
|
||||
*/
|
||||
get routes(): Map<string, InstanceWrapper<Controller>> {
|
||||
get routes(): Map<InstanceToken, InstanceWrapper<Controller>> {
|
||||
return this._controllers;
|
||||
}
|
||||
|
||||
get injectables(): Map<string, InstanceWrapper<Injectable>> {
|
||||
get injectables(): Map<InstanceToken, InstanceWrapper<Injectable>> {
|
||||
return this._injectables;
|
||||
}
|
||||
|
||||
get controllers(): Map<string, InstanceWrapper<Controller>> {
|
||||
get controllers(): Map<InstanceToken, InstanceWrapper<Controller>> {
|
||||
return this._controllers;
|
||||
}
|
||||
|
||||
get exports(): Set<string | symbol> {
|
||||
get exports(): Set<InstanceToken> {
|
||||
return this._exports;
|
||||
}
|
||||
|
||||
get instance(): NestModule {
|
||||
if (!this._providers.has(this._metatype.name)) {
|
||||
if (!this._providers.has(this._metatype)) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
const module = this._providers.get(this._metatype.name);
|
||||
const module = this._providers.get(this._metatype);
|
||||
return module.instance as NestModule;
|
||||
}
|
||||
|
||||
@@ -134,8 +146,9 @@ export class Module {
|
||||
public addModuleRef() {
|
||||
const moduleRef = this.createModuleReferenceType();
|
||||
this._providers.set(
|
||||
ModuleRef.name,
|
||||
ModuleRef,
|
||||
new InstanceWrapper({
|
||||
token: ModuleRef,
|
||||
name: ModuleRef.name,
|
||||
metatype: ModuleRef as any,
|
||||
isResolved: true,
|
||||
@@ -147,8 +160,9 @@ export class Module {
|
||||
|
||||
public addModuleAsProvider() {
|
||||
this._providers.set(
|
||||
this._metatype.name,
|
||||
this._metatype,
|
||||
new InstanceWrapper({
|
||||
token: this._metatype,
|
||||
name: this._metatype.name,
|
||||
metatype: this._metatype,
|
||||
isResolved: false,
|
||||
@@ -160,8 +174,9 @@ export class Module {
|
||||
|
||||
public addApplicationConfig() {
|
||||
this._providers.set(
|
||||
ApplicationConfig.name,
|
||||
ApplicationConfig,
|
||||
new InstanceWrapper({
|
||||
token: ApplicationConfig,
|
||||
name: ApplicationConfig.name,
|
||||
isResolved: true,
|
||||
instance: this.container.applicationConfig,
|
||||
@@ -177,9 +192,10 @@ export class Module {
|
||||
if (this.isCustomProvider(injectable)) {
|
||||
return this.addCustomProvider(injectable, this._injectables);
|
||||
}
|
||||
let instanceWrapper = this.injectables.get(injectable.name);
|
||||
let instanceWrapper = this.injectables.get(injectable);
|
||||
if (!instanceWrapper) {
|
||||
instanceWrapper = new InstanceWrapper({
|
||||
token: injectable,
|
||||
name: injectable.name,
|
||||
metatype: injectable,
|
||||
instance: null,
|
||||
@@ -187,23 +203,23 @@ export class Module {
|
||||
scope: getClassScope(injectable),
|
||||
host: this,
|
||||
});
|
||||
this._injectables.set(injectable.name, instanceWrapper);
|
||||
this._injectables.set(injectable, instanceWrapper);
|
||||
}
|
||||
if (host) {
|
||||
const token = host && host.name;
|
||||
const hostWrapper =
|
||||
this._controllers.get(host && host.name) || this._providers.get(token);
|
||||
this._controllers.get(host) || this._providers.get(host);
|
||||
hostWrapper && hostWrapper.addEnhancerMetadata(instanceWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
public addProvider(provider: Provider): string {
|
||||
public addProvider(provider: Provider) {
|
||||
if (this.isCustomProvider(provider)) {
|
||||
return this.addCustomProvider(provider, this._providers);
|
||||
}
|
||||
this._providers.set(
|
||||
(provider as Type<Injectable>).name,
|
||||
provider,
|
||||
new InstanceWrapper({
|
||||
token: provider,
|
||||
name: (provider as Type<Injectable>).name,
|
||||
metatype: provider as Type<Injectable>,
|
||||
instance: null,
|
||||
@@ -212,7 +228,7 @@ export class Module {
|
||||
host: this,
|
||||
}),
|
||||
);
|
||||
return (provider as Type<Injectable>).name;
|
||||
return provider as Type<Injectable>;
|
||||
}
|
||||
|
||||
public isCustomProvider(
|
||||
@@ -232,20 +248,13 @@ export class Module {
|
||||
}
|
||||
|
||||
public addCustomProvider(
|
||||
provider: (
|
||||
provider:
|
||||
| ClassProvider
|
||||
| FactoryProvider
|
||||
| ValueProvider
|
||||
| ExistingProvider
|
||||
) &
|
||||
ProviderName,
|
||||
collection: Map<string, any>,
|
||||
): string {
|
||||
const name = this.getProviderStaticToken(provider.provide) as string;
|
||||
provider = {
|
||||
...provider,
|
||||
name,
|
||||
};
|
||||
| ExistingProvider,
|
||||
collection: Map<Function | string | symbol, any>,
|
||||
) {
|
||||
if (this.isCustomClass(provider)) {
|
||||
this.addCustomClass(provider, collection);
|
||||
} else if (this.isCustomValue(provider)) {
|
||||
@@ -255,7 +264,7 @@ export class Module {
|
||||
} else if (this.isCustomUseExisting(provider)) {
|
||||
this.addCustomUseExisting(provider, collection);
|
||||
}
|
||||
return name;
|
||||
return provider.provide;
|
||||
}
|
||||
|
||||
public isCustomClass(provider: any): provider is ClassProvider {
|
||||
@@ -279,19 +288,20 @@ export class Module {
|
||||
}
|
||||
|
||||
public addCustomClass(
|
||||
provider: ClassProvider & ProviderName,
|
||||
collection: Map<string, InstanceWrapper>,
|
||||
provider: ClassProvider,
|
||||
collection: Map<InstanceToken, InstanceWrapper>,
|
||||
) {
|
||||
const { name, useClass } = provider;
|
||||
|
||||
let { scope } = provider;
|
||||
|
||||
const { useClass } = provider;
|
||||
if (isUndefined(scope)) {
|
||||
scope = getClassScope(useClass);
|
||||
}
|
||||
collection.set(
|
||||
name as string,
|
||||
provider.provide,
|
||||
new InstanceWrapper({
|
||||
name,
|
||||
token: provider.provide,
|
||||
name: useClass?.name || useClass,
|
||||
metatype: useClass,
|
||||
instance: null,
|
||||
isResolved: false,
|
||||
@@ -302,14 +312,15 @@ export class Module {
|
||||
}
|
||||
|
||||
public addCustomValue(
|
||||
provider: ValueProvider & ProviderName,
|
||||
collection: Map<string, InstanceWrapper>,
|
||||
provider: ValueProvider,
|
||||
collection: Map<Function | string | symbol, InstanceWrapper>,
|
||||
) {
|
||||
const { name, useValue: value } = provider;
|
||||
const { useValue: value, provide: providerToken } = provider;
|
||||
collection.set(
|
||||
name as string,
|
||||
providerToken,
|
||||
new InstanceWrapper({
|
||||
name,
|
||||
token: providerToken,
|
||||
name: (providerToken as Function)?.name || providerToken,
|
||||
metatype: null,
|
||||
instance: value,
|
||||
isResolved: true,
|
||||
@@ -320,14 +331,21 @@ export class Module {
|
||||
}
|
||||
|
||||
public addCustomFactory(
|
||||
provider: FactoryProvider & ProviderName,
|
||||
collection: Map<string, InstanceWrapper>,
|
||||
provider: FactoryProvider,
|
||||
collection: Map<Function | string | symbol, InstanceWrapper>,
|
||||
) {
|
||||
const { name, useFactory: factory, inject, scope } = provider;
|
||||
const {
|
||||
useFactory: factory,
|
||||
inject,
|
||||
scope,
|
||||
provide: providerToken,
|
||||
} = provider;
|
||||
|
||||
collection.set(
|
||||
name as string,
|
||||
providerToken,
|
||||
new InstanceWrapper({
|
||||
name,
|
||||
token: providerToken,
|
||||
name: (providerToken as Function)?.name || providerToken,
|
||||
metatype: factory as any,
|
||||
instance: null,
|
||||
isResolved: false,
|
||||
@@ -339,14 +357,15 @@ export class Module {
|
||||
}
|
||||
|
||||
public addCustomUseExisting(
|
||||
provider: ExistingProvider & ProviderName,
|
||||
collection: Map<string, InstanceWrapper>,
|
||||
provider: ExistingProvider,
|
||||
collection: Map<Function | string | symbol, InstanceWrapper>,
|
||||
) {
|
||||
const { name, useExisting } = provider;
|
||||
const { useExisting, provide: providerToken } = provider;
|
||||
collection.set(
|
||||
name as string,
|
||||
providerToken,
|
||||
new InstanceWrapper({
|
||||
name,
|
||||
token: providerToken,
|
||||
name: (providerToken as Function)?.name || providerToken,
|
||||
metatype: (instance => instance) as any,
|
||||
instance: null,
|
||||
isResolved: false,
|
||||
@@ -358,9 +377,9 @@ export class Module {
|
||||
}
|
||||
|
||||
public addExportedProvider(
|
||||
provider: (Provider & ProviderName) | string | symbol | DynamicModule,
|
||||
provider: Provider | string | symbol | DynamicModule,
|
||||
) {
|
||||
const addExportedUnit = (token: string | symbol) =>
|
||||
const addExportedUnit = (token: InstanceToken) =>
|
||||
this._exports.add(this.validateExportedProvider(token));
|
||||
|
||||
if (this.isCustomProvider(provider as any)) {
|
||||
@@ -371,7 +390,7 @@ export class Module {
|
||||
const { module } = provider;
|
||||
return addExportedUnit(module.name);
|
||||
}
|
||||
addExportedUnit(provider.name);
|
||||
addExportedUnit(provider as Type<any>);
|
||||
}
|
||||
|
||||
public addCustomExportedProvider(
|
||||
@@ -385,10 +404,10 @@ export class Module {
|
||||
if (isString(provide) || isSymbol(provide)) {
|
||||
return this._exports.add(this.validateExportedProvider(provide));
|
||||
}
|
||||
this._exports.add(this.validateExportedProvider(provide.name));
|
||||
this._exports.add(this.validateExportedProvider(provide));
|
||||
}
|
||||
|
||||
public validateExportedProvider(token: string | symbol) {
|
||||
public validateExportedProvider(token: InstanceToken) {
|
||||
if (this._providers.has(token)) {
|
||||
return token;
|
||||
}
|
||||
@@ -402,15 +421,17 @@ export class Module {
|
||||
|
||||
if (!importsNames.includes(token as string)) {
|
||||
const { name } = this.metatype;
|
||||
throw new UnknownExportException(token, name);
|
||||
const providerName = isFunction(token) ? (token as Function).name : token;
|
||||
throw new UnknownExportException(providerName as string, name);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
public addController(controller: Type<Controller>) {
|
||||
this._controllers.set(
|
||||
controller.name,
|
||||
controller,
|
||||
new InstanceWrapper({
|
||||
token: controller,
|
||||
name: controller.name,
|
||||
metatype: controller,
|
||||
instance: null,
|
||||
@@ -436,15 +457,13 @@ export class Module {
|
||||
this._imports.add(module);
|
||||
}
|
||||
|
||||
public replace(toReplace: string | symbol | Type<any>, options: any) {
|
||||
public replace(toReplace: InstanceToken, options: any) {
|
||||
if (options.isProvider && this.hasProvider(toReplace)) {
|
||||
const name = this.getProviderStaticToken(toReplace);
|
||||
const originalProvider = this._providers.get(name);
|
||||
const originalProvider = this._providers.get(toReplace);
|
||||
|
||||
return originalProvider.mergeWith({ provide: toReplace, ...options });
|
||||
} else if (!options.isProvider && this.hasInjectable(toReplace)) {
|
||||
const name = this.getProviderStaticToken(toReplace);
|
||||
const originalInjectable = this._injectables.get(name);
|
||||
const originalInjectable = this._injectables.get(toReplace);
|
||||
|
||||
return originalInjectable.mergeWith({
|
||||
provide: toReplace,
|
||||
@@ -453,29 +472,21 @@ export class Module {
|
||||
}
|
||||
}
|
||||
|
||||
public hasProvider(token: string | symbol | Type<any>): boolean {
|
||||
const name = this.getProviderStaticToken(token);
|
||||
return this._providers.has(name);
|
||||
public hasProvider(token: InstanceToken): boolean {
|
||||
return this._providers.has(token);
|
||||
}
|
||||
|
||||
public hasInjectable(token: string | symbol | Type<any>): boolean {
|
||||
const name = this.getProviderStaticToken(token);
|
||||
return this._injectables.has(name);
|
||||
public hasInjectable(token: InstanceToken): boolean {
|
||||
return this._injectables.has(token);
|
||||
}
|
||||
|
||||
public getProviderStaticToken(
|
||||
provider: string | symbol | Type<any> | Abstract<any>,
|
||||
): string | symbol {
|
||||
return isFunction(provider)
|
||||
? (provider as Function).name
|
||||
: (provider as string | symbol);
|
||||
}
|
||||
|
||||
public getProviderByKey<T = any>(name: string | symbol): InstanceWrapper<T> {
|
||||
public getProviderByKey<T = any>(name: InstanceToken): InstanceWrapper<T> {
|
||||
return this._providers.get(name) as InstanceWrapper<T>;
|
||||
}
|
||||
|
||||
public getNonAliasProviders(): Array<[string, InstanceWrapper<Injectable>]> {
|
||||
public getNonAliasProviders(): Array<
|
||||
[InstanceToken, InstanceWrapper<Injectable>]
|
||||
> {
|
||||
return [...this._providers].filter(([_, wrapper]) => !wrapper.isAlias);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { INTERCEPTORS_METADATA } from '@nestjs/common/constants';
|
||||
import { Controller, NestInterceptor } from '@nestjs/common/interfaces';
|
||||
import { Controller, NestInterceptor, Type } from '@nestjs/common/interfaces';
|
||||
import { isEmpty, isFunction } from '@nestjs/common/utils/shared.utils';
|
||||
import { iterate } from 'iterare';
|
||||
import { ApplicationConfig } from '../application-config';
|
||||
@@ -59,15 +59,17 @@ export class InterceptorsContextCreator extends ContextCreator {
|
||||
}
|
||||
|
||||
public getInterceptorInstance(
|
||||
interceptor: Function | NestInterceptor,
|
||||
metatype: Function | NestInterceptor,
|
||||
contextId = STATIC_CONTEXT,
|
||||
inquirerId?: string,
|
||||
): NestInterceptor | null {
|
||||
const isObject = (interceptor as NestInterceptor).intercept;
|
||||
const isObject = (metatype as NestInterceptor).intercept;
|
||||
if (isObject) {
|
||||
return interceptor as NestInterceptor;
|
||||
return metatype as NestInterceptor;
|
||||
}
|
||||
const instanceWrapper = this.getInstanceByMetatype(interceptor);
|
||||
const instanceWrapper = this.getInstanceByMetatype(
|
||||
metatype as Type<unknown>,
|
||||
);
|
||||
if (!instanceWrapper) {
|
||||
return null;
|
||||
}
|
||||
@@ -78,8 +80,8 @@ export class InterceptorsContextCreator extends ContextCreator {
|
||||
return instanceHost && instanceHost.instance;
|
||||
}
|
||||
|
||||
public getInstanceByMetatype<T extends Record<string, any> = any>(
|
||||
metatype: T,
|
||||
public getInstanceByMetatype(
|
||||
metatype: Type<unknown>,
|
||||
): InstanceWrapper | undefined {
|
||||
if (!this.moduleContext) {
|
||||
return;
|
||||
@@ -89,7 +91,7 @@ export class InterceptorsContextCreator extends ContextCreator {
|
||||
if (!moduleRef) {
|
||||
return;
|
||||
}
|
||||
return moduleRef.injectables.get(metatype.name as string);
|
||||
return moduleRef.injectables.get(metatype);
|
||||
}
|
||||
|
||||
public getGlobalMetadata<T extends unknown[]>(
|
||||
|
||||
@@ -3,9 +3,13 @@ import { SCOPE_OPTIONS_METADATA } from '@nestjs/common/constants';
|
||||
import { MiddlewareConfiguration } from '@nestjs/common/interfaces/middleware/middleware-configuration.interface';
|
||||
import { NestContainer } from '../injector';
|
||||
import { InstanceWrapper } from '../injector/instance-wrapper';
|
||||
import { InstanceToken } from '../injector/module';
|
||||
|
||||
export class MiddlewareContainer {
|
||||
private readonly middleware = new Map<string, Map<string, InstanceWrapper>>();
|
||||
private readonly middleware = new Map<
|
||||
string,
|
||||
Map<InstanceToken, InstanceWrapper>
|
||||
>();
|
||||
private readonly configurationSets = new Map<
|
||||
string,
|
||||
Set<MiddlewareConfiguration>
|
||||
@@ -15,7 +19,7 @@ export class MiddlewareContainer {
|
||||
|
||||
public getMiddlewareCollection(
|
||||
moduleKey: string,
|
||||
): Map<string, InstanceWrapper> {
|
||||
): Map<InstanceToken, InstanceWrapper> {
|
||||
if (!this.middleware.has(moduleKey)) {
|
||||
const moduleRef = this.container.getModuleByKey(moduleKey);
|
||||
this.middleware.set(moduleKey, moduleRef.middlewares);
|
||||
@@ -36,13 +40,14 @@ export class MiddlewareContainer {
|
||||
|
||||
const configurations = configList || [];
|
||||
const insertMiddleware = <T extends Type<unknown>>(metatype: T) => {
|
||||
const token = metatype.name;
|
||||
const token = metatype;
|
||||
middleware.set(
|
||||
token,
|
||||
new InstanceWrapper({
|
||||
scope: this.getClassScope(metatype),
|
||||
metatype,
|
||||
name: token,
|
||||
metatype,
|
||||
token,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ import { STATIC_CONTEXT } from '../injector/constants';
|
||||
import { NestContainer } from '../injector/container';
|
||||
import { Injector } from '../injector/injector';
|
||||
import { InstanceWrapper } from '../injector/instance-wrapper';
|
||||
import { Module } from '../injector/module';
|
||||
import { InstanceToken, Module } from '../injector/module';
|
||||
import { REQUEST_CONTEXT_ID } from '../router/request/request-constants';
|
||||
import { RouterExceptionFilters } from '../router/router-exception-filters';
|
||||
import { RouterProxy } from '../router/router-proxy';
|
||||
@@ -70,13 +70,13 @@ export class MiddlewareModule {
|
||||
modules: Map<string, Module>,
|
||||
) {
|
||||
const moduleEntries = [...modules.entries()];
|
||||
const loadMiddlewareConfiguration = async ([name, module]: [
|
||||
const loadMiddlewareConfiguration = async ([moduleName, moduleRef]: [
|
||||
string,
|
||||
Module,
|
||||
]) => {
|
||||
const instance = module.instance;
|
||||
await this.loadConfiguration(middlewareContainer, instance, name);
|
||||
await this.resolver.resolveInstances(module, name);
|
||||
const instance = moduleRef.instance;
|
||||
await this.loadConfiguration(middlewareContainer, instance, moduleName);
|
||||
await this.resolver.resolveInstances(moduleRef, moduleName);
|
||||
};
|
||||
await Promise.all(moduleEntries.map(loadMiddlewareConfiguration));
|
||||
}
|
||||
@@ -164,7 +164,7 @@ export class MiddlewareModule {
|
||||
|
||||
for (const metatype of middlewareCollection) {
|
||||
const collection = middlewareContainer.getMiddlewareCollection(moduleKey);
|
||||
const instanceWrapper = collection.get(metatype.name);
|
||||
const instanceWrapper = collection.get(metatype);
|
||||
if (isUndefined(instanceWrapper)) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
@@ -188,7 +188,7 @@ export class MiddlewareModule {
|
||||
method: RequestMethod,
|
||||
path: string,
|
||||
moduleRef: Module,
|
||||
collection: Map<string, InstanceWrapper>,
|
||||
collection: Map<InstanceToken, InstanceWrapper>,
|
||||
) {
|
||||
const { instance, metatype } = wrapper;
|
||||
if (isUndefined(instance.use)) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injector } from '../injector/injector';
|
||||
import { InstanceWrapper } from '../injector/instance-wrapper';
|
||||
import { Module } from '../injector/module';
|
||||
import { InstanceToken, Module } from '../injector/module';
|
||||
import { MiddlewareContainer } from './container';
|
||||
|
||||
export class MiddlewareResolver {
|
||||
@@ -19,7 +19,7 @@ export class MiddlewareResolver {
|
||||
|
||||
private async resolveMiddlewareInstance(
|
||||
wrapper: InstanceWrapper,
|
||||
middleware: Map<string, InstanceWrapper>,
|
||||
middleware: Map<InstanceToken, InstanceWrapper>,
|
||||
moduleRef: Module,
|
||||
) {
|
||||
await this.instanceLoader.loadMiddleware(wrapper, middleware, moduleRef);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PIPES_METADATA } from '@nestjs/common/constants';
|
||||
import { Controller, PipeTransform } from '@nestjs/common/interfaces';
|
||||
import { Controller, PipeTransform, Type } from '@nestjs/common/interfaces';
|
||||
import { isEmpty, isFunction } from '@nestjs/common/utils/shared.utils';
|
||||
import { iterate } from 'iterare';
|
||||
import { ApplicationConfig } from '../application-config';
|
||||
@@ -59,7 +59,7 @@ export class PipesContextCreator extends ContextCreator {
|
||||
if (isObject) {
|
||||
return pipe as PipeTransform;
|
||||
}
|
||||
const instanceWrapper = this.getInstanceByMetatype(pipe as Function);
|
||||
const instanceWrapper = this.getInstanceByMetatype(pipe as Type<unknown>);
|
||||
if (!instanceWrapper) {
|
||||
return null;
|
||||
}
|
||||
@@ -70,8 +70,8 @@ export class PipesContextCreator extends ContextCreator {
|
||||
return instanceHost && instanceHost.instance;
|
||||
}
|
||||
|
||||
public getInstanceByMetatype<T extends Record<'name', string> = any>(
|
||||
metatype: T,
|
||||
public getInstanceByMetatype(
|
||||
metatype: Type<unknown>,
|
||||
): InstanceWrapper | undefined {
|
||||
if (!this.moduleContext) {
|
||||
return;
|
||||
@@ -81,7 +81,7 @@ export class PipesContextCreator extends ContextCreator {
|
||||
if (!moduleRef) {
|
||||
return;
|
||||
}
|
||||
return moduleRef.injectables.get(metatype.name);
|
||||
return moduleRef.injectables.get(metatype);
|
||||
}
|
||||
|
||||
public getGlobalMetadata<T extends unknown[]>(
|
||||
|
||||
@@ -51,7 +51,7 @@ export class RoutesResolver implements Resolver {
|
||||
}
|
||||
|
||||
public registerRouters(
|
||||
routes: Map<string, InstanceWrapper<Controller>>,
|
||||
routes: Map<string | symbol | Function, InstanceWrapper<Controller>>,
|
||||
moduleName: string,
|
||||
basePath: string,
|
||||
applicationRef: HttpServer,
|
||||
|
||||
@@ -357,11 +357,10 @@ export class DependenciesScanner {
|
||||
scope,
|
||||
} as Provider;
|
||||
|
||||
if (
|
||||
this.isRequestOrTransient(
|
||||
(newProvider as FactoryProvider | ClassProvider).scope,
|
||||
)
|
||||
) {
|
||||
const factoryOrClassProvider = newProvider as
|
||||
| FactoryProvider
|
||||
| ClassProvider;
|
||||
if (this.isRequestOrTransient(factoryOrClassProvider.scope)) {
|
||||
return this.container.addInjectable(newProvider, token);
|
||||
}
|
||||
this.container.addProvider(newProvider, token);
|
||||
|
||||
@@ -112,10 +112,11 @@ describe('GuardsContextCreator', () => {
|
||||
(guardsContextCreator as any).moduleContext = 'test';
|
||||
});
|
||||
|
||||
describe('and when module exists', () => {
|
||||
describe('bud module does not exist', () => {
|
||||
it('should return undefined', () => {
|
||||
expect(guardsContextCreator.getInstanceByMetatype({})).to.be
|
||||
.undefined;
|
||||
expect(
|
||||
guardsContextCreator.getInstanceByMetatype(class RandomModule {}),
|
||||
).to.be.undefined;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('BeforeAppShutdown', () => {
|
||||
sampleProvider = new SampleProvider();
|
||||
moduleRef = new Module(SampleModule, new NestContainer());
|
||||
|
||||
const moduleWrapperRef = moduleRef.getProviderByKey(SampleModule.name);
|
||||
const moduleWrapperRef = moduleRef.getProviderByKey(SampleModule);
|
||||
moduleWrapperRef.instance = new SampleModule();
|
||||
|
||||
moduleRef.addProvider({
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('OnApplicationBootstrap', () => {
|
||||
sampleProvider = new SampleProvider();
|
||||
moduleRef = new Module(SampleModule, new NestContainer());
|
||||
|
||||
const moduleWrapperRef = moduleRef.getProviderByKey(SampleModule.name);
|
||||
const moduleWrapperRef = moduleRef.getProviderByKey(SampleModule);
|
||||
moduleWrapperRef.instance = new SampleModule();
|
||||
|
||||
moduleRef.addProvider({
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('OnApplicationShutdown', () => {
|
||||
sampleProvider = new SampleProvider();
|
||||
moduleRef = new Module(SampleModule, new NestContainer());
|
||||
|
||||
const moduleWrapperRef = moduleRef.getProviderByKey(SampleModule.name);
|
||||
const moduleWrapperRef = moduleRef.getProviderByKey(SampleModule);
|
||||
moduleWrapperRef.instance = new SampleModule();
|
||||
|
||||
moduleRef.addProvider({
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('OnModuleDestroy', () => {
|
||||
sampleProvider = new SampleProvider();
|
||||
moduleRef = new Module(SampleModule, new NestContainer());
|
||||
|
||||
const moduleWrapperRef = moduleRef.getProviderByKey(SampleModule.name);
|
||||
const moduleWrapperRef = moduleRef.getProviderByKey(SampleModule);
|
||||
moduleWrapperRef.instance = new SampleModule();
|
||||
|
||||
moduleRef.addProvider({
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('OnModuleInit', () => {
|
||||
sampleProvider = new SampleProvider();
|
||||
moduleRef = new Module(SampleModule, new NestContainer());
|
||||
|
||||
const moduleWrapperRef = moduleRef.getProviderByKey(SampleModule.name);
|
||||
const moduleWrapperRef = moduleRef.getProviderByKey(SampleModule);
|
||||
moduleWrapperRef.instance = new SampleModule();
|
||||
|
||||
moduleRef.addProvider({
|
||||
|
||||
@@ -39,18 +39,21 @@ describe('Injector', () => {
|
||||
moduleDeps = new Module(DependencyTwo, new NestContainer());
|
||||
mainTest = new InstanceWrapper({
|
||||
name: 'MainTest',
|
||||
token: 'MainTest',
|
||||
metatype: MainTest,
|
||||
instance: Object.create(MainTest.prototype),
|
||||
isResolved: false,
|
||||
});
|
||||
depOne = new InstanceWrapper({
|
||||
name: DependencyOne,
|
||||
token: DependencyOne,
|
||||
metatype: DependencyOne,
|
||||
instance: Object.create(DependencyOne.prototype),
|
||||
isResolved: false,
|
||||
});
|
||||
depTwo = new InstanceWrapper({
|
||||
name: DependencyTwo,
|
||||
token: DependencyTwo,
|
||||
metatype: DependencyTwo,
|
||||
instance: Object.create(DependencyOne.prototype),
|
||||
isResolved: false,
|
||||
@@ -110,7 +113,6 @@ describe('Injector', () => {
|
||||
});
|
||||
|
||||
it('should return undefined when metatype is resolved', async () => {
|
||||
const value = 'test';
|
||||
const result = await injector.loadInstance(
|
||||
new InstanceWrapper({
|
||||
name: 'MainTestResolved',
|
||||
@@ -136,6 +138,7 @@ describe('Injector', () => {
|
||||
moduleDeps = new Module(Test, new NestContainer());
|
||||
test = new InstanceWrapper({
|
||||
name: 'Test',
|
||||
token: 'Test',
|
||||
metatype: Test,
|
||||
instance: null,
|
||||
isResolved: false,
|
||||
@@ -694,10 +697,10 @@ describe('Injector', () => {
|
||||
const module = await container.addModule(moduleCtor, []);
|
||||
|
||||
module.addProvider({
|
||||
name: 'TestClass',
|
||||
provide: TestClass,
|
||||
useClass: TestClass,
|
||||
});
|
||||
|
||||
const instance = await injector.loadPerContext(
|
||||
new TestClass(),
|
||||
module,
|
||||
|
||||
@@ -37,10 +37,12 @@ describe('InstanceLoader', () => {
|
||||
const providerWrapper: InstanceWrapper = {
|
||||
instance: null,
|
||||
metatype: TestProvider,
|
||||
token: 'TestProvider',
|
||||
} as any;
|
||||
const routeWrapper: InstanceWrapper = {
|
||||
instance: null,
|
||||
metatype: TestRoute,
|
||||
token: 'TestRoute',
|
||||
} as any;
|
||||
|
||||
module.providers.set('TestProvider', providerWrapper);
|
||||
@@ -78,6 +80,7 @@ describe('InstanceLoader', () => {
|
||||
instance: null,
|
||||
metatype: TestProvider,
|
||||
name: 'TestProvider',
|
||||
token: 'TestProvider',
|
||||
});
|
||||
module.providers.set('TestProvider', testComp);
|
||||
|
||||
@@ -109,6 +112,7 @@ describe('InstanceLoader', () => {
|
||||
};
|
||||
const wrapper = new InstanceWrapper({
|
||||
name: 'TestRoute',
|
||||
token: 'TestRoute',
|
||||
instance: null,
|
||||
metatype: TestRoute,
|
||||
});
|
||||
@@ -144,6 +148,7 @@ describe('InstanceLoader', () => {
|
||||
instance: null,
|
||||
metatype: TestProvider,
|
||||
name: 'TestProvider',
|
||||
token: 'TestProvider',
|
||||
});
|
||||
module.injectables.set('TestProvider', testComp);
|
||||
|
||||
|
||||
@@ -36,9 +36,10 @@ describe('Module', () => {
|
||||
module.addController(Test);
|
||||
expect(
|
||||
setSpy.calledWith(
|
||||
'Test',
|
||||
Test,
|
||||
new InstanceWrapper({
|
||||
host: module,
|
||||
token: Test,
|
||||
name: 'Test',
|
||||
scope: Scope.REQUEST,
|
||||
metatype: Test,
|
||||
@@ -57,10 +58,11 @@ describe('Module', () => {
|
||||
module.addInjectable(TestProvider, TestModule);
|
||||
expect(
|
||||
setSpy.calledWith(
|
||||
'TestProvider',
|
||||
TestProvider,
|
||||
new InstanceWrapper({
|
||||
host: module,
|
||||
name: 'TestProvider',
|
||||
token: TestProvider,
|
||||
scope: undefined,
|
||||
metatype: TestProvider,
|
||||
instance: null,
|
||||
@@ -87,10 +89,11 @@ describe('Module', () => {
|
||||
module.addProvider(TestProvider);
|
||||
expect(
|
||||
setSpy.calledWith(
|
||||
'TestProvider',
|
||||
TestProvider,
|
||||
new InstanceWrapper({
|
||||
host: module,
|
||||
name: 'TestProvider',
|
||||
token: TestProvider,
|
||||
scope: undefined,
|
||||
metatype: TestProvider,
|
||||
instance: null,
|
||||
@@ -152,7 +155,7 @@ describe('Module', () => {
|
||||
|
||||
describe('addCustomClass', () => {
|
||||
const type = { name: 'TypeTest' };
|
||||
const provider = { provide: type, useClass: type, name: 'test' };
|
||||
const provider = { provide: type, useClass: type };
|
||||
let setSpy;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -164,10 +167,11 @@ describe('Module', () => {
|
||||
module.addCustomClass(provider as any, (module as any)._providers);
|
||||
expect(
|
||||
setSpy.calledWith(
|
||||
provider.name,
|
||||
provider.provide,
|
||||
new InstanceWrapper({
|
||||
host: module,
|
||||
name: provider.name,
|
||||
token: type as any,
|
||||
name: provider.provide.name,
|
||||
scope: undefined,
|
||||
metatype: type as any,
|
||||
instance: null,
|
||||
@@ -181,8 +185,7 @@ describe('Module', () => {
|
||||
describe('addCustomValue', () => {
|
||||
let setSpy;
|
||||
const value = () => ({});
|
||||
const name = 'test';
|
||||
const provider = { provide: value, name, useValue: value };
|
||||
const provider = { provide: value, useValue: value };
|
||||
|
||||
beforeEach(() => {
|
||||
const collection = new Map();
|
||||
@@ -194,10 +197,11 @@ describe('Module', () => {
|
||||
module.addCustomValue(provider as any, (module as any)._providers);
|
||||
expect(
|
||||
setSpy.calledWith(
|
||||
name,
|
||||
provider.provide,
|
||||
new InstanceWrapper({
|
||||
host: module,
|
||||
name,
|
||||
token: provider.provide,
|
||||
name: provider.provide.name,
|
||||
scope: Scope.DEFAULT,
|
||||
metatype: null,
|
||||
instance: value,
|
||||
@@ -212,7 +216,7 @@ describe('Module', () => {
|
||||
describe('addCustomFactory', () => {
|
||||
const type = { name: 'TypeTest' };
|
||||
const inject = [1, 2, 3];
|
||||
const provider = { provide: type, useFactory: type, name: 'test', inject };
|
||||
const provider = { provide: type, useFactory: type, inject };
|
||||
|
||||
let setSpy;
|
||||
beforeEach(() => {
|
||||
@@ -222,12 +226,14 @@ describe('Module', () => {
|
||||
});
|
||||
it('should store provider', () => {
|
||||
module.addCustomFactory(provider as any, (module as any)._providers);
|
||||
|
||||
expect(
|
||||
setSpy.calledWith(
|
||||
provider.name,
|
||||
provider.provide,
|
||||
new InstanceWrapper({
|
||||
host: module,
|
||||
name: provider.name,
|
||||
token: provider.provide as any,
|
||||
name: provider.provide.name,
|
||||
scope: undefined,
|
||||
metatype: type as any,
|
||||
instance: null,
|
||||
@@ -241,7 +247,7 @@ describe('Module', () => {
|
||||
|
||||
describe('addCustomUseExisting', () => {
|
||||
const type = { name: 'TypeTest' };
|
||||
const provider = { provide: type, useExisting: type, name: 'test' };
|
||||
const provider = { provide: type, useExisting: type };
|
||||
|
||||
let setSpy;
|
||||
beforeEach(() => {
|
||||
@@ -251,13 +257,17 @@ describe('Module', () => {
|
||||
});
|
||||
it('should store provider', () => {
|
||||
module.addCustomUseExisting(provider as any, (module as any)._providers);
|
||||
const factoryFn = (module as any)._providers.get(provider.name).metatype;
|
||||
const factoryFn = (module as any)._providers.get(provider.provide)
|
||||
.metatype;
|
||||
|
||||
const token = provider.provide as any;
|
||||
expect(
|
||||
setSpy.calledWith(
|
||||
provider.name,
|
||||
token,
|
||||
new InstanceWrapper({
|
||||
host: module,
|
||||
name: provider.name,
|
||||
token,
|
||||
name: provider.provide.name,
|
||||
metatype: factoryFn,
|
||||
instance: null,
|
||||
inject: [provider.useExisting as any],
|
||||
@@ -477,7 +487,7 @@ describe('Module', () => {
|
||||
describe('otherwise', () => {
|
||||
it('should return instance wrapper', () => {
|
||||
module.addProvider(TestProvider);
|
||||
expect(module.getProviderByKey('TestProvider')).to.not.be.undefined;
|
||||
expect(module.getProviderByKey(TestProvider)).to.not.be.undefined;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -74,16 +74,22 @@ export class MicroservicesModule {
|
||||
}
|
||||
|
||||
public bindListeners(
|
||||
controllers: Map<string, InstanceWrapper<Controller>>,
|
||||
controllers: Map<string | symbol | Function, InstanceWrapper<Controller>>,
|
||||
server: Server & CustomTransportStrategy,
|
||||
module: string,
|
||||
moduleName: string,
|
||||
) {
|
||||
controllers.forEach(wrapper =>
|
||||
this.listenersController.registerPatternHandlers(wrapper, server, module),
|
||||
this.listenersController.registerPatternHandlers(
|
||||
wrapper,
|
||||
server,
|
||||
moduleName,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public bindClients(items: Map<string, InstanceWrapper<unknown>>) {
|
||||
public bindClients(
|
||||
items: Map<string | symbol | Function, InstanceWrapper<unknown>>,
|
||||
) {
|
||||
items.forEach(({ instance, isNotMetatype }) => {
|
||||
!isNotMetatype &&
|
||||
this.listenersController.assignClientsToProperties(instance);
|
||||
|
||||
@@ -5,6 +5,7 @@ import { GuardsContextCreator } from '@nestjs/core/guards/guards-context-creator
|
||||
import { loadAdapter } from '@nestjs/core/helpers/load-adapter';
|
||||
import { NestContainer } from '@nestjs/core/injector/container';
|
||||
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
||||
import { InstanceToken } from '@nestjs/core/injector/module';
|
||||
import { InterceptorsConsumer } from '@nestjs/core/interceptors/interceptors-consumer';
|
||||
import { InterceptorsContextCreator } from '@nestjs/core/interceptors/interceptors-context-creator';
|
||||
import { PipesConsumer } from '@nestjs/core/pipes/pipes-consumer';
|
||||
@@ -51,7 +52,7 @@ export class SocketModule<HttpServer = any> {
|
||||
}
|
||||
|
||||
public combineAllGateways(
|
||||
providers: Map<string, InstanceWrapper<Injectable>>,
|
||||
providers: Map<InstanceToken, InstanceWrapper<Injectable>>,
|
||||
moduleName: string,
|
||||
) {
|
||||
iterate(providers.values())
|
||||
|
||||
Reference in New Issue
Block a user