Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename all decorators to lowercase #55

Merged
merged 1 commit into from
Jul 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,32 @@ Please refer to the [InversifyJS documentation](https://github.com/inversify/Inv
## The Basics

### Step 1: Decorate your controllers
To use a class as a "controller" for your express app, simply add the `@Controller` decorator to the class. Similarly, decorate methods of the class to serve as request handlers.
To use a class as a "controller" for your express app, simply add the `@controller` decorator to the class. Similarly, decorate methods of the class to serve as request handlers.
The following example will declare a controller that responds to `GET /foo'.

```ts
import * as express from 'express';
import { interfaces, Controller, Get, Post, Delete } from 'inversify-express-utils';
import { injectable, inject } from 'inversify';

@Controller('/foo')
@controller('/foo')
@injectable()
export class FooController implements interfaces.Controller {

constructor( @inject('FooService') private fooService: FooService ) {}

@Get('/')
@httpGet('/')
private index(req: express.Request, res: express.Response, next: express.NextFunction): string {
return this.fooService.get(req.query.id);
}

@Get('/')
private list(@QueryParams('start') start: number, @QueryParams('count') cound: number): string {
@httpGet('/')
private list(@queryParams('start') start: number, @queryParams('count') cound: number): string {
return this.fooService.get(start, count);
}

@Post('/')
private async create(@Response() res: express.Response) {
@httpPost('/')
private async create(@response() res: express.Response) {
try {
await this.fooService.create(req.body)
res.sendStatus(201)
Expand All @@ -61,8 +61,8 @@ export class FooController implements interfaces.Controller {
}
}

@Delete('/:id')
private delete(@RequestParam("id") id: string, @Response() res: express.Response): Promise<void> {
@httpDelete('/:id')
private delete(@requestParam("id") id: string, @response() res: express.Response): Promise<void> {
return this.fooService.delete(id)
.then(() => res.sendStatus(204))
.catch((err) => {
Expand Down Expand Up @@ -181,40 +181,40 @@ let server = new InversifyExpressServer(container, null, null, app);

## Decorators

### `@Controller(path, [middleware, ...])`
### `@controller(path, [middleware, ...])`

Registers the decorated class as a controller with a root path, and optionally registers any global middleware for this controller.

### `@Method(method, path, [middleware, ...])`
### `@httpMethod(method, path, [middleware, ...])`

Registers the decorated controller method as a request handler for a particular path and method, where the method name is a valid express routing method.

### `@SHORTCUT(path, [middleware, ...])`

Shortcut decorators which are simply wrappers for `@Method`. Right now these include `@Get`, `@Post`, `@Put`, `@Patch`, `@Head`, `@Delete`, and `@All`. For anything more obscure, use `@Method` (Or make a PR :smile:).
Shortcut decorators which are simply wrappers for `@httpMethod`. Right now these include `@httpGet`, `@httpPost`, `@httpPut`, `@httpPatch`, `@httpHead`, `@httpDelete`, and `@All`. For anything more obscure, use `@httpMethod` (Or make a PR :smile:).

### `@Request()`
### `@request()`
Binds a method parameter to the request object.

### `@Response()`
### `@response()`
Binds a method parameter to the response object.

### `@RequestParam(name?: string)`
### `@requestParam(name?: string)`
Binds a method parameter to request.params object or to a specific parameter if a name is passed.

### `@QueryParam(name?: string)`
### `@queryParam(name?: string)`
Binds a method parameter to request.query or to a specific query parameter if a name is passed.

### `@RequestBody(name?: string)`
### `@requestBody(name?: string)`
Binds a method parameter to request.body or to a specific body property if a name is passed.

### `@RequestHeaders(name?: string)`
### `@requestHeaders(name?: string)`
Binds a method parameter to the request headers.

### `@Cookies()`
### `@cookies()`
Binds a method parameter to the request cookies.

### `@Next()`
### `@next()`
Binds a method parameter to the next() function.

## Examples
Expand Down
52 changes: 26 additions & 26 deletions src/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,42 @@ import * as express from "express";
import { interfaces } from "./interfaces";
import { METADATA_KEY, PARAMETER_TYPE } from "./constants";

export function Controller(path: string, ...middleware: interfaces.Middleware[]) {
export function controller(path: string, ...middleware: interfaces.Middleware[]) {
return function (target: any) {
let metadata: interfaces.ControllerMetadata = {path, middleware, target};
Reflect.defineMetadata(METADATA_KEY.controller, metadata, target);
};
}

export function All (path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return Method("all", path, ...middleware);
export function all (path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return httpMethod("all", path, ...middleware);
}

export function Get (path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return Method("get", path, ...middleware);
export function httpGet (path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return httpMethod("get", path, ...middleware);
}

export function Post (path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return Method("post", path, ...middleware);
export function httpPost (path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return httpMethod("post", path, ...middleware);
}

export function Put (path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return Method("put", path, ...middleware);
export function httpPut (path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return httpMethod("put", path, ...middleware);
}

export function Patch (path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return Method("patch", path, ...middleware);
export function httpPatch (path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return httpMethod("patch", path, ...middleware);
}

export function Head (path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return Method("head", path, ...middleware);
export function httpHead (path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return httpMethod("head", path, ...middleware);
}

export function Delete(path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return Method("delete", path, ...middleware);
export function httpDelete(path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return httpMethod("delete", path, ...middleware);
}

export function Method(method: string, path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
export function httpMethod(method: string, path: string, ...middleware: interfaces.Middleware[]): interfaces.HandlerDecorator {
return function (target: any, key: string, value: any) {
let metadata: interfaces.ControllerMethodMetadata = {path, middleware, method, target, key};
let metadataList: interfaces.ControllerMethodMetadata[] = [];
Expand All @@ -52,23 +52,23 @@ export function Method(method: string, path: string, ...middleware: interfaces.M
};
}

export const Request = paramDecoratorFactory(PARAMETER_TYPE.REQUEST);
export const Response = paramDecoratorFactory(PARAMETER_TYPE.RESPONSE);
export const RequestParam = paramDecoratorFactory(PARAMETER_TYPE.PARAMS);
export const QueryParam = paramDecoratorFactory(PARAMETER_TYPE.QUERY);
export const RequestBody = paramDecoratorFactory(PARAMETER_TYPE.BODY);
export const RequestHeaders = paramDecoratorFactory(PARAMETER_TYPE.HEADERS);
export const Cookies = paramDecoratorFactory(PARAMETER_TYPE.COOKIES);
export const Next = paramDecoratorFactory(PARAMETER_TYPE.NEXT);
export const request = paramDecoratorFactory(PARAMETER_TYPE.REQUEST);
export const response = paramDecoratorFactory(PARAMETER_TYPE.RESPONSE);
export const requestParam = paramDecoratorFactory(PARAMETER_TYPE.PARAMS);
export const queryParam = paramDecoratorFactory(PARAMETER_TYPE.QUERY);
export const requestBody = paramDecoratorFactory(PARAMETER_TYPE.BODY);
export const requestHeaders = paramDecoratorFactory(PARAMETER_TYPE.HEADERS);
export const cookies = paramDecoratorFactory(PARAMETER_TYPE.COOKIES);
export const next = paramDecoratorFactory(PARAMETER_TYPE.NEXT);

function paramDecoratorFactory(parameterType: PARAMETER_TYPE): (name?: string) => ParameterDecorator {
return function (name?: string): ParameterDecorator {
name = name || "default";
return Params(parameterType, name);
return params(parameterType, name);
};
}

export function Params(type: PARAMETER_TYPE, parameterName: string) {
export function params(type: PARAMETER_TYPE, parameterName: string) {
return function (target: Object, methodName: string, index: number) {

let metadataList: interfaces.ControllerParameterMetadata = {};
Expand Down
40 changes: 20 additions & 20 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import { InversifyExpressServer } from "./server";
import { Controller, Method, Get, Put, Post, Patch, Head, All, Delete,
Request, Response, RequestParam, QueryParam, RequestBody, RequestHeaders,
Cookies, Next } from "./decorators";
import { controller, httpMethod, httpGet, httpPut, httpPost, httpPatch,
httpHead, all, httpDelete, request, response, requestParam, queryParam,
requestBody, requestHeaders, cookies, next } from "./decorators";
import { TYPE } from "./constants";
import { interfaces } from "./interfaces";

export {
interfaces,
InversifyExpressServer,
Controller,
Method,
Get,
Put,
Post,
Patch,
Head,
All,
Delete,
controller,
httpMethod,
httpGet,
httpPut,
httpPost,
httpPatch,
httpHead,
all,
httpDelete,
TYPE,
Request,
Response,
RequestParam,
QueryParam,
RequestBody,
RequestHeaders,
Cookies,
Next
request,
response,
requestParam,
queryParam,
requestBody,
requestHeaders,
cookies,
next
};
81 changes: 41 additions & 40 deletions test/bugs.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { expect } from "chai";
import * as express from "express";
import { Controller, Method, Get, Request, Response, RequestParam, QueryParam } from "../src/decorators";
import { controller, httpMethod, httpGet, request, response, requestParam,
queryParam } from "../src/decorators";
import { interfaces } from "../src/interfaces";
import { METADATA_KEY, PARAMETER_TYPE } from "../src/constants";
import { InversifyExpressServer } from "../src/server";
import { Container, injectable } from "inversify";
import { TYPE } from "../src/constants";
import * as request from "supertest";
import * as supertest from "supertest";

describe("Unit Test: Previous bugs", () => {

Expand All @@ -15,24 +16,24 @@ describe("Unit Test: Previous bugs", () => {
let container = new Container();

@injectable()
@Controller("/api/test")
@controller("/api/test")
class TestController {
@Get("/")
@httpGet("/")
public get(
@Request() req: express.Request,
@Response() res: express.Response
@request() req: express.Request,
@response() res: express.Response
) {
expect(req.url).not.to.eql(undefined);
expect((req as any).setHeader).to.eql(undefined);
expect(res.setHeader).not.to.eql(undefined);
expect((res as any).url).to.eql(undefined);
res.json([{ id: 1 }, { id: 2 }]);
}
@Get("/:id")
@httpGet("/:id")
public getById(
@RequestParam("id") id: string,
@Request() req: express.Request,
@Response() res: express.Response
@requestParam("id") id: string,
@request() req: express.Request,
@response() res: express.Response
) {
expect(id).to.eql("5");
expect(req.url).not.to.eql(undefined);
Expand All @@ -47,37 +48,37 @@ describe("Unit Test: Previous bugs", () => {
let server = new InversifyExpressServer(container);
let app = server.build();

request(app).get("/api/test/")
.expect("Content-Type", /json/)
.expect(200)
.then(response1 => {
expect(Array.isArray(response1.body)).to.eql(true);
expect(response1.body[0].id).to.eql("1");
expect(response1.body[0].id).to.eql("2");
});
supertest(app).get("/api/test/")
.expect("Content-Type", /json/)
.expect(200)
.then(response1 => {
expect(Array.isArray(response1.body)).to.eql(true);
expect(response1.body[0].id).to.eql("1");
expect(response1.body[0].id).to.eql("2");
});

request(app).get("/api/test/5")
.expect("Content-Type", /json/)
.expect(200)
.then(response2 => {
expect(Array.isArray(response2.body)).to.eql(false);
expect(response2.body.id).to.eql("5");
done();
});
supertest(app).get("/api/test/5")
.expect("Content-Type", /json/)
.expect(200)
.then(response2 => {
expect(Array.isArray(response2.body)).to.eql(false);
expect(response2.body.id).to.eql("5");
done();
});

});
it("should support empty query params", (done) => {
let container = new Container();

@injectable()
@Controller("/api/test")
@controller("/api/test")
class TestController {
@Get("/")
@httpGet("/")
public get(
@Request() req: express.Request,
@Response() res: express.Response,
@QueryParam("empty") empty: string,
@QueryParam("test") test: string
@request() req: express.Request,
@response() res: express.Response,
@queryParam("empty") empty: string,
@queryParam("test") test: string
) {
return {empty: empty, test: test};
}
Expand All @@ -88,14 +89,14 @@ describe("Unit Test: Previous bugs", () => {
let server = new InversifyExpressServer(container);
let app = server.build();

request(app).get("/api/test?test=testquery")
.expect("Content-Type", /json/)
.expect(200)
.then(response1 => {
expect(response1.body.test).to.eql("testquery");
expect(response1.body.empty).to.be.undefined;
done();
});
supertest(app).get("/api/test?test=testquery")
.expect("Content-Type", /json/)
.expect(200)
.then(response1 => {
expect(response1.body.test).to.eql("testquery");
expect(response1.body.empty).to.be.undefined;
done();
});

});

Expand Down
Loading