Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement →
Sign In

@nestjs/core

Package Overview
Dependencies
Maintainers
1
Versions
447
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nestjs/core - npm Package Compare versions

Comparing version
11.1.19
to
11.1.20
+28
-11
injector/injector.d.ts

@@ -42,2 +42,7 @@ import { InjectionToken } from '@nestjs/common';

}
interface ResolutionContext {
contextId: ContextId;
inquirer?: InstanceWrapper;
effectiveInquirerId?: string;
}
export declare class Injector {

@@ -53,2 +58,6 @@ private readonly options?;

/**
* Whether to enable deterministic graph snapshot generation.
*/
snapshot?: boolean;
/**
* Function to decorate a freshly created instance.

@@ -59,9 +68,9 @@ */

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>;
loadInstance<T>(wrapper: InstanceWrapper<T>, collection: Map<InjectionToken, InstanceWrapper>, moduleRef: Module, resolutionContext?: ResolutionContext): 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>;
loadProvider(wrapper: InstanceWrapper<Injectable>, moduleRef: Module, resolutionContext?: ResolutionContext): 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>;
resolveConstructorParams<T>(wrapper: InstanceWrapper<T>, moduleRef: Module, inject: InjectorDependency[] | undefined, callback: (args: unknown[]) => void | Promise<void>, resolutionContext?: ResolutionContext, parentInquirer?: InstanceWrapper): Promise<void>;
getClassDependencies<T>(wrapper: InstanceWrapper<T>): [InjectorDependency[], number[]];

@@ -72,13 +81,13 @@ getFactoryProviderDependencies<T>(wrapper: InstanceWrapper<T>): [InjectorDependency[], number[]];

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>>;
resolveSingleParam<T>(wrapper: InstanceWrapper<T>, param: Type<any> | string | symbol, dependencyContext: InjectorDependencyContext, moduleRef: Module, resolutionContext?: ResolutionContext, 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[]>;
resolveComponentWrapper<T>(moduleRef: Module, token: InjectionToken, dependencyContext: InjectorDependencyContext, wrapper: InstanceWrapper<T>, resolutionContext?: ResolutionContext, keyOrIndex?: symbol | string | number): Promise<InstanceWrapper>;
resolveComponentHost<T>(moduleRef: Module, instanceWrapper: InstanceWrapper<T | Promise<T>>, resolutionContext?: ResolutionContext): Promise<InstanceWrapper>;
lookupComponent<T = any>(providers: Map<Function | string | symbol, InstanceWrapper>, moduleRef: Module, dependencyContext: InjectorDependencyContext, wrapper: InstanceWrapper<T>, resolutionContext?: ResolutionContext, keyOrIndex?: symbol | string | number): Promise<InstanceWrapper<T>>;
lookupComponentInParentModules<T = any>(dependencyContext: InjectorDependencyContext, moduleRef: Module, wrapper: InstanceWrapper<T>, resolutionContext?: ResolutionContext, keyOrIndex?: symbol | string | number): Promise<any>;
lookupComponentInImports(moduleRef: Module, name: InjectionToken, wrapper: InstanceWrapper, moduleRegistry?: Set<string>, resolutionContext?: ResolutionContext, keyOrIndex?: symbol | string | number, isTraversing?: boolean): Promise<any>;
resolveProperties<T>(wrapper: InstanceWrapper<T>, moduleRef: Module, inject?: InjectorDependency[], resolutionContext?: ResolutionContext, 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>;
instantiateClass<T = any>(instances: any[], wrapper: InstanceWrapper, targetMetatype: InstanceWrapper, resolutionContext?: ResolutionContext): Promise<T>;
loadPerContext<T = any>(instance: T, moduleRef: Module, collection: Map<InjectionToken, InstanceWrapper>, ctx: ContextId, wrapper?: InstanceWrapper): Promise<T>;

@@ -89,2 +98,6 @@ loadEnhancersPerContext(wrapper: InstanceWrapper, ctx: ContextId, inquirer?: InstanceWrapper): Promise<void>;

private getInquirerId;
private createResolutionContext;
private getContextInquirerId;
private isInContext;
private shouldSkipProviderLoading;
/**

@@ -98,2 +111,5 @@ * For nested TRANSIENT dependencies (TRANSIENT -> TRANSIENT) in non-static contexts,

private getEffectiveInquirer;
private getEffectiveInquirerId;
private getStaticTransientResolutionContext;
private getEffectiveResolutionContext;
private resolveScopedComponentHost;

@@ -111,1 +127,2 @@ private isInquirerRequest;

}
export {};

@@ -42,8 +42,9 @@ "use strict";

}
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);
async loadInstance(wrapper, collection, moduleRef, resolutionContext = { contextId: constants_2.STATIC_CONTEXT }) {
const inquirerId = this.getContextInquirerId(resolutionContext);
const instanceHost = wrapper.getInstanceByContextId(this.getContextId(resolutionContext.contextId, wrapper), inquirerId);
if (instanceHost.isPending) {
const settlementSignal = wrapper.settlementSignal;
if (inquirer && settlementSignal?.isCycle(inquirer.id)) {
if (resolutionContext.inquirer &&
settlementSignal?.isCycle(resolutionContext.inquirer.id)) {
throw new exceptions_1.CircularDependencyException(`"${wrapper.name}"`);

@@ -69,5 +70,6 @@ }

const t0 = this.getNowTimestamp();
const localResolutionContext = this.createResolutionContext(resolutionContext.contextId, wrapper, inquirerId);
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);
const properties = await this.resolveProperties(wrapper, moduleRef, inject, localResolutionContext, resolutionContext.inquirer);
const instance = await this.instantiateClass(instances, wrapper, targetWrapper, wrapper.isTransient ? localResolutionContext : resolutionContext);
this.applyProperties(instance, properties);

@@ -77,6 +79,6 @@ wrapper.initTime = this.getNowTimestamp() - t0;

};
await this.resolveConstructorParams(wrapper, moduleRef, inject, callback, contextId, wrapper, inquirer);
await this.resolveConstructorParams(wrapper, moduleRef, inject, callback, localResolutionContext, resolutionContext.inquirer);
}
catch (err) {
wrapper.removeInstanceByContextId(this.getContextId(contextId, wrapper), inquirerId);
wrapper.removeInstanceByContextId(this.getContextId(resolutionContext.contextId, wrapper), inquirerId);
settlementSignal.error(err);

@@ -93,7 +95,7 @@ throw err;

targetWrapper.instance = Object.create(metatype.prototype);
await this.loadInstance(wrapper, collection, moduleRef, contextId, inquirer || wrapper);
await this.loadInstance(wrapper, collection, moduleRef, this.createResolutionContext(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.loadInstance(wrapper, controllers, moduleRef, this.createResolutionContext(contextId, wrapper));
await this.loadEnhancersPerContext(wrapper, contextId, wrapper);

@@ -103,8 +105,11 @@ }

const injectables = moduleRef.injectables;
await this.loadInstance(wrapper, injectables, moduleRef, contextId, inquirer);
await this.loadInstance(wrapper, injectables, moduleRef, this.createResolutionContext(contextId, inquirer));
}
async loadProvider(wrapper, moduleRef, contextId = constants_2.STATIC_CONTEXT, inquirer) {
async loadProvider(wrapper, moduleRef, resolutionContext = { contextId: constants_2.STATIC_CONTEXT }) {
if (this.shouldSkipProviderLoading(wrapper, resolutionContext)) {
return;
}
const providers = moduleRef.providers;
await this.loadInstance(wrapper, providers, moduleRef, contextId, inquirer);
await this.loadEnhancersPerContext(wrapper, contextId, wrapper);
await this.loadInstance(wrapper, providers, moduleRef, resolutionContext);
await this.loadEnhancersPerContext(wrapper, resolutionContext.contextId, wrapper);
}

@@ -118,6 +123,6 @@ applySettlementSignal(instancePerContext, host) {

}
async resolveConstructorParams(wrapper, moduleRef, inject, callback, contextId = constants_2.STATIC_CONTEXT, inquirer, parentInquirer) {
async resolveConstructorParams(wrapper, moduleRef, inject, callback, resolutionContext = { contextId: constants_2.STATIC_CONTEXT }, parentInquirer) {
const metadata = wrapper.getCtorMetadata();
if (metadata && contextId !== constants_2.STATIC_CONTEXT) {
const deps = await this.loadCtorMetadata(metadata, contextId, inquirer, parentInquirer);
if (metadata && resolutionContext.contextId !== constants_2.STATIC_CONTEXT) {
const deps = await this.loadCtorMetadata(metadata, resolutionContext.contextId, resolutionContext.inquirer, parentInquirer);
return callback(deps);

@@ -140,9 +145,10 @@ }

}
if (inquirer?.isTransient && parentInquirer) {
if (resolutionContext.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);
resolutionContext.inquirer.attachRootInquirer(parentInquirer);
}
const paramWrapper = await this.resolveSingleParam(wrapper, param, { index, dependencies }, moduleRef, contextId, inquirer, index);
const nestedResolutionContext = this.getStaticTransientResolutionContext(resolutionContext, parentInquirer);
const paramWrapper = await this.resolveSingleParam(wrapper, param, { index, dependencies }, moduleRef, nestedResolutionContext, index);
/*

@@ -154,5 +160,5 @@ * Ensure that all instance wrappers are resolved at this point before we continue.

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));
const effectiveResolutionContext = this.getEffectiveResolutionContext(paramWrapper, resolutionContext, parentInquirer);
const paramWrapperWithInstance = await this.resolveComponentHost(moduleRef, paramWrapper, effectiveResolutionContext);
const instanceHost = paramWrapperWithInstance.getInstanceByContextId(this.getContextId(effectiveResolutionContext.contextId, paramWrapperWithInstance), effectiveResolutionContext.effectiveInquirerId);
if (!instanceHost.isResolved && !paramWrapperWithInstance.forwardRef) {

@@ -229,3 +235,3 @@ isResolved = false;

}
async resolveSingleParam(wrapper, param, dependencyContext, moduleRef, contextId = constants_2.STATIC_CONTEXT, inquirer, keyOrIndex) {
async resolveSingleParam(wrapper, param, dependencyContext, moduleRef, resolutionContext = { contextId: constants_2.STATIC_CONTEXT }, keyOrIndex) {
if ((0, shared_utils_1.isUndefined)(param)) {

@@ -236,3 +242,3 @@ this.logger.log('Nest encountered an undefined dependency. This may be due to a circular import or a missing dependency declaration.');

const token = this.resolveParamToken(wrapper, param);
return this.resolveComponentWrapper(moduleRef, token, dependencyContext, wrapper, contextId, inquirer, keyOrIndex);
return this.resolveComponentWrapper(moduleRef, token, dependencyContext, wrapper, resolutionContext, keyOrIndex);
}

@@ -246,18 +252,18 @@ resolveParamToken(wrapper, param) {

}
async resolveComponentWrapper(moduleRef, token, dependencyContext, wrapper, contextId = constants_2.STATIC_CONTEXT, inquirer, keyOrIndex) {
this.printResolvingDependenciesLog(token, inquirer);
async resolveComponentWrapper(moduleRef, token, dependencyContext, wrapper, resolutionContext = { contextId: constants_2.STATIC_CONTEXT }, keyOrIndex) {
this.printResolvingDependenciesLog(token, resolutionContext.inquirer);
this.printLookingForProviderLog(token, moduleRef);
const providers = moduleRef.providers;
return this.lookupComponent(providers, moduleRef, { ...dependencyContext, name: token }, wrapper, contextId, inquirer, keyOrIndex);
return this.lookupComponent(providers, moduleRef, { ...dependencyContext, name: token }, wrapper, resolutionContext, 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);
async resolveComponentHost(moduleRef, instanceWrapper, resolutionContext = { contextId: constants_2.STATIC_CONTEXT }) {
const inquirerId = this.getContextInquirerId(resolutionContext);
const instanceHost = instanceWrapper.getInstanceByContextId(this.getContextId(resolutionContext.contextId, instanceWrapper), inquirerId);
if (!instanceHost.isResolved && !instanceWrapper.forwardRef) {
inquirer?.settlementSignal?.insertRef(instanceWrapper.id);
await this.loadProvider(instanceWrapper, instanceWrapper.host ?? moduleRef, contextId, inquirer);
resolutionContext.inquirer?.settlementSignal?.insertRef(instanceWrapper.id);
await this.loadProvider(instanceWrapper, instanceWrapper.host ?? moduleRef, resolutionContext);
}
else if (!instanceHost.isResolved &&
instanceWrapper.forwardRef &&
(contextId !== constants_2.STATIC_CONTEXT || !!inquirerId)) {
(resolutionContext.contextId !== constants_2.STATIC_CONTEXT || !!inquirerId)) {
/**

@@ -272,3 +278,3 @@ * When circular dependency has been detected between

void instanceHost.donePromise
.then(() => this.loadProvider(instanceWrapper, moduleRef, contextId, inquirer))
.then(() => this.loadProvider(instanceWrapper, moduleRef, resolutionContext))
.catch(err => {

@@ -279,9 +285,9 @@ instanceWrapper.settlementSignal?.error(err);

if (instanceWrapper.async) {
const host = instanceWrapper.getInstanceByContextId(this.getContextId(contextId, instanceWrapper), inquirerId);
const host = instanceWrapper.getInstanceByContextId(this.getContextId(resolutionContext.contextId, instanceWrapper), inquirerId);
host.instance = await host.instance;
instanceWrapper.setInstanceByContextId(contextId, host, inquirerId);
instanceWrapper.setInstanceByContextId(resolutionContext.contextId, host, inquirerId);
}
return instanceWrapper;
}
async lookupComponent(providers, moduleRef, dependencyContext, wrapper, contextId = constants_2.STATIC_CONTEXT, inquirer, keyOrIndex) {
async lookupComponent(providers, moduleRef, dependencyContext, wrapper, resolutionContext = { contextId: constants_2.STATIC_CONTEXT }, keyOrIndex) {
const token = wrapper.token || wrapper.name;

@@ -298,6 +304,6 @@ const { name } = dependencyContext;

}
return this.lookupComponentInParentModules(dependencyContext, moduleRef, wrapper, contextId, inquirer, keyOrIndex);
return this.lookupComponentInParentModules(dependencyContext, moduleRef, wrapper, resolutionContext, 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);
async lookupComponentInParentModules(dependencyContext, moduleRef, wrapper, resolutionContext = { contextId: constants_2.STATIC_CONTEXT }, keyOrIndex) {
const instanceWrapper = await this.lookupComponentInImports(moduleRef, dependencyContext.name, wrapper, new Set(), resolutionContext, keyOrIndex);
if ((0, shared_utils_1.isNil)(instanceWrapper)) {

@@ -308,3 +314,3 @@ throw new unknown_dependencies_exception_1.UnknownDependenciesException(wrapper.name, dependencyContext, moduleRef, { id: wrapper.id });

}
async lookupComponentInImports(moduleRef, name, wrapper, moduleRegistry = new Set(), contextId = constants_2.STATIC_CONTEXT, inquirer, keyOrIndex, isTraversing) {
async lookupComponentInImports(moduleRef, name, wrapper, moduleRegistry = new Set(), resolutionContext = { contextId: constants_2.STATIC_CONTEXT }, keyOrIndex, isTraversing) {
let instanceWrapperRef = null;

@@ -326,3 +332,3 @@ const imports = moduleRef.imports || new Set();

if (!exports.has(name) || !providers.has(name)) {
const instanceRef = await this.lookupComponentInImports(relatedModule, name, wrapper, moduleRegistry, contextId, inquirer, keyOrIndex, true);
const instanceRef = await this.lookupComponentInImports(relatedModule, name, wrapper, moduleRegistry, resolutionContext, keyOrIndex, true);
if (instanceRef) {

@@ -337,4 +343,4 @@ this.addDependencyMetadata(keyOrIndex, wrapper, instanceRef);

this.addDependencyMetadata(keyOrIndex, wrapper, instanceWrapperRef);
const inquirerId = this.getInquirerId(inquirer);
const instanceHost = instanceWrapperRef.getInstanceByContextId(this.getContextId(contextId, instanceWrapperRef), inquirerId);
const inquirerId = this.getContextInquirerId(resolutionContext);
const instanceHost = instanceWrapperRef.getInstanceByContextId(this.getContextId(resolutionContext.contextId, instanceWrapperRef), inquirerId);
if (!instanceHost.isResolved && !instanceWrapperRef.forwardRef) {

@@ -351,3 +357,3 @@ /*

}
async resolveProperties(wrapper, moduleRef, inject, contextId = constants_2.STATIC_CONTEXT, inquirer, parentInquirer) {
async resolveProperties(wrapper, moduleRef, inject, resolutionContext = { contextId: constants_2.STATIC_CONTEXT }, parentInquirer) {
if (!(0, shared_utils_1.isNil)(inject)) {

@@ -357,4 +363,4 @@ return [];

const metadata = wrapper.getPropertiesMetadata();
if (metadata && contextId !== constants_2.STATIC_CONTEXT) {
return this.loadPropertiesMetadata(metadata, contextId, inquirer);
if (metadata && resolutionContext.contextId !== constants_2.STATIC_CONTEXT) {
return this.loadPropertiesMetadata(metadata, resolutionContext.contextId, resolutionContext.inquirer);
}

@@ -376,3 +382,4 @@ const properties = this.reflectProperties(wrapper.metatype);

}
const paramWrapper = await this.resolveSingleParam(wrapper, item.name, dependencyContext, moduleRef, contextId, inquirer, item.key);
const nestedResolutionContext = this.getStaticTransientResolutionContext(resolutionContext, parentInquirer);
const paramWrapper = await this.resolveSingleParam(wrapper, item.name, dependencyContext, moduleRef, nestedResolutionContext, item.key);
/*

@@ -384,8 +391,8 @@ * Ensure that all instance wrappers are resolved at this point before we continue.

await propertyBarrier.signalAndWait();
const effectivePropertyInquirer = this.getEffectiveInquirer(paramWrapper, inquirer, parentInquirer, contextId);
const paramWrapperWithInstance = await this.resolveComponentHost(moduleRef, paramWrapper, contextId, effectivePropertyInquirer);
const effectivePropertyResolutionContext = this.getEffectiveResolutionContext(paramWrapper, resolutionContext, parentInquirer);
const paramWrapperWithInstance = await this.resolveComponentHost(moduleRef, paramWrapper, effectivePropertyResolutionContext);
if (!paramWrapperWithInstance) {
return undefined;
}
const instanceHost = paramWrapperWithInstance.getInstanceByContextId(this.getContextId(contextId, paramWrapperWithInstance), this.getInquirerId(effectivePropertyInquirer));
const instanceHost = paramWrapperWithInstance.getInstanceByContextId(this.getContextId(effectivePropertyResolutionContext.contextId, paramWrapperWithInstance), effectivePropertyResolutionContext.effectiveInquirerId);
return instanceHost.instance;

@@ -428,10 +435,7 @@ }

}
async instantiateClass(instances, wrapper, targetMetatype, contextId = constants_2.STATIC_CONTEXT, inquirer) {
async instantiateClass(instances, wrapper, targetMetatype, resolutionContext = { contextId: constants_2.STATIC_CONTEXT }) {
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);
const inquirerId = this.getContextInquirerId(resolutionContext);
const instanceHost = targetMetatype.getInstanceByContextId(this.getContextId(resolutionContext.contextId, targetMetatype), inquirerId);
const isInContext = this.isInContext(wrapper, resolutionContext);
if (this.options?.preview && !wrapper.host?.initOnPreview) {

@@ -462,3 +466,6 @@ instanceHost.isResolved = true;

}
await this.loadInstance(wrapper, collection, moduleRef, ctx, wrapper);
else {
wrapper = collection.get(wrapper.token) ?? wrapper;
}
await this.loadInstance(wrapper, collection, moduleRef, this.createResolutionContext(ctx, wrapper));
await this.loadEnhancersPerContext(wrapper, ctx, wrapper);

@@ -469,6 +476,9 @@ const host = wrapper.getInstanceByContextId(this.getContextId(ctx, wrapper), wrapper.id);

async loadEnhancersPerContext(wrapper, ctx, inquirer) {
if (ctx === constants_2.STATIC_CONTEXT) {
return;
}
const enhancers = wrapper.getEnhancersMetadata() || [];
const loadEnhancer = (item) => {
const hostModule = item.host;
return this.loadInstance(item, hostModule.injectables, hostModule, ctx, inquirer);
return this.loadInstance(item, hostModule.injectables, hostModule, this.createResolutionContext(ctx, inquirer));
};

@@ -481,4 +491,4 @@ await Promise.all(enhancers.map(loadEnhancer));

const dependency = metadata[index];
const effectiveInquirer = this.getEffectiveInquirer(dependency, inquirer, parentInquirer, contextId);
return item?.getInstanceByContextId(this.getContextId(contextId, item), this.getInquirerId(effectiveInquirer)).instance;
const effectiveInquirerId = this.getEffectiveInquirerId(dependency, this.createResolutionContext(contextId, inquirer), parentInquirer);
return item?.getInstanceByContextId(this.getContextId(contextId, item), effectiveInquirerId).instance;
});

@@ -489,3 +499,3 @@ }

key,
host: await this.resolveComponentHost(item.host, item, contextId, inquirer),
host: await this.resolveComponentHost(item.host, item, this.createResolutionContext(contextId, inquirer)),
})));

@@ -502,2 +512,30 @@ const inquirerId = this.getInquirerId(inquirer);

}
createResolutionContext(contextId, inquirer, effectiveInquirerId) {
return {
contextId,
inquirer,
effectiveInquirerId,
};
}
getContextInquirerId({ inquirer, effectiveInquirerId, }) {
return effectiveInquirerId ?? this.getInquirerId(inquirer);
}
isInContext(wrapper, resolutionContext) {
return (wrapper.isStatic(resolutionContext.contextId, resolutionContext.inquirer) ||
wrapper.isInRequestScope(resolutionContext.contextId, resolutionContext.inquirer) ||
wrapper.isLazyTransient(resolutionContext.contextId, resolutionContext.inquirer) ||
wrapper.isExplicitlyRequested(resolutionContext.contextId, resolutionContext.inquirer));
}
shouldSkipProviderLoading(wrapper, resolutionContext) {
const isSnapshotGraphCompilation = !!this.options?.snapshot;
const isStaticContext = resolutionContext.contextId === constants_2.STATIC_CONTEXT;
const hasNoInquirer = !resolutionContext.inquirer;
const isTopLevelStaticTransientOrRequestProvider = hasNoInquirer && (wrapper.isTransient || wrapper.scope === common_1.Scope.REQUEST);
const isStaticInquirerOutsideResolutionContext = !!resolutionContext.inquirer &&
!this.isInContext(resolutionContext.inquirer, this.createResolutionContext(resolutionContext.contextId, resolutionContext.inquirer));
const shouldSkipForStaticBootstrap = isStaticContext &&
(isTopLevelStaticTransientOrRequestProvider ||
isStaticInquirerOutsideResolutionContext);
return !isSnapshotGraphCompilation && shouldSkipForStaticBootstrap;
}
/**

@@ -510,14 +548,41 @@ * For nested TRANSIENT dependencies (TRANSIENT -> TRANSIENT) in non-static contexts,

*/
getEffectiveInquirer(dependency, inquirer, parentInquirer, contextId) {
return dependency?.isTransient &&
getEffectiveInquirer(dependency, resolutionContext, parentInquirer) {
const { inquirer, contextId } = resolutionContext;
if (dependency?.isTransient && inquirer?.isTransient && parentInquirer) {
if (contextId === constants_2.STATIC_CONTEXT) {
return inquirer.getRootInquirer() ?? parentInquirer;
}
return parentInquirer;
}
return inquirer;
}
getEffectiveInquirerId(dependency, resolutionContext, parentInquirer) {
const { contextId, inquirer, effectiveInquirerId } = resolutionContext;
if (contextId === constants_2.STATIC_CONTEXT &&
dependency?.isTransient &&
inquirer?.isTransient &&
parentInquirer &&
contextId !== constants_2.STATIC_CONTEXT
? parentInquirer
: inquirer;
parentInquirer) {
const baseInquirerId = effectiveInquirerId ?? this.getInquirerId(parentInquirer);
return `${baseInquirerId}:${inquirer.id}`;
}
const effectiveInquirer = this.getEffectiveInquirer(dependency, resolutionContext, parentInquirer);
return this.getInquirerId(effectiveInquirer);
}
getStaticTransientResolutionContext(resolutionContext, parentInquirer) {
const { contextId, inquirer, effectiveInquirerId } = resolutionContext;
if (contextId === constants_2.STATIC_CONTEXT &&
inquirer?.isTransient &&
parentInquirer) {
const baseInquirerId = effectiveInquirerId ?? this.getInquirerId(parentInquirer);
return this.createResolutionContext(contextId, inquirer, `${baseInquirerId}:${inquirer.id}`);
}
return resolutionContext;
}
getEffectiveResolutionContext(dependency, resolutionContext, parentInquirer) {
return this.createResolutionContext(resolutionContext.contextId, this.getEffectiveInquirer(dependency, resolutionContext, parentInquirer), this.getEffectiveInquirerId(dependency, resolutionContext, parentInquirer));
}
resolveScopedComponentHost(item, contextId, inquirer, parentInquirer) {
return this.isInquirerRequest(item, parentInquirer)
? parentInquirer
: this.resolveComponentHost(item.host, item, contextId, this.getEffectiveInquirer(item, inquirer, parentInquirer, contextId));
: this.resolveComponentHost(item.host, item, this.getEffectiveResolutionContext(item, this.createResolutionContext(contextId, inquirer), parentInquirer));
}

@@ -524,0 +589,0 @@ isInquirerRequest(item, parentInquirer) {

@@ -22,5 +22,7 @@ "use strict";

this.container = container;
const contextOptions = container.contextOptions;
this.injector = new injector_1.Injector({
preview: container.contextOptions?.preview,
instanceDecorator: container.contextOptions?.instrument?.instanceDecorator,
preview: contextOptions?.preview ?? false,
snapshot: contextOptions?.snapshot,
instanceDecorator: contextOptions?.instrument?.instanceDecorator,
});

@@ -58,7 +60,9 @@ }

}
/* 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, wrapper);
const properties = await this.injector.resolveProperties(wrapper, moduleRef, undefined, {
contextId: contextId ?? constants_1.STATIC_CONTEXT,
inquirer: wrapper,
});
const instance = new type(...instances);

@@ -68,3 +72,6 @@ this.injector.applyProperties(instance, properties);

};
await this.injector.resolveConstructorParams(wrapper, moduleRef, undefined, callback, contextId, wrapper);
await this.injector.resolveConstructorParams(wrapper, moduleRef, undefined, callback, {
contextId: contextId ?? constants_1.STATIC_CONTEXT,
inquirer: wrapper,
});
}

@@ -71,0 +78,0 @@ catch (err) {

@@ -100,2 +100,3 @@ "use strict";

preview: options.preview,
snapshot: options.snapshot,
instanceDecorator: options.instrument?.instanceDecorator,

@@ -102,0 +103,0 @@ });

{
"name": "@nestjs/core",
"version": "11.1.19",
"version": "11.1.20",
"description": "Nest - modern, fast, powerful node.js web framework (@core)",

@@ -42,3 +42,3 @@ "author": "Kamil Mysliwiec",

"devDependencies": {
"@nestjs/common": "11.1.19"
"@nestjs/common": "11.1.20"
},

@@ -64,3 +64,3 @@ "peerDependencies": {

},
"gitHead": "67309956821c0626c050fe6725c90645d2577e3d"
"gitHead": "7caeb3fb70de81085c4c3e8502a2a0e62e4f8eda"
}

@@ -32,3 +32,3 @@ <p align="center">

<p>In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front-end and back-end applications, giving rise to awesome projects like <a href="https://angular.io/" target="_blank">Angular</a>, <a href="https://github.com/facebook/react" target="_blank">React</a>, and <a href="https://github.com/vuejs/vue" target="_blank">Vue</a>, which improve developer productivity and enable the construction of fast, testable, and extensible frontend applications. However, on the server-side, while there are a lot of superb libraries, helpers, and tools for Node, none of them effectively solve the main problem - the architecture.</p>
<p>In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front-end and back-end applications, giving rise to awesome projects like <a href="https://angular.dev/" target="_blank">Angular</a>, <a href="https://react.dev/" target="_blank">React</a>, and <a href="https://vuejs.org/" target="_blank">Vue</a>, which improve developer productivity and enable the construction of fast, testable, and extensible frontend applications. However, on the server-side, while there are a lot of superb libraries, helpers, and tools for Node, none of them effectively solve the main problem - the architecture.</p>
<p>Nest aims to provide an application architecture out of the box which allows for effortless creation of highly testable, scalable, and loosely coupled and easily maintainable applications. The architecture is heavily inspired by Angular.</p>

@@ -99,2 +99,3 @@

<td align="center" valign="middle"><a href="https://pandektes.com" target="_blank"><img src="https://nestjs.com/img/logos/pandektes-logo.png" width="65" valign="middle" /></a></td>
<td align="center" valign="middle"><a href="https://www.fintechcrafts.com/" target="_blank"><img src="https://nestjs.com/img/logos/fintechcrafts-logo.svg" width="65" valign="middle" /></a></td>
</tr>

@@ -101,0 +102,0 @@ </table>

@@ -170,3 +170,8 @@ "use strict";

return async (result, res, req) => {
await this.responseController.sse(result, res.raw || res, req.raw || req, { additionalHeaders: res.getHeaders?.() });
const rawResponse = res.raw ?? res;
await this.responseController.sse(result, rawResponse, req.raw || req, {
additionalHeaders: res.getHeaders?.(),
statusCode: res.statusCode ??
rawResponse.statusCode,
});
};

@@ -173,0 +178,0 @@ }

@@ -25,5 +25,6 @@ import { HttpServer, RequestMethod } from '@nestjs/common';

sse<TInput extends Observable<unknown> = any, TResponse extends WritableHeaderStream = any, TRequest extends IncomingMessage = any>(result: TInput | Promise<TInput>, response: TResponse, request: TRequest, options?: {
additionalHeaders: AdditionalHeaders;
additionalHeaders?: AdditionalHeaders;
statusCode?: number;
}): Promise<void>;
private assertObservable;
}

@@ -59,34 +59,68 @@ "use strict";

const stream = new sse_stream_1.SseStream(request);
// Extract custom status code from response if it was set
const customStatusCode = response.statusCode;
const pipeOptions = typeof customStatusCode !== 'undefined'
? { ...options, statusCode: customStatusCode }
: options;
stream.pipe(response, pipeOptions);
const subscription = observableResult
.pipe((0, operators_1.map)((message) => {
if ((0, shared_utils_1.isObject)(message)) {
return message;
}
return { data: message };
}), (0, operators_1.concatMap)(message => new Promise(resolve => stream.writeMessage(message, () => resolve()))), (0, operators_1.catchError)(err => {
const data = err instanceof Error ? err.message : err;
stream.writeMessage({ type: 'error', data }, writeError => {
if (writeError) {
this.logger.error(writeError);
const statusCode = options?.statusCode ??
response.statusCode ??
200;
stream.pipe(response, {
additionalHeaders: options?.additionalHeaders,
statusCode,
});
return new Promise((resolve, reject) => {
let settled = false;
const onClose = () => {
settled = true;
subscription.unsubscribe();
if (!stream.writableEnded) {
stream.end();
}
response.end();
resolve();
};
const subscription = observableResult
.pipe((0, operators_1.map)((message) => {
if ((0, shared_utils_1.isObject)(message)) {
return message;
}
return { data: message };
}), (0, operators_1.concatMap)(message => new Promise(resolve => stream.writeMessage(message, () => resolve()))), (0, operators_1.catchError)(err => {
if (!stream.headersCommitted) {
throw err;
}
const data = err instanceof Error ? err.message : err;
stream.writeMessage({ type: 'error', data }, writeError => {
if (writeError) {
this.logger.error(writeError);
}
});
return rxjs_1.EMPTY;
}))
.subscribe({
error: err => {
settled = true;
request.removeListener('close', onClose);
if (!stream.writableEnded) {
stream.end();
}
reject(err);
},
complete: () => {
settled = true;
request.removeListener('close', onClose);
if (!stream.writableEnded) {
stream.end();
}
resolve();
},
});
return rxjs_1.EMPTY;
}))
.subscribe({
complete: () => {
response.end();
},
// Commit SSE headers on the next macrotask. Pipe validation errors
// propagate through microtasks (which complete before macrotasks),
// so if the lifecycle errored, `settled` is already true and we
// skip the write. Otherwise headers are sent immediately rather
// than waiting for the first Observable emission.
setTimeout(() => {
if (!settled) {
stream.commitHeaders();
}
}, 0);
request.on('close', onClose);
});
request.on('close', () => {
subscription.unsubscribe();
if (!stream.writableEnded) {
stream.end();
}
});
}

@@ -93,0 +127,0 @@ assertObservable(value) {

@@ -31,3 +31,8 @@ import { MessageEvent } from '@nestjs/common/interfaces';

private lastEventId;
private _headersCommitted;
private _destination;
private _statusCode;
private _additionalHeaders;
constructor(req?: IncomingMessage);
get headersCommitted(): boolean;
pipe<T extends WritableHeaderStream>(destination: T, options?: {

@@ -38,2 +43,9 @@ additionalHeaders?: AdditionalHeaders;

}): T;
/**
* Writes SSE headers to the destination if they have not been sent yet.
* Headers are deferred until the first message so that, if the observable
* errors before any data is emitted, the HTTP status code can still be
* changed by an exception filter.
*/
commitHeaders(): void;
_transform(message: MessageEvent, encoding: string, callback: (error?: Error | null, data?: any) => void): void;

@@ -40,0 +52,0 @@ /**

@@ -32,2 +32,5 @@ "use strict";

this.lastEventId = null;
this._headersCommitted = false;
this._destination = null;
this._statusCode = 200;
if (req && req.socket) {

@@ -39,7 +42,30 @@ req.socket.setKeepAlive(true);

}
get headersCommitted() {
return this._headersCommitted;
}
pipe(destination, options) {
if (destination.writeHead) {
const statusCode = options?.statusCode ?? 200;
destination.writeHead(statusCode, {
...options?.additionalHeaders,
this._destination = destination;
this._statusCode = options?.statusCode ?? 200;
this._additionalHeaders = options?.additionalHeaders;
return super.pipe(destination, options);
}
/**
* Writes SSE headers to the destination if they have not been sent yet.
* Headers are deferred until the first message so that, if the observable
* errors before any data is emitted, the HTTP status code can still be
* changed by an exception filter.
*/
commitHeaders() {
if (this._headersCommitted || !this._destination) {
return;
}
if (this._destination.writableEnded) {
return;
}
this._headersCommitted = true;
const statusCode = this._statusCode ?? 200;
const additionalHeaders = this._additionalHeaders;
if (this._destination.writeHead) {
this._destination.writeHead(statusCode, {
...additionalHeaders,
// See https://github.com/dunglas/mercure/blob/master/hub/subscribe.go#L124-L130

@@ -55,11 +81,14 @@ 'Content-Type': 'text/event-stream',

});
destination.flushHeaders?.();
this._destination.flushHeaders?.();
}
destination.write('\n');
return super.pipe(destination, options);
this._destination.write('\n');
}
_transform(message, encoding, callback) {
this.commitHeaders();
const sanitize = (val) => String(val).replace(/[\r\n]/g, '');
let data = message.type ? `event: ${sanitize(message.type)}\n` : '';
data += message.id ? `id: ${sanitize(message.id)}\n` : '';
data +=
message.id !== undefined && message.id !== null
? `id: ${sanitize(message.id)}\n`
: '';
data += message.retry ? `retry: ${sanitize(message.retry)}\n` : '';

@@ -75,3 +104,3 @@ data += message.data ? toDataString(message.data) : '';

writeMessage(message, cb) {
if (!message.id) {
if (message.id === undefined || message.id === null) {
this.lastEventId++;

@@ -78,0 +107,0 @@ message.id = this.lastEventId.toString();