From 79759b7a71beb19686b8ad46fd0455f2c4e7b924 Mon Sep 17 00:00:00 2001 From: Romain Lenzotti Date: Tue, 5 Apr 2022 05:50:43 +0200 Subject: [PATCH] fix(common): refactoring adapter and centralize code --- .nycrc | 4 +- .../apollo/src/interfaces/ApolloSettings.ts | 2 +- .../apollo/src/services/ApolloService.ts | 15 +- packages/graphql/typegraphql/package.json | 5 +- .../graphql/typegraphql/test/app/Server.ts | 36 +---- .../typegraphql/test/app/index.express.ts | 46 ++++++ .../test/app/{index.ts => index.koa.ts} | 9 +- packages/graphql/typegraphql/test/poc/koa.js | 73 ++++++++++ .../graphql/typegraphql/test/poc/package.json | 6 + .../src/builder/PlatformBuilder.spec.ts | 7 +- .../common/src/builder/PlatformBuilder.ts | 22 +-- packages/platform/common/src/index.ts | 4 +- .../common/src/interfaces/PlatformAdapter.ts | 21 --- .../common/src/services/FakeAdapter.ts | 58 ++++++++ .../common/src/services/FakeRawDriver.ts | 24 ---- .../common/src/services/PlatformAdapter.ts | 47 +++++++ .../src/services/PlatformApplication.spec.ts | 21 +-- .../src/services/PlatformApplication.ts | 15 +- .../common/src/services/PlatformRouter.ts | 57 +++----- .../common/src/services/PlatformTest.ts | 4 +- .../common/src/utils/createInjector.spec.ts | 10 +- .../common/src/utils/createInjector.ts | 21 ++- .../test/integration/configuration.spec.ts | 2 + .../src/components/PlatformExpress.ts | 131 +++++++++++++++--- .../platform/platform-express/src/index.ts | 2 - .../services/PlatformExpressApplication.ts | 38 ----- .../src/services/PlatformExpressRequest.ts | 16 --- .../services/PlatformExpressRouter.spec.ts | 13 +- .../src/services/PlatformExpressRouter.ts | 42 ------ .../src/components/PlatformKoa.ts | 99 ++++++++++--- packages/platform/platform-koa/src/index.ts | 2 - .../src/services/PlatformKoaApplication.ts | 36 ----- .../src/services/PlatformKoaRouter.ts | 65 --------- .../src/builder/PlatformServerlessHttp.ts | 2 +- .../src/PlatformServerlessTest.ts | 8 +- .../src/interfaces/index.ts | 2 +- .../agenda/test/integration.spec.ts | 4 +- 37 files changed, 541 insertions(+), 428 deletions(-) create mode 100644 packages/graphql/typegraphql/test/app/index.express.ts rename packages/graphql/typegraphql/test/app/{index.ts => index.koa.ts} (50%) create mode 100644 packages/graphql/typegraphql/test/poc/koa.js create mode 100644 packages/graphql/typegraphql/test/poc/package.json delete mode 100644 packages/platform/common/src/interfaces/PlatformAdapter.ts create mode 100644 packages/platform/common/src/services/FakeAdapter.ts delete mode 100644 packages/platform/common/src/services/FakeRawDriver.ts create mode 100644 packages/platform/common/src/services/PlatformAdapter.ts delete mode 100644 packages/platform/platform-express/src/services/PlatformExpressApplication.ts delete mode 100644 packages/platform/platform-express/src/services/PlatformExpressRouter.ts delete mode 100644 packages/platform/platform-koa/src/services/PlatformKoaApplication.ts delete mode 100644 packages/platform/platform-koa/src/services/PlatformKoaRouter.ts diff --git a/.nycrc b/.nycrc index 82141ddca69..ebf4abe40e0 100644 --- a/.nycrc +++ b/.nycrc @@ -41,8 +41,8 @@ "lcov" ], "check-coverage": true, - "lines": 99.52, + "lines": 99.48, "statements": 98.48, - "functions": 98.83, + "functions": 98.73, "branches": 86.66 } diff --git a/packages/graphql/apollo/src/interfaces/ApolloSettings.ts b/packages/graphql/apollo/src/interfaces/ApolloSettings.ts index ebbb99a1e54..22577c7ecee 100644 --- a/packages/graphql/apollo/src/interfaces/ApolloSettings.ts +++ b/packages/graphql/apollo/src/interfaces/ApolloSettings.ts @@ -1,7 +1,7 @@ import type {ApolloServerBase, Config, ApolloServerPluginLandingPageGraphQLPlaygroundOptions} from "apollo-server-core"; export type ApolloMiddlewareOptions = Record; -export type ApolloServer = ApolloServerBase & {applyMiddleware(settings: ApolloMiddlewareOptions): any}; +export type ApolloServer = ApolloServerBase & {getMiddleware(settings: ApolloMiddlewareOptions): any}; export type ApolloCustomServerCB = (config: ApolloConfig) => ApolloServer; export type ApolloConfig = Config; diff --git a/packages/graphql/apollo/src/services/ApolloService.ts b/packages/graphql/apollo/src/services/ApolloService.ts index 7a8664b201a..95a69ef3444 100644 --- a/packages/graphql/apollo/src/services/ApolloService.ts +++ b/packages/graphql/apollo/src/services/ApolloService.ts @@ -1,6 +1,6 @@ import {Constant, Inject, Service} from "@tsed/di"; import {Logger} from "@tsed/logger"; -import {PlatformApplication} from "@tsed/common"; +import {PlatformAdapter, PlatformApplication} from "@tsed/common"; import type {Config} from "apollo-server-core"; import { ApolloServerBase, @@ -36,7 +36,7 @@ export class ApolloService { > = new Map(); @Inject() - private app: PlatformApplication; + private adapter: PlatformAdapter; @Inject(Http.Server) private httpServer: Http.Server | null; @@ -71,11 +71,12 @@ export class ApolloService { await server.start(); - await server.applyMiddleware({ - path: settings.path, - ...middlewareOptions, - app: this.app.raw - }); + this.adapter.useMiddleware( + server.getMiddleware({ + path: settings.path, + ...middlewareOptions + }) + ); return server; } diff --git a/packages/graphql/typegraphql/package.json b/packages/graphql/typegraphql/package.json index 7738612c9ce..72efab15b26 100644 --- a/packages/graphql/typegraphql/package.json +++ b/packages/graphql/typegraphql/package.json @@ -18,7 +18,8 @@ "build:cjs": "tsc --build tsconfig.compile.json", "build:esm": "tsc --build tsconfig.compile.esm.json", "barrels": "yarn barrelsby --delete -d ./src -e \"\\.spec\\.ts\" -e \"__mock__\" -e \".benchmark.ts\"", - "start": "ts-node -r tsconfig-paths/register test/app/index.ts", + "start:express": "ts-node -r tsconfig-paths/register test/app/index.express.ts", + "start:koa": "ts-node -r tsconfig-paths/register test/app/index.koa.ts", "test": "cross-env NODE_ENV=test nyc mocha" }, "dependencies": { @@ -40,4 +41,4 @@ "graphql": ">=15.0.0", "type-graphql": ">=1.0.0" } -} \ No newline at end of file +} diff --git a/packages/graphql/typegraphql/test/app/Server.ts b/packages/graphql/typegraphql/test/app/Server.ts index a11bb10b2b2..c1c1f86c5c0 100644 --- a/packages/graphql/typegraphql/test/app/Server.ts +++ b/packages/graphql/typegraphql/test/app/Server.ts @@ -9,7 +9,6 @@ import {buildContext} from "graphql-passport"; import methodOverride from "method-override"; import {resolve} from "path"; import {User} from "./graphql/auth/User"; -import session from "express-session"; const rootDir = resolve(__dirname); @@ -44,37 +43,4 @@ const rootDir = resolve(__dirname); userInfoModel: User } }) -export class Server { - @Inject() - app: PlatformApplication; - - /** - * This method let you configure the middleware required by your application to works. - * @returns {Server} - */ - public $beforeRoutesInit(): void { - this.app - .use(bodyParser.json()) - .use( - bodyParser.urlencoded({ - extended: true - }) - ) - .use(cookieParser()) - .use(compress({})) - .use(methodOverride()) - .use( - session({ - secret: "mysecretkey", - resave: true, - saveUninitialized: true, - // maxAge: 36000, - cookie: { - path: "/", - httpOnly: true, - secure: false - } - }) - ); - } -} +export class Server {} diff --git a/packages/graphql/typegraphql/test/app/index.express.ts b/packages/graphql/typegraphql/test/app/index.express.ts new file mode 100644 index 00000000000..c8ca9709f0d --- /dev/null +++ b/packages/graphql/typegraphql/test/app/index.express.ts @@ -0,0 +1,46 @@ +import {$log} from "@tsed/common"; +import {PlatformExpress} from "@tsed/platform-express"; +import session from "express-session"; +import {Server} from "./Server"; +import bodyParser from "body-parser"; +import cookieParser from "cookie-parser"; +import compress from "compression"; +import methodOverride from "method-override"; + +if (process.env.NODE_ENV !== "test") { + async function bootstrap() { + try { + const platform = await PlatformExpress.bootstrap(Server, { + port: 8082, + middlewares: [ + bodyParser.urlencoded({ + extended: true + }), + bodyParser.json(), + cookieParser(), + compress({}), + methodOverride(), + session({ + secret: "mysecretkey", + resave: true, + saveUninitialized: true, + // maxAge: 36000, + cookie: { + path: "/", + httpOnly: true, + secure: false + } + }) + ] + }); + + await platform.listen(); + $log.debug("Server initialized"); + } catch (er) { + console.error(er); + $log.error(er); + } + } + + bootstrap(); +} diff --git a/packages/graphql/typegraphql/test/app/index.ts b/packages/graphql/typegraphql/test/app/index.koa.ts similarity index 50% rename from packages/graphql/typegraphql/test/app/index.ts rename to packages/graphql/typegraphql/test/app/index.koa.ts index 88c3bb358dd..3b13ea8c5ff 100644 --- a/packages/graphql/typegraphql/test/app/index.ts +++ b/packages/graphql/typegraphql/test/app/index.koa.ts @@ -1,11 +1,16 @@ import {$log} from "@tsed/common"; -import {PlatformExpress} from "@tsed/platform-express"; +import {PlatformKoa} from "@tsed/platform-koa"; import {Server} from "./Server"; +import compress from "koa-compress"; +import bodyParser from "koa-bodyparser"; +import methodOverride from "method-override"; if (process.env.NODE_ENV !== "test") { async function bootstrap() { try { - const platform = await PlatformExpress.bootstrap(Server); + const platform = await PlatformKoa.bootstrap(Server, { + middlewares: [compress(), methodOverride(), bodyParser()] + }); await platform.listen(); $log.debug("Server initialized"); diff --git a/packages/graphql/typegraphql/test/poc/koa.js b/packages/graphql/typegraphql/test/poc/koa.js new file mode 100644 index 00000000000..65940a538c7 --- /dev/null +++ b/packages/graphql/typegraphql/test/poc/koa.js @@ -0,0 +1,73 @@ +import {ApolloServer, gql} from "apollo-server-koa"; +import {ApolloServerPluginDrainHttpServer} from "apollo-server-core"; +import Koa from "koa"; +import KoaRouter from "@koa/router"; +import http from "http"; + +const app = new Koa(); +const mainRouter = new KoaRouter(); +const httpServer = http.createServer(); + +async function startApolloServer({typeDefs, resolvers}) { + const server = new ApolloServer({ + typeDefs, + resolvers, + plugins: [ApolloServerPluginDrainHttpServer({httpServer})] + }); + + await server.start(); + + const router = new KoaRouter(); + const middlewares = server.getMiddleware({path: "/graphql", app: router}); + + return {server, middlewares: middlewares}; +} + +const books = [ + { + title: "The Awakening", + author: "Kate Chopin" + }, + { + title: "City of Glass", + author: "Paul Auster" + } +]; + +const resolvers = { + Query: { + books: () => books + } +}; + +const typeDefs = gql` + # Comments in GraphQL strings (such as this one) start with the hash (#) symbol. + # This "Book" type defines the queryable fields for every book in our data source. + + type Book { + title: String + author: String + } + + # The "Query" type is special: it lists all of the available queries that + # clients can execute, along with the return type for each. In this + # case, the "books" query returns an array of zero or more Books (defined above). + type Query { + books: [Book] + } +`; + +startApolloServer({ + typeDefs, + app, + resolvers +}).then(async ({middlewares, server}) => { + app.use(middlewares); + app.listen(3000); + + httpServer.on("request", app.callback()); + + await new Promise((resolve) => httpServer.listen({port: 4000}, resolve)); + + console.log(`🚀 Server ready at http://localhost:3000${server.graphqlPath}`); +}); diff --git a/packages/graphql/typegraphql/test/poc/package.json b/packages/graphql/typegraphql/test/poc/package.json new file mode 100644 index 00000000000..bb4f7762e6f --- /dev/null +++ b/packages/graphql/typegraphql/test/poc/package.json @@ -0,0 +1,6 @@ +{ + "type": "module", + "scripts": { + "start:koa": "node koa.js" + } +} diff --git a/packages/platform/common/src/builder/PlatformBuilder.spec.ts b/packages/platform/common/src/builder/PlatformBuilder.spec.ts index 12233cec0c4..f35a4e25d44 100644 --- a/packages/platform/common/src/builder/PlatformBuilder.spec.ts +++ b/packages/platform/common/src/builder/PlatformBuilder.spec.ts @@ -20,6 +20,7 @@ import {join, resolve} from "path"; import Sinon from "sinon"; import {Platform} from "../services/Platform"; import {PlatformBuilder} from "./PlatformBuilder"; +import {FakeAdapter} from "../services/FakeAdapter"; const sandbox = Sinon.createSandbox(); @@ -27,14 +28,16 @@ describe("PlatformBuilder", () => { @Controller("/") class RestCtrl {} - class PlatformCustom implements PlatformAdapter { + class PlatformCustom extends FakeAdapter { readonly providers = [ { provide: class Test {} } ]; - constructor(private platform: PlatformBuilder) {} + constructor(private platform: PlatformBuilder) { + super(); + } static create(module: Type, settings: Partial = {}) { return PlatformBuilder.create(module, { diff --git a/packages/platform/common/src/builder/PlatformBuilder.ts b/packages/platform/common/src/builder/PlatformBuilder.ts index fd9dbeb0652..bba29c78716 100644 --- a/packages/platform/common/src/builder/PlatformBuilder.ts +++ b/packages/platform/common/src/builder/PlatformBuilder.ts @@ -7,8 +7,8 @@ import {PlatformStaticsSettings} from "../config/interfaces/PlatformStaticsSetti import {getStaticsOptions} from "../utils/getStaticsOptions"; import {Route} from "../interfaces/Route"; import {getConfiguration} from "../utils/getConfiguration"; -import type {IncomingMessage, ServerResponse, Server} from "http"; -import {PlatformAdapter, PlatformBuilderSettings} from "../interfaces/PlatformAdapter"; +import type {IncomingMessage, Server, ServerResponse} from "http"; +import {PlatformAdapter, PlatformBuilderSettings} from "../services/PlatformAdapter"; import {importProviders} from "../utils/importProviders"; import {createInjector} from "../utils/createInjector"; import {GlobalAcceptMimesMiddleware} from "../middlewares/GlobalAcceptMimesMiddleware"; @@ -21,34 +21,34 @@ import type Https from "https"; * @platform */ export class PlatformBuilder { - public static adapter: Type; + public static adapter: Type>; readonly name: string = ""; protected startedAt = new Date(); protected current = new Date(); - - #injector: InjectorService; - #rootModule: Type; + readonly #injector: InjectorService; + readonly #rootModule: Type; + readonly #adapter: PlatformAdapter; #promise: Promise; - #adapter: PlatformAdapter; #servers: (() => Promise)[]; #listeners: (Server | Https.Server)[] = []; protected constructor(adapter: Type> | undefined, module: Type, settings: Partial) { this.#rootModule = module; - const adapterKlass = adapter || PlatformBuilder.adapter; + const adapterKlass: Type> = adapter || (PlatformBuilder.adapter as any); const name = nameOf(adapterKlass).replace("Platform", "").toLowerCase(); const configuration = getConfiguration(settings, module); configuration.PLATFORM_NAME = name; this.name = name; - this.#adapter = new adapterKlass(this); this.#injector = createInjector({ - settings: configuration, - providers: this.#adapter.providers + adapter: adapterKlass, + settings: configuration }); + this.#adapter = this.#injector.get>(PlatformAdapter)!; + this.createHttpServers(); this.#adapter.onInit && this.#adapter.onInit(); diff --git a/packages/platform/common/src/index.ts b/packages/platform/common/src/index.ts index c458a63c4e1..8ce41c49ed8 100644 --- a/packages/platform/common/src/index.ts +++ b/packages/platform/common/src/index.ts @@ -44,7 +44,6 @@ export * from "./interfaces/OnReady"; export * from "./interfaces/OnRequest"; export * from "./interfaces/OnResponse"; export * from "./interfaces/OnRoutesInit"; -export * from "./interfaces/PlatformAdapter"; export * from "./interfaces/PlatformRouteOptions"; export * from "./interfaces/ResponseErrorObject"; export * from "./interfaces/Route"; @@ -53,8 +52,9 @@ export * from "./middlewares/GlobalAcceptMimesMiddleware"; export * from "./middlewares/PlatformAcceptMimesMiddleware"; export * from "./middlewares/PlatformMulterMiddleware"; export * from "./middlewares/bindEndpointMiddleware"; -export * from "./services/FakeRawDriver"; +export * from "./services/FakeAdapter"; export * from "./services/Platform"; +export * from "./services/PlatformAdapter"; export * from "./services/PlatformApplication"; export * from "./services/PlatformHandler"; export * from "./services/PlatformMiddlewaresChain"; diff --git a/packages/platform/common/src/interfaces/PlatformAdapter.ts b/packages/platform/common/src/interfaces/PlatformAdapter.ts deleted file mode 100644 index 88da5bb5ada..00000000000 --- a/packages/platform/common/src/interfaces/PlatformAdapter.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {Type} from "@tsed/core"; -import {ProviderOpts} from "@tsed/di"; - -export interface PlatformAdapter { - /** - * Load providers in top priority - */ - readonly providers: ProviderOpts[]; - /** - * Called after the injector instantiation - */ - onInit?: () => any; - beforeLoadRoutes?: () => Promise; - afterLoadRoutes?: () => Promise; - useRouter?: () => any; - useContext?: () => any; -} - -export interface PlatformBuilderSettings extends Partial { - adapter?: Type>; -} diff --git a/packages/platform/common/src/services/FakeAdapter.ts b/packages/platform/common/src/services/FakeAdapter.ts new file mode 100644 index 00000000000..41e6d151f18 --- /dev/null +++ b/packages/platform/common/src/services/FakeAdapter.ts @@ -0,0 +1,58 @@ +import {ProviderOpts} from "@tsed/di"; +import {PlatformAdapter} from "./PlatformAdapter"; +import {PlatformMulter, PlatformMulterSettings} from "../config/interfaces/PlatformMulterSettings"; +import {PlatformStaticsOptions} from "../config/interfaces/PlatformStaticsSettings"; + +export class FakeAdapter implements PlatformAdapter { + providers: ProviderOpts[] = []; + + static createFakeRawDriver() { + // istanbul ignore next + function FakeRawDriver() {} + + // istanbul ignore next + function use() { + return this; + } + + FakeRawDriver.use = use; + FakeRawDriver.all = use; + FakeRawDriver.get = use; + FakeRawDriver.patch = use; + FakeRawDriver.post = use; + FakeRawDriver.put = use; + FakeRawDriver.head = use; + FakeRawDriver.delete = use; + FakeRawDriver.options = use; + + return FakeRawDriver; + } + + app(): {app: any; callback(): any} { + const app = FakeAdapter.createFakeRawDriver(); + return { + app, + callback() { + return app; + } + }; + } + + multipart(options: PlatformMulterSettings): PlatformMulter { + return {} as any; + } + + router(routerOptions: any): {router: any; callback(): any} { + const router = FakeAdapter.createFakeRawDriver(); + return { + router, + callback() { + return router; + } + }; + } + + statics(endpoint: string, options: PlatformStaticsOptions): any { + return {}; + } +} diff --git a/packages/platform/common/src/services/FakeRawDriver.ts b/packages/platform/common/src/services/FakeRawDriver.ts deleted file mode 100644 index 841469ba38f..00000000000 --- a/packages/platform/common/src/services/FakeRawDriver.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @ignore - */ -export const createFakeRawDriver = () => { - // istanbul ignore next - function FakeRawDriver() {} - - // istanbul ignore next - function use() { - return this; - } - - FakeRawDriver.use = use; - FakeRawDriver.all = use; - FakeRawDriver.get = use; - FakeRawDriver.patch = use; - FakeRawDriver.post = use; - FakeRawDriver.put = use; - FakeRawDriver.head = use; - FakeRawDriver.delete = use; - FakeRawDriver.options = use; - - return FakeRawDriver; -}; diff --git a/packages/platform/common/src/services/PlatformAdapter.ts b/packages/platform/common/src/services/PlatformAdapter.ts new file mode 100644 index 00000000000..83cbba91595 --- /dev/null +++ b/packages/platform/common/src/services/PlatformAdapter.ts @@ -0,0 +1,47 @@ +import {Type} from "@tsed/core"; +import {InjectorService, ProviderOpts, registerProvider} from "@tsed/di"; +import {PlatformMulter, PlatformMulterSettings} from "../config/interfaces/PlatformMulterSettings"; +import {PlatformStaticsOptions} from "../config/interfaces/PlatformStaticsSettings"; +import {RouterOptions} from "express"; +import {FakeAdapter} from "./FakeAdapter"; + +export abstract class PlatformAdapter { + /** + * Load providers in top priority + */ + providers: ProviderOpts[]; + /** + * Called after the injector instantiation + */ + onInit?: () => any; + beforeLoadRoutes?: () => Promise; + afterLoadRoutes?: () => Promise; + useRouter?: () => any; + useContext?: () => any; + + abstract app(): {app: App; callback(): any}; + + abstract router(routerOptions?: Partial): {router: Router; callback(): any}; + /** + * Return the statics middlewares + * @param endpoint + * @param options + */ + abstract statics(endpoint: string, options: PlatformStaticsOptions): any; + + /** + * Return the multipart middleware + * @param options + */ + abstract multipart(options: PlatformMulterSettings): PlatformMulter; +} + +export interface PlatformBuilderSettings extends Partial { + adapter?: Type>; +} + +registerProvider({ + provide: PlatformAdapter, + deps: [InjectorService], + useClass: FakeAdapter +}); diff --git a/packages/platform/common/src/services/PlatformApplication.spec.ts b/packages/platform/common/src/services/PlatformApplication.spec.ts index e5e73dc3caa..cfcd3d99e31 100644 --- a/packages/platform/common/src/services/PlatformApplication.spec.ts +++ b/packages/platform/common/src/services/PlatformApplication.spec.ts @@ -24,7 +24,7 @@ async function getPlatformApp() { const platformHandler = { createHandler: sandbox.stub().callsFake((o) => o) }; - const platformApp = await PlatformTest.invoke(PlatformApplication, [ + const platformApp = await PlatformTest.invoke>(PlatformApplication, [ { token: PlatformHandler, use: platformHandler @@ -61,10 +61,6 @@ describe("PlatformApplication", () => { }); describe("use()", () => { - beforeEach(() => { - // @ts-ignore - sandbox.stub(PlatformRouter, "createRawRouter").returns(createDriver() as any); - }); afterEach(() => { sandbox.restore(); }); @@ -83,16 +79,25 @@ describe("PlatformApplication", () => { it("should add router to app", async () => { // GIVEN const {platformApp, platformHandler} = await getPlatformApp(); + const router = createDriver(); + const adapter = { + router() { + return { + router, + callback() { + return router; + } + }; + } + }; // @ts-ignore - const handler = new PlatformRouter(platformHandler as any); + const handler = new PlatformRouter(platformHandler as any, adapter); // WHEN platformApp.use("/", handler); // THEN - // @ts-ignore - expect(PlatformRouter.createRawRouter).to.have.been.calledWithExactly(); expect(platformApp.rawRouter.use).to.have.been.calledWithExactly("/", handler.raw); }); }); diff --git a/packages/platform/common/src/services/PlatformApplication.ts b/packages/platform/common/src/services/PlatformApplication.ts index 40c29481bc2..b573031fe46 100644 --- a/packages/platform/common/src/services/PlatformApplication.ts +++ b/packages/platform/common/src/services/PlatformApplication.ts @@ -1,7 +1,7 @@ import {Injectable, ProviderScope} from "@tsed/di"; -import {createFakeRawDriver} from "./FakeRawDriver"; import {PlatformHandler} from "./PlatformHandler"; import {PlatformRouter} from "./PlatformRouter"; +import {PlatformAdapter} from "./PlatformAdapter"; declare global { namespace TsED { @@ -18,18 +18,17 @@ declare global { @Injectable({ scope: ProviderScope.SINGLETON }) -export class PlatformApplication extends PlatformRouter { +export class PlatformApplication extends PlatformRouter { raw: App; rawApp: App; declare rawRouter: Router; - constructor(platformHandler: PlatformHandler) { - super(platformHandler); - this.rawApp = this.raw = PlatformApplication.createRawApp() as any; - } + constructor(platformHandler: PlatformHandler, adapter: PlatformAdapter) { + super(platformHandler, adapter); + const {app, callback} = adapter.app(); - protected static createRawApp(): any { - return createFakeRawDriver(); + this.rawApp = this.raw = app; + this.callback = callback; } getApp(): App { diff --git a/packages/platform/common/src/services/PlatformRouter.ts b/packages/platform/common/src/services/PlatformRouter.ts index 84cf631bdca..131481723b5 100644 --- a/packages/platform/common/src/services/PlatformRouter.ts +++ b/packages/platform/common/src/services/PlatformRouter.ts @@ -1,11 +1,11 @@ import {Inject, Injectable, InjectorService, PathType, ProviderScope} from "@tsed/di"; -import {promisify} from "util"; -import {createFakeRawDriver} from "./FakeRawDriver"; import {PlatformHandler} from "./PlatformHandler"; -import type multer from "multer"; import {PlatformRouteOptions, PlatformRouteWithoutHandlers} from "../interfaces/PlatformRouteOptions"; import {PlatformStaticsOptions} from "../config/interfaces/PlatformStaticsSettings"; import {PlatformMulter, PlatformMulterSettings} from "../config/interfaces/PlatformMulterSettings"; +import {PlatformAdapter} from "./PlatformAdapter"; +import {RouterOptions} from "express"; + /** * @ignore */ @@ -25,7 +25,7 @@ declare global { @Injectable({ scope: ProviderScope.INSTANCE }) -export class PlatformRouter { +export class PlatformRouter { rawRouter: Router; raw: any; isBuilt: boolean = false; @@ -33,11 +33,17 @@ export class PlatformRouter { @Inject() injector: InjectorService; - #multer: typeof multer; + callback: () => any; + + constructor( + protected platformHandler: PlatformHandler, + readonly adapter: PlatformAdapter, + @Inject(PLATFORM_ROUTER_OPTIONS) routerOptions: Partial = {} + ) { + const {router, callback} = adapter.router(routerOptions); - constructor(protected platformHandler: PlatformHandler) { - this.rawRouter = this.raw = PlatformRouter.createRawRouter(); - import("multer").then(({default: multer}) => (this.#multer = multer)); + this.rawRouter = this.raw = router; + this.callback = callback; } /** @@ -52,14 +58,6 @@ export class PlatformRouter { return injector.invoke(PlatformRouter, locals); } - protected static createRawRouter(): any { - return createFakeRawDriver(); - } - - callback(): any { - return this.raw; - } - getRouter(): Router { return this.rawRouter; } @@ -112,33 +110,12 @@ export class PlatformRouter { return this.addRoute({method: "options", path, handlers, isFinal: true}); } - statics(path: string, options: PlatformStaticsOptions): this { - return this; + statics(path: string, options: PlatformStaticsOptions) { + return this.use(path, this.adapter.statics(path, options)); } multer(options: PlatformMulterSettings): PlatformMulter { - const m = this.#multer(options); - - const makePromise = (multer: any, name: string) => { - // istanbul ignore next - if (!multer[name]) return; - - const fn = multer[name]; - - multer[name] = function apply(...args: any[]) { - const middleware = Reflect.apply(fn, this, args); - - return (req: any, res: any) => promisify(middleware)(req, res); - }; - }; - - makePromise(m, "any"); - makePromise(m, "array"); - makePromise(m, "fields"); - makePromise(m, "none"); - makePromise(m, "single"); - - return m; + return this.adapter.multipart(options); } protected mapHandlers(handlers: any[], options: PlatformRouteWithoutHandlers = {}): any[] { diff --git a/packages/platform/common/src/services/PlatformTest.ts b/packages/platform/common/src/services/PlatformTest.ts index 8745e7776a4..f0fdf307a39 100644 --- a/packages/platform/common/src/services/PlatformTest.ts +++ b/packages/platform/common/src/services/PlatformTest.ts @@ -5,8 +5,9 @@ import {PlatformContext, PlatformContextOptions} from "../domain/PlatformContext import {createInjector} from "../utils/createInjector"; import {PlatformApplication} from "./PlatformApplication"; import {getConfiguration} from "../utils/getConfiguration"; -import {PlatformAdapter, PlatformBuilderSettings} from "../interfaces/PlatformAdapter"; +import {PlatformAdapter, PlatformBuilderSettings} from "./PlatformAdapter"; import accepts from "accepts"; +import {FakeAdapter} from "./FakeAdapter"; /** * @platform @@ -24,7 +25,6 @@ export class PlatformTest extends DITest { */ static createInjector(settings: any = {}): InjectorService { return createInjector({ - providers: [], settings: DITest.configure({httpPort: false, httpsPort: false, ...settings}) }); } diff --git a/packages/platform/common/src/utils/createInjector.spec.ts b/packages/platform/common/src/utils/createInjector.spec.ts index a1fe39075a3..bad1f290f8e 100644 --- a/packages/platform/common/src/utils/createInjector.spec.ts +++ b/packages/platform/common/src/utils/createInjector.spec.ts @@ -1,9 +1,10 @@ import {expect} from "chai"; -import {createInjector, PlatformConfiguration} from "@tsed/common"; +import {createInjector, PlatformAdapter, PlatformConfiguration} from "@tsed/common"; import {Env} from "@tsed/core"; import {$log} from "@tsed/logger"; import Sinon from "sinon"; import {stub} from "../../../../../test/helper/tools"; +import {FakeAdapter} from "../services/FakeAdapter"; describe("createInjector", () => { beforeEach(() => { @@ -18,11 +19,12 @@ describe("createInjector", () => { env: Env.TEST }; - const injector = createInjector({settings}); + const injector = createInjector({settings, adapter: FakeAdapter}); expect(injector.settings).to.be.instanceof(PlatformConfiguration); expect(injector.settings.test).to.eq("test"); expect(injector.logger).to.eq($log); + expect(injector.get(PlatformAdapter)).to.be.instanceOf(FakeAdapter); }); it("should create injector", () => { @@ -31,8 +33,8 @@ describe("createInjector", () => { env: Env.PROD }; - const injector = createInjector({settings}); + const injector = createInjector({settings, adapter: FakeAdapter}); - return expect(injector.logger.stop).to.not.have.been.called; + expect(injector.logger.stop).to.not.have.been.called; }); }); diff --git a/packages/platform/common/src/utils/createInjector.ts b/packages/platform/common/src/utils/createInjector.ts index 90ba15d4a5a..6bca495c907 100644 --- a/packages/platform/common/src/utils/createInjector.ts +++ b/packages/platform/common/src/utils/createInjector.ts @@ -1,6 +1,6 @@ import {InjectorService, ProviderOpts, setLoggerLevel} from "@tsed/di"; import {$log} from "@tsed/logger"; -import {toMap} from "@tsed/core"; +import {toMap, Type} from "@tsed/core"; import {PlatformConfiguration} from "../config/services/PlatformConfiguration"; import {PlatformHandler} from "../services/PlatformHandler"; import {PlatformResponse} from "../services/PlatformResponse"; @@ -8,6 +8,7 @@ import {PlatformRouter} from "../services/PlatformRouter"; import {PlatformApplication} from "../services/PlatformApplication"; import {Platform} from "../services/Platform"; import {PlatformRequest} from "../services/PlatformRequest"; +import {PlatformAdapter} from "../services/PlatformAdapter"; $log.name = "TSED"; @@ -21,11 +22,11 @@ const DEFAULT_PROVIDERS = [ ]; interface CreateInjectorOptions { - providers?: ProviderOpts[]; + adapter?: Type>; settings?: Partial; } -export function createInjector({providers = [], settings = {}}: CreateInjectorOptions) { +export function createInjector({adapter, settings = {}}: CreateInjectorOptions) { const injector = new InjectorService(); injector.addProvider(PlatformConfiguration); @@ -33,11 +34,21 @@ export function createInjector({providers = [], settings = {}}: CreateInjectorOp injector.logger = $log; injector.settings.set(settings); + if (adapter) { + injector.addProvider(PlatformAdapter, { + useClass: adapter + }); + } + + injector.invoke(PlatformAdapter); + setLoggerLevel(injector); - providers = [...DEFAULT_PROVIDERS, ...providers]; + const instance = injector.get(PlatformAdapter)!; + + instance.providers = [...DEFAULT_PROVIDERS, ...instance.providers]; - toMap(providers, "provide").forEach((provider, token) => { + toMap(instance.providers, "provide").forEach((provider, token) => { injector.addProvider(token, provider); }); diff --git a/packages/platform/common/test/integration/configuration.spec.ts b/packages/platform/common/test/integration/configuration.spec.ts index 34f4c42cc03..0332a6febae 100644 --- a/packages/platform/common/test/integration/configuration.spec.ts +++ b/packages/platform/common/test/integration/configuration.spec.ts @@ -1,6 +1,7 @@ import {Controller, createInjector, Get} from "@tsed/common"; import {Module} from "@tsed/di"; import {expect} from "chai"; +import {FakeAdapter} from "../../src/services/FakeAdapter"; describe("DI", () => { it("should merge DI configuration", async () => { @@ -24,6 +25,7 @@ describe("DI", () => { class MyModule {} const injector = createInjector({ + adapter: new FakeAdapter(), settings: { mount: { "/rest": [ControllerGlobal] diff --git a/packages/platform/platform-express/src/components/PlatformExpress.ts b/packages/platform/platform-express/src/components/PlatformExpress.ts index 9a3bc31a8c3..5b37f0a4de7 100644 --- a/packages/platform/platform-express/src/components/PlatformExpress.ts +++ b/packages/platform/platform-express/src/components/PlatformExpress.ts @@ -1,23 +1,51 @@ -import Express from "express"; +import type multer from "multer"; +import Express, {RouterOptions} from "express"; import type {PlatformViews} from "@tsed/platform-views"; import { createContext, + InjectorService, PlatformAdapter, PlatformApplication, PlatformBuilder, + PlatformContext, PlatformExceptions, PlatformHandler, + PlatformMulter, + PlatformMulterSettings, PlatformRequest, PlatformResponse, - PlatformRouter + PlatformStaticsOptions } from "@tsed/common"; +import {promisify} from "util"; import {Env, Type} from "@tsed/core"; import {rawBodyMiddleware} from "../middlewares/rawBodyMiddleware"; -import {PlatformExpressApplication} from "../services/PlatformExpressApplication"; -import {PlatformExpressRouter} from "../services/PlatformExpressRouter"; import {PlatformExpressHandler} from "../services/PlatformExpressHandler"; import {PlatformExpressResponse} from "../services/PlatformExpressResponse"; import {PlatformExpressRequest} from "../services/PlatformExpressRequest"; +import {staticsMiddleware} from "../middlewares/staticsMiddleware"; +import {PlatformExpressStaticsOptions} from "../interfaces/PlatformExpressStaticsOptions"; + +declare module "express" { + export interface Request { + id: string; + $ctx: PlatformContext; + } +} + +declare global { + namespace TsED { + export interface Router extends Express.Router {} + + export interface Application extends Express.Application {} + + export interface StaticsOptions extends PlatformExpressStaticsOptions {} + + export interface Request extends Express.Request { + id: string; + $ctx: PlatformContext; + } + } +} /** * @platform @@ -25,14 +53,6 @@ import {PlatformExpressRequest} from "../services/PlatformExpressRequest"; */ export class PlatformExpress implements PlatformAdapter { readonly providers = [ - { - provide: PlatformApplication, - useClass: PlatformExpressApplication - }, - { - provide: PlatformRouter, - useClass: PlatformExpressRouter - }, { provide: PlatformHandler, useClass: PlatformExpressHandler @@ -46,8 +66,11 @@ export class PlatformExpress implements PlatformAdapter) {} + constructor(protected injector: InjectorService) { + import("multer").then(({default: multer}) => (this.#multer = multer)); + } /** * Create new serverless application. In this mode, the component scan are disabled. @@ -74,7 +97,8 @@ export class PlatformExpress implements PlatformAdapter>(PlatformApplication)!; logger.debug("Mount app router"); app.getApp().use(rawBodyMiddleware); @@ -84,7 +108,9 @@ export class PlatformExpress implements PlatformAdapter>(PlatformApplication)!; + // disable x-powered-by header injector.settings.get("env") === Env.PROD && app.getApp().disable("x-powered-by"); @@ -92,7 +118,9 @@ export class PlatformExpress implements PlatformAdapter>(PlatformApplication)!; + // NOT FOUND app.use((req: any, res: any, next: any) => { !res.headersSent && injector.get(PlatformExceptions)?.resourceNotFound(req.$ctx); @@ -105,11 +133,12 @@ export class PlatformExpress implements PlatformAdapter>(PlatformApplication)!; app.getApp().use(async (request: any, response: any, next: any) => { await invoke({request, response}); @@ -120,10 +149,72 @@ export class PlatformExpress implements PlatformAdapter { + // istanbul ignore next + if (!multer[name]) return; + + const fn = multer[name]; + + multer[name] = function apply(...args: any[]) { + const middleware = Reflect.apply(fn, this, args); + + return (req: any, res: any) => promisify(middleware)(req, res); + }; + }; + + makePromise(m, "any"); + makePromise(m, "array"); + makePromise(m, "fields"); + makePromise(m, "none"); + makePromise(m, "single"); + + return m; + } + + app() { + const app = this.injector.settings.get("express.app") || Express(); + return { + app, + callback() { + return app; + } + }; + } + + router(routerOptions: Partial = {}) { + const options = Object.assign( + { + mergeParams: true + }, + this.injector.settings.express?.router || {}, + routerOptions + ); + + const router = Express.Router(options); + + return { + router, + callback() { + return router; + } + }; + } + + statics(endpoint: string, options: PlatformStaticsOptions) { + const {root, ...props} = options; + + return staticsMiddleware(root, props); + } + private async configureViewsEngine() { - const {settings, injector, app} = this.platform; + const injector = this.injector; + const app = this.injector.get>(PlatformApplication)!; + try { - const {exists, disabled} = settings.get("views") || {}; + const {exists, disabled} = this.injector.settings.get("views") || {}; if (exists && !disabled) { const {PlatformViews} = await import("@tsed/platform-views"); diff --git a/packages/platform/platform-express/src/index.ts b/packages/platform/platform-express/src/index.ts index 432bdcc8811..f06c2e8955a 100644 --- a/packages/platform/platform-express/src/index.ts +++ b/packages/platform/platform-express/src/index.ts @@ -13,8 +13,6 @@ export * from "./interfaces/PlatformExpressStaticsOptions"; export * from "./interfaces/interfaces"; export * from "./middlewares/rawBodyMiddleware"; export * from "./middlewares/staticsMiddleware"; -export * from "./services/PlatformExpressApplication"; export * from "./services/PlatformExpressHandler"; export * from "./services/PlatformExpressRequest"; export * from "./services/PlatformExpressResponse"; -export * from "./services/PlatformExpressRouter"; diff --git a/packages/platform/platform-express/src/services/PlatformExpressApplication.ts b/packages/platform/platform-express/src/services/PlatformExpressApplication.ts deleted file mode 100644 index fe977401b98..00000000000 --- a/packages/platform/platform-express/src/services/PlatformExpressApplication.ts +++ /dev/null @@ -1,38 +0,0 @@ -import {Configuration, Inject, PlatformApplication, PlatformHandler} from "@tsed/common"; -import Express from "express"; -import {PlatformExpressStaticsOptions} from "../interfaces/PlatformExpressStaticsOptions"; -import {PlatformExpressRouter} from "./PlatformExpressRouter"; - -declare global { - namespace TsED { - export interface Application extends Express.Application {} - - export interface StaticsOptions extends PlatformExpressStaticsOptions {} - } -} - -/** - * @platform - * @express - */ -export class PlatformExpressApplication extends PlatformExpressRouter implements PlatformApplication { - app: Express.Application; - rawApp: Express.Application; - rawRouter: Express.Router; - - constructor(@Inject() platformHandler: PlatformHandler, @Configuration() configuration: Configuration) { - super(platformHandler, configuration, { - mergeParams: true - }); - - this.rawApp = configuration.get("express.app") || Express(); - } - - getApp() { - return this.rawApp; - } - - callback() { - return this.rawApp; - } -} diff --git a/packages/platform/platform-express/src/services/PlatformExpressRequest.ts b/packages/platform/platform-express/src/services/PlatformExpressRequest.ts index be7fd4db084..6a9eb27e1ca 100644 --- a/packages/platform/platform-express/src/services/PlatformExpressRequest.ts +++ b/packages/platform/platform-express/src/services/PlatformExpressRequest.ts @@ -1,22 +1,6 @@ import {PlatformContext, PlatformRequest} from "@tsed/common"; import type Express from "express"; -declare module "express" { - export interface Request { - id: string; - $ctx: PlatformContext; - } -} - -declare global { - namespace TsED { - export interface Request extends Express.Request { - id: string; - $ctx: PlatformContext; - } - } -} - /** * @platform * @express diff --git a/packages/platform/platform-express/src/services/PlatformExpressRouter.spec.ts b/packages/platform/platform-express/src/services/PlatformExpressRouter.spec.ts index 65a7b9bb81b..7090c615919 100644 --- a/packages/platform/platform-express/src/services/PlatformExpressRouter.spec.ts +++ b/packages/platform/platform-express/src/services/PlatformExpressRouter.spec.ts @@ -1,10 +1,10 @@ -import {PlatformHandler, PlatformRouter} from "@tsed/common"; +import {PlatformAdapter, PlatformHandler, PlatformRouter} from "@tsed/common"; import {InjectorService} from "@tsed/di"; import {expect} from "chai"; import Express from "express"; import Sinon from "sinon"; import {stub} from "../../../../../test/helper/tools"; -import {PlatformExpressRouter} from "./PlatformExpressRouter"; +import {PlatformExpress} from "@tsed/platform-express"; const sandbox = Sinon.createSandbox(); describe("PlatformExpressRouter", () => { @@ -39,9 +39,14 @@ describe("PlatformExpressRouter", () => { injector.addProvider(PlatformHandler, { useValue: platformHandler }); - injector.addProvider(PlatformRouter, { - useClass: PlatformExpressRouter + + injector.addProvider(PlatformAdapter, { + useValue: new PlatformExpress({ + settings: injector.settings, + injector + } as any) }); + injector.settings.express = { router: { mergeParams: true diff --git a/packages/platform/platform-express/src/services/PlatformExpressRouter.ts b/packages/platform/platform-express/src/services/PlatformExpressRouter.ts deleted file mode 100644 index cf29d6ff0e6..00000000000 --- a/packages/platform/platform-express/src/services/PlatformExpressRouter.ts +++ /dev/null @@ -1,42 +0,0 @@ -import {PLATFORM_ROUTER_OPTIONS, PlatformHandler, PlatformRouter, PlatformStaticsOptions} from "@tsed/common"; -import {Configuration, Inject} from "@tsed/di"; -import Express from "express"; -import {RouterOptions} from "express"; -import {staticsMiddleware} from "../middlewares/staticsMiddleware"; - -declare global { - namespace TsED { - export interface Router extends Express.Router {} - } -} - -/** - * @platform - * @express - */ -export class PlatformExpressRouter extends PlatformRouter { - constructor( - platform: PlatformHandler, - @Configuration() configuration: Configuration, - @Inject(PLATFORM_ROUTER_OPTIONS) routerOptions: Partial = {} - ) { - super(platform); - - const options = Object.assign( - { - mergeParams: true - }, - configuration.express?.router || {}, - routerOptions - ); - this.rawRouter = this.raw = Express.Router(options); - } - - statics(endpoint: string, options: PlatformStaticsOptions) { - const {root, ...props} = options; - - this.use(endpoint, staticsMiddleware(root, props)); - - return this; - } -} diff --git a/packages/platform/platform-koa/src/components/PlatformKoa.ts b/packages/platform/platform-koa/src/components/PlatformKoa.ts index 973ac6d87f6..5f49d88e0ee 100644 --- a/packages/platform/platform-koa/src/components/PlatformKoa.ts +++ b/packages/platform/platform-koa/src/components/PlatformKoa.ts @@ -1,14 +1,17 @@ -import KoaRouter from "@koa/router"; +import KoaRouter, {RouterOptions as KoaRouterOptions} from "@koa/router"; import { createContext, + InjectorService, PlatformAdapter, PlatformApplication, PlatformBuilder, PlatformExceptions, PlatformHandler, + PlatformMulter, + PlatformMulterSettings, PlatformRequest, PlatformResponse, - PlatformRouter + PlatformStaticsOptions } from "@tsed/common"; import {Type} from "@tsed/core"; import Koa, {Context, Next} from "koa"; @@ -16,8 +19,38 @@ import {resourceNotFoundMiddleware} from "../middlewares/resourceNotFoundMiddlew import {PlatformKoaResponse} from "../services/PlatformKoaResponse"; import {PlatformKoaRequest} from "../services/PlatformKoaRequest"; import {PlatformKoaHandler} from "../services/PlatformKoaHandler"; -import {PlatformKoaRouter} from "../services/PlatformKoaRouter"; -import {PlatformKoaApplication} from "../services/PlatformKoaApplication"; +import {getMulter} from "../utils/multer"; +import {staticsMiddleware} from "../middlewares/staticsMiddleware"; +import send from "koa-send"; +// @ts-ignore +import koaQs from "koa-qs"; + +declare global { + namespace TsED { + export interface Application extends Koa {} + } + + namespace TsED { + export interface Router extends KoaRouter {} + + export interface RouterOptions extends KoaRouterOptions {} + + export interface StaticsOptions extends send.SendOptions {} + } +} + +// @ts-ignore +KoaRouter.prototype.$$match = KoaRouter.prototype.match; +KoaRouter.prototype.match = function match(...args: any[]) { + const matched = this.$$match(...args); + if (matched) { + if (matched.path.length) { + matched.route = true; + } + } + + return matched; +}; /** * @platform @@ -36,18 +69,10 @@ export class PlatformKoa implements PlatformAdapter { { provide: PlatformHandler, useClass: PlatformKoaHandler - }, - { - provide: PlatformRouter, - useClass: PlatformKoaRouter - }, - { - provide: PlatformApplication, - useClass: PlatformKoaApplication } ]; - constructor(private platform: PlatformBuilder) {} + constructor(private injector: InjectorService) {} /** * Create new serverless application. In this mode, the component scan are disabled. @@ -74,7 +99,8 @@ export class PlatformKoa implements PlatformAdapter { } onInit() { - const {injector, app} = this.platform; + const injector = this.injector; + const app = this.injector.get(PlatformApplication)!; const listener: any = (error: any, ctx: Koa.Context) => { injector.get(PlatformExceptions)?.catch(error, ctx.request.$ctx); @@ -85,17 +111,20 @@ export class PlatformKoa implements PlatformAdapter { } useRouter(): this { - const {app} = this.platform; - app.getApp().use(resourceNotFoundMiddleware).use(app.getRouter().routes()).use(app.getRouter().allowedMethods()); + const app = this.injector.get>(PlatformApplication)!; + + app.getApp().use(resourceNotFoundMiddleware); + app.getApp().use(app.getRouter().routes()).use(app.getRouter().allowedMethods()); return this; } useContext(): this { - const {injector, app, logger} = this.platform; + const app = this.injector.get>(PlatformApplication)!; + const {logger} = this.injector; logger.info("Mount app context"); - const invoke = createContext(injector); + const invoke = createContext(this.injector); app.getApp().use(async (ctx: Context, next: Next) => { await invoke({ @@ -109,4 +138,38 @@ export class PlatformKoa implements PlatformAdapter { return this; } + + app() { + const app = this.injector.settings.get("koa.app") || new Koa(); + koaQs(app, "extended"); + + return { + app, + callback() { + return app.callback(); + } + }; + } + + router(routerOptions: any = {}) { + const {settings} = this.injector; + + const options = Object.assign({}, settings.koa?.router || {}, routerOptions); + const router = new KoaRouter(options) as any; + + return { + router, + callback() { + return [router.routes(), router.allowedMethods()]; + } + }; + } + + multipart(options: PlatformMulterSettings): PlatformMulter { + return getMulter(options); + } + + statics(endpoint: string, options: PlatformStaticsOptions) { + return staticsMiddleware(options); + } } diff --git a/packages/platform/platform-koa/src/index.ts b/packages/platform/platform-koa/src/index.ts index b3d58f8eaf6..f35afd165ef 100644 --- a/packages/platform/platform-koa/src/index.ts +++ b/packages/platform/platform-koa/src/index.ts @@ -13,9 +13,7 @@ export * from "./interfaces/PlatformKoaSettings"; export * from "./interfaces/interfaces"; export * from "./middlewares/resourceNotFoundMiddleware"; export * from "./middlewares/staticsMiddleware"; -export * from "./services/PlatformKoaApplication"; export * from "./services/PlatformKoaHandler"; export * from "./services/PlatformKoaRequest"; export * from "./services/PlatformKoaResponse"; -export * from "./services/PlatformKoaRouter"; export * from "./utils/multer"; diff --git a/packages/platform/platform-koa/src/services/PlatformKoaApplication.ts b/packages/platform/platform-koa/src/services/PlatformKoaApplication.ts deleted file mode 100644 index b9b86773ba6..00000000000 --- a/packages/platform/platform-koa/src/services/PlatformKoaApplication.ts +++ /dev/null @@ -1,36 +0,0 @@ -import KoaRouter from "@koa/router"; -import {Configuration, Inject, PlatformApplication, PlatformHandler} from "@tsed/common"; -import Koa from "koa"; -import {PlatformKoaRouter} from "./PlatformKoaRouter"; - -const koaQs = require("koa-qs"); - -declare global { - namespace TsED { - export interface Application extends Koa {} - } -} - -/** - * @platform - * @express - */ -export class PlatformKoaApplication extends PlatformKoaRouter implements PlatformApplication { - app: Koa; - rawApp: Koa; - - constructor(@Inject() platformHandler: PlatformHandler, @Configuration() configuration: Configuration) { - super(platformHandler, configuration, {}); - - this.rawApp = configuration.get("koa.app") || new Koa(); - koaQs(this.rawApp, "extended"); - } - - getApp(): Koa { - return this.rawApp; - } - - callback(): any { - return this.getApp().callback(); - } -} diff --git a/packages/platform/platform-koa/src/services/PlatformKoaRouter.ts b/packages/platform/platform-koa/src/services/PlatformKoaRouter.ts deleted file mode 100644 index 89f4ad27850..00000000000 --- a/packages/platform/platform-koa/src/services/PlatformKoaRouter.ts +++ /dev/null @@ -1,65 +0,0 @@ -import KoaRouter from "@koa/router"; -import {RouterOptions as KoaRouterOptions} from "@koa/router"; - -import { - PLATFORM_ROUTER_OPTIONS, - PlatformHandler, - PlatformMulter, - PlatformMulterSettings, - PlatformRouter, - PlatformStaticsOptions -} from "@tsed/common"; -import {Configuration, Inject} from "@tsed/di"; -import send from "koa-send"; -import {staticsMiddleware} from "../middlewares/staticsMiddleware"; -import {getMulter} from "../utils/multer"; - -declare global { - namespace TsED { - export interface Router extends KoaRouter {} - - export interface RouterOptions extends KoaRouterOptions {} - - export interface StaticsOptions extends send.SendOptions {} - } -} - -// @ts-ignore -KoaRouter.prototype.$$match = KoaRouter.prototype.match; -KoaRouter.prototype.match = function match(...args: any[]) { - const matched = this.$$match(...args); - if (matched) { - if (matched.path.length) { - matched.route = true; - } - } - - return matched; -}; - -export class PlatformKoaRouter extends PlatformRouter { - constructor( - platform: PlatformHandler, - @Configuration() configuration: Configuration, - @Inject(PLATFORM_ROUTER_OPTIONS) routerOptions: any - ) { - super(platform); - - const options = Object.assign({}, configuration.koa?.router || {}, routerOptions); - this.rawRouter = new KoaRouter(options) as any; - } - - callback() { - return [this.getRouter().routes(), this.getRouter().allowedMethods()]; - } - - multer(options: PlatformMulterSettings): PlatformMulter { - return getMulter(options); - } - - statics(path: string, options: PlatformStaticsOptions) { - this.rawRouter.use(path, staticsMiddleware(options) as any); - - return this; - } -} diff --git a/packages/platform/platform-serverless-http/src/builder/PlatformServerlessHttp.ts b/packages/platform/platform-serverless-http/src/builder/PlatformServerlessHttp.ts index 1804b03369a..234a5ff7a70 100644 --- a/packages/platform/platform-serverless-http/src/builder/PlatformServerlessHttp.ts +++ b/packages/platform/platform-serverless-http/src/builder/PlatformServerlessHttp.ts @@ -4,7 +4,7 @@ import type {Handler} from "aws-lambda"; import serverless from "serverless-http"; export class PlatformServerlessHttp { - static bootstrap(module: Type, settings: PlatformBuilderSettings): PlatformBuilder & {handler(): Handler} { + static bootstrap(module: Type, settings: PlatformBuilderSettings): PlatformBuilder & {handler(): Handler} { const platform = PlatformBuilder.create(module, settings); const promise = platform.listen(); diff --git a/packages/platform/platform-serverless-testing/src/PlatformServerlessTest.ts b/packages/platform/platform-serverless-testing/src/PlatformServerlessTest.ts index 2eb07d7fa98..feb1e083f89 100644 --- a/packages/platform/platform-serverless-testing/src/PlatformServerlessTest.ts +++ b/packages/platform/platform-serverless-testing/src/PlatformServerlessTest.ts @@ -152,14 +152,14 @@ export class PlatformServerlessTest extends DITest { static request = LambdaClientRequest; static bootstrap( - serverless: {bootstrap: (server: Type, settings: PlatformBuilderSettings) => PlatformBuilder}, - {server, ...settings}: PlatformBuilderSettings & {server: Type} + serverless: {bootstrap: (server: Type, settings: PlatformBuilderSettings) => PlatformBuilder}, + {server, ...settings}: PlatformBuilderSettings & {server: Type} ): () => Promise; static bootstrap( serverless: {bootstrap: (settings: Partial & {lambda?: Type[]}) => any}, - {server, ...settings}: PlatformBuilderSettings + {server, ...settings}: PlatformBuilderSettings ): () => Promise; - static bootstrap(serverless: any, {server, ...settings}: PlatformBuilderSettings) { + static bootstrap(serverless: any, {server, ...settings}: PlatformBuilderSettings) { return async function before(): Promise { settings = DITest.configure(settings); diff --git a/packages/platform/platform-test-utils/src/interfaces/index.ts b/packages/platform/platform-test-utils/src/interfaces/index.ts index c0c3d3bc5a2..c4cb1bd3f44 100644 --- a/packages/platform/platform-test-utils/src/interfaces/index.ts +++ b/packages/platform/platform-test-utils/src/interfaces/index.ts @@ -3,7 +3,7 @@ import {Type} from "@tsed/core"; export interface PlatformTestOptions { rootDir: string; - platform: Type; + platform: Type>; server: Type; [key: string]: any; diff --git a/packages/third-parties/agenda/test/integration.spec.ts b/packages/third-parties/agenda/test/integration.spec.ts index f030edc60e1..a58a2aa0e70 100644 --- a/packages/third-parties/agenda/test/integration.spec.ts +++ b/packages/third-parties/agenda/test/integration.spec.ts @@ -35,9 +35,7 @@ describe("Agenda integration", () => { enabled: true, db: { address: url, - options: { - useUnifiedTopology: true - } + options: {} } } });