From 9cdcfd2a35ebf20039f37c98a0dbc1aa0b7a3c0f Mon Sep 17 00:00:00 2001 From: Romain Lenzotti Date: Tue, 24 Jan 2023 07:31:22 +0100 Subject: [PATCH] fix(platform-router): produce routes for all nested controllers add to multiple parent controller Close: #2221 --- .../common/src/services/Platform.spec.ts | 26 ++++- .../platform/common/src/services/Platform.ts | 13 ++- .../platform/platform-router/package.json | 2 +- .../src/domain/PlatformLayer.ts | 8 +- .../routers.integration.spec.ts.snap | 22 ++++ .../test/routers-nested.integration.spec.ts | 32 +++++- .../test/routers.integration.spec.ts | 12 +- .../swagger.nested-controllers.spec.ts.snap | 103 ++++++++++++++++++ .../test/swagger.nested-controllers.spec.ts | 11 +- 9 files changed, 213 insertions(+), 16 deletions(-) diff --git a/packages/platform/common/src/services/Platform.spec.ts b/packages/platform/common/src/services/Platform.spec.ts index c294bf3dc8d..8d771a33e7d 100644 --- a/packages/platform/common/src/services/Platform.spec.ts +++ b/packages/platform/common/src/services/Platform.spec.ts @@ -39,7 +39,7 @@ export class FlaggedCommentController { children: [FlaggedCommentController] }) export class CommentController { - @Get("/") + @Get("/all") get() {} } @@ -48,6 +48,14 @@ export class CommentController { children: [CommentController] }) export class DomainController { + @Get("/all") + get() {} +} +@Controller({ + path: "/platform/:platform", + children: [CommentController] +}) +export class PlatformController { @Get("/") get() {} } @@ -93,10 +101,12 @@ describe("Platform", () => { // WHEN platform.addRoutes([{route: "/rest", token: DomainController}]); + platform.addRoutes([{route: "/rest", token: PlatformController}]); + platform.getLayers(); const result = platform.getMountedControllers(); - + console.log(result); // THEN const data = result.map((c) => ({route: c.route, name: nameOf(c.provider)})); expect(data).toEqual([ @@ -111,6 +121,18 @@ describe("Platform", () => { { name: "Token:FlaggedCommentController:FlaggedCommentController", route: "/rest/domain/:contextID/comments" + }, + { + name: "Token:PlatformController:PlatformController", + route: "/rest" + }, + { + name: "Token:CommentController:CommentController", + route: "/rest/platform/:platform" + }, + { + name: "Token:FlaggedCommentController:FlaggedCommentController", + route: "/rest/platform/:platform/comments" } ]); }); diff --git a/packages/platform/common/src/services/Platform.ts b/packages/platform/common/src/services/Platform.ts index ba2f431bef4..c81c0e42a35 100644 --- a/packages/platform/common/src/services/Platform.ts +++ b/packages/platform/common/src/services/Platform.ts @@ -61,10 +61,15 @@ export class Platform { public getMountedControllers() { const controllers = this.getLayers().reduce((controllers, layer) => { if (layer.isProvider()) { - controllers.set(layer.provider.token, { - route: String(layer.getBasePath()), - provider: layer.provider - }); + const route = String(layer.getBasePath()); + const key = `${layer.provider.toString()}:${route}`; + + if (!controllers.has(key)) { + controllers.set(key, { + route, + provider: layer.provider + }); + } } return controllers; diff --git a/packages/platform/platform-router/package.json b/packages/platform/platform-router/package.json index 05dc7bf3c95..909e36911c7 100644 --- a/packages/platform/platform-router/package.json +++ b/packages/platform/platform-router/package.json @@ -59,4 +59,4 @@ "optional": false } } -} \ No newline at end of file +} diff --git a/packages/platform/platform-router/src/domain/PlatformLayer.ts b/packages/platform/platform-router/src/domain/PlatformLayer.ts index 0c1e94a8a07..f5601048e45 100644 --- a/packages/platform/platform-router/src/domain/PlatformLayer.ts +++ b/packages/platform/platform-router/src/domain/PlatformLayer.ts @@ -39,8 +39,11 @@ export class PlatformLayer { constructor(props: Partial = {}) { Object.assign(this, props); - this.layers.forEach((layer) => { - layer.parent = this; + this.layers = this.layers.map((layer) => { + return new PlatformLayer({ + ...layer, + parent: this + }); }); } @@ -58,6 +61,7 @@ export class PlatformLayer { inspect() { return { + basePath: this.getBasePath(), path: this.path, method: this.method, handlers: this.handlers.map((item: any) => String(item)), diff --git a/packages/platform/platform-router/test/__snapshots__/routers.integration.spec.ts.snap b/packages/platform/platform-router/test/__snapshots__/routers.integration.spec.ts.snap index 26a975b3429..f74a7cf05ef 100644 --- a/packages/platform/platform-router/test/__snapshots__/routers.integration.spec.ts.snap +++ b/packages/platform/platform-router/test/__snapshots__/routers.integration.spec.ts.snap @@ -3,6 +3,7 @@ exports[`routers integration getLayers() should declare router - appRouter 1`] = ` Array [ Object { + "basePath": "/rest", "handlers": Array [ "", "useBefore", @@ -20,6 +21,7 @@ Array [ "path": "/rest/controller", }, Object { + "basePath": "/rest", "handlers": Array [ "", "useBefore", @@ -37,6 +39,7 @@ Array [ "path": "/rest/controller", }, Object { + "basePath": "/rest", "handlers": Array [ "", "useBefore", @@ -54,6 +57,7 @@ Array [ "path": "/rest/controller/:id", }, Object { + "basePath": "/rest", "handlers": Array [ "", "useBefore", @@ -71,6 +75,7 @@ Array [ "path": "/rest/controller/:id", }, Object { + "basePath": "/rest", "handlers": Array [ "", "useBefore", @@ -88,6 +93,7 @@ Array [ "path": "/rest/controller/:id", }, Object { + "basePath": "/rest", "handlers": Array [ "", "useBefore", @@ -105,6 +111,7 @@ Array [ "path": "/rest/controller/:id", }, Object { + "basePath": "/rest", "handlers": Array [ "", "useBefore", @@ -122,6 +129,7 @@ Array [ "path": "/rest/controller/:id", }, Object { + "basePath": "/rest/controller", "handlers": Array [ "", "useBefore", @@ -139,6 +147,7 @@ Array [ "path": "/rest/controller/nested", }, Object { + "basePath": "/rest/controller", "handlers": Array [ "", "useBefore", @@ -156,6 +165,7 @@ Array [ "path": "/rest/controller/nested", }, Object { + "basePath": "/rest/controller", "handlers": Array [ "", "useBefore", @@ -173,6 +183,7 @@ Array [ "path": "/rest/controller/nested/:id", }, Object { + "basePath": "/rest/controller", "handlers": Array [ "", "useBefore", @@ -190,6 +201,7 @@ Array [ "path": "/rest/controller/nested/:id", }, Object { + "basePath": "/rest/controller", "handlers": Array [ "", "useBefore", @@ -207,6 +219,7 @@ Array [ "path": "/rest/controller/nested/:id", }, Object { + "basePath": "/rest/controller", "handlers": Array [ "", "useBefore", @@ -224,6 +237,7 @@ Array [ "path": "/rest/controller/nested/:id", }, Object { + "basePath": "/rest/controller", "handlers": Array [ "", "useBefore", @@ -246,6 +260,7 @@ Array [ exports[`routers integration getLayers() should declare router 1`] = ` Array [ Object { + "basePath": "", "handlers": Array [ "", "useBefore", @@ -263,6 +278,7 @@ Array [ "path": "/controller", }, Object { + "basePath": "", "handlers": Array [ "", "useBefore", @@ -280,6 +296,7 @@ Array [ "path": "/controller", }, Object { + "basePath": "", "handlers": Array [ "", "useBefore", @@ -297,6 +314,7 @@ Array [ "path": "/controller/:id", }, Object { + "basePath": "", "handlers": Array [ "", "useBefore", @@ -314,6 +332,7 @@ Array [ "path": "/controller/:id", }, Object { + "basePath": "", "handlers": Array [ "", "useBefore", @@ -331,6 +350,7 @@ Array [ "path": "/controller/:id", }, Object { + "basePath": "", "handlers": Array [ "", "useBefore", @@ -348,6 +368,7 @@ Array [ "path": "/controller/:id", }, Object { + "basePath": "", "handlers": Array [ "", "useBefore", @@ -365,6 +386,7 @@ Array [ "path": "/controller/:id", }, Object { + "basePath": "/controller", "handlers": Array [ "[object Object]", ], diff --git a/packages/platform/platform-router/test/routers-nested.integration.spec.ts b/packages/platform/platform-router/test/routers-nested.integration.spec.ts index da55ae55933..7ac0194c760 100644 --- a/packages/platform/platform-router/test/routers-nested.integration.spec.ts +++ b/packages/platform/platform-router/test/routers-nested.integration.spec.ts @@ -32,6 +32,15 @@ export class DomainController { get() {} } +@Controller({ + path: "/platform/:platform", + children: [CommentController] +}) +export class PlatformController { + @Get("/") + get() {} +} + function createAppRouterFixture() { const injector = new InjectorService(); const platformRouters = injector.invoke(PlatformRouters); @@ -41,6 +50,7 @@ function createAppRouterFixture() { injector.addProvider(FlaggedCommentController, {}); injector.addProvider(CommentController, {}); injector.addProvider(DomainController, {}); + injector.addProvider(PlatformController, {}); return {injector, appRouter, platformRouters, platformParams}; } @@ -54,9 +64,8 @@ describe("routers integration", () => { platformRouters.prebuild(); - const router = platformRouters.from(DomainController); - - appRouter.use("/rest", router); + appRouter.use("/rest", platformRouters.from(DomainController)); + appRouter.use("/rest", platformRouters.from(PlatformController)); const layers = platformRouters.getLayers(appRouter); @@ -68,14 +77,27 @@ describe("routers integration", () => { "/rest/domain/:contextID", "/rest/domain/:contextID/comments", "/rest/domain/:contextID/comments/flag", - "/rest/domain/:contextID/comments/:commentID/flag" + "/rest/domain/:contextID/comments/:commentID/flag", + "/rest/platform/:platform", + "/rest/platform/:platform/comments", + "/rest/platform/:platform/comments/flag", + "/rest/platform/:platform/comments/:commentID/flag" ]); expect( layers.map((layer) => { return layer.getBasePath(); }) - ).toEqual(["/rest", "/rest/domain/:contextID", "/rest/domain/:contextID/comments", "/rest/domain/:contextID/comments"]); + ).toEqual([ + "/rest", + "/rest/domain/:contextID", + "/rest/domain/:contextID/comments", + "/rest/domain/:contextID/comments", + "/rest", + "/rest/platform/:platform", + "/rest/platform/:platform/comments", + "/rest/platform/:platform/comments" + ]); }); }); }); diff --git a/packages/platform/platform-router/test/routers.integration.spec.ts b/packages/platform/platform-router/test/routers.integration.spec.ts index d1e8593286b..91babecfc31 100644 --- a/packages/platform/platform-router/test/routers.integration.spec.ts +++ b/packages/platform/platform-router/test/routers.integration.spec.ts @@ -1,4 +1,4 @@ -import {PlatformContext, PlatformHandlerMetadata, PlatformParamsScope, PlatformTest, useResponseHandler} from "@tsed/common"; +import {PlatformContext, PlatformHandlerMetadata, PlatformTest, useResponseHandler} from "@tsed/common"; import {catchError} from "@tsed/core"; import {Controller, InjectorService} from "@tsed/di"; import {UseBefore} from "@tsed/platform-middlewares"; @@ -150,6 +150,7 @@ describe("routers integration", () => { expect(router.inspect()).toEqual([ { + basePath: "/hello", handlers: ["h"], method: "use", opts: {}, @@ -166,6 +167,7 @@ describe("routers integration", () => { expect(appRouter.inspect()).toEqual([ { + basePath: "", handlers: ["h"], method: "get", opts: {}, @@ -182,6 +184,7 @@ describe("routers integration", () => { expect(appRouter.inspect()).toEqual([ { + basePath: "", handlers: ["h"], method: "post", opts: {}, @@ -198,6 +201,7 @@ describe("routers integration", () => { expect(appRouter.inspect()).toEqual([ { + basePath: "", handlers: ["h"], method: "put", opts: {}, @@ -214,6 +218,7 @@ describe("routers integration", () => { expect(appRouter.inspect()).toEqual([ { + basePath: "", handlers: ["h"], method: "patch", opts: {}, @@ -230,6 +235,7 @@ describe("routers integration", () => { expect(appRouter.inspect()).toEqual([ { + basePath: "", handlers: ["h"], method: "head", opts: {}, @@ -246,6 +252,7 @@ describe("routers integration", () => { expect(appRouter.inspect()).toEqual([ { + basePath: "", handlers: ["h"], method: "delete", opts: {}, @@ -262,6 +269,7 @@ describe("routers integration", () => { expect(appRouter.inspect()).toEqual([ { + basePath: "", handlers: ["h"], method: "options", opts: {}, @@ -278,6 +286,7 @@ describe("routers integration", () => { expect(appRouter.inspect()).toEqual([ { + basePath: "", handlers: ["h"], method: "all", opts: {}, @@ -294,6 +303,7 @@ describe("routers integration", () => { expect(appRouter.inspect()).toEqual([ { + basePath: "", handlers: [], method: "statics", opts: { diff --git a/packages/specs/swagger/test/__snapshots__/swagger.nested-controllers.spec.ts.snap b/packages/specs/swagger/test/__snapshots__/swagger.nested-controllers.spec.ts.snap index e411f57c6b2..7bf5c13dd8e 100644 --- a/packages/specs/swagger/test/__snapshots__/swagger.nested-controllers.spec.ts.snap +++ b/packages/specs/swagger/test/__snapshots__/swagger.nested-controllers.spec.ts.snap @@ -108,6 +108,106 @@ Object { ], }, }, + "/rest/platform/{platform}": Object { + "get": Object { + "operationId": "platformControllerGet", + "parameters": Array [ + Object { + "in": "path", + "name": "platform", + "required": true, + "schema": Object { + "type": "string", + }, + }, + ], + "responses": Object { + "200": Object { + "description": "Success", + }, + }, + "tags": Array [ + "PlatformController", + ], + }, + }, + "/rest/platform/{platform}/comments": Object { + "get": Object { + "operationId": "commentControllerGetByPlatform", + "parameters": Array [ + Object { + "in": "path", + "name": "platform", + "required": true, + "schema": Object { + "type": "string", + }, + }, + ], + "responses": Object { + "200": Object { + "description": "Success", + }, + }, + "tags": Array [ + "CommentController", + ], + }, + }, + "/rest/platform/{platform}/comments/flag": Object { + "get": Object { + "operationId": "flaggedCommentControllerListByPlatform", + "parameters": Array [ + Object { + "in": "path", + "name": "platform", + "required": true, + "schema": Object { + "type": "string", + }, + }, + ], + "responses": Object { + "200": Object { + "description": "Success", + }, + }, + "tags": Array [ + "FlaggedCommentController", + ], + }, + }, + "/rest/platform/{platform}/comments/{commentID}/flag": Object { + "post": Object { + "operationId": "flaggedCommentControllerCreateByPlatformCommentId", + "parameters": Array [ + Object { + "in": "path", + "name": "platform", + "required": true, + "schema": Object { + "type": "string", + }, + }, + Object { + "in": "path", + "name": "commentID", + "required": true, + "schema": Object { + "type": "string", + }, + }, + ], + "responses": Object { + "200": Object { + "description": "Success", + }, + }, + "tags": Array [ + "FlaggedCommentController", + ], + }, + }, }, "tags": Array [ Object { @@ -119,6 +219,9 @@ Object { Object { "name": "FlaggedCommentController", }, + Object { + "name": "PlatformController", + }, ], } `; diff --git a/packages/specs/swagger/test/swagger.nested-controllers.spec.ts b/packages/specs/swagger/test/swagger.nested-controllers.spec.ts index 225641b5004..b8791704f65 100644 --- a/packages/specs/swagger/test/swagger.nested-controllers.spec.ts +++ b/packages/specs/swagger/test/swagger.nested-controllers.spec.ts @@ -30,6 +30,15 @@ export class DomainController { get() {} } +@Controller({ + path: "/platform/:platform", + children: [CommentController] +}) +export class PlatformController { + @Get("/") + get() {} +} + describe("Swagger - nested controllers", () => { describe("OpenSpec3", () => { let request: SuperTest.SuperTest; @@ -37,7 +46,7 @@ describe("Swagger - nested controllers", () => { PlatformTest.bootstrap(Server, { platform: PlatformExpress, mount: { - "/rest": [DomainController, CommentController, FlaggedCommentController] + "/rest": [DomainController, CommentController, FlaggedCommentController, PlatformController] } }) );