/
githubmirror
/
nest
Обзор
Документация
Войти
/
githubmirror
/
nest
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
packages/core/injector/module-ref.ts
212 строк
7 KB
Mohammed Said
refactor(core): remove async promise executor anti-patterns
31 июл 2026, 02:12
31 июл 2026, 02:12
8539f87
Код
Авторство
О чём код?
import { IntrospectionResult, Scope, Type } from '@nestjs/common'; import { getClassScope } from '../helpers/get-class-scope'; import { isDurable } from '../helpers/is-durable'; import { AbstractInstanceResolver } from './abstract-instance-resolver'; import { STATIC_CONTEXT } from './constants'; import { NestContainer } from './container'; import { Injector } from './injector'; import { InstanceLinksHost } from './instance-links-host'; import { ContextId, InstanceWrapper } 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 abstract class ModuleRef extends AbstractInstanceResolver { protected readonly injector: Injector; private _instanceLinksHost: InstanceLinksHost; protected get instanceLinksHost() { if (!this._instanceLinksHost) { this._instanceLinksHost = new InstanceLinksHost(this.container); } return this._instanceLinksHost; } constructor(protected readonly container: NestContainer) { super(); const contextOptions = container.contextOptions; this.injector = new Injector({ preview: contextOptions?.preview ?? false, snapshot: contextOptions?.snapshot, instanceDecorator: contextOptions?.instrument?.instanceDecorator, }); } /** * 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>>; public abstract create<T = any>( type: Type<T>, contextId?: ContextId, ): Promise<T>; public introspect<T = any>( token: Type<T> | string | symbol, ): IntrospectionResult { const { wrapperRef } = this.instanceLinksHost.get(token); let scope = Scope.DEFAULT; if (!wrapperRef.isDependencyTreeStatic()) { scope = Scope.REQUEST; } else if (wrapperRef.isTransient) { scope = Scope.TRANSIENT; } return { scope }; } public registerRequestByContextId<T = any>(request: T, contextId: ContextId) { this.container.registerRequestProvider(request, contextId); } protected async instantiateClass<T = any>( type: Type<T>, moduleRef: Module, contextId?: ContextId, ): Promise<T> { const wrapper = new InstanceWrapper({ name: type && type.name, metatype: type, isResolved: false, scope: getClassScope(type), durable: isDurable(type), host: moduleRef, }); if (type?.prototype) { wrapper.setInstanceByContextId(contextId ?? STATIC_CONTEXT, { instance: Object.create(type.prototype), isResolved: false, isPending: false, }); } return new Promise<T>((resolve, reject) => { const callback = async (instances: any[]) => { try { const properties = await this.injector.resolveProperties( wrapper, moduleRef, undefined, { contextId: contextId ?? STATIC_CONTEXT, inquirer: wrapper, }, ); const instance = new type(...instances); this.injector.applyProperties(instance, properties); resolve(instance); } catch (err) { reject(err); } }; this.injector .resolveConstructorParams<T>(wrapper, moduleRef, undefined, callback, { contextId: contextId ?? STATIC_CONTEXT, inquirer: wrapper, }) .catch(reject); }); } }