Skip to content

Commit

Permalink
feat(core): introduce entry providers concept
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilmysliwiec committed Feb 10, 2023
1 parent 7a90b7c commit a2b3e1b
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 12 deletions.
1 change: 1 addition & 0 deletions packages/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ export const VERSION_METADATA = '__version__';
export const INJECTABLE_WATERMARK = '__injectable__';
export const CONTROLLER_WATERMARK = '__controller__';
export const CATCH_WATERMARK = '__catch__';
export const ENTRY_PROVIDER_WATERMARK = '__entryProvider__';
34 changes: 31 additions & 3 deletions packages/core/injector/module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { EnhancerSubtype } from '@nestjs/common/constants';
import {
EnhancerSubtype,
ENTRY_PROVIDER_WATERMARK,
} from '@nestjs/common/constants';
import {
ClassProvider,
Controller,
Expand Down Expand Up @@ -61,7 +64,9 @@ export class Module {
InstanceToken,
InstanceWrapper<Controller>
>();
private readonly _entryProviderKeys = new Set<InstanceToken>();
private readonly _exports = new Set<InstanceToken>();

private _distance = 0;
private _initOnPreview = false;
private _isGlobal = false;
Expand Down Expand Up @@ -148,6 +153,12 @@ export class Module {
return this._controllers;
}

get entryProviders(): Array<InstanceWrapper<Injectable>> {
return Array.from(this._entryProviderKeys).map(token =>
this.providers.get(token),
);
}

get exports(): Set<InstanceToken> {
return this._exports;
}
Expand Down Expand Up @@ -258,8 +269,12 @@ export class Module {
): Provider | InjectionToken;
public addProvider(provider: Provider, enhancerSubtype?: EnhancerSubtype) {
if (this.isCustomProvider(provider)) {
if (this.isEntryProvider(provider.provide)) {
this._entryProviderKeys.add(provider.provide);
}
return this.addCustomProvider(provider, this._providers, enhancerSubtype);
}

this._providers.set(
provider,
new InstanceWrapper({
Expand All @@ -273,6 +288,11 @@ export class Module {
host: this,
}),
);

if (this.isEntryProvider(provider)) {
this._entryProviderKeys.add(provider);
}

return provider as Type<Injectable>;
}

Expand Down Expand Up @@ -349,10 +369,12 @@ export class Module {
if (isUndefined(durable)) {
durable = isDurable(useClass);
}

const token = provider.provide;
collection.set(
provider.provide,
token,
new InstanceWrapper({
token: provider.provide,
token,
name: useClass?.name || useClass,
metatype: useClass,
instance: null,
Expand Down Expand Up @@ -632,6 +654,12 @@ export class Module {
};
}

private isEntryProvider(metatype: InjectionToken): boolean {
return typeof metatype === 'function'
? !!Reflect.getMetadata(ENTRY_PROVIDER_WATERMARK, metatype)
: false;
}

private generateUuid(): string {
const prefix = 'M_';
const key = this.name?.toString() ?? this.token?.toString();
Expand Down
21 changes: 12 additions & 9 deletions packages/core/scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,18 @@ import {
import {
CanActivate,
ClassProvider,
Controller,
ExceptionFilter,
ExistingProvider,
FactoryProvider,
Injectable,
InjectionToken,
NestInterceptor,
PipeTransform,
Scope,
ValueProvider,
Controller,
Injectable,
Type,
ValueProvider,
} from '@nestjs/common/interfaces';
import { randomStringGenerator } from '@nestjs/common/utils/random-string-generator.util';
import {
isFunction,
isNil,
Expand All @@ -54,7 +53,6 @@ import { Module } from './injector/module';
import { GraphInspector } from './inspector/graph-inspector';
import { UuidFactory } from './inspector/uuid-factory';
import { MetadataScanner } from './metadata-scanner';
import { ParamsMetadata } from './helpers/interfaces/params-metadata.interface';

interface ApplicationProviderWrapper {
moduleKey: string;
Expand Down Expand Up @@ -529,11 +527,16 @@ export class DependenciesScanner {
const { injectables } = modulesContainer.get(moduleKey);
const instanceWrapper = injectables.get(providerKey);

iterate(modulesContainer.values())
.map(module => module.controllers.values())
const iterableIterator = modulesContainer.values();
iterate(iterableIterator)
.map(moduleRef =>
Array.from<InstanceWrapper>(moduleRef.controllers.values()).concat(
moduleRef.entryProviders,
),
)
.flatten()
.forEach(controller =>
controller.addEnhancerMetadata(instanceWrapper),
.forEach(controllerOrEntryProvider =>
controllerOrEntryProvider.addEnhancerMetadata(instanceWrapper),
);
});
}
Expand Down

0 comments on commit a2b3e1b

Please sign in to comment.