Skip to content

Commit bc527be

Browse files
fix(core): resolve conflicts
2 parents 5143fc6 + b90a1a6 commit bc527be

13 files changed

Lines changed: 241 additions & 4 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { INestApplication, Logger } from '@nestjs/common';
2+
import { Test } from '@nestjs/testing';
3+
import { expect } from 'chai';
4+
import * as sinon from 'sinon';
5+
import * as request from 'supertest';
6+
import { HelloModule } from '../src/inject-inquirer/hello.module';
7+
8+
describe('Inject Inquirer', () => {
9+
let logger: Record<string, any>;
10+
let server: any;
11+
let app: INestApplication;
12+
13+
beforeEach(async () => {
14+
logger = { log: sinon.spy() };
15+
16+
const module = await Test.createTestingModule({
17+
imports: [HelloModule],
18+
})
19+
.overrideProvider(Logger)
20+
.useValue(logger)
21+
.compile();
22+
23+
app = module.createNestApplication();
24+
server = app.getHttpServer();
25+
await app.init();
26+
});
27+
28+
it(`should allow the injection of inquirer in a Transient Scope`, async () => {
29+
await request(server).get('/hello/transient');
30+
31+
expect(
32+
logger.log.calledWith({
33+
message: 'Hello transient!',
34+
feature: 'transient',
35+
}),
36+
).to.be.true;
37+
});
38+
39+
it(`should allow the injection of the inquirer in a Request Scope`, async () => {
40+
await request(server).get('/hello/request');
41+
42+
expect(
43+
logger.log.calledWith({
44+
message: 'Hello request!',
45+
requestId: sinon.match.string,
46+
feature: 'request',
47+
}),
48+
).to.be.true;
49+
50+
const requestId = logger.log.getCall(0).args[0].requestId;
51+
52+
expect(
53+
logger.log.calledWith({
54+
message: 'Goodbye request!',
55+
requestId,
56+
feature: 'request',
57+
}),
58+
);
59+
});
60+
61+
afterEach(async () => {
62+
await app.close();
63+
});
64+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Injectable, Scope } from '@nestjs/common';
2+
import { RequestLogger } from './request-logger.service';
3+
4+
@Injectable({ scope: Scope.REQUEST })
5+
export class HelloRequestService {
6+
static logger = { feature: 'request' };
7+
8+
constructor(private readonly logger: RequestLogger) {}
9+
10+
greeting() {
11+
this.logger.log('Hello request!');
12+
}
13+
14+
farewell() {
15+
this.logger.log('Goodbye request!');
16+
}
17+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Inject, Logger, Injectable, Scope } from '@nestjs/common';
2+
import { REQUEST, INQUIRER } from '@nestjs/core';
3+
4+
@Injectable({ scope: Scope.TRANSIENT })
5+
export class RequestLogger {
6+
config: object;
7+
8+
constructor(
9+
@Inject(INQUIRER) { constructor },
10+
@Inject(REQUEST) private readonly request,
11+
private readonly logger: Logger,
12+
) {
13+
this.config = (constructor && constructor.logger) || {};
14+
}
15+
16+
get requestId() {
17+
if (!this.request.id) {
18+
this.request.id = `${Date.now()}.${Math.floor(Math.random() * 1000000)}`;
19+
}
20+
return this.request.id;
21+
}
22+
23+
log(message: string) {
24+
this.logger.log({ message, requestId: this.requestId, ...this.config });
25+
}
26+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { TransientLogger } from './transient-logger.service';
3+
4+
@Injectable()
5+
export class HelloTransientService {
6+
static logger = { feature: 'transient' };
7+
8+
constructor(private readonly logger: TransientLogger) {}
9+
10+
greeting() {
11+
this.logger.log('Hello transient!');
12+
}
13+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Inject, Injectable, Logger, Scope } from '@nestjs/common';
2+
import { INQUIRER } from '@nestjs/core';
3+
4+
@Injectable({ scope: Scope.TRANSIENT })
5+
export class TransientLogger {
6+
// @Inject(INQUIRER) inquirer: any;
7+
config: object;
8+
9+
constructor(
10+
@Inject(INQUIRER) { constructor },
11+
private readonly logger: Logger,
12+
) {
13+
this.config = (constructor && constructor.logger) || {};
14+
}
15+
16+
log(message: string) {
17+
this.logger.log({ message, ...this.config });
18+
}
19+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Controller, Get, Scope } from '@nestjs/common';
2+
import { HelloRequestService } from './hello-request/hello-request.service';
3+
import { HelloTransientService } from './hello-transient/hello-transient.service';
4+
5+
@Controller({
6+
path: 'hello',
7+
scope: Scope.REQUEST,
8+
})
9+
export class HelloController {
10+
constructor(
11+
private readonly helloTransientService: HelloTransientService,
12+
private readonly helloRequestService: HelloRequestService,
13+
) {}
14+
15+
@Get('transient')
16+
greetingTransient() {
17+
this.helloTransientService.greeting();
18+
}
19+
20+
@Get('request')
21+
greetingRequest() {
22+
this.helloRequestService.greeting();
23+
this.helloRequestService.farewell();
24+
}
25+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Module, Logger } from '@nestjs/common';
2+
import { HelloController } from './hello.controller';
3+
import { HelloRequestService } from './hello-request/hello-request.service';
4+
import { HelloTransientService } from './hello-transient/hello-transient.service';
5+
import { RequestLogger } from './hello-request/request-logger.service';
6+
import { TransientLogger } from './hello-transient/transient-logger.service';
7+
8+
@Module({
9+
controllers: [HelloController],
10+
providers: [
11+
HelloRequestService,
12+
HelloTransientService,
13+
RequestLogger,
14+
TransientLogger,
15+
Logger,
16+
],
17+
})
18+
export class HelloModule {}

packages/core/injector/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * from './container';
22
export { ContextId } from './instance-wrapper';
33
export * from './module-ref';
44
export * from './modules-container';
5+
export * from './inquirer';

packages/core/injector/injector.ts

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { RuntimeException } from '../errors/exceptions/runtime.exception';
1919
import { UndefinedDependencyException } from '../errors/exceptions/undefined-dependency.exception';
2020
import { UnknownDependenciesException } from '../errors/exceptions/unknown-dependencies.exception';
2121
import { STATIC_CONTEXT } from './constants';
22+
import { INQUIRER } from './inquirer';
2223
import {
2324
ContextId,
2425
InstancePerContext,
@@ -218,6 +219,7 @@ export class Injector {
218219
callback,
219220
contextId,
220221
wrapper,
222+
inquirer,
221223
);
222224
}
223225

@@ -228,11 +230,17 @@ export class Injector {
228230
callback: (args: any[]) => void,
229231
contextId = STATIC_CONTEXT,
230232
inquirer?: InstanceWrapper,
233+
parentInquirer?: InstanceWrapper,
231234
) {
232235
const inquirerId = this.getInquirerId(inquirer);
233236
const metadata = wrapper.getCtorMetadata();
234237
if (metadata && contextId !== STATIC_CONTEXT) {
235-
const deps = await this.loadCtorMetadata(metadata, contextId, inquirer);
238+
const deps = await this.loadCtorMetadata(
239+
metadata,
240+
contextId,
241+
inquirer,
242+
parentInquirer,
243+
);
236244
return callback(deps);
237245
}
238246
const dependencies = isNil(inject)
@@ -245,6 +253,9 @@ export class Injector {
245253
let isResolved = true;
246254
const resolveParam = async (param: unknown, index: number) => {
247255
try {
256+
if (this.isInquirer(param, parentInquirer)) {
257+
return parentInquirer && parentInquirer.instance;
258+
}
248259
const paramWrapper = await this.resolveSingleParam<T>(
249260
wrapper,
250261
param,
@@ -666,10 +677,16 @@ export class Injector {
666677
metadata: InstanceWrapper<any>[],
667678
contextId: ContextId,
668679
inquirer?: InstanceWrapper,
680+
parentInquirer?: InstanceWrapper,
669681
): Promise<any[]> {
670682
const hosts = await Promise.all(
671683
metadata.map(async item =>
672-
this.resolveComponentHost(item.host, item, contextId, inquirer),
684+
this.resolveScopedComponentHost(
685+
item,
686+
contextId,
687+
inquirer,
688+
parentInquirer,
689+
),
673690
),
674691
);
675692
const inquirerId = this.getInquirerId(inquirer);
@@ -705,4 +722,29 @@ export class Injector {
705722
private getInquirerId(inquirer: InstanceWrapper | undefined): string {
706723
return inquirer && inquirer.id;
707724
}
725+
726+
private resolveScopedComponentHost(
727+
item: InstanceWrapper,
728+
contextId: ContextId,
729+
inquirer?: InstanceWrapper,
730+
parentInquirer?: InstanceWrapper,
731+
) {
732+
return this.isInquirerRequest(item, parentInquirer)
733+
? parentInquirer
734+
: this.resolveComponentHost(item.host, item, contextId, inquirer);
735+
}
736+
737+
private isInquirerRequest(
738+
item: InstanceWrapper,
739+
parentInquirer: InstanceWrapper | undefined,
740+
) {
741+
return item.isTransient && item.name === INQUIRER && parentInquirer;
742+
}
743+
744+
private isInquirer(
745+
param: unknown,
746+
parentInquirer: InstanceWrapper | undefined,
747+
) {
748+
return param === INQUIRER && parentInquirer;
749+
}
708750
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './inquirer-constants';

0 commit comments

Comments
 (0)