Skip to content

Commit 08fc594

Browse files
feature(@nestjs/core) injectable APP_REF
1 parent 1812567 commit 08fc594

11 files changed

Lines changed: 60 additions & 27 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
## 4.6.0
2+
- **core** add ability to inject application reference (`APP_REF` token)
3+
- **core**: [bugfix] interceptor `$stream` observable returns another observable instead of the response object #376
4+
- **core**: [bugfix] `Observable.throw` from controller results in unhandled rejection promise #373
5+
16
## 4.5.10
27
- **core**: [bugfix] #343
3-
4-
## 4.5.7
58
- **core**: [bugfix] #337
69

710
## 4.5.6

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nestjs",
3-
"version": "4.5.10",
3+
"version": "4.6.0",
44
"description": "Modern, fast, powerful node.js web framework",
55
"main": "index.js",
66
"scripts": {

src/core/injector/container.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { ModuleTokenFactory } from './module-token-factory';
1111
import { InvalidModuleException } from './../errors/exceptions/invalid-module.exception';
1212
import { DynamicModule } from '@nestjs/common';
1313
import { ModulesContainer } from './modules-container';
14+
import { HostProvidersModule } from './host-module';
15+
import { NestApplicationContext } from './../nest-application-context';
1416

1517
export class NestContainer {
1618
private readonly globalModules = new Set<Module>();
@@ -21,6 +23,10 @@ export class NestContainer {
2123
>();
2224
private readonly moduleTokenFactory = new ModuleTokenFactory();
2325

26+
public addHostModule<T extends NestApplicationContext>(applicationRef: T) {
27+
this.addModule(HostProvidersModule.extend(applicationRef), []);
28+
}
29+
2430
public addModule(
2531
metatype: NestModuleMetatype | DynamicModule,
2632
scope: NestModuleMetatype[],
@@ -78,7 +84,7 @@ export class NestContainer {
7884
if (!modules) {
7985
return;
8086
}
81-
modules.map((module) => this.addModule(module, scope));
87+
modules.map(module => this.addModule(module, scope));
8288
}
8389

8490
public isGlobalModule(metatype: NestModuleMetatype): boolean {

src/core/injector/host-module.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Module, Global, DynamicModule } from '@nestjs/common';
2+
import { Reflector } from '../services/reflector.service';
3+
import { NestApplicationContext } from './../nest-application-context';
4+
import { APP_REF } from './tokens';
5+
6+
@Global()
7+
@Module({
8+
components: [Reflector],
9+
exports: [Reflector],
10+
})
11+
export class HostProvidersModule {
12+
static extend<T extends NestApplicationContext>(
13+
applicationRef: T,
14+
): DynamicModule {
15+
const providers = [
16+
{
17+
provide: APP_REF,
18+
useValue: applicationRef,
19+
},
20+
];
21+
return {
22+
module: HostProvidersModule,
23+
components: providers,
24+
exports: providers,
25+
};
26+
}
27+
}

src/core/injector/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './modules-container';
2+
export * from './tokens';

src/core/injector/module.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
isSymbol,
1313
} from '@nestjs/common/utils/shared.utils';
1414
import { RuntimeException } from '../errors/exceptions/runtime.exception';
15-
import { Reflector } from '../services/reflector.service';
1615
import { ExternalContextCreator } from './../helpers/external-context-creator';
1716
import { GuardsContextCreator } from './../guards/guards-context-creator';
1817
import { InterceptorsContextCreator } from './../interceptors/interceptors-context-creator';
@@ -91,7 +90,6 @@ export class Module {
9190
public addCoreInjectables(container: NestContainer) {
9291
this.addModuleRef();
9392
this.addModuleAsComponent();
94-
this.addReflector();
9593
this.addExternalContextCreator(container);
9694
this.addModulesContainer(container);
9795
}
@@ -115,15 +113,6 @@ export class Module {
115113
});
116114
}
117115

118-
public addReflector() {
119-
this._components.set(Reflector.name, {
120-
name: Reflector.name,
121-
metatype: Reflector,
122-
isResolved: false,
123-
instance: null,
124-
});
125-
}
126-
127116
public addExternalContextCreator(container: NestContainer) {
128117
this._components.set(ExternalContextCreator.name, {
129118
name: ExternalContextCreator.name,

src/core/injector/tokens.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const APP_REF = 'APP_REF';

src/core/interceptors/interceptors-consumer.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import { HttpStatus, ExecutionContext, NestInterceptor } from '@nestjs/common';
1111
import { Observable } from 'rxjs/Observable';
1212
import 'rxjs/add/operator/toPromise';
1313
import 'rxjs/add/observable/defer';
14+
import 'rxjs/add/observable/fromPromise';
1415
import 'rxjs/add/operator/take';
16+
import 'rxjs/add/operator/switchMap';
1517

1618
export class InterceptorsConsumer {
1719
public async intercept(
@@ -25,7 +27,7 @@ export class InterceptorsConsumer {
2527
return await (await next());
2628
}
2729
const context = this.createContext(instance, callback);
28-
const start$ = Observable.defer(async () => await this.transformDeffered(next));
30+
const start$ = Observable.defer(() => this.transformDeffered(next));
2931
const result$ = await interceptors.reduce(
3032
async (stream$, interceptor) =>
3133
await interceptor.intercept(dataOrRequest, context, await stream$),
@@ -44,9 +46,11 @@ export class InterceptorsConsumer {
4446
};
4547
}
4648

47-
public async transformDeffered(next: () => any): Promise<any> {
48-
const res = await next();
49-
const isDeffered = res instanceof Promise || res instanceof Observable;
50-
return isDeffered ? res : Promise.resolve(res);
49+
public transformDeffered(next: () => Promise<any>): Observable<any> {
50+
return Observable.fromPromise(next())
51+
.switchMap((res) => {
52+
const isDeffered = res instanceof Promise || res instanceof Observable;
53+
return isDeffered ? res : Promise.resolve(res);
54+
});
5155
}
5256
}

src/core/nest-application-context.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ export class NestApplicationContext implements INestApplicationContext {
1212
protected readonly container: NestContainer,
1313
private readonly scope: NestModuleMetatype[],
1414
protected contextModule,
15-
) {}
15+
) {
16+
this.container.addHostModule(this);
17+
}
1618

1719
public select<T>(module: Metatype<T>): INestApplicationContext {
1820
const modules = this.container.getModules();

src/core/router/router-execution-context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export class RouterExecutionContext {
9797
callback,
9898
handler,
9999
);
100-
!isResponseHandled && this.responseController.apply(result, res, httpStatusCode)
100+
!isResponseHandled && await this.responseController.apply(result, res, httpStatusCode)
101101
};
102102
}
103103

0 commit comments

Comments
 (0)