bugfix(@nestjs/core) fix express adapter incompatibility

This commit is contained in:
Kamil Myśliwiec
2018-03-13 18:53:18 +01:00
parent 10781a7a8e
commit 15a8225ec1
7 changed files with 73 additions and 37 deletions

View File

@@ -1,8 +1,8 @@
import { Injectable, NestMiddleware, ExpressMiddleware } from '@nestjs/common';
import { Injectable, NestMiddleware, FunctionMiddleware } from '@nestjs/common';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
resolve(context: string): ExpressMiddleware {
resolve(context: string): FunctionMiddleware {
return (req, res, next) => {
console.log(`[${context}] Request...`);
next();

View File

@@ -51,7 +51,6 @@
"rxjs-grpc": "^0.1.6",
"socket.io": "^2.0.3",
"trouter": "^1.0.0",
"turbo-http": "^0.1.1",
"typescript": "^2.4.1"
},
"devDependencies": {

View File

@@ -4,12 +4,12 @@ export interface ErrorHandler {
(
error: any,
req: Partial<IncomingMessage>,
res: ServerResponse,
next: Function,
res: ServerResponse | any,
next?: Function,
): any;
}
export interface RequestHandler {
(req: Partial<IncomingMessage>, res: ServerResponse, next: Function): any;
(req: Partial<IncomingMessage>, res: ServerResponse | any, next?: Function): any;
}
export interface HttpServer {

View File

@@ -6,8 +6,6 @@ import {
import { isNil, isObject } from '@nestjs/common/utils/shared.utils';
export class ExpressAdapter implements HttpServer {
private readonly isExpress = true;
constructor(private readonly instance) {}
use(handler: RequestHandler | ErrorHandler);

View File

@@ -39,6 +39,8 @@ import { NestApplicationContext } from './nest-application-context';
import { HttpsOptions } from '@nestjs/common/interfaces/external/https-options.interface';
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
import { HttpServer } from '@nestjs/common/interfaces';
import { ExpressAdapter } from './adapters/express-adapter';
const { SocketModule } =
optional('@nestjs/websockets/socket-module') || ({} as any);
@@ -65,7 +67,7 @@ export class NestApplication extends NestApplicationContext
constructor(
container: NestContainer,
private readonly httpAdapter: any,
private httpAdapter: HttpServer,
private readonly config: ApplicationConfig,
private readonly appOptions: NestApplicationOptions = {},
) {
@@ -74,6 +76,7 @@ export class NestApplication extends NestApplicationContext
this.applyOptions();
this.selectContextModule();
this.registerHttpServer();
this.routesResolver = new RoutesResolver(this.container, this.config);
}
@@ -98,17 +101,22 @@ export class NestApplication extends NestApplicationContext
public createServer(): any {
const isHttpsEnabled = this.appOptions && this.appOptions.httpsOptions;
if (isHttpsEnabled && this.httpAdapter.isExpress) {
return https.createServer(this.appOptions.httpsOptions, this.httpAdapter);
const isExpress = this.isExpress();
if (isHttpsEnabled && isExpress) {
return https.createServer(
this.appOptions.httpsOptions,
this.httpAdapter.getHttpServer(),
);
}
if (this.httpAdapter.isExpress) {
if (isExpress) {
return http.createServer(this.httpAdapter.getHttpServer());
}
return this.httpAdapter;
}
public getUnderlyingHttpServer(): any {
return this.httpAdapter.isExpress
return this.isExpress()
? this.httpServer
: this.httpAdapter.getHttpServer();
}
@@ -143,7 +151,7 @@ export class NestApplication extends NestApplicationContext
}
public registerParserMiddlewares() {
if (!this.httpAdapter.isExpress) {
if (!this.isExpress()) {
return void 0;
}
const parserMiddlewares = {
@@ -155,7 +163,8 @@ export class NestApplication extends NestApplicationContext
.forEach(parserKey => this.httpAdapter.use(parserMiddlewares[parserKey]));
}
public isMiddlewareApplied(app, name: string): boolean {
public isMiddlewareApplied(httpAdapter: HttpServer, name: string): boolean {
const app = this.httpAdapter.getHttpServer();
return (
!!app._router &&
!!app._router.stack &&
@@ -185,7 +194,7 @@ export class NestApplication extends NestApplicationContext
config as any,
applicationConfig,
);
instance.setupListeners();
instance.registerListeners();
instance.setIsInitialized(true);
instance.setIsInitHookCalled(true);
@@ -212,28 +221,40 @@ export class NestApplication extends NestApplicationContext
return new Promise(resolve => this.startAllMicroservices(resolve));
}
public use(...args): this {
this.httpAdapter.use(...args);
public use(...args: any[]): this {
(this.httpAdapter as any).use(...args);
return this;
}
public engine(...args): this {
this.httpAdapter.engine && this.httpAdapter.engine(...args);
if (!this.isExpress()) {
return this;
}
(this.httpAdapter as ExpressAdapter).engine(...args);
return this;
}
public set(...args): this {
this.httpAdapter.set && this.httpAdapter.set(...args);
if (!this.isExpress()) {
return this;
}
(this.httpAdapter as ExpressAdapter).set(...args);
return this;
}
public disable(...args): this {
this.httpAdapter.disable && this.httpAdapter.disable(...args);
if (!this.isExpress()) {
return this;
}
(this.httpAdapter as ExpressAdapter).disable(...args);
return this;
}
public enable(...args): this {
this.httpAdapter.enable && this.httpAdapter.enable(...args);
if (!this.isExpress()) {
return this;
}
(this.httpAdapter as ExpressAdapter).enable(...args);
return this;
}
@@ -308,6 +329,14 @@ export class NestApplication extends NestApplicationContext
);
}
private isExpress(): boolean {
const isExpress = !this.httpAdapter.getHttpServer;
if (isExpress) {
return isExpress;
}
return this.httpAdapter instanceof ExpressAdapter;
}
private listenToPromise(microservice: INestMicroservice) {
return new Promise(async (resolve, reject) => {
await microservice.listen(resolve);

View File

@@ -23,6 +23,7 @@ import { HttpsOptions } from '@nestjs/common/interfaces/external/https-options.i
import { NestApplicationContextOptions } from '@nestjs/common/interfaces/nest-application-context-options.interface';
import { NestMicroserviceOptions } from '@nestjs/common/interfaces/microservices/nest-microservice-options.interface';
import { ApplicationConfig } from './application-config';
import { ExpressAdapter } from './adapters/express-adapter';
const { NestMicroservice } =
optional('@nestjs/microservices/nest-microservice') || ({} as any);
@@ -40,7 +41,7 @@ export class NestFactoryStatic {
): Promise<INestApplication>;
public async create(
module: any,
httpServer: HttpServer,
httpServer: HttpServer | any,
options?: NestApplicationOptions,
): Promise<INestApplication>;
public async create(
@@ -49,27 +50,18 @@ export class NestFactoryStatic {
options?: NestApplicationOptions,
): Promise<INestApplication> {
const isHttpServer = serverOrOptions && serverOrOptions.patch;
const [httpServer, appOptions] = isHttpServer
let [httpServer, appOptions] = isHttpServer
? [serverOrOptions, options]
: [ExpressFactory.create(), serverOrOptions];
const applicationConfig = new ApplicationConfig();
const container = new NestContainer(applicationConfig);
httpServer = this.applyExpressAdapter(httpServer);
this.applyLogger(appOptions);
await this.initialize(
module,
container,
applicationConfig,
httpServer,
);
await this.initialize(module, container, applicationConfig, httpServer);
return this.createNestInstance<NestApplication>(
new NestApplication(
container,
httpServer,
applicationConfig,
appOptions,
),
new NestApplication(container, httpServer, applicationConfig, appOptions),
);
}
@@ -180,6 +172,14 @@ export class NestFactoryStatic {
}
Logger.overrideLogger(options.logger);
}
private applyExpressAdapter(httpAdapter: HttpServer): HttpServer {
const isAdapter = !!httpAdapter.getHttpServer;
if (isAdapter) {
return httpAdapter;
}
return new ExpressAdapter(httpAdapter);
}
}
export const NestFactory = new NestFactoryStatic();

View File

@@ -8,6 +8,7 @@ import { MicroservicesPackageNotFoundException } from '@nestjs/core/errors/excep
import { ApplicationConfig } from '@nestjs/core/application-config';
import { HttpServer } from '@nestjs/common';
import { ExpressFactory } from '@nestjs/core/adapters/express-factory';
import { ExpressAdapter } from '@nestjs/core/adapters/express-adapter';
const { NestMicroservice } =
optional('@nestjs/microservices/nest-microservice') || ({} as any);
@@ -20,6 +21,7 @@ export class TestingModule extends NestApplicationContext {
public createNestApplication(
httpServer: HttpServer = ExpressFactory.create(),
): INestApplication {
httpServer = this.applyExpressAdapter(httpServer);
this.container.setApplicationRef(httpServer);
return new NestApplication(
this.container,
@@ -40,4 +42,12 @@ export class TestingModule extends NestApplicationContext {
new ApplicationConfig(),
);
}
private applyExpressAdapter(httpAdapter: HttpServer): HttpServer {
const isAdapter = !!httpAdapter.getHttpServer;
if (isAdapter) {
return httpAdapter;
}
return new ExpressAdapter(httpAdapter);
}
}