@nestia/core 3.14.1 → 3.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import { IResponseBodyStringifier } from "../options/IResponseBodyStringifier";
2
+ import { TypedRoute } from "./TypedRoute";
2
3
  /**
3
4
  * Encrypted router decorator functions.
4
5
  *
@@ -75,4 +76,22 @@ export declare namespace EncryptedRoute {
75
76
  <T>(stringify?: IResponseBodyStringifier<T> | null): MethodDecorator;
76
77
  <T>(path: string | string[], stringify?: IResponseBodyStringifier<T> | null): MethodDecorator;
77
78
  };
79
+ /**
80
+ * Set the logger function for the response validation failure.
81
+ *
82
+ * If you've configured the transformation option to `validate.log`
83
+ * in the `tsconfig.json` file, then the error log information of the
84
+ * response validation failure would be logged through this function
85
+ * instead of throwing the 400 bad request error.
86
+ *
87
+ * By the way, be careful. If you've configured the response
88
+ * transformation option to be `validate.log` or `validateEquals.log`,
89
+ * client may get wrong response data. Therefore, this way is not
90
+ * recommended in the common backend server case.
91
+ *
92
+ * @param func Logger function
93
+ * @default console.log
94
+ */
95
+ function setValidateErrorLogger(func: (log: IValidateErrorLog) => void): void;
96
+ export import IValidateErrorLog = TypedRoute.IValidateErrorLog;
78
97
  }
@@ -9,6 +9,7 @@ const common_1 = require("@nestjs/common");
9
9
  const operators_1 = require("rxjs/operators");
10
10
  const typia_1 = __importDefault(require("typia"));
11
11
  const Singleton_1 = require("../utils/Singleton");
12
+ const TypedRoute_1 = require("./TypedRoute");
12
13
  const EncryptedConstant_1 = require("./internal/EncryptedConstant");
13
14
  const get_path_and_stringify_1 = require("./internal/get_path_and_stringify");
14
15
  const headers_to_object_1 = require("./internal/headers_to_object");
@@ -70,9 +71,32 @@ var EncryptedRoute;
70
71
  * @returns Method decorator
71
72
  */
72
73
  EncryptedRoute.Delete = Generator("Delete");
