Skip to content

Commit aaa5fd1

Browse files
update(@nestjs) update to 4.3.0 version
1 parent 2847b32 commit aaa5fd1

12 files changed

Lines changed: 172 additions & 76 deletions

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 4.3.0
2+
- **core**: `json` and `urlencoded` (`body-parser`) middlewares are applied by default now, bugfix #252
3+
- **core** more informative error message (injector) #223
4+
example: `[ExceptionHandler] Nest can't resolve dependencies of the UsersService (+, +, ?, +, +, +). Please verify whether [2] argument is available in the current context.`
5+
- **core**: bugfix #240 - middlewares container state
6+
- **core**: bugifx #257 - `@Next()` issue
7+
- **testing**: testing module is now independent from `@nestjs/microservices`
8+
19
## 4.2.2
210
- **websockets**: bugfix #242
311

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nestjs",
3-
"version": "4.2.0",
3+
"version": "4.3.0",
44
"description": "Modern, fast, powerful node.js web framework",
55
"main": "index.js",
66
"scripts": {
@@ -41,7 +41,7 @@
4141
"devDependencies": {
4242
"@types/chai": "^3.5.2",
4343
"@types/chai-as-promised": "0.0.31",
44-
"@types/express": "^4.0.36",
44+
"@types/express": "^4.0.39",
4545
"@types/mocha": "^2.2.38",
4646
"@types/node": "^7.0.5",
4747
"@types/redis": "^0.12.36",

src/core/errors/exceptions/undefined-dependency.exception.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { RuntimeException } from './runtime.exception';
22
import { UnknownDependenciesMessage } from '../messages';
33

44
export class UndefinedDependencyException extends RuntimeException {
5-
constructor(type: string) {
6-
super(UnknownDependenciesMessage(type));
5+
constructor(type: string, index: number, length: number) {
6+
super(UnknownDependenciesMessage(type, index, length));
77
}
88
}

src/core/errors/exceptions/unknown-dependencies.exception.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { RuntimeException } from './runtime.exception';
22
import { UnknownDependenciesMessage } from '../messages';
33

44
export class UnknownDependenciesException extends RuntimeException {
5-
constructor(type: string) {
6-
super(UnknownDependenciesMessage(type));
5+
constructor(type: string, index: number, length: number) {
6+
super(UnknownDependenciesMessage(type, index, length));
77
}
88
}

src/core/errors/messages.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1+
export const UnknownDependenciesMessage = (type: string, index: number, length: number) => {
2+
let message = `Nest can't resolve dependencies of the ${type}`;
3+
message += ` (`;
4+
5+
const args = new Array(length).fill('+');
6+
args[index] = '?';
7+
message += args.join(', ');
8+
9+
message += `). Please verify whether [${index}] argument is available in the current context.`;
10+
return message;
11+
};
12+
113
export const InvalidMiddlewareMessage = (name: string) =>
214
`The middleware doesn't provide the 'resolve' method (${name})`;
315

416
export const InvalidModuleMessage = (scope: string) =>
517
`Nest can't create the module instance. The frequent reason of this exception is the circular dependency between modules. Use forwardRef() to avoid it (read more https://docs.nestjs.com/advanced/circular-dependency). Scope [${scope}]`;
618

7-
export const UnknownDependenciesMessage = (type: string) =>
8-
`Nest can't resolve dependencies of the ${type}. Please verify whether all of them are available in the current context.`;
9-
1019
export const UnknownExportMessage = (name: string) =>
1120
`You are trying to export unknown component (${name}). Remember - your component should be listed both in exports and components arrays!`;
1221

src/core/injector/injector.ts

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,14 @@ export class Injector {
100100
let isResolved = true;
101101
const args = isNil(inject) ? this.reflectConstructorParams(wrapper.metatype) : inject;
102102

103-
const instances = await Promise.all(args.map(async (param) => {
104-
const paramWrapper = await this.resolveSingleParam<T>(wrapper, param, module, context);
103+
const instances = await Promise.all(args.map(async (param, index) => {
104+
const paramWrapper = await this.resolveSingleParam<T>(
105+
wrapper,
106+
param,
107+
{ index, length: args.length },
108+
module,
109+
context,
110+
);
105111
if (!paramWrapper.isResolved && !paramWrapper.forwardRef) {
106112
isResolved = false;
107113
}
@@ -125,16 +131,18 @@ export class Injector {
125131
public async resolveSingleParam<T>(
126132
wrapper: InstanceWrapper<T>,
127133
param: Metatype<any> | string | symbol | any,
134+
{ index, length }: { index: number, length: number },
128135
module: Module,
129-
context: Module[]) {
130-
136+
context: Module[],
137+
) {
131138
if (isUndefined(param)) {
132-
throw new UndefinedDependencyException(wrapper.name);
139+
throw new UndefinedDependencyException(wrapper.name, index, length);
133140
}
134141
const token = this.resolveParamToken(wrapper, param);
135142
return await this.resolveComponentInstance<T>(
136143
module,
137144
isFunction(token) ? (token as Metatype<any>).name : token,
145+
{ index, length },
138146
wrapper,
139147
context,
140148
);
@@ -151,10 +159,21 @@ export class Injector {
151159
return param.forwardRef();
152160
}
153161

154-
public async resolveComponentInstance<T>(module: Module, name: any, wrapper: InstanceWrapper<T>, context: Module[]) {
162+
public async resolveComponentInstance<T>(
163+
module: Module,
164+
name: any,
165+
{ index, length }: { index: number, length: number },
166+
wrapper: InstanceWrapper<T>,
167+
context: Module[],
168+
) {
155169
const components = module.components;
156-
const instanceWrapper = await this.scanForComponent(components, name, module, wrapper, context);
157-
170+
const instanceWrapper = await this.scanForComponent(
171+
components,
172+
module,
173+
{ name, index, length },
174+
wrapper,
175+
context,
176+
);
158177
if (!instanceWrapper.isResolved && !instanceWrapper.forwardRef) {
159178
await this.loadInstanceOfComponent(instanceWrapper, module);
160179
}
@@ -164,36 +183,62 @@ export class Injector {
164183
return instanceWrapper;
165184
}
166185

167-
public async scanForComponent(components: Map<string, any>, name: any, module: Module, { metatype }, context: Module[] = []) {
168-
const component = await this.scanForComponentInScopes(context, name, metatype);
186+
public async scanForComponent(
187+
components: Map<string, any>,
188+
module: Module,
189+
{ name, index, length }: { name: any, index: number, length: number },
190+
{ metatype },
191+
context: Module[] = [],
192+
) {
193+
const component = await this.scanForComponentInScopes(context, { name, index, length }, metatype);
169194
if (component) {
170195
return component;
171196
}
172-
const scanInExports = () => this.scanForComponentInExports(components, name, module, metatype, context);
197+
const scanInExports = () => this.scanForComponentInExports(
198+
components,
199+
{ name, index, length },
200+
module,
201+
metatype,
202+
context,
203+
);
173204
return components.has(name) ? components.get(name) : await scanInExports();
174205
}
175206

176-
public async scanForComponentInExports(components: Map<string, any>, name: any, module: Module, metatype, context: Module[] = []) {
207+
public async scanForComponentInExports(
208+
components: Map<string, any>,
209+
{ name, index, length }: { name: any, index: number, length: number },
210+
module: Module,
211+
metatype,
212+
context: Module[] = [],
213+
) {
177214
const instanceWrapper = await this.scanForComponentInRelatedModules(module, name, context);
178215
if (isNil(instanceWrapper)) {
179-
throw new UnknownDependenciesException(metatype.name);
216+
throw new UnknownDependenciesException(metatype.name, index, length);
180217
}
181218
return instanceWrapper;
182219
}
183220

184-
public async scanForComponentInScopes(context: Module[], name: any, metatype) {
221+
public async scanForComponentInScopes(
222+
context: Module[],
223+
{ name, index, length }: { name: any, index: number, length: number },
224+
metatype,
225+
) {
185226
context = context || [];
186227
for (const ctx of context) {
187-
const component = await this.scanForComponentInScope(ctx, name, metatype);
228+
const component = await this.scanForComponentInScope(ctx, { name, index, length }, metatype);
188229
if (component) return component;
189230
}
190231
return null;
191232
}
192233

193-
public async scanForComponentInScope(context: Module, name: any, metatype) {
234+
public async scanForComponentInScope(
235+
context: Module,
236+
{ name, index, length }: { name: any, index: number, length: number },
237+
metatype,
238+
) {
194239
try {
195240
const component = await this.scanForComponent(
196-
context.components, name, context, { metatype }, null,
241+
context.components, context, { name, index, length }, { metatype }, null,
197242
);
198243
if (!component.isResolved && !component.forwardRef) {
199244
await this.loadInstanceOfComponent(component, context);

src/core/middlewares/middlewares-module.ts

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,71 +21,84 @@ import { RouterExceptionFilters } from './../router/router-exception-filters';
2121

2222
export class MiddlewaresModule {
2323
private static readonly routesMapper = new RoutesMapper();
24-
private static readonly container = new MiddlewaresContainer();
2524
private static readonly routerProxy = new RouterProxy();
2625
private static readonly routerMethodFactory = new RouterMethodFactory();
2726
private static routerExceptionFilter: RouterExceptionFilters;
2827
private static resolver: MiddlewaresResolver;
2928

30-
public static async setup(container: NestContainer, config: ApplicationConfig) {
29+
public static async setup(
30+
middlewaresContainer: MiddlewaresContainer,
31+
container: NestContainer,
32+
config: ApplicationConfig,
33+
) {
3134
this.routerExceptionFilter = new RouterExceptionFilters(config);
32-
this.resolver = new MiddlewaresResolver(this.container);
35+
this.resolver = new MiddlewaresResolver(middlewaresContainer);
3336

3437
const modules = container.getModules();
35-
await this.resolveMiddlewares(modules);
38+
await this.resolveMiddlewares(middlewaresContainer, modules);
3639
}
3740

38-
public static getContainer(): MiddlewaresContainer {
39-
return this.container;
40-
}
41-
42-
public static async resolveMiddlewares(modules: Map<string, Module>) {
41+
public static async resolveMiddlewares(
42+
middlewaresContainer: MiddlewaresContainer,
43+
modules: Map<string, Module>,
44+
) {
4345
await Promise.all([...modules.entries()].map(async ([name, module]) => {
4446
const instance = module.instance;
4547

46-
this.loadConfiguration(instance, name);
48+
this.loadConfiguration(middlewaresContainer, instance, name);
4749
await this.resolver.resolveInstances(module, name);
4850
}));
4951
}
5052

51-
public static loadConfiguration(instance: NestModule, module: string) {
53+
public static loadConfiguration(
54+
middlewaresContainer: MiddlewaresContainer,
55+
instance: NestModule,
56+
module: string,
57+
) {
5258
if (!instance.configure) return;
5359

5460
const middlewaresBuilder = new MiddlewareBuilder(this.routesMapper);
5561
instance.configure(middlewaresBuilder);
62+
5663
if (!(middlewaresBuilder instanceof MiddlewareBuilder)) return;
5764

5865
const config = middlewaresBuilder.build();
59-
this.container.addConfig(config, module);
66+
middlewaresContainer.addConfig(config, module);
6067
}
6168

62-
public static async setupMiddlewares(app) {
63-
const configs = this.container.getConfigs();
69+
public static async setupMiddlewares(middlewaresContainer: MiddlewaresContainer, app) {
70+
const configs = middlewaresContainer.getConfigs();
6471
await Promise.all([...configs.entries()].map(async ([module, moduleConfigs]) => {
6572
await Promise.all([...moduleConfigs].map(async (config: MiddlewareConfiguration) => {
66-
await this.setupMiddlewareConfig(config, module, app);
73+
await this.setupMiddlewareConfig(middlewaresContainer, config, module, app);
6774
}));
6875
}));
6976
}
7077

71-
public static async setupMiddlewareConfig(config: MiddlewareConfiguration, module: string, app) {
78+
public static async setupMiddlewareConfig(
79+
middlewaresContainer: MiddlewaresContainer,
80+
config: MiddlewareConfiguration,
81+
module: string,
82+
app,
83+
) {
7284
const { forRoutes } = config;
7385
await Promise.all(forRoutes.map(async (route: ControllerMetadata & { method: RequestMethod }) => {
74-
await this.setupRouteMiddleware(route, config, module, app);
86+
await this.setupRouteMiddleware(middlewaresContainer, route, config, module, app);
7587
}));
7688
}
7789

7890
public static async setupRouteMiddleware(
91+
middlewaresContainer: MiddlewaresContainer,
7992
route: ControllerMetadata & { method: RequestMethod },
8093
config: MiddlewareConfiguration,
8194
module: string,
82-
app) {
83-
95+
app,
96+
) {
8497
const { path, method } = route;
8598

8699
const middlewares = [].concat(config.middlewares);
87100
await Promise.all(middlewares.map(async (metatype: Metatype<NestMiddleware>) => {
88-
const collection = this.container.getMiddlewares(module);
101+
const collection = middlewaresContainer.getMiddlewares(module);
89102
const middleware = collection.get(metatype.name);
90103
if (isUndefined(middleware)) {
91104
throw new RuntimeException();

src/core/nest-application.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as http from 'http';
22
import * as optional from 'optional';
3+
import * as bodyParser from 'body-parser';
34
import iterate from 'iterare';
45
import {
56
CanActivate,
@@ -22,13 +23,15 @@ import { MiddlewaresModule } from './middlewares/middlewares-module';
2223
import { Resolver } from './router/interfaces/resolver.interface';
2324
import { RoutesResolver } from './router/routes-resolver';
2425
import { MicroservicesPackageNotFoundException } from './errors/exceptions/microservices-package-not-found.exception';
26+
import { MiddlewaresContainer } from './middlewares/container';
2527

2628
const { SocketModule } = optional('@nestjs/websockets/socket-module') || {} as any;
2729
const { MicroservicesModule } = optional('@nestjs/microservices/microservices-module') || {} as any;
2830
const { NestMicroservice } = optional('@nestjs/microservices/nest-microservice') || {} as any;
2931
const { IoAdapter } = optional('@nestjs/websockets/adapters/io-adapter') || {} as any;
3032

3133
export class NestApplication implements INestApplication {
34+
private readonly middlewaresContainer = new MiddlewaresContainer();
3235
private readonly logger = new Logger(NestApplication.name, true);
3336
private readonly httpServer: http.Server = null;
3437
private readonly routesResolver: Resolver = null;
@@ -40,6 +43,7 @@ export class NestApplication implements INestApplication {
4043
private readonly container: NestContainer,
4144
private readonly express,
4245
) {
46+
this.setupParserMiddlewares();
4347
this.httpServer = http.createServer(express);
4448

4549
const ioAdapter = IoAdapter ? new IoAdapter(this.httpServer) : null;
@@ -49,14 +53,23 @@ export class NestApplication implements INestApplication {
4953
);
5054
}
5155

56+
public setupParserMiddlewares() {
57+
this.express.use(bodyParser.json());
58+
this.express.use(bodyParser.urlencoded({ extended: true }));
59+
}
60+
5261
public async setupModules() {
5362
SocketModule && SocketModule.setup(this.container, this.config);
5463

5564
if (MicroservicesModule) {
5665
MicroservicesModule.setup(this.container, this.config);
5766
MicroservicesModule.setupClients(this.container);
5867
}
59-
await MiddlewaresModule.setup(this.container, this.config);
68+
await MiddlewaresModule.setup(
69+
this.middlewaresContainer,
70+
this.container,
71+
this.config,
72+
);
6073
}
6174

6275
public async init() {
@@ -158,7 +171,7 @@ export class NestApplication implements INestApplication {
158171
}
159172

160173
private async setupMiddlewares(instance) {
161-
await MiddlewaresModule.setupMiddlewares(instance);
174+
await MiddlewaresModule.setupMiddlewares(this.middlewaresContainer, instance);
162175
}
163176

164177
private listenToPromise(microservice: INestMicroservice) {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export class RouterExecutionContext {
4545
const interceptors = this.interceptorsContextCreator.create(instance, callback, module);
4646
const httpCode = this.reflectHttpStatusCode(callback);
4747
const paramsMetadata = this.exchangeKeysForValues(keys, metadata);
48-
const isResponseObj = paramsMetadata.some(({ type }) => type === RouteParamtypes.RESPONSE);
48+
const isResponseHandled = paramsMetadata.some(({ type }) => type === RouteParamtypes.RESPONSE || type === RouteParamtypes.NEXT);
4949
const paramsOptions = this.mergeParamsMetatypes(paramsMetadata, paramtypes);
5050

5151
return async (req, res, next) => {
@@ -68,7 +68,7 @@ export class RouterExecutionContext {
6868
const result = await this.interceptorsConsumer.intercept(
6969
interceptors, req, instance, callback, handler,
7070
);
71-
return !isResponseObj ?
71+
return !isResponseHandled ?
7272
this.responseController.apply(result, res, requestMethod, httpCode) :
7373
undefined;
7474
};

0 commit comments

Comments
 (0)