Skip to content

Commit cd26ae1

Browse files
committed
Merge branch 'master' of https://github.com/epiphone/routing-controllers into epiphone-master
2 parents 09a6d6a + 19a931a commit cd26ae1

24 files changed

+408
-98
lines changed

README.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ You can use routing-controllers with [express.js][1] or [koa.js][2].
4242
- [Throw HTTP errors](#throw-http-errors)
4343
- [Enable CORS](#enable-cors)
4444
- [Default settings](#default-settings)
45+
- [Selectively disabling request/response transform](#selectively-disable-requestresponse-transforming)
4546
* [Using middlewares](#using-middlewares)
4647
+ [Use exist middleware](#use-exist-middleware)
4748
+ [Creating your own express middleware](#creating-your-own-express-middleware)
@@ -733,7 +734,7 @@ There are set of prepared errors you can use:
733734
* UnauthorizedError
734735

735736

736-
You can also create and use your own errors by extending `HttpError` class.
737+
You can also create and use your own errors by extending `HttpError` class.
737738
To define the data returned to the client, you could define a toJSON method in your error.
738739

739740
```typescript
@@ -755,7 +756,7 @@ class DbError extends HttpError {
755756
}
756757
}
757758
}
758-
```
759+
```
759760

760761
#### Enable CORS
761762

@@ -796,7 +797,7 @@ app.listen(3000);
796797

797798
#### Default settings
798799

799-
You can override default status code in routing-controllers options.
800+
You can override default status code in routing-controllers options.
800801

801802
```typescript
802803
import "reflect-metadata";
@@ -809,9 +810,9 @@ const app = createExpressServer({
809810
//with this option, null will return 404 by default
810811
nullResultCode: 404,
811812

812-
//with this option, void or Promise<void> will return 204 by default
813+
//with this option, void or Promise<void> will return 204 by default
813814
undefinedResultCode: 204,
814-
815+
815816
paramOptions: {
816817
//with this option, argument will be required by default
817818
required: true
@@ -822,6 +823,20 @@ const app = createExpressServer({
822823
app.listen(3000);
823824
```
824825

826+
#### Selectively disable request/response transform
827+
828+
To disable `class-transformer` on a per-controller or per-route basis, use the `transformRequest` and `transformResponse` options on your controller and route decorators:
829+
830+
```typescript
831+
@Controller("/users", {transformRequest: false, transformResponse: false})
832+
export class UserController {
833+
834+
@Get("/", {transformResponse: true}) {
835+
// route option overrides controller option
836+
}
837+
}
838+
```
839+
825840
## Using middlewares
826841

827842
You can use any existing express / koa middleware, or create your own.
@@ -1210,7 +1225,7 @@ If its a class - then instance of this class will be created.
12101225
This technique works with `@Body`, `@Param`, `@QueryParam`, `@BodyParam`, and other decorators.
12111226
Learn more about class-transformer and how to handle more complex object constructions [here][4].
12121227
This behaviour is enabled by default.
1213-
If you want to disable it simply pass `classTransformer: false` to createExpressServer method.
1228+
If you want to disable it simply pass `classTransformer: false` to createExpressServer method. Alternatively you can disable transforming for [individual controllers or routes](#selectively-disable-requestresponse-transforming).
12141229

12151230
## Auto validating action params
12161231

src/ActionParameterHandler.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ export class ActionParameterHandler<T extends BaseDriver> {
209209
*/
210210
protected transformValue(value: any, paramMetadata: ParamMetadata): any {
211211
if (this.driver.useClassTransformer &&
212+
paramMetadata.actionMetadata.options.transformRequest !== false &&
212213
paramMetadata.targetType &&
213214
paramMetadata.targetType !== Object &&
214215
!(value instanceof paramMetadata.targetType)) {

src/RoutingControllersOptions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export interface RoutingControllersOptions {
8585
* Special function used to get currently authorized user.
8686
*/
8787
currentUserChecker?: CurrentUserChecker;
88-
88+
8989
/**
9090
* Default settings
9191
*/
@@ -110,4 +110,4 @@ export interface RoutingControllersOptions {
110110
required?: boolean;
111111
};
112112
};
113-
}
113+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Extra options that apply to each controller action.
3+
*/
4+
export interface ControllerOptions {
5+
/**
6+
* If set to false, class-transformer won't be used to perform request serialization.
7+
*/
8+
transformRequest?: boolean;
9+
10+
/**
11+
* If set to false, class-transformer won't be used to perform response serialization.
12+
*/
13+
transformResponse?: boolean;
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Extra handler-specific options.
3+
*/
4+
export interface HandlerOptions {
5+
/**
6+
* If set to false, class-transformer won't be used to perform request serialization.
7+
*/
8+
transformRequest?: boolean;
9+
10+
/**
11+
* If set to false, class-transformer won't be used to perform response serialization.
12+
*/
13+
transformResponse?: boolean;
14+
}

src/decorator/Controller.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
import {getMetadataArgsStorage} from "../index";
2+
import {ControllerOptions} from "../decorator-options/ControllerOptions";
23

34
/**
45
* Defines a class as a controller.
56
* Each decorated controller method is served as a controller action.
67
* Controller actions are executed when request come.
78
*
89
* @param baseRoute Extra path you can apply as a base route to all controller actions
10+
* @param options Extra options that apply to all controller actions
911
*/
10-
export function Controller(baseRoute?: string): Function {
12+
export function Controller(baseRoute?: string, options?: ControllerOptions): Function {
1113
return function (object: Function) {
1214
getMetadataArgsStorage().controllers.push({
1315
type: "default",
1416
target: object,
15-
route: baseRoute
17+
route: baseRoute,
18+
options
1619
});
1720
};
18-
}
21+
}

src/decorator/Delete.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
1+
import {HandlerOptions} from "../decorator-options/HandlerOptions";
12
import {getMetadataArgsStorage} from "../index";
23

34
/**
45
* Registers a controller method to be executed when DELETE request comes on a given route.
56
* Must be applied on a controller action.
67
*/
7-
export function Delete(route?: RegExp): Function;
8+
export function Delete(route?: RegExp, options?: HandlerOptions): Function;
89

910
/**
1011
* Registers a controller method to be executed when DELETE request comes on a given route.
1112
* Must be applied on a controller action.
1213
*/
13-
export function Delete(route?: string): Function;
14+
export function Delete(route?: string, options?: HandlerOptions): Function;
1415

1516
/**
1617
* Registers a controller method to be executed when DELETE request comes on a given route.
1718
* Must be applied on a controller action.
1819
*/
19-
export function Delete(route?: string|RegExp): Function {
20+
export function Delete(route?: string|RegExp, options?: HandlerOptions): Function {
2021
return function (object: Object, methodName: string) {
2122
getMetadataArgsStorage().actions.push({
2223
type: "delete",
2324
target: object.constructor,
2425
method: methodName,
25-
route: route
26+
route: route,
27+
options
2628
});
2729
};
2830
}

src/decorator/Get.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
1+
import {HandlerOptions} from "../decorator-options/HandlerOptions";
12
import {getMetadataArgsStorage} from "../index";
23

34
/**
45
* Registers an action to be executed when GET request comes on a given route.
56
* Must be applied on a controller action.
67
*/
7-
export function Get(route?: RegExp): Function;
8+
export function Get(route?: RegExp, options?: HandlerOptions): Function;
89

910
/**
1011
* Registers an action to be executed when GET request comes on a given route.
1112
* Must be applied on a controller action.
1213
*/
13-
export function Get(route?: string): Function;
14+
export function Get(route?: string, options?: HandlerOptions): Function;
1415

1516
/**
1617
* Registers an action to be executed when GET request comes on a given route.
1718
* Must be applied on a controller action.
1819
*/
19-
export function Get(route?: string|RegExp): Function {
20+
export function Get(route?: string|RegExp, options?: HandlerOptions): Function {
2021
return function (object: Object, methodName: string) {
2122
getMetadataArgsStorage().actions.push({
2223
type: "get",
2324
target: object.constructor,
2425
method: methodName,
25-
route: route
26+
options,
27+
route
2628
});
2729
};
28-
}
30+
}

src/decorator/Head.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
1+
import {HandlerOptions} from "../decorator-options/HandlerOptions";
12
import {getMetadataArgsStorage} from "../index";
23

34
/**
45
* Registers an action to be executed when HEAD request comes on a given route.
56
* Must be applied on a controller action.
67
*/
7-
export function Head(route?: RegExp): Function;
8+
export function Head(route?: RegExp, options?: HandlerOptions): Function;
89

910
/**
1011
* Registers an action to be executed when HEAD request comes on a given route.
1112
* Must be applied on a controller action.
1213
*/
13-
export function Head(route?: string): Function;
14+
export function Head(route?: string, options?: HandlerOptions): Function;
1415

1516
/**
1617
* Registers an action to be executed when HEAD request comes on a given route.
1718
* Must be applied on a controller action.
1819
*/
19-
export function Head(route?: string|RegExp): Function {
20+
export function Head(route?: string|RegExp, options?: HandlerOptions): Function {
2021
return function (object: Object, methodName: string) {
2122
getMetadataArgsStorage().actions.push({
2223
type: "head",
2324
target: object.constructor,
2425
method: methodName,
25-
route: route
26+
options,
27+
route
2628
});
2729
};
28-
}
30+
}

src/decorator/JsonController.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
import {getMetadataArgsStorage} from "../index";
2+
import {ControllerOptions} from "../decorator-options/ControllerOptions";
23

34
/**
45
* Defines a class as a JSON controller. If JSON controller is used, then all controller actions will return
56
* a serialized json data, and its response content-type always will be application/json.
67
*
78
* @param baseRoute Extra path you can apply as a base route to all controller actions
9+
* @param options Extra options that apply to all controller actions
810
*/
9-
export function JsonController(baseRoute?: string) {
11+
export function JsonController(baseRoute?: string, options?: ControllerOptions) {
1012
return function (object: Function) {
1113
getMetadataArgsStorage().controllers.push({
1214
type: "json",
1315
target: object,
14-
route: baseRoute
16+
route: baseRoute,
17+
options
1518
});
1619
};
1720
}

src/decorator/Method.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
1+
import {HandlerOptions} from "../decorator-options/HandlerOptions";
12
import {getMetadataArgsStorage} from "../index";
23
import {ActionType} from "../metadata/types/ActionType";
34

45
/**
56
* Registers an action to be executed when request with specified method comes on a given route.
67
* Must be applied on a controller action.
78
*/
8-
export function Method(method: ActionType, route?: RegExp): Function;
9+
export function Method(method: ActionType, route?: RegExp, options?: HandlerOptions): Function;
910

1011
/**
1112
* Registers an action to be executed when request with specified method comes on a given route.
1213
* Must be applied on a controller action.
1314
*/
14-
export function Method(method: ActionType, route?: string): Function;
15+
export function Method(method: ActionType, route?: string, options?: HandlerOptions): Function;
1516

1617
/**
1718
* Registers an action to be executed when request with specified method comes on a given route.
1819
* Must be applied on a controller action.
1920
*/
20-
export function Method(method: ActionType, route?: string|RegExp): Function {
21+
export function Method(method: ActionType, route?: string|RegExp, options?: HandlerOptions): Function {
2122
return function (object: Object, methodName: string) {
2223
getMetadataArgsStorage().actions.push({
2324
type: method,
2425
target: object.constructor,
2526
method: methodName,
26-
route: route
27+
options,
28+
route
2729
});
2830
};
2931
}

src/decorator/Patch.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
1+
import {HandlerOptions} from "../decorator-options/HandlerOptions";
12
import {getMetadataArgsStorage} from "../index";
23

34
/**
45
* Registers an action to be executed when PATCH request comes on a given route.
56
* Must be applied on a controller action.
67
*/
7-
export function Patch(route?: RegExp): Function;
8+
export function Patch(route?: RegExp, options?: HandlerOptions): Function;
89

910
/**
1011
* Registers an action to be executed when PATCH request comes on a given route.
1112
* Must be applied on a controller action.
1213
*/
13-
export function Patch(route?: string): Function;
14+
export function Patch(route?: string, options?: HandlerOptions): Function;
1415

1516
/**
1617
* Registers an action to be executed when PATCH request comes on a given route.
1718
* Must be applied on a controller action.
1819
*/
19-
export function Patch(route?: string|RegExp): Function {
20+
export function Patch(route?: string|RegExp, options?: HandlerOptions): Function {
2021
return function (object: Object, methodName: string) {
2122
getMetadataArgsStorage().actions.push({
2223
type: "patch",
2324
target: object.constructor,
2425
method: methodName,
25-
route: route
26+
route: route,
27+
options
2628
});
2729
};
28-
}
30+
}

src/decorator/Post.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
1+
import {HandlerOptions} from "../decorator-options/HandlerOptions";
12
import {getMetadataArgsStorage} from "../index";
23

34
/**
45
* Registers an action to be executed when POST request comes on a given route.
56
* Must be applied on a controller action.
67
*/
7-
export function Post(route?: RegExp): Function;
8+
export function Post(route?: RegExp, options?: HandlerOptions): Function;
89

910
/**
1011
* Registers an action to be executed when POST request comes on a given route.
1112
* Must be applied on a controller action.
1213
*/
13-
export function Post(route?: string): Function;
14+
export function Post(route?: string, options?: HandlerOptions): Function;
1415

1516
/**
1617
* Registers an action to be executed when POST request comes on a given route.
1718
* Must be applied on a controller action.
1819
*/
19-
export function Post(route?: string|RegExp): Function {
20+
export function Post(route?: string|RegExp, options?: HandlerOptions): Function {
2021
return function (object: Object, methodName: string) {
2122
getMetadataArgsStorage().actions.push({
2223
type: "post",
2324
target: object.constructor,
2425
method: methodName,
25-
route: route
26+
options,
27+
route
2628
});
2729
};
2830
}

0 commit comments

Comments
 (0)