74
+ /**
75
+ * Set the logger function for the response validation failure.
76
+ *
77
+ * If you've configured the transformation option to `validate.log`
78
+ * in the `tsconfig.json` file, then the error log information of the
79
+ * response validation failure would be logged through this function
80
+ * instead of throwing the 400 bad request error.
81
+ *
82
+ * By the way, be careful. If you've configured the response
83
+ * transformation option to be `validate.log` or `validateEquals.log`,
84
+ * client may get wrong response data. Therefore, this way is not
85
+ * recommended in the common backend server case.
86
+ *
87
+ * @param func Logger function
88
+ * @default console.log
89
+ */
90
+ function setValidateErrorLogger(func) {
91
+ TypedRoute_1.TypedRoute.setValidateErrorLogger(func);
92
+ }
93
+ EncryptedRoute.setValidateErrorLogger = setValidateErrorLogger;
94
+ /**
95
+ * @internal
96
+ */
73
97
  function Generator(method) {
74
98
  function route(...args) {
75
- const [path, stringify] = (0, get_path_and_stringify_1.get_path_and_stringify)(`EncryptedRoute.${method}`)(...args);
99
+ const [path, stringify] = (0, get_path_and_stringify_1.get_path_and_stringify)(() => TypedRoute_1.TypedRoute.__logger)(`EncryptedRoute.${method}`)(...args);
76
100
  return (0, common_1.applyDecorators)(ROUTERS[method](path), (0, common_1.UseInterceptors)(new EncryptedRouteInterceptor(method, stringify)));
77
101
  }
78
102
  return route;
@@ -107,11 +131,9 @@ class EncryptedRouteInterceptor {
107
131
  const param = Reflect.getMetadata(EncryptedConstant_1.ENCRYPTION_METADATA_KEY, context.getClass());
108
132
  if (!param)
109
133
  return Error(`Error on EncryptedRoute.${this.method}(): no password found.`);
110
- const headers = new Singleton_1.Singleton(() => {
111
- const request = http.getRequest();
112
- return (0, headers_to_object_1.headers_to_object)(request.headers);
113
- });
114
- const body = this.stringify(value);
134
+ const request = http.getRequest();
135
+ const headers = new Singleton_1.Singleton(() => (0, headers_to_object_1.headers_to_object)(request.headers));
136
+ const body = this.stringify(value, request.method, request.url);
115
137
  const password = typeof param === "function"
116
138
  ? param({
117
139
  headers: headers.get(),
@@ -1 +1 @@
1
- {"version":3,"file":"EncryptedRoute.js","sourceRoot":"","sources":["../../src/decorators/EncryptedRoute.ts"],"names":[],"mappings":";;;;;;AAAA,2DAAwD;AAExD,2CAWwB;AAGxB,8CAAiD;AACjD,kDAA0B;AAG1B,kDAA+C;AAC/C,oEAAuE;AACvE,8EAA2E;AAC3E,oEAAiE;AACjE,wDAAqD;AAErD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,IAAiB,cAAc,CA8D9B;AA9DD,WAAiB,cAAc;IAC7B;;;;;OAKG;IACU,kBAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAEpC;;;;;OAKG;IACU,mBAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAEtC;;;;;OAKG;IACU,oBAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAExC;;;;;OAKG;IACU,kBAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAEpC;;;;;OAKG;IACU,qBAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAE1C,SAAS,SAAS,CAAC,MAAmD;QAUpE,SAAS,KAAK,CAAC,GAAG,IAAW;YAC3B,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,IAAA,+CAAsB,EAC9C,kBAAkB,MAAM,EAAE,CAC3B,CAAC,GAAG,IAAI,CAAC,CAAC;YACX,OAAO,IAAA,wBAAe,EACpB,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EACrB,IAAA,wBAAe,EAAC,IAAI,yBAAyB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAClE,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,EA9DgB,cAAc,8BAAd,cAAc,QA8D9B;AAED,KAAK,MAAM,MAAM,IAAI;IACnB,eAAK,CAAC,IAAI,CAAC,WAAW;IACtB,eAAK,CAAC,IAAI,CAAC,eAAe;IAC1B,eAAK,CAAC,IAAI,CAAC,iBAAiB;IAC5B,eAAK,CAAC,IAAI,CAAC,SAAS;CACrB;IACC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QAC/C,KAAK,MAAM,IAAI,IAAI;YACjB,cAAc,CAAC,GAAG;YAClB,cAAc,CAAC,MAAM;YACrB,cAAc,CAAC,IAAI;YACnB,cAAc,CAAC,GAAG;YAClB,cAAc,CAAC,KAAK;SACrB;YACE,IAAY,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEjC;;GAEG;AACH,MAAM,yBAAyB;IAC7B,YACmB,MAAc,EACd,SAAiC;QADjC,WAAM,GAAN,MAAM,CAAQ;QACd,cAAS,GAAT,SAAS,CAAwB;IACjD,CAAC;IAEG,SAAS,CAAC,OAAyB,EAAE,IAAiB;QAC3D,MAAM,IAAI,GAAsB,OAAO,CAAC,YAAY,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,eAAG,EAAC,CAAC,KAAK,EAAE,EAAE;YACZ,MAAM,KAAK,GAGK,OAAO,CAAC,WAAW,CACjC,2CAAuB,EACvB,OAAO,CAAC,QAAQ,EAAE,CACnB,CAAC;YACF,IAAI,CAAC,KAAK;gBACR,OAAO,KAAK,CACV,2BAA2B,IAAI,CAAC,MAAM,wBAAwB,CAC/D,CAAC;YAEJ,MAAM,OAAO,GAAsC,IAAI,qBAAS,CAAC,GAAG,EAAE;gBACpE,MAAM,OAAO,GAAoB,IAAI,CAAC,UAAU,EAAE,CAAC;gBACnD,OAAO,IAAA,qCAAiB,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC5C,CAAC,CAAC,CAAC;YACH,MAAM,IAAI,GAAuB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACvD,MAAM,QAAQ,GACZ,OAAO,KAAK,KAAK,UAAU;gBACzB,CAAC,CAAC,KAAK,CAAC;oBACJ,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE;oBACtB,IAAI;oBACJ,SAAS,EAAE,QAAQ;iBACpB,CAAC;gBACJ,CAAC,CAAC,KAAK,CAAC;YAEZ,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC;YACpC,OAAO,mBAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC3D,CAAC,CAAC,EACF,IAAA,sBAAU,EAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAA,yBAAW,EAAC,IAAI,CAAC,UAAU,EAAE,EAAE,GAAG,CAAC,CAAC,CACzD,CAAC;IACJ,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,GAAG;IACd,GAAG,EAAH,YAAG;IACH,IAAI,EAAJ,aAAI;IACJ,GAAG,EAAH,YAAG;IACH,KAAK,EAAL,cAAK;IACL,MAAM,EAAN,eAAM;CACP,CAAC"}
1
+ {"version":3,"file":"EncryptedRoute.js","sourceRoot":"","sources":["../../src/decorators/EncryptedRoute.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { IValidation } from "typia";
1
2
  import { IResponseBodyStringifier } from "../options/IResponseBodyStringifier";
2
3
  /**
3
4
  * Type safe router decorator functions.
@@ -70,4 +71,49 @@ export declare namespace TypedRoute {
70
71
  <T>(stringify?: IResponseBodyStringifier<T>): MethodDecorator;
71
72
  <T>(path: string | string[], stringify?: IResponseBodyStringifier<T>): MethodDecorator;
72
73
  };
74
+ /**
75
+ * Set the logger function for the response validation failure.
76
+ *
77
+ * If you've configured the transformation option to `validate.log`
78
+ * in the `tsconfig.json` file, then the error log information of the
79
+ * response validation failure would be logged through this function
80
+ * instead of throwing the 400 bad request error.
81
+ *
82
+ * By the way, be careful. If you've configured the response
83
+ * transformation option to be `validate.log` or `validateEquals.log`,
84
+ * client may get wrong response data. Therefore, this way is not
85
+ * recommendedin the common backend server case.
86
+ *
87
+ * @param func Logger function
88
+ * @default console.log
89
+ */
90
+ function setValidateErrorLogger(func: (log: IValidateErrorLog) => void): void;
91
+ /**
92
+ * Error log information of the response validation failure.
93
+ *
94
+ * `IValidationErrorLog` is a structure representing the error log
95
+ * information when the returned value from the `@TypedRoute` or
96
+ * `@EncryptedRoute` decorated controller method is not following
97
+ * the promised type `T`.
98
+ *
99
+ * If you've configured the transformation option to `validate.log` or
100
+ * `validateEquals.log` in the `tsconfig.json` file, then this error log
101
+ * information `IValidateErrorLog` would be logged through the
102
+ * {@link setValidateErrorLogger} function instead of throwing the
103
+ * 400 bad request error.
104
+ */
105
+ interface IValidateErrorLog {
106
+ /**
107
+ * HTTP method of the request.
108
+ */
109
+ method: string;
110
+ /**
111
+ * HTTP path of the request.
112
+ */
113
+ path: string;
114
+ /**
115
+ * Validation error informations with detailed reasons.
116
+ */
117
+ errors: IValidation.IError[];
118
+ }
73
119
  }
@@ -61,12 +61,36 @@ var TypedRoute;
61
61
  * @returns Method decorator
62
62
  */
63
63
  TypedRoute.Delete = Generator("Delete");
64
+ /**
65
+ * Set the logger function for the response validation failure.
66
+ *
67
+ * If you've configured the transformation option to `validate.log`
68
+ * in the `tsconfig.json` file, then the error log information of the
69
+ * response validation failure would be logged through this function
70
+ * instead of throwing the 400 bad request error.
71
+ *
72
+ * By the way, be careful. If you've configured the response
73
+ * transformation option to be `validate.log` or `validateEquals.log`,
74
+ * client may get wrong response data. Therefore, this way is not
75
+ * recommendedin the common backend server case.
76
+ *
77
+ * @param func Logger function
78
+ * @default console.log
79
+ */
80
+ function setValidateErrorLogger(func) {
81
+ TypedRoute.__logger = func;
82
+ }
83
+ TypedRoute.setValidateErrorLogger = setValidateErrorLogger;
84
+ /**
85
+ * @internal
86
+ */
87
+ TypedRoute.__logger = console.log;
64
88
  /**
65
89
  * @internal
66
90
  */
67
91
  function Generator(method) {
68
92
  function route(...args) {
69
- const [path, stringify] = (0, get_path_and_stringify_1.get_path_and_stringify)(`TypedRoute.${method}`)(...args);
93
+ const [path, stringify] = (0, get_path_and_stringify_1.get_path_and_stringify)(() => TypedRoute.__logger)(`TypedRoute.${method}`)(...args);
70
94
  return (0, common_1.applyDecorators)(ROUTERS[method](path), (0, common_1.UseInterceptors)(new TypedRouteInterceptor(stringify)));
71
95
  }
72
96
  return route;
@@ -96,9 +120,10 @@ class TypedRouteInterceptor {
96
120
  }
97
121
  intercept(context, next) {
98
122
  const http = context.switchToHttp();
123
+ const request = http.getRequest();
99
124
  const response = http.getResponse();
100
125
  response.header("Content-Type", "application/json");
101
- return next.handle().pipe((0, operators_1.map)((value) => this.stringify(value)), (0, operators_1.catchError)((err) => (0, route_error_1.route_error)(http.getRequest(), err)));
126
+ return next.handle().pipe((0, operators_1.map)((value) => this.stringify(value, request.method, request.url)), (0, operators_1.catchError)((err) => (0, route_error_1.route_error)(http.getRequest(), err)));
102
127
  }
103
128
  }
104
129
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"TypedRoute.js","sourceRoot":"","sources":["../../src/decorators/TypedRoute.ts"],"names":[],"mappings":";;;;;;AAAA,2CAWwB;AAGxB,8CAAiD;AACjD,kDAA0B;AAG1B,8EAA2E;AAC3E,wDAAqD;AAErD;;;;;;;;;;;;;;GAcG;AACH,IAAiB,UAAU,CA+D1B;AA/DD,WAAiB,UAAU;IACzB;;;;;OAKG;IACU,cAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAEpC;;;;;OAKG;IACU,eAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAEtC;;;;;OAKG;IACU,gBAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAExC;;;;;OAKG;IACU,cAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAEpC;;;;;OAKG;IACU,iBAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAE1C;;OAEG;IACH,SAAS,SAAS,CAAC,MAAmD;QAQpE,SAAS,KAAK,CAAC,GAAG,IAAW;YAC3B,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,IAAA,+CAAsB,EAAC,cAAc,MAAM,EAAE,CAAC,CACtE,GAAG,IAAI,CACR,CAAC;YACF,OAAO,IAAA,wBAAe,EACpB,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EACrB,IAAA,wBAAe,EAAC,IAAI,qBAAqB,CAAC,SAAS,CAAC,CAAC,CACtD,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,EA/DgB,UAAU,0BAAV,UAAU,QA+D1B;AACD,KAAK,MAAM,MAAM,IAAI;IACnB,eAAK,CAAC,IAAI,CAAC,SAAS;IACpB,eAAK,CAAC,IAAI,CAAC,WAAW;IACtB,eAAK,CAAC,IAAI,CAAC,eAAe;IAC1B,eAAK,CAAC,IAAI,CAAC,iBAAiB;CAC7B;IACC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QAC/C,KAAK,MAAM,IAAI,IAAI;YACjB,UAAU,CAAC,GAAG;YACd,UAAU,CAAC,MAAM;YACjB,UAAU,CAAC,IAAI;YACf,UAAU,CAAC,GAAG;YACd,UAAU,CAAC,KAAK;SACjB;YACE,IAAY,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEjC;;GAEG;AACH,MAAM,qBAAqB;IACzB,YAAoC,SAAiC;QAAjC,cAAS,GAAT,SAAS,CAAwB;IAAG,CAAC;IAElE,SAAS,CAAC,OAAyB,EAAE,IAAiB;QAC3D,MAAM,IAAI,GAAsB,OAAO,CAAC,YAAY,EAAE,CAAC;QACvD,MAAM,QAAQ,GAAqB,IAAI,CAAC,WAAW,EAAE,CAAC;QACtD,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;QAEpD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,eAAG,EAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EACrC,IAAA,sBAAU,EAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAA,yBAAW,EAAC,IAAI,CAAC,UAAU,EAAE,EAAE,GAAG,CAAC,CAAC,CACzD,CAAC;IACJ,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,GAAG;IACd,GAAG,EAAH,YAAG;IACH,IAAI,EAAJ,aAAI;IACJ,KAAK,EAAL,cAAK;IACL,GAAG,EAAH,YAAG;IACH,MAAM,EAAN,eAAM;CACP,CAAC"}
1
+ {"version":3,"file":"TypedRoute.js","sourceRoot":"","sources":["../../src/decorators/TypedRoute.ts"],"names":[],"mappings":"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"}
@@ -10,26 +10,26 @@ const NoTransformConfigurationError_1 = require("../NoTransformConfigurationErro
10
10
  /**
11
11
  * @internal
12
12
  */
13
- const get_path_and_stringify = (method) => (...args) => {
13
+ const get_path_and_stringify = (logger) => (method) => (...args) => {
14
14
  const path = args[0] === undefined ||
15
15
  typeof args[0] === "string" ||
16
16
  Array.isArray(args[0])
17
17
  ? args[0]
18
18
  : null;
19
19
  const functor = path === null ? args[0] : args[1];
20
- return [path !== null && path !== void 0 ? path : undefined, take(method)(functor)];
20
+ return [path !== null && path !== void 0 ? path : undefined, take(logger)(method)(functor)];
21
21
  };
22
22
  exports.get_path_and_stringify = get_path_and_stringify;
23
23
  /**
24
24
  * @internal
25
25
  */
26
- const take = (method) => (functor) => {
26
+ const take = (logger) => (method) => (functor) => {
27
27
  if (functor === undefined) {
28
28
  (0, NoTransformConfigurationError_1.NoTransformConfigurationError)(method);
29
- return JSON.stringify;
29
+ return (input, _method, _path) => JSON.stringify(input);
30
30
  }
31
31
  else if (functor === null)
32
- return JSON.stringify;
32
+ return (input, _method, _path) => JSON.stringify(input);
33
33
  else if (functor.type === "stringify")
34
34
  return functor.stringify;
35
35
  else if (functor.type === "assert")
@@ -38,6 +38,9 @@ const take = (method) => (functor) => {
38
38
  return is(functor.is);
39
39
  else if (functor.type === "validate")
40
40
  return validate(functor.validate);
41
+ else if (functor.type === "validate.log" ||
42
+ functor.type === "validateEquals.log")
43
+ return validateLog(logger)(functor.validate);
41
44
  throw new Error(`Error on nestia.core.${method}(): invalid typed stringify function.`);
42
45
  };
43
46
  /**
@@ -62,7 +65,7 @@ const assert = (closure) => (data) => {
62
65
  /**
63
66
  * @internal
64
67
  */
65
- const is = (closure) => (data) => {
68
+ const is = (closure) => (data, _method, _path) => {
66
69
  const result = closure(data);
67
70
  if (result === null)
68
71
  throw new common_1.InternalServerErrorException(MESSAGE);
@@ -71,7 +74,7 @@ const is = (closure) => (data) => {
71
74
  /**
72
75
  * @internal
73
76
  */
74
- const validate = (closure) => (data) => {
77
+ const validate = (closure) => (data, _method, _path) => {
75
78
  const result = closure(data);
76
79
  if (result.success === false)
77
80
  throw new common_1.InternalServerErrorException({
@@ -80,6 +83,16 @@ const validate = (closure) => (data) => {
80
83
  });
81
84
  return result.data;
82
85
  };
86
+ const validateLog = (logger) => (closure) => (data, method, path) => {
87
+ const result = closure(data);
88
+ if (result.success === false)
89
+ logger()({
90
+ errors: result.errors,
91
+ method,
92
+ path,
93
+ });
94
+ return JSON.stringify(data);
95
+ };
83
96
  /**
84
97
  * @internal
85
98
  */
@@ -1 +1 @@
1
- {"version":3,"file":"get_path_and_stringify.js","sourceRoot":"","sources":["../../../src/decorators/internal/get_path_and_stringify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"get_path_and_stringify.js","sourceRoot":"","sources":["../../../src/decorators/internal/get_path_and_stringify.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export interface INestiaTransformOptions {
2
2
  validate?: "assert" | "is" | "validate" | "assertEquals" | "equals" | "validateEquals" | "assertClone" | "validateClone" | "assertPrune" | "validatePrune";
3
- stringify?: "stringify" | "assert" | "is" | "validate" | null;
3
+ stringify?: "stringify" | "assert" | "is" | "validate" | "validate.log" | "validateEquals.log" | null;
4
4
  throws?: boolean;
5
5
  }
@@ -1,5 +1,5 @@
1
1
  import { IValidation } from "typia";
2
- export type IResponseBodyStringifier<T> = IResponseBodyStringifier.IStringify<T> | IResponseBodyStringifier.IIs<T> | IResponseBodyStringifier.IAssert<T> | IResponseBodyStringifier.IValidate<T>;
2
+ export type IResponseBodyStringifier<T> = IResponseBodyStringifier.IStringify<T> | IResponseBodyStringifier.IIs<T> | IResponseBodyStringifier.IAssert<T> | IResponseBodyStringifier.IValidate<T> | IResponseBodyStringifier.IValidateLog<T>;
3
3
  export declare namespace IResponseBodyStringifier {
4
4
  interface IStringify<T> {
5
5
  type: "stringify";
@@ -17,4 +17,8 @@ export declare namespace IResponseBodyStringifier {
17
17
  type: "validate";
18
18
  validate: (input: T) => IValidation<string>;
19
19
  }
20
+ interface IValidateLog<T> {
21
+ type: "validate.log" | "validateEquals.log";
22
+ validate: (input: T) => IValidation<T>;
23
+ }
20
24
  }
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.TypedRouteProgrammer = void 0;
7
7
  const typescript_1 = __importDefault(require("typescript"));
8
+ const ValidateProgrammer_1 = require("typia/lib/programmers/ValidateProgrammer");
8
9
  const JsonAssertStringifyProgrammer_1 = require("typia/lib/programmers/json/JsonAssertStringifyProgrammer");
9
10
  const JsonIsStringifyProgrammer_1 = require("typia/lib/programmers/json/JsonIsStringifyProgrammer");
10
11
  const JsonStringifyProgrammer_1 = require("typia/lib/programmers/json/JsonStringifyProgrammer");
@@ -13,21 +14,49 @@ var TypedRouteProgrammer;
13
14
  (function (TypedRouteProgrammer) {
14
15
  TypedRouteProgrammer.generate = (project) => (modulo) => (type) => {
15
16
  // GENERATE STRINGIFY PLAN
16
- const parameter = (key, programmer) => typescript_1.default.factory.createObjectLiteralExpression([
17
- typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier("type"), typescript_1.default.factory.createStringLiteral(key)),
18
- typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(key), programmer(Object.assign(Object.assign({}, project), { options: {} }))(modulo)(type)),
17
+ const parameter = (props) => typescript_1.default.factory.createObjectLiteralExpression([
18
+ typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier("type"), typescript_1.default.factory.createStringLiteral(props.type)),
19
+ typescript_1.default.factory.createPropertyAssignment(typescript_1.default.factory.createIdentifier(props.key), props.programmer(Object.assign(Object.assign({}, project), { options: {} }))(modulo)(type)),
19
20
  ]);
20
21
  // RETURNS
21
22
  if (project.options.stringify === "is")
22
- return parameter("is", JsonIsStringifyProgrammer_1.JsonIsStringifyProgrammer.write);
23
+ return parameter({
24
+ type: "is",
25
+ key: "is",
26
+ programmer: JsonIsStringifyProgrammer_1.JsonIsStringifyProgrammer.write,
27
+ });
23
28
  else if (project.options.stringify === "validate")
24
- return parameter("validate", JsonValidateStringifyProgrammer_1.JsonValidateStringifyProgrammer.write);
29
+ return parameter({
30
+ type: "validate",
31
+ key: "validate",
32
+ programmer: JsonValidateStringifyProgrammer_1.JsonValidateStringifyProgrammer.write,
33
+ });
25
34
  else if (project.options.stringify === "stringify")
26
- return parameter("stringify", JsonStringifyProgrammer_1.JsonStringifyProgrammer.write);
35
+ return parameter({
36
+ type: "stringify",
37
+ key: "stringify",
38
+ programmer: JsonStringifyProgrammer_1.JsonStringifyProgrammer.write,
39
+ });
40
+ else if (project.options.stringify === "validate.log")
41
+ return parameter({
42
+ type: "validate.log",
43
+ key: "validate",
44
+ programmer: (project) => (modulo) => ValidateProgrammer_1.ValidateProgrammer.write(project)(modulo)(false),
45
+ });
46
+ else if (project.options.stringify === "validateEquals.log")
47
+ return parameter({
48
+ type: "validateEquals.log",
49
+ key: "validate",
50
+ programmer: (project) => (modulo) => ValidateProgrammer_1.ValidateProgrammer.write(project)(modulo)(true),
51
+ });
27
52
  else if (project.options.stringify === null)
28
53
  return typescript_1.default.factory.createNull();
29
54
  // ASSERT IS DEFAULT
30
- return parameter("assert", JsonAssertStringifyProgrammer_1.JsonAssertStringifyProgrammer.write);
55
+ return parameter({
56
+ type: "assert",
57
+ key: "assert",
58
+ programmer: JsonAssertStringifyProgrammer_1.JsonAssertStringifyProgrammer.write,
59
+ });
31
60
  };
32
61
  })(TypedRouteProgrammer || (exports.TypedRouteProgrammer = TypedRouteProgrammer = {}));
33
62
  //# sourceMappingURL=TypedRouteProgrammer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TypedRouteProgrammer.js","sourceRoot":"","sources":["../../src/programmers/TypedRouteProgrammer.ts"],"names":[],"mappings":";;;;;;AAAA,4DAA4B;AAC5B,4GAAyG;AACzG,oGAAiG;AACjG,gGAA6F;AAC7F,gHAA6G;AAK7G,IAAiB,oBAAoB,CAyCpC;AAzCD,WAAiB,oBAAoB;IACtB,6BAAQ,GACnB,CAAC,OAAgC,EAAE,EAAE,CACrC,CAAC,MAAiC,EAAE,EAAE,CACtC,CAAC,IAAa,EAAiB,EAAE;QAC/B,0BAA0B;QAC1B,MAAM,SAAS,GAAG,CAChB,GAAW,EACX,UAIqC,EACrC,EAAE,CACF,oBAAE,CAAC,OAAO,CAAC,6BAA6B,CAAC;YACvC,oBAAE,CAAC,OAAO,CAAC,wBAAwB,CACjC,oBAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,EACnC,oBAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,GAAG,CAAC,CACpC;YACD,oBAAE,CAAC,OAAO,CAAC,wBAAwB,CACjC,oBAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAChC,UAAU,iCACL,OAAO,KACV,OAAO,EAAE,EAAE,IACX,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CACjB;SACF,CAAC,CAAC;QAEL,UAAU;QACV,IAAI,OAAO,CAAC,OAAO,CAAC,SAAS,KAAK,IAAI;YACpC,OAAO,SAAS,CAAC,IAAI,EAAE,qDAAyB,CAAC,KAAK,CAAC,CAAC;aACrD,IAAI,OAAO,CAAC,OAAO,CAAC,SAAS,KAAK,UAAU;YAC/C,OAAO,SAAS,CAAC,UAAU,EAAE,iEAA+B,CAAC,KAAK,CAAC,CAAC;aACjE,IAAI,OAAO,CAAC,OAAO,CAAC,SAAS,KAAK,WAAW;YAChD,OAAO,SAAS,CAAC,WAAW,EAAE,iDAAuB,CAAC,KAAK,CAAC,CAAC;aAC1D,IAAI,OAAO,CAAC,OAAO,CAAC,SAAS,KAAK,IAAI;YACzC,OAAO,oBAAE,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QAEjC,oBAAoB;QACpB,OAAO,SAAS,CAAC,QAAQ,EAAE,6DAA6B,CAAC,KAAK,CAAC,CAAC;IAClE,CAAC,CAAC;AACN,CAAC,EAzCgB,oBAAoB,oCAApB,oBAAoB,QAyCpC"}
1
+ {"version":3,"file":"TypedRouteProgrammer.js","sourceRoot":"","sources":["../../src/programmers/TypedRouteProgrammer.ts"],"names":[],"mappings":";;;;;;AAAA,4DAA4B;AAC5B,iFAA8E;AAC9E,4GAAyG;AACzG,oGAAiG;AACjG,gGAA6F;AAC7F,gHAA6G;AAK7G,IAAiB,oBAAoB,CAwEpC;AAxED,WAAiB,oBAAoB;IACtB,6BAAQ,GACnB,CAAC,OAAgC,EAAE,EAAE,CACrC,CAAC,MAAiC,EAAE,EAAE,CACtC,CAAC,IAAa,EAAiB,EAAE;QAC/B,0BAA0B;QAC1B,MAAM,SAAS,GAAG,CAAC,KAQlB,EAAE,EAAE,CACH,oBAAE,CAAC,OAAO,CAAC,6BAA6B,CAAC;YACvC,oBAAE,CAAC,OAAO,CAAC,wBAAwB,CACjC,oBAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,EACnC,oBAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,CAC3C;YACD,oBAAE,CAAC,OAAO,CAAC,wBAAwB,CACjC,oBAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,EACtC,KAAK,CAAC,UAAU,iCACX,OAAO,KACV,OAAO,EAAE,EAAE,IACX,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CACjB;SACF,CAAC,CAAC;QAEL,UAAU;QACV,IAAI,OAAO,CAAC,OAAO,CAAC,SAAS,KAAK,IAAI;YACpC,OAAO,SAAS,CAAC;gBACf,IAAI,EAAE,IAAI;gBACV,GAAG,EAAE,IAAI;gBACT,UAAU,EAAE,qDAAyB,CAAC,KAAK;aAC5C,CAAC,CAAC;aACA,IAAI,OAAO,CAAC,OAAO,CAAC,SAAS,KAAK,UAAU;YAC/C,OAAO,SAAS,CAAC;gBACf,IAAI,EAAE,UAAU;gBAChB,GAAG,EAAE,UAAU;gBACf,UAAU,EAAE,iEAA+B,CAAC,KAAK;aAClD,CAAC,CAAC;aACA,IAAI,OAAO,CAAC,OAAO,CAAC,SAAS,KAAK,WAAW;YAChD,OAAO,SAAS,CAAC;gBACf,IAAI,EAAE,WAAW;gBACjB,GAAG,EAAE,WAAW;gBAChB,UAAU,EAAE,iDAAuB,CAAC,KAAK;aAC1C,CAAC,CAAC;aACA,IAAI,OAAO,CAAC,OAAO,CAAC,SAAS,KAAK,cAAc;YACnD,OAAO,SAAS,CAAC;gBACf,IAAI,EAAE,cAAc;gBACpB,GAAG,EAAE,UAAU;gBACf,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAClC,uCAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC;aACnD,CAAC,CAAC;aACA,IAAI,OAAO,CAAC,OAAO,CAAC,SAAS,KAAK,oBAAoB;YACzD,OAAO,SAAS,CAAC;gBACf,IAAI,EAAE,oBAAoB;gBAC1B,GAAG,EAAE,UAAU;gBACf,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAClC,uCAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;aAClD,CAAC,CAAC;aACA,IAAI,OAAO,CAAC,OAAO,CAAC,SAAS,KAAK,IAAI;YACzC,OAAO,oBAAE,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QAEjC,oBAAoB;QACpB,OAAO,SAAS,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,GAAG,EAAE,QAAQ;YACb,UAAU,EAAE,6DAA6B,CAAC,KAAK;SAChD,CAAC,CAAC;IACL,CAAC,CAAC;AACN,CAAC,EAxEgB,oBAAoB,oCAApB,oBAAoB,QAwEpC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestia/core",
3
- "version": "3.14.1",
3
+ "version": "3.15.0",
4
4
  "description": "Super-fast validation decorators of NestJS",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -36,10 +36,10 @@
36
36
  },
37
37
  "homepage": "https://nestia.io",
38
38
  "dependencies": {
39
- "@nestia/fetcher": "^3.14.1",
39
+ "@nestia/fetcher": "^3.15.0",
40
40
  "@nestjs/common": ">=7.0.1",
41
41
  "@nestjs/core": ">=7.0.1",
42
- "@samchon/openapi": "^1.0.2",
42
+ "@samchon/openapi": "^1.1.0",
43
43
  "detect-ts-node": "^1.0.5",
44
44
  "get-function-location": "^2.0.0",
45
45
  "glob": "^7.2.0",
@@ -49,16 +49,16 @@
49
49
  "reflect-metadata": ">=0.1.12",
50
50
  "rxjs": ">=6.0.3",
51
51
  "tgrid": "^1.0.0",
52
- "typia": "^6.10.0",
52
+ "typia": "^6.11.0",
53
53
  "ws": "^7.5.3"
54
54
  },
55
55
  "peerDependencies": {
56
- "@nestia/fetcher": ">=3.14.1",
56
+ "@nestia/fetcher": ">=3.15.0",
57
57
  "@nestjs/common": ">=7.0.1",
58
58
  "@nestjs/core": ">=7.0.1",
59
59
  "reflect-metadata": ">=0.1.12",
60
60
  "rxjs": ">=6.0.3",
61
- "typia": ">=6.10.0 <7.0.0"
61
+ "typia": ">=6.11.0 <7.0.0"
62
62
  },
63
63
  "devDependencies": {
64
64
  "@fastify/multipart": "^8.1.0",
@@ -19,6 +19,7 @@ import typia from "typia";
19
19
 
20
20
  import { IResponseBodyStringifier } from "../options/IResponseBodyStringifier";
21
21
  import { Singleton } from "../utils/Singleton";
22
+ import { TypedRoute } from "./TypedRoute";
22
23
  import { ENCRYPTION_METADATA_KEY } from "./internal/EncryptedConstant";
23
24
  import { get_path_and_stringify } from "./internal/get_path_and_stringify";
24
25
  import { headers_to_object } from "./internal/headers_to_object";
@@ -85,6 +86,33 @@ export namespace EncryptedRoute {
85
86
  */
86
87
  export const Delete = Generator("Delete");
87
88
 
89
+ /**
90
+ * Set the logger function for the response validation failure.
91
+ *
92
+ * If you've configured the transformation option to `validate.log`
93
+ * in the `tsconfig.json` file, then the error log information of the
94
+ * response validation failure would be logged through this function
95
+ * instead of throwing the 400 bad request error.
96
+ *
97
+ * By the way, be careful. If you've configured the response
98
+ * transformation option to be `validate.log` or `validateEquals.log`,
99
+ * client may get wrong response data. Therefore, this way is not
100
+ * recommended in the common backend server case.
101
+ *
102
+ * @param func Logger function
103
+ * @default console.log
104
+ */
105
+ export function setValidateErrorLogger(
106
+ func: (log: IValidateErrorLog) => void,
107
+ ): void {
108
+ TypedRoute.setValidateErrorLogger(func);
109
+ }
110
+
111
+ export import IValidateErrorLog = TypedRoute.IValidateErrorLog;
112
+
113
+ /**
114
+ * @internal
115
+ */
88
116
  function Generator(method: "Get" | "Post" | "Put" | "Patch" | "Delete") {
89
117
  function route(path?: string | string[]): MethodDecorator;
90
118
  function route<T>(
@@ -97,8 +125,8 @@ export namespace EncryptedRoute {
97
125
 
98
126
  function route(...args: any[]): MethodDecorator {
99
127
  const [path, stringify] = get_path_and_stringify(
100
- `EncryptedRoute.${method}`,
101
- )(...args);
128
+ () => TypedRoute.__logger,
129
+ )(`EncryptedRoute.${method}`)(...args);
102
130
  return applyDecorators(
103
131
  ROUTERS[method](path),
104
132
  UseInterceptors(new EncryptedRouteInterceptor(method, stringify)),
@@ -130,7 +158,11 @@ for (const method of [
130
158
  class EncryptedRouteInterceptor implements NestInterceptor {
131
159
  public constructor(
132
160
  private readonly method: string,
133
- private readonly stringify: (input: any) => string,
161
+ private readonly stringify: (
162
+ input: any,
163
+ method: string,
164
+ path: string,
165
+ ) => string,
134
166
  ) {}
135
167
 
136
168
  public intercept(context: ExecutionContext, next: CallHandler) {
@@ -149,11 +181,15 @@ class EncryptedRouteInterceptor implements NestInterceptor {
149
181
  `Error on EncryptedRoute.${this.method}(): no password found.`,
150
182
  );
151
183
 
152
- const headers: Singleton<Record<string, string>> = new Singleton(() => {
153
- const request: express.Request = http.getRequest();
154
- return headers_to_object(request.headers);
155
- });
156
- const body: string | undefined = this.stringify(value);
184
+ const request: express.Request = http.getRequest();
185
+ const headers: Singleton<Record<string, string>> = new Singleton(() =>
186
+ headers_to_object(request.headers),
187
+ );
188
+ const body: string | undefined = this.stringify(
189
+ value,
190
+ request.method,
191
+ request.url,
192
+ );
157
193
  const password: IEncryptionPassword =
158
194
  typeof param === "function"
159
195
  ? param({
@@ -13,7 +13,7 @@ import {
13
13
  import { HttpArgumentsHost } from "@nestjs/common/interfaces";
14
14
  import type express from "express";
15
15
  import { catchError, map } from "rxjs/operators";
16
- import typia from "typia";
16
+ import typia, { IValidation } from "typia";
17
17
 
18
18
  import { IResponseBodyStringifier } from "../options/IResponseBodyStringifier";
19
19
  import { get_path_and_stringify } from "./internal/get_path_and_stringify";
@@ -75,6 +75,64 @@ export namespace TypedRoute {
75
75
  */
76
76
  export const Delete = Generator("Delete");
77
77
 
78
+ /**
79
+ * Set the logger function for the response validation failure.
80
+ *
81
+ * If you've configured the transformation option to `validate.log`
82
+ * in the `tsconfig.json` file, then the error log information of the
83
+ * response validation failure would be logged through this function
84
+ * instead of throwing the 400 bad request error.
85
+ *
86
+ * By the way, be careful. If you've configured the response
87
+ * transformation option to be `validate.log` or `validateEquals.log`,
88
+ * client may get wrong response data. Therefore, this way is not
89
+ * recommendedin the common backend server case.
90
+ *
91
+ * @param func Logger function
92
+ * @default console.log
93
+ */
94
+ export function setValidateErrorLogger(
95
+ func: (log: IValidateErrorLog) => void,
96
+ ): void {
97
+ __logger = func;
98
+ }
99
+
100
+ /**
101
+ * Error log information of the response validation failure.
102
+ *
103
+ * `IValidationErrorLog` is a structure representing the error log
104
+ * information when the returned value from the `@TypedRoute` or
105
+ * `@EncryptedRoute` decorated controller method is not following
106
+ * the promised type `T`.
107
+ *
108
+ * If you've configured the transformation option to `validate.log` or
109
+ * `validateEquals.log` in the `tsconfig.json` file, then this error log
110
+ * information `IValidateErrorLog` would be logged through the
111
+ * {@link setValidateErrorLogger} function instead of throwing the
112
+ * 400 bad request error.
113
+ */
114
+ export interface IValidateErrorLog {
115
+ /**
116
+ * HTTP method of the request.
117
+ */
118
+ method: string;
119
+
120
+ /**
121
+ * HTTP path of the request.
122
+ */
123
+ path: string;
124
+
125
+ /**
126
+ * Validation error informations with detailed reasons.
127
+ */
128
+ errors: IValidation.IError[];
129
+ }
130
+
131
+ /**
132
+ * @internal
133
+ */
134
+ export let __logger: (log: IValidateErrorLog) => void = console.log;
135
+
78
136
  /**
79
137
  * @internal
80
138
  */
@@ -87,9 +145,9 @@ export namespace TypedRoute {
87
145
  ): MethodDecorator;
88
146
 
89
147
  function route(...args: any[]): MethodDecorator {
90
- const [path, stringify] = get_path_and_stringify(`TypedRoute.${method}`)(
91
- ...args,
92
- );
148
+ const [path, stringify] = get_path_and_stringify(() => __logger)(
149
+ `TypedRoute.${method}`,
150
+ )(...args);
93
151
  return applyDecorators(
94
152
  ROUTERS[method](path),
95
153
  UseInterceptors(new TypedRouteInterceptor(stringify)),
@@ -118,15 +176,22 @@ for (const method of [
118
176
  * @internal
119
177
  */
120
178
  class TypedRouteInterceptor implements NestInterceptor {
121
- public constructor(private readonly stringify: (input: any) => string) {}
179
+ public constructor(
180
+ private readonly stringify: (
181
+ input: any,
182
+ method: string,
183
+ path: string,
184
+ ) => string,
185
+ ) {}
122
186
 
123
187
  public intercept(context: ExecutionContext, next: CallHandler) {
124
188
  const http: HttpArgumentsHost = context.switchToHttp();
189
+ const request: express.Request = http.getRequest();
125
190
  const response: express.Response = http.getResponse();
126
191
  response.header("Content-Type", "application/json");
127
192
 
128
193
  return next.handle().pipe(
129
- map((value) => this.stringify(value)),
194
+ map((value) => this.stringify(value, request.method, request.url)),
130
195
  catchError((err) => route_error(http.getRequest(), err)),
131
196
  );
132
197
  }
@@ -3,13 +3,20 @@ import typia, { IValidation, TypeGuardError } from "typia";
3
3
 
4
4
  import { IResponseBodyStringifier } from "../../options/IResponseBodyStringifier";
5
5
  import { NoTransformConfigurationError } from "../NoTransformConfigurationError";
6
+ import { TypedRoute } from "../TypedRoute";
6
7
 
7
8
  /**
8
9
  * @internal
9
10
  */
10
11
  export const get_path_and_stringify =
12
+ (logger: () => (log: TypedRoute.IValidateErrorLog) => void) =>
11
13
  (method: string) =>
12
- (...args: any[]): [string | string[] | undefined, (input: any) => string] => {
14
+ (
15
+ ...args: any[]
16
+ ): [
17
+ string | string[] | undefined,
18
+ (input: any, _method: string, _path: string) => string,
19
+ ] => {
13
20
  const path: string | string[] | null | undefined =
14
21
  args[0] === undefined ||
15
22
  typeof args[0] === "string" ||
@@ -18,23 +25,32 @@ export const get_path_and_stringify =
18
25
  : null;
19
26
  const functor: IResponseBodyStringifier<any> | undefined =
20
27
  path === null ? args[0] : args[1];
21
- return [path ?? undefined, take(method)(functor)];
28
+ return [path ?? undefined, take(logger)(method)(functor)];
22
29
  };
23
30
 
24
31
  /**
25
32
  * @internal
26
33
  */
27
34
  const take =
35
+ (logger: () => (log: TypedRoute.IValidateErrorLog) => void) =>
28
36
  (method: string) =>
29
37
  <T>(functor?: IResponseBodyStringifier<T> | null) => {
30
38
  if (functor === undefined) {
31
39
  NoTransformConfigurationError(method);
32
- return JSON.stringify;
33
- } else if (functor === null) return JSON.stringify;
40
+ return (input: T, _method: string, _path: string) =>
41
+ JSON.stringify(input);
42
+ } else if (functor === null)
43
+ return (input: T, _method: string, _path: string) =>
44
+ JSON.stringify(input);
34
45
  else if (functor.type === "stringify") return functor.stringify;
35
46
  else if (functor.type === "assert") return assert(functor.assert);
36
47
  else if (functor.type === "is") return is(functor.is);
37
48
  else if (functor.type === "validate") return validate(functor.validate);
49
+ else if (
50
+ functor.type === "validate.log" ||
51
+ functor.type === "validateEquals.log"
52
+ )
53
+ return validateLog(logger)(functor.validate);
38
54
  throw new Error(
39
55
  `Error on nestia.core.${method}(): invalid typed stringify function.`,
40
56
  );
@@ -45,7 +61,7 @@ const take =
45
61
  */
46
62
  const assert =
47
63
  <T>(closure: (data: T) => string) =>
48
- (data: T) => {
64
+ (data: T): string => {
49
65
  try {
50
66
  return closure(data);
51
67
  } catch (exp) {
@@ -66,7 +82,7 @@ const assert =
66
82
  */
67
83
  const is =
68
84
  <T>(closure: (data: T) => string | null) =>
69
- (data: T) => {
85
+ (data: T, _method: string, _path: string) => {
70
86
  const result: string | null = closure(data);
71
87
  if (result === null) throw new InternalServerErrorException(MESSAGE);
72
88
  return result;
@@ -77,7 +93,7 @@ const is =
77
93
  */
78
94
  const validate =
79
95
  <T>(closure: (data: T) => IValidation<string>) =>
80
- (data: T) => {
96
+ (data: T, _method: string, _path: string): string => {
81
97
  const result: IValidation<string> = closure(data);
82
98
  if (result.success === false)
83
99
  throw new InternalServerErrorException({
@@ -87,6 +103,20 @@ const validate =
87
103
  return result.data;
88
104
  };
89
105
 
106
+ const validateLog =
107
+ (logger: () => (log: TypedRoute.IValidateErrorLog) => void) =>
108
+ <T>(closure: (data: T) => IValidation<any>) =>
109
+ (data: T, method: string, path: string): string => {
110
+ const result: IValidation<any> = closure(data);
111
+ if (result.success === false)
112
+ logger()({
113
+ errors: result.errors,
114
+ method,
115
+ path,
116
+ });
117
+ return JSON.stringify(data);
118
+ };
119
+
90
120
  /**
91
121
  * @internal
92
122
  */
@@ -13,6 +13,13 @@ export interface INestiaTransformOptions {
13
13
  // PRUNE
14
14
  | "assertPrune"
15
15
  | "validatePrune";
16
- stringify?: "stringify" | "assert" | "is" | "validate" | null;
16
+ stringify?:
17
+ | "stringify"
18
+ | "assert"
19
+ | "is"
20
+ | "validate"
21
+ | "validate.log"
22
+ | "validateEquals.log"
23
+ | null;
17
24
  throws?: boolean;
18
25
  }
@@ -4,7 +4,8 @@ export type IResponseBodyStringifier<T> =
4
4
  | IResponseBodyStringifier.IStringify<T>
5
5
  | IResponseBodyStringifier.IIs<T>
6
6
  | IResponseBodyStringifier.IAssert<T>
7
- | IResponseBodyStringifier.IValidate<T>;
7
+ | IResponseBodyStringifier.IValidate<T>
8
+ | IResponseBodyStringifier.IValidateLog<T>;
8
9
  export namespace IResponseBodyStringifier {
9
10
  export interface IStringify<T> {
10
11
  type: "stringify";
@@ -22,4 +23,8 @@ export namespace IResponseBodyStringifier {
22
23
  type: "validate";
23
24
  validate: (input: T) => IValidation<string>;
24
25
  }
26
+ export interface IValidateLog<T> {
27
+ type: "validate.log" | "validateEquals.log";
28
+ validate: (input: T) => IValidation<T>;
29
+ }
25
30
  }
@@ -1,4 +1,5 @@
1
1
  import ts from "typescript";
2
+ import { ValidateProgrammer } from "typia/lib/programmers/ValidateProgrammer";
2
3
  import { JsonAssertStringifyProgrammer } from "typia/lib/programmers/json/JsonAssertStringifyProgrammer";
3
4
  import { JsonIsStringifyProgrammer } from "typia/lib/programmers/json/JsonIsStringifyProgrammer";
4
5
  import { JsonStringifyProgrammer } from "typia/lib/programmers/json/JsonStringifyProgrammer";
@@ -13,22 +14,23 @@ export namespace TypedRouteProgrammer {
13
14
  (modulo: ts.LeftHandSideExpression) =>
14
15
  (type: ts.Type): ts.Expression => {
15
16
  // GENERATE STRINGIFY PLAN
16
- const parameter = (
17
- key: string,
17
+ const parameter = (props: {
18
+ type: string;
19
+ key: string;
18
20
  programmer: (
19
21
  project: IProject,
20
22
  ) => (
21
23
  modulo: ts.LeftHandSideExpression,
22
- ) => (type: ts.Type) => ts.Expression,
23
- ) =>
24
+ ) => (type: ts.Type) => ts.Expression;
25
+ }) =>
24
26
  ts.factory.createObjectLiteralExpression([
25
27
  ts.factory.createPropertyAssignment(
26
28
  ts.factory.createIdentifier("type"),
27
- ts.factory.createStringLiteral(key),
29
+ ts.factory.createStringLiteral(props.type),
28
30
  ),
29
31
  ts.factory.createPropertyAssignment(
30
- ts.factory.createIdentifier(key),
31
- programmer({
32
+ ts.factory.createIdentifier(props.key),
33
+ props.programmer({
32
34
  ...project,
33
35
  options: {}, // use default option
34
36
  })(modulo)(type),
@@ -37,15 +39,45 @@ export namespace TypedRouteProgrammer {
37
39
 
38
40
  // RETURNS
39
41
  if (project.options.stringify === "is")
40
- return parameter("is", JsonIsStringifyProgrammer.write);
42
+ return parameter({
43
+ type: "is",
44
+ key: "is",
45
+ programmer: JsonIsStringifyProgrammer.write,
46
+ });
41
47
  else if (project.options.stringify === "validate")
42
- return parameter("validate", JsonValidateStringifyProgrammer.write);
48
+ return parameter({
49
+ type: "validate",
50
+ key: "validate",
51
+ programmer: JsonValidateStringifyProgrammer.write,
52
+ });
43
53
  else if (project.options.stringify === "stringify")
44
- return parameter("stringify", JsonStringifyProgrammer.write);
54
+ return parameter({
55
+ type: "stringify",
56
+ key: "stringify",
57
+ programmer: JsonStringifyProgrammer.write,
58
+ });
59
+ else if (project.options.stringify === "validate.log")
60
+ return parameter({
61
+ type: "validate.log",
62
+ key: "validate",
63
+ programmer: (project) => (modulo) =>
64
+ ValidateProgrammer.write(project)(modulo)(false),
65
+ });
66
+ else if (project.options.stringify === "validateEquals.log")
67
+ return parameter({
68
+ type: "validateEquals.log",
69
+ key: "validate",
70
+ programmer: (project) => (modulo) =>
71
+ ValidateProgrammer.write(project)(modulo)(true),
72
+ });
45
73
  else if (project.options.stringify === null)
46
74
  return ts.factory.createNull();
47
75
 
48
76
  // ASSERT IS DEFAULT
49
- return parameter("assert", JsonAssertStringifyProgrammer.write);
77
+ return parameter({
78
+ type: "assert",
79
+ key: "assert",
80
+ programmer: JsonAssertStringifyProgrammer.write,
81
+ });
50
82
  };
51
83
  }