@nestjs/core
Version:
Nest - modern, fast, powerful node.js web framework (@core)
97 lines (96 loc) • 4.24 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { flatten, Injectable, SetMetadata, } from '@nestjs/common';
import { uid } from 'uid';
import { ModulesContainer } from '../injector/modules-container.js';
import { DiscoverableMetaHostCollection } from './discoverable-meta-host-collection.js';
/**
* @publicApi
*/
let DiscoveryService = class DiscoveryService {
modulesContainer;
constructor(modulesContainer) {
this.modulesContainer = modulesContainer;
}
/**
* Creates a decorator that can be used to decorate classes and methods with metadata.
* The decorator will also add the class to the collection of discoverable classes (by metadata key).
* Decorated classes can be discovered using the `getProviders` and `getControllers` methods.
* @returns A decorator function.
*/
static createDecorator() {
const metadataKey = uid(21);
const decoratorFn = (opts) => (target, key, descriptor) => {
if (!descriptor) {
DiscoverableMetaHostCollection.addClassMetaHostLink(target, metadataKey);
}
SetMetadata(metadataKey, opts ?? {})(target, key, descriptor);
};
decoratorFn.KEY = metadataKey;
return decoratorFn;
}
/**
* Returns an array of instance wrappers (providers).
* Depending on the options, the array will contain either all providers or only providers with the specified metadata key.
* @param options Discovery options.
* @param modules A list of modules to filter by.
* @returns An array of instance wrappers (providers).
*/
getProviders(options = {}, modules = this.getModules(options)) {
if ('metadataKey' in options) {
const providers = DiscoverableMetaHostCollection.getProvidersByMetaKey(this.modulesContainer, options.metadataKey);
return Array.from(providers);
}
const providers = modules.map(item => [...item.providers.values()]);
return flatten(providers);
}
/**
* Returns an array of instance wrappers (controllers).
* Depending on the options, the array will contain either all controllers or only controllers with the specified metadata key.
* @param options Discovery options.
* @param modules A list of modules to filter by.
* @returns An array of instance wrappers (controllers).
*/
getControllers(options = {}, modules = this.getModules(options)) {
if ('metadataKey' in options) {
const controllers = DiscoverableMetaHostCollection.getControllersByMetaKey(this.modulesContainer, options.metadataKey);
return Array.from(controllers);
}
const controllers = modules.map(item => [...item.controllers.values()]);
return flatten(controllers);
}
/**
* Retrieves metadata from the specified instance wrapper.
* @param decorator The decorator to retrieve metadata of.
* @param instanceWrapper Reference to the instance wrapper.
* @param methodKey An optional method key to retrieve metadata from.
* @returns Discovered metadata.
*/
getMetadataByDecorator(decorator, instanceWrapper, methodKey) {
if (methodKey) {
return Reflect.getMetadata(decorator.KEY, instanceWrapper.instance[methodKey]);
}
const clsRef = instanceWrapper.instance?.constructor ?? instanceWrapper.metatype;
return Reflect.getMetadata(decorator.KEY, clsRef);
}
/**
* Returns a list of modules to be used for discovery.
*/
getModules(options = {}) {
const includeInOpts = 'include' in options;
if (!includeInOpts) {
const moduleRefs = [...this.modulesContainer.values()];
return moduleRefs;
}
const whitelisted = this.includeWhitelisted(options.include);
return whitelisted;
}
includeWhitelisted(include) {
const moduleRefs = [...this.modulesContainer.values()];
return moduleRefs.filter(({ metatype }) => include.some(item => item === metatype));
}
};
DiscoveryService = __decorate([
Injectable(),
__metadata("design:paramtypes", [ModulesContainer])
], DiscoveryService);
export { DiscoveryService };