mirror of
https://github.com/nestjs/nest.git
synced 2026-02-21 23:11:44 +00:00
feature(core/common) extract HTTP adapters (express/fastify)
This commit is contained in:
@@ -23,8 +23,6 @@ export {
|
||||
HttpServer,
|
||||
INestApplication,
|
||||
INestApplicationContext,
|
||||
INestExpressApplication,
|
||||
INestFastifyApplication,
|
||||
INestMicroservice,
|
||||
MiddlewareConsumer,
|
||||
MiddlewareFunction,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { RequestMethod } from '../../enums';
|
||||
import { NestApplicationOptions } from './../../interfaces/nest-application-options.interface';
|
||||
|
||||
export type ErrorHandler<TRequest = any, TResponse = any> = (
|
||||
error: any,
|
||||
@@ -54,6 +55,8 @@ export interface HttpServer<TRequest = any, TResponse = any> {
|
||||
getRequestMethod?(request: TRequest): string;
|
||||
getRequestUrl?(request: TResponse): string;
|
||||
getInstance(): any;
|
||||
registerParserMiddleware(): any;
|
||||
getHttpServer(): any;
|
||||
initHttpServer(options: NestApplicationOptions): void;
|
||||
close(): any;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ export * from './modules/on-init.interface';
|
||||
export * from './modules/provider.interface';
|
||||
export * from './nest-application-context.interface';
|
||||
export * from './nest-application.interface';
|
||||
export * from './nest-express-application.interface';
|
||||
export * from './nest-fastify-application.interface';
|
||||
export * from './nest-microservice.interface';
|
||||
export * from './on-application-bootstrap.interface';
|
||||
export * from './request-mapping-metadata.interface';
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
import { RequestMethod } from '@nestjs/common';
|
||||
import { HttpServer, RequestHandler } from '@nestjs/common/interfaces';
|
||||
import { ServeStaticOptions } from '@nestjs/common/interfaces/external/serve-static-options.interface';
|
||||
import { isNil, isObject } from '@nestjs/common/utils/shared.utils';
|
||||
import * as express from 'express';
|
||||
import { RouterMethodFactory } from '../helpers/router-method-factory';
|
||||
|
||||
export class ExpressAdapter implements HttpServer {
|
||||
private readonly routerMethodFactory = new RouterMethodFactory();
|
||||
private httpServer: any = null;
|
||||
|
||||
constructor(private readonly instance: any) {}
|
||||
|
||||
use(...args: any[]) {
|
||||
return this.instance.use(...args);
|
||||
}
|
||||
|
||||
get(handler: RequestHandler);
|
||||
get(path: any, handler: RequestHandler);
|
||||
get(...args: any[]) {
|
||||
return this.instance.get(...args);
|
||||
}
|
||||
|
||||
post(handler: RequestHandler);
|
||||
post(path: any, handler: RequestHandler);
|
||||
post(...args: any[]) {
|
||||
return this.instance.post(...args);
|
||||
}
|
||||
|
||||
head(handler: RequestHandler);
|
||||
head(path: any, handler: RequestHandler);
|
||||
head(...args: any[]) {
|
||||
return this.instance.head(...args);
|
||||
}
|
||||
|
||||
delete(handler: RequestHandler);
|
||||
delete(path: any, handler: RequestHandler);
|
||||
delete(...args: any[]) {
|
||||
return this.instance.delete(...args);
|
||||
}
|
||||
|
||||
put(handler: RequestHandler);
|
||||
put(path: any, handler: RequestHandler);
|
||||
put(...args: any[]) {
|
||||
return this.instance.put(...args);
|
||||
}
|
||||
|
||||
patch(handler: RequestHandler);
|
||||
patch(path: any, handler: RequestHandler);
|
||||
patch(...args: any[]) {
|
||||
return this.instance.patch(...args);
|
||||
}
|
||||
|
||||
options(handler: RequestHandler);
|
||||
options(path: any, handler: RequestHandler);
|
||||
options(...args: any[]) {
|
||||
return this.instance.options(...args);
|
||||
}
|
||||
|
||||
listen(port: string | number, callback?: () => void);
|
||||
listen(port: string | number, hostname: string, callback?: () => void);
|
||||
listen(port: any, hostname?: any, callback?: any) {
|
||||
return this.instance.listen(port, hostname, callback);
|
||||
}
|
||||
|
||||
reply(response, body: any, statusCode: number) {
|
||||
const res = response.status(statusCode);
|
||||
if (isNil(body)) {
|
||||
return res.send();
|
||||
}
|
||||
return isObject(body) ? res.json(body) : res.send(String(body));
|
||||
}
|
||||
|
||||
render(response, view: string, options: any) {
|
||||
return response.render(view, options);
|
||||
}
|
||||
|
||||
setErrorHandler(handler: Function) {
|
||||
return this.use(handler);
|
||||
}
|
||||
|
||||
setNotFoundHandler(handler: Function) {
|
||||
return this.use(handler);
|
||||
}
|
||||
|
||||
setHeader(response, name: string, value: string) {
|
||||
return response.set(name, value);
|
||||
}
|
||||
|
||||
getHttpServer<T = any>(): T {
|
||||
return this.httpServer as T;
|
||||
}
|
||||
|
||||
setHttpServer(httpServer) {
|
||||
this.httpServer = httpServer;
|
||||
}
|
||||
|
||||
getInstance<T = any>(): T {
|
||||
return this.instance as T;
|
||||
}
|
||||
|
||||
close() {
|
||||
return this.instance.close();
|
||||
}
|
||||
|
||||
set(...args: any[]) {
|
||||
return this.instance.set(...args);
|
||||
}
|
||||
|
||||
enable(...args: any[]) {
|
||||
return this.instance.enable(...args);
|
||||
}
|
||||
|
||||
disable(...args: any[]) {
|
||||
return this.instance.disable(...args);
|
||||
}
|
||||
|
||||
engine(...args: any[]) {
|
||||
return this.instance.engine(...args);
|
||||
}
|
||||
|
||||
useStaticAssets(path: string, options: ServeStaticOptions) {
|
||||
if (options && options.prefix) {
|
||||
return this.use(options.prefix, express.static(path, options));
|
||||
}
|
||||
return this.use(express.static(path, options));
|
||||
}
|
||||
|
||||
setBaseViewsDir(path: string) {
|
||||
return this.set('views', path);
|
||||
}
|
||||
|
||||
setViewEngine(engine: string) {
|
||||
return this.set('view engine', engine);
|
||||
}
|
||||
|
||||
getRequestMethod(request): string {
|
||||
return request.method;
|
||||
}
|
||||
|
||||
getRequestUrl(request): string {
|
||||
return request.url;
|
||||
}
|
||||
|
||||
createMiddlewareFactory(
|
||||
requestMethod: RequestMethod,
|
||||
): (path: string, callback: Function) => any {
|
||||
return this.routerMethodFactory
|
||||
.get(this.instance, requestMethod)
|
||||
.bind(this.instance);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import * as express from 'express';
|
||||
import { ExpressAdapter } from './express-adapter';
|
||||
|
||||
export class ExpressFactory {
|
||||
public static create(): any {
|
||||
return new ExpressAdapter(express());
|
||||
}
|
||||
}
|
||||
90
packages/core/adapters/http-adapter.ts
Normal file
90
packages/core/adapters/http-adapter.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { HttpServer, RequestMethod } from '@nestjs/common';
|
||||
import { RequestHandler } from '@nestjs/common/interfaces';
|
||||
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
|
||||
|
||||
export abstract class AbstractHttpAdapter<T = any> implements HttpServer {
|
||||
protected httpServer: T;
|
||||
|
||||
constructor(protected readonly instance: any) {}
|
||||
|
||||
public use(...args: any[]) {
|
||||
return this.instance.use(...args);
|
||||
}
|
||||
|
||||
public get(handler: RequestHandler);
|
||||
public get(path: any, handler: RequestHandler);
|
||||
public get(...args: any[]) {
|
||||
return this.instance.get(...args);
|
||||
}
|
||||
|
||||
public post(handler: RequestHandler);
|
||||
public post(path: any, handler: RequestHandler);
|
||||
public post(...args: any[]) {
|
||||
return this.instance.post(...args);
|
||||
}
|
||||
|
||||
public head(handler: RequestHandler);
|
||||
public head(path: any, handler: RequestHandler);
|
||||
public head(...args: any[]) {
|
||||
return this.instance.head(...args);
|
||||
}
|
||||
|
||||
public delete(handler: RequestHandler);
|
||||
public delete(path: any, handler: RequestHandler);
|
||||
public delete(...args: any[]) {
|
||||
return this.instance.delete(...args);
|
||||
}
|
||||
|
||||
public put(handler: RequestHandler);
|
||||
public put(path: any, handler: RequestHandler);
|
||||
public put(...args: any[]) {
|
||||
return this.instance.put(...args);
|
||||
}
|
||||
|
||||
public patch(handler: RequestHandler);
|
||||
public patch(path: any, handler: RequestHandler);
|
||||
public patch(...args: any[]) {
|
||||
return this.instance.patch(...args);
|
||||
}
|
||||
|
||||
public options(handler: RequestHandler);
|
||||
public options(path: any, handler: RequestHandler);
|
||||
public options(...args: any[]) {
|
||||
return this.instance.options(...args);
|
||||
}
|
||||
|
||||
public listen(port: string | number, callback?: () => void);
|
||||
public listen(port: string | number, hostname: string, callback?: () => void);
|
||||
public listen(port: any, hostname?: any, callback?: any) {
|
||||
return this.instance.listen(port, hostname, callback);
|
||||
}
|
||||
|
||||
public getHttpServer(): T {
|
||||
return this.httpServer as T;
|
||||
}
|
||||
|
||||
public setHttpServer(httpServer: T) {
|
||||
this.httpServer = httpServer;
|
||||
}
|
||||
|
||||
public getInstance(): any {
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
abstract close();
|
||||
abstract initHttpServer(options: NestApplicationOptions);
|
||||
abstract useStaticAssets(path: string, options: any);
|
||||
abstract setBaseViewsDir(path: string);
|
||||
abstract setViewEngine(engine: string);
|
||||
abstract getRequestMethod(request);
|
||||
abstract getRequestUrl(request);
|
||||
abstract reply(response, body: any, statusCode: number);
|
||||
abstract render(response, view: string, options: any);
|
||||
abstract setErrorHandler(handler: Function);
|
||||
abstract setNotFoundHandler(handler: Function);
|
||||
abstract setHeader(response, name: string, value: string);
|
||||
abstract registerParserMiddleware();
|
||||
abstract createMiddlewareFactory(
|
||||
requestMethod: RequestMethod,
|
||||
): (path: string, callback: Function) => any;
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
export * from './fastify-adapter';
|
||||
export * from './http-adapter';
|
||||
|
||||
1
packages/core/exceptions/index.ts
Normal file
1
packages/core/exceptions/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './base-exception-filter';
|
||||
1
packages/core/helpers/index.ts
Normal file
1
packages/core/helpers/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './application-ref-host';
|
||||
@@ -8,11 +8,10 @@ import 'reflect-metadata';
|
||||
|
||||
export * from './adapters';
|
||||
export { APP_FILTER, APP_GUARD, APP_INTERCEPTOR, APP_PIPE } from './constants';
|
||||
export { BaseExceptionFilter } from './exceptions/base-exception-filter';
|
||||
export { ApplicationReferenceHost } from './helpers/application-ref-host';
|
||||
export { ModuleRef } from './injector/module-ref';
|
||||
export { HTTP_SERVER_REF } from './injector/tokens';
|
||||
export { MiddlewareBuilder } from './middleware/builder';
|
||||
export * from './exceptions';
|
||||
export * from './helpers';
|
||||
export * from './injector';
|
||||
export * from './middleware';
|
||||
export * from './nest-application';
|
||||
export * from './nest-application-context';
|
||||
export { NestFactory } from './nest-factory';
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './module-ref';
|
||||
export * from './modules-container';
|
||||
export * from './tokens';
|
||||
|
||||
1
packages/core/middleware/index.ts
Normal file
1
packages/core/middleware/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './builder';
|
||||
@@ -9,26 +9,16 @@ import {
|
||||
} from '@nestjs/common';
|
||||
import { HttpServer } from '@nestjs/common/interfaces';
|
||||
import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
|
||||
import { ServeStaticOptions } from '@nestjs/common/interfaces/external/serve-static-options.interface';
|
||||
import { MicroserviceOptions } from '@nestjs/common/interfaces/microservices/microservice-configuration.interface';
|
||||
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
|
||||
import { INestExpressApplication } from '@nestjs/common/interfaces/nest-express-application.interface';
|
||||
import { INestFastifyApplication } from '@nestjs/common/interfaces/nest-fastify-application.interface';
|
||||
import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { loadPackage } from '@nestjs/common/utils/load-package.util';
|
||||
import {
|
||||
isFunction,
|
||||
isObject,
|
||||
validatePath,
|
||||
} from '@nestjs/common/utils/shared.utils';
|
||||
import * as bodyParser from 'body-parser';
|
||||
import { isObject, validatePath } from '@nestjs/common/utils/shared.utils';
|
||||
import * as cors from 'cors';
|
||||
import * as http from 'http';
|
||||
import * as https from 'https';
|
||||
import { Server } from 'http';
|
||||
import { Server as HttpsServer } from 'https';
|
||||
import iterate from 'iterare';
|
||||
import * as optional from 'optional';
|
||||
import { ExpressAdapter } from './adapters/express-adapter';
|
||||
import { FastifyAdapter } from './adapters/fastify-adapter';
|
||||
import { ApplicationConfig } from './application-config';
|
||||
import { MESSAGES } from './constants';
|
||||
import { NestContainer } from './injector/container';
|
||||
@@ -46,9 +36,7 @@ const { IoAdapter } =
|
||||
optional('@nestjs/websockets/adapters/io-adapter') || ({} as any);
|
||||
|
||||
export class NestApplication extends NestApplicationContext
|
||||
implements INestApplication,
|
||||
INestExpressApplication,
|
||||
INestFastifyApplication {
|
||||
implements INestApplication {
|
||||
private readonly logger = new Logger(NestApplication.name, true);
|
||||
private readonly middlewareModule = new MiddlewareModule();
|
||||
private readonly middlewareContainer = new MiddlewareContainer();
|
||||
@@ -58,7 +46,7 @@ export class NestApplication extends NestApplicationContext
|
||||
private readonly socketModule = SocketModule ? new SocketModule() : null;
|
||||
private readonly routesResolver: Resolver;
|
||||
private readonly microservices: any[] = [];
|
||||
private httpServer: http.Server;
|
||||
private httpServer: Server | HttpsServer;
|
||||
private isInitialized = false;
|
||||
|
||||
constructor(
|
||||
@@ -83,11 +71,14 @@ export class NestApplication extends NestApplicationContext
|
||||
public registerHttpServer() {
|
||||
this.httpServer = this.createServer();
|
||||
|
||||
const server = this.getUnderlyingHttpServer();
|
||||
const ioAdapter = IoAdapter ? new IoAdapter(server) : null;
|
||||
const ioAdapter = IoAdapter ? new IoAdapter(this.httpServer) : null;
|
||||
this.config.setIoAdapter(ioAdapter);
|
||||
}
|
||||
|
||||
public getUnderlyingHttpServer<T>(): T {
|
||||
return this.httpAdapter.getHttpServer();
|
||||
}
|
||||
|
||||
public applyOptions() {
|
||||
if (!this.appOptions || !this.appOptions.cors) {
|
||||
return undefined;
|
||||
@@ -100,29 +91,8 @@ export class NestApplication extends NestApplicationContext
|
||||
}
|
||||
|
||||
public createServer(): any {
|
||||
const isHttpsEnabled = this.appOptions && this.appOptions.httpsOptions;
|
||||
const isExpress = this.isExpress();
|
||||
|
||||
if (isHttpsEnabled && isExpress) {
|
||||
const server = https.createServer(
|
||||
this.appOptions.httpsOptions,
|
||||
this.httpAdapter.getInstance(),
|
||||
);
|
||||
(this.httpAdapter as ExpressAdapter).setHttpServer(server);
|
||||
return server;
|
||||
}
|
||||
if (isExpress) {
|
||||
const server = http.createServer(this.httpAdapter.getInstance());
|
||||
(this.httpAdapter as ExpressAdapter).setHttpServer(server);
|
||||
return server;
|
||||
}
|
||||
return this.httpAdapter;
|
||||
}
|
||||
|
||||
public getUnderlyingHttpServer(): any {
|
||||
return this.isExpress()
|
||||
? this.httpServer
|
||||
: this.httpAdapter.getHttpServer();
|
||||
this.httpAdapter.initHttpServer(this.appOptions);
|
||||
return this.httpAdapter.getHttpServer();
|
||||
}
|
||||
|
||||
public async registerModules() {
|
||||
@@ -157,37 +127,12 @@ export class NestApplication extends NestApplicationContext
|
||||
}
|
||||
|
||||
public registerParserMiddleware() {
|
||||
if (this.httpAdapter instanceof FastifyAdapter) {
|
||||
return this.httpAdapter.register(
|
||||
this.loadPackage('fastify-formbody', 'FastifyAdapter'),
|
||||
);
|
||||
}
|
||||
if (!this.isExpress()) {
|
||||
return undefined;
|
||||
}
|
||||
const parserMiddleware = {
|
||||
jsonParser: bodyParser.json(),
|
||||
urlencodedParser: bodyParser.urlencoded({ extended: true }),
|
||||
};
|
||||
Object.keys(parserMiddleware)
|
||||
.filter(parser => !this.isMiddlewareApplied(this.httpAdapter, parser))
|
||||
.forEach(parserKey => this.httpAdapter.use(parserMiddleware[parserKey]));
|
||||
}
|
||||
|
||||
public isMiddlewareApplied(httpAdapter: HttpServer, name: string): boolean {
|
||||
const app = httpAdapter.getInstance();
|
||||
return (
|
||||
!!app._router &&
|
||||
!!app._router.stack &&
|
||||
isFunction(app._router.stack.filter) &&
|
||||
app._router.stack.some(
|
||||
(layer: any) => layer && layer.handle && layer.handle.name === name,
|
||||
)
|
||||
);
|
||||
this.httpAdapter.registerParserMiddleware();
|
||||
}
|
||||
|
||||
public async registerRouter() {
|
||||
await this.registerMiddleware(this.httpAdapter);
|
||||
|
||||
const prefix = this.config.getGlobalPrefix();
|
||||
const basePath = prefix ? validatePath(prefix) : '';
|
||||
this.routesResolver.resolve(this.httpAdapter, basePath);
|
||||
@@ -199,7 +144,7 @@ export class NestApplication extends NestApplicationContext
|
||||
}
|
||||
|
||||
public connectMicroservice(options: MicroserviceOptions): INestMicroservice {
|
||||
const { NestMicroservice } = loadPackage(
|
||||
const { NestMicroservice } = this.loadPackage(
|
||||
'@nestjs/microservices',
|
||||
'NestFactory',
|
||||
);
|
||||
@@ -237,54 +182,11 @@ export class NestApplication extends NestApplicationContext
|
||||
return new Promise(resolve => this.startAllMicroservices(resolve));
|
||||
}
|
||||
|
||||
public use(...args: any[]): this {
|
||||
(this.httpAdapter as any).use(...args);
|
||||
public use(...args: [any, any?]): this {
|
||||
this.httpAdapter.use(...args);
|
||||
return this;
|
||||
}
|
||||
|
||||
public engine(...args: any[]): this {
|
||||
if (!this.isExpress()) {
|
||||
return this;
|
||||
}
|
||||
(this.httpAdapter as ExpressAdapter).engine(...args);
|
||||
return this;
|
||||
}
|
||||
|
||||
public set(...args: any[]): this {
|
||||
if (!this.isExpress()) {
|
||||
return this;
|
||||
}
|
||||
(this.httpAdapter as ExpressAdapter).set(...args);
|
||||
return this;
|
||||
}
|
||||
|
||||
public disable(...args: any[]): this {
|
||||
if (!this.isExpress()) {
|
||||
return this;
|
||||
}
|
||||
(this.httpAdapter as ExpressAdapter).disable(...args);
|
||||
return this;
|
||||
}
|
||||
|
||||
public enable(...args: any[]): this {
|
||||
if (!this.isExpress()) {
|
||||
return this;
|
||||
}
|
||||
(this.httpAdapter as ExpressAdapter).enable(...args);
|
||||
return this;
|
||||
}
|
||||
|
||||
public register(...args: any[]): this {
|
||||
const adapter = this.httpAdapter as FastifyAdapter;
|
||||
adapter.register && adapter.register(...args);
|
||||
return this;
|
||||
}
|
||||
|
||||
public inject(...args: any[]) {
|
||||
const adapter = this.httpAdapter as FastifyAdapter;
|
||||
return adapter.inject && adapter.inject(...args);
|
||||
}
|
||||
|
||||
public enableCors(options?: CorsOptions): this {
|
||||
this.httpAdapter.use(cors(options) as any);
|
||||
return this;
|
||||
@@ -356,11 +258,8 @@ export class NestApplication extends NestApplicationContext
|
||||
}
|
||||
|
||||
public useStaticAssets(options: any): this;
|
||||
public useStaticAssets(path: string, options?: ServeStaticOptions): this;
|
||||
public useStaticAssets(
|
||||
pathOrOptions: any,
|
||||
options?: ServeStaticOptions,
|
||||
): this {
|
||||
public useStaticAssets(path: string, options?: any): this;
|
||||
public useStaticAssets(pathOrOptions: any, options?: any): this {
|
||||
this.httpAdapter.useStaticAssets &&
|
||||
this.httpAdapter.useStaticAssets(pathOrOptions, options);
|
||||
return this;
|
||||
@@ -388,14 +287,6 @@ 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);
|
||||
|
||||
@@ -8,14 +8,9 @@ import { MicroserviceOptions } from '@nestjs/common/interfaces/microservices/mic
|
||||
import { NestMicroserviceOptions } from '@nestjs/common/interfaces/microservices/nest-microservice-options.interface';
|
||||
import { NestApplicationContextOptions } from '@nestjs/common/interfaces/nest-application-context-options.interface';
|
||||
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
|
||||
import { INestExpressApplication } from '@nestjs/common/interfaces/nest-express-application.interface';
|
||||
import { INestFastifyApplication } from '@nestjs/common/interfaces/nest-fastify-application.interface';
|
||||
import { Logger } from '@nestjs/common/services/logger.service';
|
||||
import { loadPackage } from '@nestjs/common/utils/load-package.util';
|
||||
import { isFunction, isNil } from '@nestjs/common/utils/shared.utils';
|
||||
import { ExpressAdapter } from './adapters/express-adapter';
|
||||
import { ExpressFactory } from './adapters/express-factory';
|
||||
import { FastifyAdapter } from './adapters/fastify-adapter';
|
||||
import { ApplicationConfig } from './application-config';
|
||||
import { MESSAGES } from './constants';
|
||||
import { ExceptionsZone } from './errors/exceptions-zone';
|
||||
@@ -32,42 +27,39 @@ export class NestFactoryStatic {
|
||||
* Creates an instance of the NestApplication
|
||||
* @returns {Promise}
|
||||
*/
|
||||
public async create(
|
||||
public async create<T extends INestApplication = INestApplication>(
|
||||
module: any,
|
||||
options?: NestApplicationOptions,
|
||||
): Promise<INestApplication & INestExpressApplication>;
|
||||
public async create(
|
||||
): Promise<T>;
|
||||
public async create<T extends INestApplication = INestApplication>(
|
||||
module: any,
|
||||
httpServer: FastifyAdapter,
|
||||
httpServer: HttpServer,
|
||||
options?: NestApplicationOptions,
|
||||
): Promise<INestApplication & INestFastifyApplication>;
|
||||
public async create(
|
||||
): Promise<T>;
|
||||
public async create<T extends INestApplication = INestApplication>(
|
||||
module: any,
|
||||
httpServer: HttpServer | any,
|
||||
serverOrOptions?: HttpServer | NestApplicationOptions,
|
||||
options?: NestApplicationOptions,
|
||||
): Promise<INestApplication & INestExpressApplication>;
|
||||
public async create(
|
||||
module: any,
|
||||
serverOrOptions?: any,
|
||||
options?: NestApplicationOptions,
|
||||
): Promise<
|
||||
INestApplication & (INestExpressApplication | INestFastifyApplication)
|
||||
> {
|
||||
const isHttpServer = serverOrOptions && serverOrOptions.patch;
|
||||
): Promise<T> {
|
||||
// tslint:disable-next-line:prefer-const
|
||||
let [httpServer, appOptions] = isHttpServer
|
||||
let [httpServer, appOptions] = this.isHttpServer(serverOrOptions)
|
||||
? [serverOrOptions, options]
|
||||
: [ExpressFactory.create(), serverOrOptions];
|
||||
: [this.createHttpAdapter(), serverOrOptions];
|
||||
|
||||
const applicationConfig = new ApplicationConfig();
|
||||
const container = new NestContainer(applicationConfig);
|
||||
httpServer = this.applyExpressAdapter(httpServer);
|
||||
|
||||
this.applyLogger(appOptions);
|
||||
await this.initialize(module, container, applicationConfig, httpServer);
|
||||
return this.createNestInstance<NestApplication>(
|
||||
new NestApplication(container, httpServer, applicationConfig, appOptions),
|
||||
|
||||
const instance = new NestApplication(
|
||||
container,
|
||||
httpServer,
|
||||
applicationConfig,
|
||||
appOptions,
|
||||
);
|
||||
const target = this.createAdapterProxy<T>(instance, httpServer);
|
||||
return this.createNestInstance<T>(target);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,8 +151,9 @@ export class NestFactoryStatic {
|
||||
|
||||
private createExceptionProxy() {
|
||||
return (receiver: Record<string, any>, prop: string) => {
|
||||
if (!(prop in receiver)) return;
|
||||
|
||||
if (!(prop in receiver)) {
|
||||
return;
|
||||
}
|
||||
if (isFunction(receiver[prop])) {
|
||||
return (...args: any[]) => {
|
||||
let result;
|
||||
@@ -181,12 +174,29 @@ export class NestFactoryStatic {
|
||||
!isNil(options.logger) && Logger.overrideLogger(options.logger);
|
||||
}
|
||||
|
||||
private applyExpressAdapter(httpAdapter: HttpServer): HttpServer {
|
||||
const isAdapter = httpAdapter.getHttpServer;
|
||||
if (isAdapter) {
|
||||
return httpAdapter;
|
||||
}
|
||||
return new ExpressAdapter(httpAdapter);
|
||||
private createHttpAdapter<T = any>(httpServer?: T): HttpServer {
|
||||
const { ExpressAdapter } = loadPackage(
|
||||
'@nestjs/platform-express',
|
||||
'NestFactory',
|
||||
);
|
||||
return new ExpressAdapter(httpServer);
|
||||
}
|
||||
|
||||
private isHttpServer(
|
||||
serverOrOptions: HttpServer | NestApplicationOptions,
|
||||
): serverOrOptions is HttpServer {
|
||||
return !!(serverOrOptions && (serverOrOptions as HttpServer).patch);
|
||||
}
|
||||
|
||||
private createAdapterProxy<T>(app: NestApplication, adapter: HttpServer): T {
|
||||
return (new Proxy(app, {
|
||||
get: (receiver: Record<string, any>, prop: string) => {
|
||||
if (!(prop in receiver) && prop in adapter) {
|
||||
return adapter[prop];
|
||||
}
|
||||
return receiver[prop];
|
||||
},
|
||||
}) as any) as T;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxtjs/opencollective": "0.1.0",
|
||||
"body-parser": "1.18.3",
|
||||
"cors": "2.8.4",
|
||||
"express": "4.16.3",
|
||||
"fast-safe-stringify": "1.2.0",
|
||||
"iterare": "0.0.8",
|
||||
"object-hash": "1.3.0",
|
||||
|
||||
76
packages/platform-express/Readme.md
Normal file
76
packages/platform-express/Readme.md
Normal file
@@ -0,0 +1,76 @@
|
||||
<p align="center">
|
||||
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo_text.svg" width="320" alt="Nest Logo" /></a>
|
||||
</p>
|
||||
|
||||
[travis-image]: https://api.travis-ci.org/nestjs/nest.svg?branch=master
|
||||
[travis-url]: https://travis-ci.org/nestjs/nest
|
||||
[linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux
|
||||
[linux-url]: https://travis-ci.org/nestjs/nest
|
||||
|
||||
<p align="center">A progressive <a href="http://nodejs.org" target="blank">Node.js</a> framework for building efficient and scalable server-side applications, heavily inspired by <a href="https://angular.io" target="blank">Angular</a>.</p>
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
|
||||
<a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
|
||||
<a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/dm/@nestjs/core.svg" alt="NPM Downloads" /></a>
|
||||
<a href="https://travis-ci.org/nestjs/nest"><img src="https://api.travis-ci.org/nestjs/nest.svg?branch=master" alt="Travis" /></a>
|
||||
<a href="https://travis-ci.org/nestjs/nest"><img src="https://img.shields.io/travis/nestjs/nest/master.svg?label=linux" alt="Linux" /></a>
|
||||
<a href="https://coveralls.io/github/nestjs/nest?branch=master"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#8" alt="Coverage" /></a>
|
||||
<a href="https://gitter.im/nestjs/nestjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge"><img src="https://badges.gitter.im/nestjs/nestjs.svg" alt="Gitter" /></a>
|
||||
<a href="https://opencollective.com/nest#backer"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
|
||||
<a href="https://opencollective.com/nest#sponsor"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
|
||||
<a href="https://paypal.me/kamilmysliwiec"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
|
||||
<a href="https://twitter.com/nestframework"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
|
||||
</p>
|
||||
<!--[](https://opencollective.com/nest#backer)
|
||||
[](https://opencollective.com/nest#sponsor)-->
|
||||
|
||||
## Description
|
||||
|
||||
<p>Nest is a framework for building efficient, scalable <a href="http://nodejs.org" target="_blank">Node.js</a> server-side applications. It uses modern JavaScript, is built with <a href="http://www.typescriptlang.org" target="_blank">TypeScript</a> (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).</p>
|
||||
|
||||
<p>Under the hood, Nest makes use of <a href="https://expressjs.com/" target="_blank">Express</a>, but also, provides compatibility with a wide range of other libraries, like e.g. <a href="https://github.com/fastify/fastify" target="blank">Fastify</a>, allowing for easy use of the myriad third-party plugins which are available.</p>
|
||||
|
||||
## Philosophy
|
||||
|
||||
<p>In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front and backend 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, 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, loosely coupled and easily maintainable applications.</p>
|
||||
|
||||
## Getting started
|
||||
|
||||
* To check out the [guide](https://docs.nestjs.com), visit [docs.nestjs.com](https://docs.nestjs.com). :books:
|
||||
* 要查看中文 [指南](readme_zh.md), 请访问 [docs.nestjs.cn](https://docs.nestjs.cn). :books:
|
||||
|
||||
## Support
|
||||
|
||||
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
|
||||
|
||||
#### Principal Sponsor
|
||||
|
||||
<a href="https://valor-software.com/"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="320" /></a>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<a href="http://xtremis.com/"><img src="https://nestjs.com/img/logo-xtremis.svg" width="220" /></a>
|
||||
|
||||
#### Silver Sponsors
|
||||
<a href="https://neoteric.eu/"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" /></a>
|
||||
<a href="http://gojob.com"><img src="http://nestjs.com/img/gojob-logo.png" valign="bottom" height="95" /></a> <a href="https://www.swingdev.io"><img src="https://nestjs.com/img/swingdev-logo.svg#1" width="150" /> </a>
|
||||
|
||||
#### Sponsors
|
||||
|
||||
<a href="https://scal.io"><img src="https://nestjs.com/img/scalio-logo.svg" width="110" /></a> <a href="http://angularity.io"><img src="http://angularity.io/media/logo.svg" height="30" /></a> <!--<a href="https://keycdn.com"><img src="https://nestjs.com/img/keycdn.svg" height="30" /></a> --> <a href="https://hostpresto.com"><img src="https://nestjs.com/img/hostpresto.png" height="30" /></a> <a href="https://genuinebee.com/"><img src="https://nestjs.com/img/genuinebee.svg" height="38" /></a> <a href="http://architectnow.net/"><img src="https://nestjs.com/img/architectnow.png" height="24" /></a> <a href="https://quander.io/"><img src="https://nestjs.com/img/quander.png" height="28" /></a>
|
||||
|
||||
|
||||
## Backers
|
||||
|
||||
<a href="https://opencollective.com/nest"><img src="https://opencollective.com/nest/backers.svg?width=890"></a>
|
||||
|
||||
## Stay in touch
|
||||
|
||||
* Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
|
||||
* Website - [https://nestjs.com](https://nestjs.com/)
|
||||
* Twitter - [@nestframework](https://twitter.com/nestframework)
|
||||
|
||||
## License
|
||||
|
||||
Nest is [MIT licensed](LICENSE).
|
||||
123
packages/platform-express/adapters/express-adapter.ts
Normal file
123
packages/platform-express/adapters/express-adapter.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import { RequestMethod } from '@nestjs/common';
|
||||
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
|
||||
import { isFunction, isNil, isObject } from '@nestjs/common/utils/shared.utils';
|
||||
import { AbstractHttpAdapter } from '@nestjs/core/adapters/http-adapter';
|
||||
import { RouterMethodFactory } from '@nestjs/core/helpers/router-method-factory';
|
||||
import * as bodyParser from 'body-parser';
|
||||
import * as express from 'express';
|
||||
import * as http from 'http';
|
||||
import * as https from 'https';
|
||||
import { ServeStaticOptions } from './../interfaces/serve-static-options.interface';
|
||||
|
||||
export class ExpressAdapter extends AbstractHttpAdapter {
|
||||
private readonly routerMethodFactory = new RouterMethodFactory();
|
||||
|
||||
public reply(response, body: any, statusCode: number) {
|
||||
const res = response.status(statusCode);
|
||||
if (isNil(body)) {
|
||||
return res.send();
|
||||
}
|
||||
return isObject(body) ? res.json(body) : res.send(String(body));
|
||||
}
|
||||
|
||||
public render(response, view: string, options: any) {
|
||||
return response.render(view, options);
|
||||
}
|
||||
|
||||
public setErrorHandler(handler: Function) {
|
||||
return this.use(handler);
|
||||
}
|
||||
|
||||
public setNotFoundHandler(handler: Function) {
|
||||
return this.use(handler);
|
||||
}
|
||||
|
||||
public setHeader(response, name: string, value: string) {
|
||||
return response.set(name, value);
|
||||
}
|
||||
|
||||
public close() {
|
||||
return this.instance.close();
|
||||
}
|
||||
|
||||
public set(...args: any[]) {
|
||||
return this.instance.set(...args);
|
||||
}
|
||||
|
||||
public enable(...args: any[]) {
|
||||
return this.instance.enable(...args);
|
||||
}
|
||||
|
||||
public disable(...args: any[]) {
|
||||
return this.instance.disable(...args);
|
||||
}
|
||||
|
||||
public engine(...args: any[]) {
|
||||
return this.instance.engine(...args);
|
||||
}
|
||||
|
||||
public useStaticAssets(path: string, options: ServeStaticOptions) {
|
||||
if (options && options.prefix) {
|
||||
return this.use(options.prefix, express.static(path, options));
|
||||
}
|
||||
return this.use(express.static(path, options));
|
||||
}
|
||||
|
||||
public setBaseViewsDir(path: string) {
|
||||
return this.set('views', path);
|
||||
}
|
||||
|
||||
public setViewEngine(engine: string) {
|
||||
return this.set('view engine', engine);
|
||||
}
|
||||
|
||||
public getRequestMethod(request): string {
|
||||
return request.method;
|
||||
}
|
||||
|
||||
public getRequestUrl(request): string {
|
||||
return request.url;
|
||||
}
|
||||
|
||||
public createMiddlewareFactory(
|
||||
requestMethod: RequestMethod,
|
||||
): (path: string, callback: Function) => any {
|
||||
return this.routerMethodFactory
|
||||
.get(this.instance, requestMethod)
|
||||
.bind(this.instance);
|
||||
}
|
||||
|
||||
public initHttpServer(options: NestApplicationOptions) {
|
||||
const isHttpsEnabled = options && options.httpsOptions;
|
||||
if (isHttpsEnabled) {
|
||||
this.httpServer = https.createServer(
|
||||
options.httpsOptions,
|
||||
this.getInstance(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.httpServer = http.createServer(this.getInstance());
|
||||
}
|
||||
|
||||
public registerParserMiddleware() {
|
||||
const parserMiddleware = {
|
||||
jsonParser: bodyParser.json(),
|
||||
urlencodedParser: bodyParser.urlencoded({ extended: true }),
|
||||
};
|
||||
Object.keys(parserMiddleware)
|
||||
.filter(parser => !this.isMiddlewareApplied(parser))
|
||||
.forEach(parserKey => this.use(parserMiddleware[parserKey]));
|
||||
}
|
||||
|
||||
private isMiddlewareApplied(name: string); : boolean; {
|
||||
const app = this.getInstance();
|
||||
return (
|
||||
!!app._router &&
|
||||
!!app._router.stack &&
|
||||
isFunction(app._router.stack.filter) &&
|
||||
app._router.stack.some(
|
||||
(layer: any) => layer && layer.handle && layer.handle.name === name,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
1
packages/platform-express/adapters/index.ts
Normal file
1
packages/platform-express/adapters/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './express-adapter';
|
||||
9
packages/platform-express/index.ts
Normal file
9
packages/platform-express/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Nest @platform-express
|
||||
* Copyright(c) 2017 - 2018 Kamil Mysliwiec
|
||||
* https://nestjs.com
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
export * from './adapters';
|
||||
export * from './interfaces';
|
||||
0
packages/platform-express/interceptors/index.ts
Normal file
0
packages/platform-express/interceptors/index.ts
Normal file
1
packages/platform-express/interfaces/index.ts
Normal file
1
packages/platform-express/interfaces/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './nest-express-application.interface';
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ServeStaticOptions } from './external/serve-static-options.interface';
|
||||
import { ServeStaticOptions } from './serve-static-options.interface';
|
||||
|
||||
export interface INestExpressApplication {
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ export interface INestExpressApplication {
|
||||
*
|
||||
* @returns {this}
|
||||
*/
|
||||
useStaticAssets(options: any): this;
|
||||
useStaticAssets(options: ServeStaticOptions): this;
|
||||
useStaticAssets(path: string, options?: ServeStaticOptions): this;
|
||||
|
||||
/**
|
||||
18
packages/platform-express/package.json
Normal file
18
packages/platform-express/package.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "@nestjs/platform-express",
|
||||
"version": "5.4.1",
|
||||
"description":
|
||||
"Nest - modern, fast, powerful node.js web framework (@platform-express)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nestjs/nest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/express": "^4.0.39",
|
||||
"body-parser": "1.18.3",
|
||||
"express": "4.16.3"
|
||||
},
|
||||
"peerDependencies": {}
|
||||
}
|
||||
7
packages/platform-express/tsconfig.json
Normal file
7
packages/platform-express/tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./"
|
||||
},
|
||||
"include": ["*.ts", "**/*.ts"]
|
||||
}
|
||||
76
packages/platform-fastify/Readme.md
Normal file
76
packages/platform-fastify/Readme.md
Normal file
@@ -0,0 +1,76 @@
|
||||
<p align="center">
|
||||
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo_text.svg" width="320" alt="Nest Logo" /></a>
|
||||
</p>
|
||||
|
||||
[travis-image]: https://api.travis-ci.org/nestjs/nest.svg?branch=master
|
||||
[travis-url]: https://travis-ci.org/nestjs/nest
|
||||
[linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux
|
||||
[linux-url]: https://travis-ci.org/nestjs/nest
|
||||
|
||||
<p align="center">A progressive <a href="http://nodejs.org" target="blank">Node.js</a> framework for building efficient and scalable server-side applications, heavily inspired by <a href="https://angular.io" target="blank">Angular</a>.</p>
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
|
||||
<a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
|
||||
<a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/dm/@nestjs/core.svg" alt="NPM Downloads" /></a>
|
||||
<a href="https://travis-ci.org/nestjs/nest"><img src="https://api.travis-ci.org/nestjs/nest.svg?branch=master" alt="Travis" /></a>
|
||||
<a href="https://travis-ci.org/nestjs/nest"><img src="https://img.shields.io/travis/nestjs/nest/master.svg?label=linux" alt="Linux" /></a>
|
||||
<a href="https://coveralls.io/github/nestjs/nest?branch=master"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#8" alt="Coverage" /></a>
|
||||
<a href="https://gitter.im/nestjs/nestjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge"><img src="https://badges.gitter.im/nestjs/nestjs.svg" alt="Gitter" /></a>
|
||||
<a href="https://opencollective.com/nest#backer"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
|
||||
<a href="https://opencollective.com/nest#sponsor"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
|
||||
<a href="https://paypal.me/kamilmysliwiec"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
|
||||
<a href="https://twitter.com/nestframework"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
|
||||
</p>
|
||||
<!--[](https://opencollective.com/nest#backer)
|
||||
[](https://opencollective.com/nest#sponsor)-->
|
||||
|
||||
## Description
|
||||
|
||||
<p>Nest is a framework for building efficient, scalable <a href="http://nodejs.org" target="_blank">Node.js</a> server-side applications. It uses modern JavaScript, is built with <a href="http://www.typescriptlang.org" target="_blank">TypeScript</a> (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).</p>
|
||||
|
||||
<p>Under the hood, Nest makes use of <a href="https://expressjs.com/" target="_blank">Express</a>, but also, provides compatibility with a wide range of other libraries, like e.g. <a href="https://github.com/fastify/fastify" target="blank">Fastify</a>, allowing for easy use of the myriad third-party plugins which are available.</p>
|
||||
|
||||
## Philosophy
|
||||
|
||||
<p>In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front and backend 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, 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, loosely coupled and easily maintainable applications.</p>
|
||||
|
||||
## Getting started
|
||||
|
||||
* To check out the [guide](https://docs.nestjs.com), visit [docs.nestjs.com](https://docs.nestjs.com). :books:
|
||||
* 要查看中文 [指南](readme_zh.md), 请访问 [docs.nestjs.cn](https://docs.nestjs.cn). :books:
|
||||
|
||||
## Support
|
||||
|
||||
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
|
||||
|
||||
#### Principal Sponsor
|
||||
|
||||
<a href="https://valor-software.com/"><img src="https://docs.nestjs.com/assets/sponsors/valor-software.png" width="320" /></a>
|
||||
|
||||
#### Gold Sponsors
|
||||
|
||||
<a href="http://xtremis.com/"><img src="https://nestjs.com/img/logo-xtremis.svg" width="220" /></a>
|
||||
|
||||
#### Silver Sponsors
|
||||
<a href="https://neoteric.eu/"><img src="https://nestjs.com/img/neoteric-cut.png" width="120" /></a>
|
||||
<a href="http://gojob.com"><img src="http://nestjs.com/img/gojob-logo.png" valign="bottom" height="95" /></a> <a href="https://www.swingdev.io"><img src="https://nestjs.com/img/swingdev-logo.svg#1" width="150" /> </a>
|
||||
|
||||
#### Sponsors
|
||||
|
||||
<a href="https://scal.io"><img src="https://nestjs.com/img/scalio-logo.svg" width="110" /></a> <a href="http://angularity.io"><img src="http://angularity.io/media/logo.svg" height="30" /></a> <!--<a href="https://keycdn.com"><img src="https://nestjs.com/img/keycdn.svg" height="30" /></a> --> <a href="https://hostpresto.com"><img src="https://nestjs.com/img/hostpresto.png" height="30" /></a> <a href="https://genuinebee.com/"><img src="https://nestjs.com/img/genuinebee.svg" height="38" /></a> <a href="http://architectnow.net/"><img src="https://nestjs.com/img/architectnow.png" height="24" /></a> <a href="https://quander.io/"><img src="https://nestjs.com/img/quander.png" height="28" /></a>
|
||||
|
||||
|
||||
## Backers
|
||||
|
||||
<a href="https://opencollective.com/nest"><img src="https://opencollective.com/nest/backers.svg?width=890"></a>
|
||||
|
||||
## Stay in touch
|
||||
|
||||
* Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
|
||||
* Website - [https://nestjs.com](https://nestjs.com/)
|
||||
* Twitter - [@nestframework](https://twitter.com/nestframework)
|
||||
|
||||
## License
|
||||
|
||||
Nest is [MIT licensed](LICENSE).
|
||||
@@ -1,13 +1,16 @@
|
||||
import { RequestMethod } from '@nestjs/common';
|
||||
import { ErrorHandler, RequestHandler } from '@nestjs/common/interfaces';
|
||||
import { loadPackage } from '@nestjs/common/utils/load-package.util';
|
||||
import { AbstractHttpAdapter } from '@nestjs/core/adapters/http-adapter';
|
||||
import * as pathToRegexp from 'path-to-regexp';
|
||||
|
||||
export class FastifyAdapter {
|
||||
protected readonly instance: any;
|
||||
|
||||
export class FastifyAdapter extends AbstractHttpAdapter {
|
||||
setBaseViewsDir(path: string) {}
|
||||
registerParserMiddleware() {
|
||||
this.register(loadPackage('fastify-formbody', 'FastifyAdapter'));
|
||||
}
|
||||
constructor(options?: any) {
|
||||
this.instance = loadPackage('fastify', 'FastifyAdapter')(options);
|
||||
super(loadPackage('fastify', 'FastifyAdapter')(options));
|
||||
}
|
||||
|
||||
use(handler: RequestHandler | ErrorHandler);
|
||||
1
packages/platform-fastify/adapters/index.ts
Normal file
1
packages/platform-fastify/adapters/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './fastify-adapter';
|
||||
9
packages/platform-fastify/index.ts
Normal file
9
packages/platform-fastify/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Nest @platform-express
|
||||
* Copyright(c) 2017 - 2018 Kamil Mysliwiec
|
||||
* https://nestjs.com
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
export * from './adapters';
|
||||
export * from './interfaces';
|
||||
0
packages/platform-fastify/interceptors/index.ts
Normal file
0
packages/platform-fastify/interceptors/index.ts
Normal file
1
packages/platform-fastify/interfaces/index.ts
Normal file
1
packages/platform-fastify/interfaces/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './nest-express-application.interface';
|
||||
18
packages/platform-fastify/package.json
Normal file
18
packages/platform-fastify/package.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "@nestjs/platform-fastify",
|
||||
"version": "5.4.1",
|
||||
"description":
|
||||
"Nest - modern, fast, powerful node.js web framework (@platform-fastify)",
|
||||
"author": "Kamil Mysliwiec",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nestjs/nest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/express": "^4.0.39",
|
||||
"body-parser": "1.18.3",
|
||||
"express": "4.16.3"
|
||||
},
|
||||
"peerDependencies": {}
|
||||
}
|
||||
7
packages/platform-fastify/tsconfig.json
Normal file
7
packages/platform-fastify/tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./"
|
||||
},
|
||||
"include": ["*.ts", "**/*.ts"]
|
||||
}
|
||||
@@ -8,14 +8,9 @@ import { MicroserviceOptions } from '@nestjs/common/interfaces/microservices/mic
|
||||
import { NestMicroserviceOptions } from '@nestjs/common/interfaces/microservices/nest-microservice-options.interface';
|
||||
import { NestApplicationContextOptions } from '@nestjs/common/interfaces/nest-application-context-options.interface';
|
||||
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
|
||||
import { INestExpressApplication } from '@nestjs/common/interfaces/nest-express-application.interface';
|
||||
import { INestFastifyApplication } from '@nestjs/common/interfaces/nest-fastify-application.interface';
|
||||
import { Type } from '@nestjs/common/interfaces/type.interface';
|
||||
import { loadPackage } from '@nestjs/common/utils/load-package.util';
|
||||
import { NestApplication, NestApplicationContext } from '@nestjs/core';
|
||||
import { ExpressAdapter } from '@nestjs/core/adapters/express-adapter';
|
||||
import { ExpressFactory } from '@nestjs/core/adapters/express-factory';
|
||||
import { FastifyAdapter } from '@nestjs/core/adapters/fastify-adapter';
|
||||
import { ApplicationConfig } from '@nestjs/core/application-config';
|
||||
import { NestContainer } from '@nestjs/core/injector/container';
|
||||
import { Module } from '@nestjs/core/injector/module';
|
||||
@@ -30,33 +25,22 @@ export class TestingModule extends NestApplicationContext {
|
||||
super(container, scope, contextModule);
|
||||
}
|
||||
|
||||
public createNestApplication(
|
||||
httpServer?: HttpServer,
|
||||
public createNestApplication<T extends INestApplication = INestApplication>(
|
||||
httpAdapter?: HttpServer,
|
||||
options?: NestApplicationOptions,
|
||||
): INestApplication & INestExpressApplication;
|
||||
public createNestApplication(
|
||||
httpServer?: FastifyAdapter,
|
||||
options?: NestApplicationOptions,
|
||||
): INestApplication & INestFastifyApplication;
|
||||
public createNestApplication(
|
||||
httpServer?: any,
|
||||
options?: NestApplicationOptions,
|
||||
): INestApplication & INestExpressApplication;
|
||||
public createNestApplication(
|
||||
httpServer: any = ExpressFactory.create(),
|
||||
options?: NestApplicationOptions,
|
||||
): INestApplication & (INestExpressApplication | INestFastifyApplication) {
|
||||
httpServer = this.applyExpressAdapter(httpServer);
|
||||
): T {
|
||||
httpAdapter = httpAdapter || this.createHttpAdapter();
|
||||
|
||||
this.applyLogger(options);
|
||||
this.container.setApplicationRef(httpServer);
|
||||
this.container.setApplicationRef(httpAdapter);
|
||||
|
||||
return new NestApplication(
|
||||
const instance = new NestApplication(
|
||||
this.container,
|
||||
httpServer,
|
||||
httpAdapter,
|
||||
this.applicationConfig,
|
||||
options,
|
||||
);
|
||||
return this.createAdapterProxy<T>(instance, httpAdapter);
|
||||
}
|
||||
|
||||
public createNestMicroservice(
|
||||
@@ -74,20 +58,29 @@ export class TestingModule extends NestApplicationContext {
|
||||
);
|
||||
}
|
||||
|
||||
private applyExpressAdapter(httpAdapter: HttpServer): HttpServer {
|
||||
const isAdapter = httpAdapter.getHttpServer;
|
||||
if (isAdapter) {
|
||||
return httpAdapter;
|
||||
}
|
||||
return new ExpressAdapter(httpAdapter);
|
||||
private createHttpAdapter<T = any>(httpServer?: T): HttpServer {
|
||||
const { ExpressAdapter } = loadPackage(
|
||||
'@nestjs/platform-express',
|
||||
'NestFactory',
|
||||
);
|
||||
return new ExpressAdapter(httpServer);
|
||||
}
|
||||
|
||||
private applyLogger(
|
||||
options: NestApplicationContextOptions | undefined,
|
||||
): void {
|
||||
private applyLogger(options: NestApplicationContextOptions | undefined) {
|
||||
if (!options || !options.logger) {
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
Logger.overrideLogger(options.logger);
|
||||
}
|
||||
|
||||
private createAdapterProxy<T>(app: NestApplication, adapter: HttpServer): T {
|
||||
return (new Proxy(app, {
|
||||
get: (receiver: Record<string, any>, prop: string) => {
|
||||
if (!(prop in receiver) && prop in adapter) {
|
||||
return adapter[prop];
|
||||
}
|
||||
return receiver[prop];
|
||||
},
|
||||
}) as any) as T;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user