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

0.7.0 #119

Merged
merged 33 commits into from
May 3, 2017
Merged

0.7.0 #119

Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
5b13b5c
updated dependencies
Apr 5, 2017
b57ed78
refactored decorators moved each into its own file
Apr 5, 2017
59b821b
moved deprecated decorators into their own directory
Apr 5, 2017
d8303d3
added deprecations in RoutingControllersOptions
Apr 5, 2017
08df531
refactored all decorators usage
Apr 6, 2017
f8f559f
refactored parameter options
Apr 6, 2017
76aba03
refactored decorators
Apr 6, 2017
c67a6ac
fixed wrong test
Apr 6, 2017
8c659ab
added new decorators
Apr 6, 2017
9840157
removed @EmptyResultCode decorator
Apr 6, 2017
36dbc51
remove interceptor functionality
Apr 6, 2017
b226073
removed deprecated decorators
Apr 7, 2017
41d575d
moved json controller back to non-deprecated decorators :(
Apr 7, 2017
9b279da
remove string casting to fix issues with buffer returning
Apr 7, 2017
4ac2766
fixed some decorators plus some refactoring
Apr 7, 2017
8e4e617
refactored RoutingControllers class
Apr 7, 2017
b7591b2
refactored action options object
Apr 7, 2017
0e84913
refactored action parameters stuff
Apr 7, 2017
460b8f2
refactored ActionParameterHandler
Apr 20, 2017
45e6c7f
refactored action metadata + beatifying all other classes
Apr 21, 2017
906fe8d
decorators and drivers refactoring
Apr 24, 2017
15c45d6
refactored named and non-named based parameters hydration
Apr 24, 2017
eaf9b39
implemented #75 - support for custom parameters decorators
Apr 24, 2017
308ade7
added custom authorized and current user decorators support
Apr 24, 2017
8552369
added context decorator for koa
Apr 25, 2017
9bb2008
small fixes; added more docs
Apr 26, 2017
f3b931d
exported metadata args storage; version bump
Apr 26, 2017
17cf0e8
added extra release note
Apr 26, 2017
c9e28df
added role checker support; fixed bug with validation and class trans…
Apr 28, 2017
c263928
implemented global metadata args storage
Apr 28, 2017
f5c5642
Update auto-validation Readme paragraph + typo
MichalLytek Apr 30, 2017
7831c64
added authorized support for controllers, added api for model control…
May 3, 2017
38de552
Merge pull request #126 from 19majkel94/patch-3
pleerock May 3, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
103 changes: 7 additions & 96 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,7 @@ You can use routing-controllers with [express.js][1] or [koa.js][2].
+ [Creating your own koa middleware](#creating-your-own-koa-middleware)
+ [Global middlewares](#global-middlewares)
+ [Error handlers](#error-handlers)
* [Using interceptors](#using-interceptors)
+ [Interceptor function](#interceptor-function)
+ [Interceptor classes](#interceptor-classes)
+ [Global interceptors](#global-interceptors)
+ [Don't forget to load your middlewares, error handlers and interceptors](#dont-forget-to-load-your-middlewares-error-handlers-and-interceptors)
+ [Don't forget to load your middlewares and error handlers](#dont-forget-to-load-your-middlewares-and-error-handlers)
* [Creating instances of classes from action params](#creating-instances-of-classes-from-action-params)
* [Auto validating action params](#auto-validating-action-params)
* [Default error handling](#default-error-handling)
Expand All @@ -58,7 +54,7 @@ You can use routing-controllers with [express.js][1] or [koa.js][2].
- [Controller Decorators](#controller-decorators)
- [Controller Method Decorators](#controller-method-decorators)
- [Method Parameter Decorators](#method-parameter-decorators)
- [Middleware and Interceptor Decorators](#middleware-and-interceptor-decorators)
- [Middleware Decorators](#middleware-decorators)
- [Other Decorators](#other-decorators)
* [Samples](#samples)
* [Release notes](#release-notes)
Expand Down Expand Up @@ -552,7 +548,7 @@ saveUser(@Param("id") id: number) {
In this example `findOneById` returns undefined in the case if user with given was not found.
This action will return 404 in the case if user was not found, and regular 200 in the case if it was found.
`@EmptyResultCode` allows to set any HTTP code in the case if controller's action returned empty result (null or undefined).
There are also `@NullResultCode` and `@UndefindeResultCode()` in the case if you want to return specific codes only
There are also `@OnNull` and `@UndefindeResultCode()` in the case if you want to return specific codes only
if controller's action returned null or undefined respectively.

#### Set custom headers
Expand Down Expand Up @@ -824,86 +820,7 @@ createExpressServer({
}).listen(3000);
```

## Using interceptors

Interceptors are used to change or replace the data returned to the client.
You can create your own interceptor class or function and use to all or specific controller or controller action.
It works pretty much the same as middlewares.

### Interceptor function

The easiest way is to use functions directly passed to `@UseInterceptor` of the action.

```typescript
import {Get, Param, UseInterceptor} from "routing-controllers";

// ...

@Get("/users")
@UseInterceptor(function(request: any, response: any, content: any) {
// here you have content returned by this action. you can replace something
// in it and return a replaced result. replaced result will be returned to the user
return content.replace(/Mike/gi, "Michael");
})
getOne(@Param("id") id: number) {
return "Hello, I am Mike!"; // client will get a "Hello, I am Michael!" response.
}
```

You can use `@UseInterceptor` per-action, on per-controller.
If its used per-controller then interceptor will apply to all controller actions.

### Interceptor classes

You can also create a class and use it with `@UseInterceptor` decorator:

```typescript
import {Interceptor, InterceptorInterface} from "routing-controllers";

@Interceptor()
export class NameCorrectionInterceptor implements InterceptorInterface {

intercept(request: any, response: any, content: any) {
return content.replace(/Mike/gi, "Michael");
}

}
```

And use it in your controllers this way:

```typescript
import {Get, Param, UseInterceptor} from "routing-controllers";
import {NameCorrectionInterceptor} from "./NameCorrectionInterceptor";

// ...

@Get("/users")
@UseInterceptor(NameCorrectionInterceptor)
getOne(@Param("id") id: number) {
return "Hello, I am Mike!"; // client will get a "Hello, I am Michael!" response.
}
```

### Global interceptors

You can create interceptors that will affect all controllers in your project by creating interceptor class
and mark it with `@InterceptorGlobal` decorator:

```typescript
import {InterceptorGlobal, InterceptorInterface} from "routing-controllers";

@InterceptorGlobal()
export class NameCorrectionInterceptor implements InterceptorInterface {

intercept(request: any, response: any, content: any) {
return content.replace(/Mike/gi, "Michael");
}

}
```

### Don't forget to load your middlewares, error handlers and interceptors
### Don't forget to load your middlewares and error handlers

Middlewares and error handlers should be loaded globally the same way as controllers, before app bootstrap:

Expand All @@ -913,7 +830,6 @@ import {createExpressServer} from "routing-controllers";
import "./UserController";
import "./MyMiddleware"; // here we load it
import "./CustomErrorHandler"; // here we load it
import "./BadWordInterceptor"; // here we load it
let app = createExpressServer();
app.listen(3000);
```
Expand Down Expand Up @@ -1052,7 +968,6 @@ useContainer(Container);
createExpressServer({
controllers: [__dirname + "/controllers/*.js"],
middlewares: [__dirname + "/middlewares/*.js"],
interceptors: [__dirname + "/interceptor/*.js"],
}).listen(3000);
```

Expand Down Expand Up @@ -1111,7 +1026,7 @@ export class UsersController {
| `@BodyParam(name: string, options?: ParamOptions)` | `post(@BodyParam("name") name: string)` | Injects a body parameter to a controller action parameter value. In options you can specify if parameter should be parsed into a json object or not. Also you can specify there if body parameter is required and action cannot work with empty parameter. | `request.body.name` |
| `@CookieParam(name: string, options?: ParamOptions)` | `get(@CookieParam("username") username: string)` | Injects a cookie parameter to a controller action parameter value. In options you can specify if parameter should be parsed into a json object or not. Also you can specify there if cookie parameter is required and action cannot work with empty parameter. | `request.cookie("username")` |

#### Middleware and Interceptor Decorators
#### Middleware Decorators

| Signature | Example | Description |
|--------------------------------------------------------------------|--------------------------------------------------|-----------------------------------------------------------------------------------------------------------------|
Expand All @@ -1121,9 +1036,6 @@ export class UsersController {
| `@ErrorHandler()` | `@ErrorHandler() class SomeErrorHandler` | Registers a new error handler. |
| `@UseBefore()` | `@UseBefore(CompressionMiddleware)` | Uses given middleware before action is being executed. |
| `@UseAfter()` | `@UseAfter(CompressionMiddleware)` | Uses given middleware after action is being executed. |
| `@Interceptor()` | `@Interceptor(InterceptorMiddleware)` | Registers a given class as an interceptor |
| `@InterceptorGlobal()` | `@InterceptorGlobal(InterceptorMiddleware)` | Registers a global interceptor. |
| `@UseInterceptor()` | `@UseInterceptor(InterceptorMiddleware)` | Uses given interceptor for the given action or controller. |

#### Other Decorators

Expand All @@ -1132,9 +1044,8 @@ export class UsersController {
| `@JsonResponse()` | `@JsonResponse()` get() | Controller actions marked with this decorator will return a json response instead of default text/html. |
| `@TextResponse()` | `@TextResponse()` get() | Controller actions marked with this decorator will return a text/html response instead of default json. |
| `@HttpCode(code: number)` | `@HttpCode(201)` post() | Allows to explicitly set HTTP code to be returned in the response. |
| `@EmptyResultCode(code: number)` | `@EmptyResultCode(201)` post() | Sets a given HTTP code when controller action returned empty result (null or undefined). |
| `@NullResultCode(code: number)` | `@NullResultCode(201)` post() | Sets a given HTTP code when controller action returned null. |
| `@UndefinedResultCode(code: number)` | `@UndefinedResultCode(201)` post() | Sets a given HTTP code when controller action returned undefined. |
| `@OnNull(code: number)` | `@OnNull(201)` post() | Sets a given HTTP code when controller action returned null. |
| `@OnUndefined(code: number)` | `@OnUndefined(201)` post() | Sets a given HTTP code when controller action returned undefined. |
| `@ResponseClassTransformOptions(options: ClassTransformOptions)` | `@ResponseClassTransformOptions({/*...*/})` get() | Sets options to be passed to class-transformer when it used for classToPlain a response result. |
| `@ContentType(contentType: string)` | `@ContentType("text/csv")` get() | Allows to explicitly set HTTP Content-type returned in the response. |
| `@Header(contentType: string)` | `@Header("Cache-Control", "private")` get() | Allows to explicitly set any HTTP Header returned in the response. |
Expand Down
1 change: 0 additions & 1 deletion gulpfile.js

This file was deleted.

5 changes: 2 additions & 3 deletions gulpfile.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import "es6-shim";
import {Gulpclass, Task, SequenceTask, MergedTask} from "gulpclass";

const gulp = require("gulp");
Expand Down Expand Up @@ -169,8 +168,8 @@ export class Gulpfile {
@Task("coveragePost", ["coveragePre"])
coveragePost() {
chai.should();
chai.use(require("sinon-chai"));
chai.use(require("chai-as-promised"));
// chai.use(require("sinon-chai"));
// chai.use(require("chai-as-promised"));

return gulp.src(["./build/es5/test/functional/**/*.js"])
.pipe(mocha())
Expand Down
62 changes: 31 additions & 31 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,57 +27,57 @@
"controllers"
],
"dependencies": {
"class-transformer": "~0.1.3",
"class-validator": "^0.6.8",
"class-transformer": "~0.1.6",
"class-validator": "^0.7.0",
"cookie": "^0.3.1",
"glob": "^7.0.5",
"reflect-metadata": "^0.1.3"
"reflect-metadata": "^0.1.10"
},
"devDependencies": {
"@types/chai": "^3.4.34",
"@types/chai-as-promised": "0.0.29",
"@types/express": "^4.0.34",
"@types/chai": "^3.4.35",
"@types/chai-as-promised": "0.0.30",
"@types/express": "^4.0.35",
"@types/express-session": "0.0.32",
"@types/koa": "^2.0.37",
"@types/mocha": "^2.2.37",
"@types/node": "^7.0.0",
"@types/sinon": "^1.16.34",
"body-parser": "^1.15.2",
"@types/koa": "^2.0.39",
"@types/mocha": "^2.2.40",
"@types/node": "^7.0.12",
"@types/sinon": "^2.1.2",
"body-parser": "^1.17.1",
"chai": "^3.4.1",
"chai-as-promised": "^6.0.0",
"chakram": "^1.4.0",
"del": "^2.2.1",
"es6-shim": "^0.35.1",
"express": "^4.14.0",
"express-session": "^1.14.1",
"express": "^4.15.2",
"express-session": "^1.15.2",
"gulp": "^3.9.1",
"gulp-istanbul": "^1.0.0",
"gulp-mocha": "^3.0.1",
"gulp-replace": "^0.5.4",
"gulp-shell": "^0.5.0",
"gulp-sourcemaps": "^2.4.0",
"gulp-tslint": "^7.0.1",
"gulp-typescript": "^3.1.4",
"gulpclass": "^0.1.1",
"gulp-shell": "^0.6.3",
"gulp-sourcemaps": "^2.5.1",
"gulp-tslint": "^7.1.0",
"gulp-typescript": "^3.1.6",
"gulpclass": "^0.1.2",
"handlebars": "^4.0.6",
"koa": "^2.0.0",
"koa-bodyparser": "^3.1.0",
"koa-bodyparser": "^4.2.0",
"koa-convert": "^1.2.0",
"koa-multer": "^1.0.1",
"koa-router": "^7.0.1",
"koa-session": "^3.4.0",
"koa-views": "^5.2.0",
"koa-router": "^7.1.1",
"koa-session": "^5.0.0",
"koa-views": "^6.0.1",
"mocha": "^3.0.0",
"multer": "^1.1.0",
"multer": "^1.3.0",
"mustache-express": "^1.2.2",
"remap-istanbul": "^0.8.4",
"request": "^2.74.0",
"sinon": "^1.17.4",
"sinon-chai": "^2.8.0",
"tslint": "^4.3.1",
"tslint-stylish": "^2.1.0-beta",
"remap-istanbul": "^0.9.5",
"request": "^2.81.0",
"sinon": "^2.1.0",
"sinon-chai": "^2.9.0",
"ts-node": "^3.0.2",
"tslint": "^5.0.0",
"tslint-stylish": "^2.1.0",
"typedi": "^0.4.2",
"typescript": "^2.1.5"
"typescript": "^2.2.2"
},
"scripts": {
"test": "gulp tests"
Expand Down
14 changes: 9 additions & 5 deletions sample/sample1-simple-controller/UserController.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import "reflect-metadata";
import {Request} from "express";
import {Controller} from "../../src/decorator/controllers";
import {Get, Post, Put, Patch, Delete} from "../../src/decorator/methods";
import {Req} from "../../src/decorator/params";
import {JsonResponse} from "../../src/decorator/decorators";
import {Controller} from "../../src/decorator/Controller";
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";
import {ContentType} from "../../src/decorator/ContentType";

@Controller()
export class UserController {

@Get("/users")
@JsonResponse()
@ContentType("application/json")
getAll() {
return [
{ id: 1, name: "First user!" },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import {Request} from "express";
import {JsonController} from "../../../../../src/decorator/controllers";
import {Get, Post, Put, Patch, Delete} from "../../../../../src/decorator/methods";
import {Req} from "../../../../../src/decorator/params";
import {JsonController} from "../../../../../src/decorator/JsonController";
import {Get} from "../../../../../src/decorator/Get";
import {Post} from "../../../../../src/decorator/Post";
import {Req} from "../../../../../src/decorator/Req";
import {Put} from "../../../../../src/decorator/Put";
import {Patch} from "../../../../../src/decorator/Patch";
import {Delete} from "../../../../../src/decorator/Delete";

@JsonController()
export class BlogController {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {MiddlewareGlobalAfter} from "../../../../../src/decorator/decorators";
import {ErrorMiddlewareInterface} from "../../../../../src/middleware/ErrorMiddlewareInterface";
import {Middleware} from "../../../../../src/decorator/Middleware";

@MiddlewareGlobalAfter()
@Middleware({ global: true, type: "after" })
export class BlogErrorHandler implements ErrorMiddlewareInterface {

error(error: any, request: any, response: any, next?: Function): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {MiddlewareInterface} from "../../../../../src/middleware/MiddlewareInterface";
import {Middleware} from "../../../../../src/decorator/decorators";
import {Middleware} from "../../../../../src/decorator/Middleware";

@Middleware()
export class BlogMiddleware implements MiddlewareInterface {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import {Request} from "express";
import {JsonController} from "../../../../../src/decorator/controllers";
import {Get, Post, Put, Patch, Delete} from "../../../../../src/decorator/methods";
import {Req} from "../../../../../src/decorator/params";
import {JsonController} from "../../../../../src/decorator/JsonController";
import {Get} from "../../../../../src/decorator/Get";
import {Post} from "../../../../../src/decorator/Post";
import {Put} from "../../../../../src/decorator/Put";
import {Req} from "../../../../../src/decorator/Req";
import {Patch} from "../../../../../src/decorator/Patch";
import {Delete} from "../../../../../src/decorator/Delete";

@JsonController()
export class PostController {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {MiddlewareGlobalAfter} from "../../../../../src/decorator/decorators";
import {ErrorMiddlewareInterface} from "../../../../../src/middleware/ErrorMiddlewareInterface";
import {Middleware} from "../../../../../src/decorator/Middleware";

@MiddlewareGlobalAfter()
@Middleware({ global: true, type: "after" })
export class PostErrorHandler implements ErrorMiddlewareInterface {

error(error: any, request: any, response: any, next?: Function): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {MiddlewareInterface} from "../../../../../src/middleware/MiddlewareInterface";
import {Middleware} from "../../../../../src/decorator/decorators";
import {Middleware} from "../../../../../src/decorator/Middleware";

@Middleware()
export class PostMiddleware implements MiddlewareInterface {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import {Request} from "express";
import {JsonController} from "../../../../../src/decorator/controllers";
import {Get, Post, Put, Patch, Delete} from "../../../../../src/decorator/methods";
import {Req, Param} from "../../../../../src/decorator/params";
import {JsonController} from "../../../../../src/decorator/JsonController";
import {Get} from "../../../../../src/decorator/Get";
import {Param} from "../../../../../src/decorator/Param";
import {Post} from "../../../../../src/decorator/Post";
import {Req} from "../../../../../src/decorator/Req";
import {Put} from "../../../../../src/decorator/Put";
import {Patch} from "../../../../../src/decorator/Patch";
import {Delete} from "../../../../../src/decorator/Delete";

@JsonController()
export class QuestionController {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {MiddlewareGlobalAfter} from "../../../../../src/decorator/decorators";
import {ErrorMiddlewareInterface} from "../../../../../src/middleware/ErrorMiddlewareInterface";
import {Middleware} from "../../../../../src/decorator/Middleware";

@MiddlewareGlobalAfter()
@Middleware({ global: true, type: "after" })
export class QuestionErrorHandler implements ErrorMiddlewareInterface {

error(error: any, request: any, response: any, next?: Function): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {MiddlewareInterface} from "../../../../../src/middleware/MiddlewareInterface";
import {Middleware} from "../../../../../src/decorator/decorators";
import {Middleware} from "../../../../../src/decorator/Middleware";

@Middleware()
export class QuestionMiddleware implements MiddlewareInterface {
Expand Down