diff --git a/sample/sample17-controllers-inheritance/app.ts b/sample/sample17-controllers-inheritance/app.ts new file mode 100644 index 00000000..cb75afc4 --- /dev/null +++ b/sample/sample17-controllers-inheritance/app.ts @@ -0,0 +1,11 @@ +import "reflect-metadata"; +import * as express from "express"; +import {useExpressServer} from "../../src/index"; + +let app = express(); // create express server +useExpressServer(app, { + controllers: [__dirname + "/controllers/*{.js,.ts}"] // register controllers routes in our express app +}); +app.listen(3001); // run express app + +console.log("Express server is running on port 3001. Open http://localhost:3001/blogs/ or http://localhost:3002/posts/"); \ No newline at end of file diff --git a/sample/sample17-controllers-inheritance/controllers/BaseController.ts b/sample/sample17-controllers-inheritance/controllers/BaseController.ts new file mode 100644 index 00000000..158d15e1 --- /dev/null +++ b/sample/sample17-controllers-inheritance/controllers/BaseController.ts @@ -0,0 +1,56 @@ +import {Request} from "express"; +import {Get} from "../../../src/decorator/Get"; +import {Req} from "../../../src/index"; +import {Post} from "../../../src/decorator/Post"; +import {Put} from "../../../src/decorator/Put"; +import {Patch} from "../../../src/decorator/Patch"; +import {Delete} from "../../../src/decorator/Delete"; + +export class BaseControllerClass { + name: string; + constructor(name: string) { + this.name = name; + } + + @Get() + getAll() { + return [ + {id: 1, name: `First ${this.name}!`}, + {id: 2, name: `Second ${this.name}!`} + ]; + } + + @Get("/:id") + getOne() { + return {id: 1, name: `First ${this.name}!`}; + } + + @Post("") + post(@Req() request: Request) { + let entity = JSON.stringify(request.body); + return `${this.name} ${entity} !saved!`; + } + + @Put("/:id") + put(@Req() request: Request) { + return `${this.name} # ${request.params.id} has been putted!`; + } + + @Patch("/:id") + patch(@Req() request: Request) { + return `${this.name} # ${request.params.id} has been patched!`; + } + + @Delete("/:id") + remove(@Req() request: Request) { + return `${this.name} # ${request.params.id} has been removed!`; + } +} + +export function BaseController(name: string): { new(): BaseControllerClass } { + return class extends BaseControllerClass { + constructor() { + super(name); + } + }; +} \ No newline at end of file diff --git a/sample/sample17-controllers-inheritance/controllers/BlogController.ts b/sample/sample17-controllers-inheritance/controllers/BlogController.ts new file mode 100644 index 00000000..a63b4184 --- /dev/null +++ b/sample/sample17-controllers-inheritance/controllers/BlogController.ts @@ -0,0 +1,19 @@ +import {JsonController} from "../../../src/decorator/JsonController"; +import {BaseController, BaseControllerClass} from "./BaseController"; +import {Get} from "../../../src/decorator/Get"; + +@JsonController("/blogs") +export class BlogController extends BaseController("blog") { + constructor() { + super(); + } + + @Get() + getAll() { + return [ + {id: 1, name: `First ${this.name}!`}, + {id: 2, name: `Second ${this.name}!`}, + {id: 3, name: `Third ${this.name}!`} + ]; + } +} \ No newline at end of file diff --git a/sample/sample17-controllers-inheritance/controllers/PostController.ts b/sample/sample17-controllers-inheritance/controllers/PostController.ts new file mode 100644 index 00000000..24929e48 --- /dev/null +++ b/sample/sample17-controllers-inheritance/controllers/PostController.ts @@ -0,0 +1,5 @@ +import {JsonController} from "../../../src/decorator/JsonController"; +import {BaseController, BaseControllerClass} from "./BaseController"; + +@JsonController("/posts") +export class PostController extends BaseController("post") {} \ No newline at end of file diff --git a/src/metadata-builder/MetadataBuilder.ts b/src/metadata-builder/MetadataBuilder.ts index 25414fb8..e5fa5107 100644 --- a/src/metadata-builder/MetadataBuilder.ts +++ b/src/metadata-builder/MetadataBuilder.ts @@ -8,6 +8,7 @@ import {ResponseHandlerMetadata} from "../metadata/ResponseHandleMetadata"; import { RoutingControllersOptions } from "../RoutingControllersOptions"; import {UseMetadata} from "../metadata/UseMetadata"; import {getMetadataArgsStorage} from "../index"; +import {ActionMetadataArgs} from "../metadata/args/ActionMetadataArgs"; /** * Builds metadata from the given metadata arguments. @@ -84,8 +85,21 @@ export class MetadataBuilder { * Creates action metadatas. */ protected createActions(controller: ControllerMetadata): ActionMetadata[] { - return getMetadataArgsStorage() - .filterActionsWithTarget(controller.target) + let target = controller.target; + let actionsWithTarget: ActionMetadataArgs[] = []; + while (target) { + actionsWithTarget.push( + ...getMetadataArgsStorage() + .filterActionsWithTarget(target) + .filter(action => { + return actionsWithTarget + .map(a => a.method) + .indexOf(action.method) === -1; + }) + ); + target = Object.getPrototypeOf(target); + } + return actionsWithTarget .map(actionArgs => { const action = new ActionMetadata(controller, actionArgs, this.options); action.params = this.createParams(action);