@loopback/rest 6.0.0 → 7.0.1

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.
Files changed (88) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/dist/body-parsers/body-parser.js +3 -0
  3. package/dist/body-parsers/body-parser.js.map +1 -1
  4. package/dist/coercion/coerce-parameter.d.ts +1 -1
  5. package/dist/coercion/coerce-parameter.js +36 -13
  6. package/dist/coercion/coerce-parameter.js.map +1 -1
  7. package/dist/coercion/utils.d.ts +1 -1
  8. package/dist/http-handler.js +5 -0
  9. package/dist/http-handler.js.map +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/providers/find-route.provider.d.ts +0 -2
  12. package/dist/providers/find-route.provider.js +11 -8
  13. package/dist/providers/find-route.provider.js.map +1 -1
  14. package/dist/providers/invoke-method.provider.d.ts +0 -2
  15. package/dist/providers/invoke-method.provider.js +21 -10
  16. package/dist/providers/invoke-method.provider.js.map +1 -1
  17. package/dist/providers/log-error.provider.js +7 -2
  18. package/dist/providers/log-error.provider.js.map +1 -1
  19. package/dist/providers/parse-params.provider.d.ts +0 -2
  20. package/dist/providers/parse-params.provider.js +16 -8
  21. package/dist/providers/parse-params.provider.js.map +1 -1
  22. package/dist/providers/reject.provider.d.ts +1 -1
  23. package/dist/providers/reject.provider.js +2 -1
  24. package/dist/providers/reject.provider.js.map +1 -1
  25. package/dist/providers/send.provider.d.ts +1 -4
  26. package/dist/providers/send.provider.js +11 -13
  27. package/dist/providers/send.provider.js.map +1 -1
  28. package/dist/request-context.js.map +1 -1
  29. package/dist/rest-http-error.d.ts +3 -1
  30. package/dist/rest-http-error.js +3 -2
  31. package/dist/rest-http-error.js.map +1 -1
  32. package/dist/rest.application.js +2 -2
  33. package/dist/rest.application.js.map +1 -1
  34. package/dist/rest.component.js +0 -2
  35. package/dist/rest.component.js.map +1 -1
  36. package/dist/rest.server.d.ts +3 -2
  37. package/dist/rest.server.js +14 -7
  38. package/dist/rest.server.js.map +1 -1
  39. package/dist/router/base-route.js +3 -3
  40. package/dist/router/base-route.js.map +1 -1
  41. package/dist/router/controller-route.js +1 -1
  42. package/dist/router/controller-route.js.map +1 -1
  43. package/dist/router/handler-route.js +1 -1
  44. package/dist/router/handler-route.js.map +1 -1
  45. package/dist/router/redirect-route.js +1 -1
  46. package/dist/router/redirect-route.js.map +1 -1
  47. package/dist/sequence.d.ts +3 -2
  48. package/dist/sequence.js +30 -7
  49. package/dist/sequence.js.map +1 -1
  50. package/dist/spec-enhancers/consolidate.spec-enhancer.js +1 -1
  51. package/dist/spec-enhancers/consolidate.spec-enhancer.js.map +1 -1
  52. package/dist/spec-enhancers/info.spec-enhancer.js +13 -5
  53. package/dist/spec-enhancers/info.spec-enhancer.js.map +1 -1
  54. package/dist/types.d.ts +4 -0
  55. package/dist/validation/ajv-factory.provider.js +5 -3
  56. package/dist/validation/ajv-factory.provider.js.map +1 -1
  57. package/dist/validation/openapi-formats.d.ts +26 -0
  58. package/dist/validation/openapi-formats.js +85 -0
  59. package/dist/validation/openapi-formats.js.map +1 -0
  60. package/dist/validation/request-body.validator.d.ts +4 -4
  61. package/dist/validation/request-body.validator.js +14 -19
  62. package/dist/validation/request-body.validator.js.map +1 -1
  63. package/package.json +24 -21
  64. package/src/body-parsers/body-parser.ts +3 -0
  65. package/src/coercion/coerce-parameter.ts +44 -20
  66. package/src/http-handler.ts +6 -0
  67. package/src/providers/find-route.provider.ts +24 -8
  68. package/src/providers/invoke-method.provider.ts +28 -10
  69. package/src/providers/log-error.provider.ts +2 -1
  70. package/src/providers/parse-params.provider.ts +28 -8
  71. package/src/providers/reject.provider.ts +4 -3
  72. package/src/providers/send.provider.ts +9 -12
  73. package/src/request-context.ts +2 -1
  74. package/src/rest-http-error.ts +6 -2
  75. package/src/rest.application.ts +2 -2
  76. package/src/rest.component.ts +0 -2
  77. package/src/rest.server.ts +17 -8
  78. package/src/router/base-route.ts +3 -3
  79. package/src/router/controller-route.ts +1 -1
  80. package/src/router/handler-route.ts +3 -1
  81. package/src/router/redirect-route.ts +1 -1
  82. package/src/sequence.ts +45 -3
  83. package/src/spec-enhancers/consolidate.spec-enhancer.ts +2 -2
  84. package/src/spec-enhancers/info.spec-enhancer.ts +15 -6
  85. package/src/types.ts +5 -0
  86. package/src/validation/ajv-factory.provider.ts +8 -4
  87. package/src/validation/openapi-formats.ts +92 -0
  88. package/src/validation/request-body.validator.ts +26 -25
@@ -21,17 +21,25 @@ let InfoSpecEnhancer = InfoSpecEnhancer_1 = class InfoSpecEnhancer {
21
21
  this.name = 'info';
22
22
  }
23
23
  modifySpec(spec) {
24
+ var _a, _b, _c, _d;
24
25
  if (this.pkg == null) {
25
26
  debug('Application metadata is not found. Skipping spec enhancing.');
26
27
  return spec;
27
28
  }
28
29
  const contact = InfoSpecEnhancer_1.parseAuthor(this.pkg.author);
30
+ // Only override `info` if the `spec.info` is not customized
31
+ const overrideInfo = spec.info.title === openapi_v3_1.DEFAULT_OPENAPI_SPEC_INFO.title &&
32
+ spec.info.version === openapi_v3_1.DEFAULT_OPENAPI_SPEC_INFO.version;
29
33
  const patchSpec = {
30
34
  info: {
31
- title: this.pkg.name,
32
- description: this.pkg.description,
33
- version: this.pkg.version,
34
- contact,
35
+ title: overrideInfo ? this.pkg.name : (_a = spec.info.title) !== null && _a !== void 0 ? _a : this.pkg.name,
36
+ description: overrideInfo
37
+ ? this.pkg.description
38
+ : (_b = spec.info.description) !== null && _b !== void 0 ? _b : this.pkg.description,
39
+ version: overrideInfo
40
+ ? this.pkg.version
41
+ : (_c = spec.info.version) !== null && _c !== void 0 ? _c : this.pkg.version,
42
+ contact: overrideInfo ? contact : (_d = spec.info.contact) !== null && _d !== void 0 ? _d : contact,
35
43
  },
36
44
  };
37
45
  debug('Enhancing OpenAPI spec with %j', patchSpec);
@@ -77,7 +85,7 @@ let InfoSpecEnhancer = InfoSpecEnhancer_1 = class InfoSpecEnhancer {
77
85
  }
78
86
  };
79
87
  InfoSpecEnhancer = InfoSpecEnhancer_1 = tslib_1.__decorate([
80
- core_1.bind(openapi_v3_1.asSpecEnhancer, { scope: core_1.BindingScope.SINGLETON }),
88
+ core_1.injectable(openapi_v3_1.asSpecEnhancer, { scope: core_1.BindingScope.SINGLETON }),
81
89
  tslib_1.__param(0, core_1.inject(core_1.CoreBindings.APPLICATION_METADATA, { optional: true })),
82
90
  tslib_1.__metadata("design:paramtypes", [Object])
83
91
  ], InfoSpecEnhancer);
@@ -1 +1 @@
1
- {"version":3,"file":"info.spec-enhancer.js","sourceRoot":"","sources":["../../src/spec-enhancers/info.spec-enhancer.ts"],"names":[],"mappings":";AAAA,iDAAiD;AACjD,8BAA8B;AAC9B,+CAA+C;AAC/C,gEAAgE;;;;;AAEhE,yCAQwB;AACxB,qDAM8B;AAC9B,0DAAiC;AAEjC,MAAM,KAAK,GAAG,eAAY,CAAC,qCAAqC,CAAC,CAAC;AAElE;;;GAGG;AAEH,IAAa,gBAAgB,wBAA7B,MAAa,gBAAgB;IAG3B,YAEW,GAAyB;QAAzB,QAAG,GAAH,GAAG,CAAsB;QAJpC,SAAI,GAAG,MAAM,CAAC;IAKX,CAAC;IAEJ,UAAU,CAAC,IAAiB;QAC1B,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE;YACpB,KAAK,CAAC,6DAA6D,CAAC,CAAC;YACrE,OAAO,IAAI,CAAC;SACb;QACD,MAAM,OAAO,GAAkB,kBAAgB,CAAC,WAAW,CACzD,IAAI,CAAC,GAAG,CAAC,MAAM,CAChB,CAAC;QACF,MAAM,SAAS,GAAG;YAChB,IAAI,EAAE;gBACJ,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI;gBACpB,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW;gBACjC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO;gBACzB,OAAO;aACR;SACF,CAAC;QACF,KAAK,CAAC,gCAAgC,EAAE,SAAS,CAAC,CAAC;QACnD,OAAO,6BAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,WAAW,CAAC,MAAiB;;QAC1C,IAAI,OAAO,GAAkB,EAAE,CAAC;QAChC,IAAI,MAAM,IAAI,IAAI,EAAE;YAClB,OAAO,GAAG,EAAE,CAAC;SACd;aAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;YACrC,kEAAkE;YAClE,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,UAAU;YAC3C,MAAM,QAAQ,GAAG,cAAc,CAAC,CAAC,QAAQ;YACzC,MAAM,SAAS,GAAG,YAAY,CAAC;YAC/B,OAAO,GAAG;gBACR,IAAI,cAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,0CAAG,CAAC,2CAAG,IAAI,EAAE;gBACzC,KAAK,cAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,0CAAG,CAAC,2CAAG,IAAI,EAAE;gBAC3C,GAAG,cAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,0CAAG,CAAC,2CAAG,IAAI,EAAE;aACxC,CAAC;SACH;aAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;YACrC,MAAM,SAAS,GAAG,MAAoB,CAAC;YACvC,OAAO,GAAG;gBACR,IAAI,EAAE,SAAS,CAAC,IAAc;gBAC9B,KAAK,EAAE,SAAS,CAAC,KAAe;gBAChC,GAAG,EAAE,SAAS,CAAC,GAAa;aAC7B,CAAC;SACH;QACD,+BAA+B;QAC/B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE;YACvB,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI;gBAAE,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;SAC3C;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF,CAAA;AA9DY,gBAAgB;IAD5B,WAAI,CAAC,2BAAc,EAAE,EAAC,KAAK,EAAE,mBAAY,CAAC,SAAS,EAAC,CAAC;IAKjD,mBAAA,aAAM,CAAC,mBAAY,CAAC,oBAAoB,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAA;;GAJnD,gBAAgB,CA8D5B;AA9DY,4CAAgB"}
1
+ {"version":3,"file":"info.spec-enhancer.js","sourceRoot":"","sources":["../../src/spec-enhancers/info.spec-enhancer.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -86,6 +86,10 @@ export interface ValueValidationOptions extends ValidationOptions {
86
86
  * 'query', 'cookie', etc...
87
87
  */
88
88
  source?: string;
89
+ /**
90
+ * Parameter name, as provided in `ParameterObject#name` property.
91
+ */
92
+ name?: string;
89
93
  }
90
94
  /**
91
95
  * Options for request body validation using AJV
@@ -10,6 +10,7 @@ const core_1 = require("@loopback/core");
10
10
  const ajv_1 = tslib_1.__importDefault(require("ajv"));
11
11
  const debug_1 = tslib_1.__importDefault(require("debug"));
12
12
  const keys_1 = require("../keys");
13
+ const openapi_formats_1 = require("./openapi-formats");
13
14
  const debug = debug_1.default('loopback:rest:ajv');
14
15
  const ajvKeywords = require('ajv-keywords');
15
16
  const ajvErrors = require('ajv-errors');
@@ -38,8 +39,6 @@ let AjvFactoryProvider = class AjvFactoryProvider {
38
39
  jsonPointers: true,
39
40
  // nullable: support keyword "nullable" from Open API 3 specification.
40
41
  nullable: true,
41
- // Allow OpenAPI spec binary format
42
- unknownFormats: ['binary'],
43
42
  ...validationOptions,
44
43
  };
45
44
  debug('AJV options', validationOptions);
@@ -62,6 +61,9 @@ let AjvFactoryProvider = class AjvFactoryProvider {
62
61
  ajvInst.addKeyword(keyword.name, keyword);
63
62
  });
64
63
  }
64
+ for (const format of openapi_formats_1.openapiFormats) {
65
+ ajvInst.addFormat(format.name, format);
66
+ }
65
67
  if (this.formats) {
66
68
  this.formats.forEach(format => {
67
69
  debug('Adding Ajv format %s', format.name);
@@ -81,7 +83,7 @@ tslib_1.__decorate([
81
83
  tslib_1.__metadata("design:type", Array)
82
84
  ], AjvFactoryProvider.prototype, "formats", void 0);
83
85
  AjvFactoryProvider = tslib_1.__decorate([
84
- core_1.bind({ scope: core_1.BindingScope.SINGLETON }),
86
+ core_1.injectable({ scope: core_1.BindingScope.SINGLETON }),
85
87
  tslib_1.__param(0, core_1.inject(keys_1.RestBindings.REQUEST_BODY_PARSER_OPTIONS.deepProperty('validation'), { optional: true })),
86
88
  tslib_1.__metadata("design:paramtypes", [Object])
87
89
  ], AjvFactoryProvider);
@@ -1 +1 @@
1
- {"version":3,"file":"ajv-factory.provider.js","sourceRoot":"","sources":["../../src/validation/ajv-factory.provider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ajv-factory.provider.js","sourceRoot":"","sources":["../../src/validation/ajv-factory.provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { AjvFormat } from '../types';
2
+ /**
3
+ * int32: [-2147483648, 21474836 47]
4
+ */
5
+ export declare const int32Format: AjvFormat;
6
+ /**
7
+ * int64: [-9223372036854775808, 9223372036854775807]
8
+ */
9
+ export declare const int64Format: AjvFormat;
10
+ /**
11
+ * float: [-2^128, 2^128]
12
+ */
13
+ export declare const floatFormat: AjvFormat;
14
+ /**
15
+ * double: [-2^1024, 2^1024]
16
+ */
17
+ export declare const doubleFormat: AjvFormat;
18
+ /**
19
+ * Base64 encoded string
20
+ */
21
+ export declare const byteFormat: AjvFormat;
22
+ /**
23
+ * Binary string
24
+ */
25
+ export declare const binaryFormat: AjvFormat;
26
+ export declare const openapiFormats: AjvFormat[];
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ // Copyright IBM Corp. 2020. All Rights Reserved.
3
+ // Node module: @loopback/rest
4
+ // This file is licensed under the MIT License.
5
+ // License text available at https://opensource.org/licenses/MIT
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.openapiFormats = exports.binaryFormat = exports.byteFormat = exports.doubleFormat = exports.floatFormat = exports.int64Format = exports.int32Format = void 0;
8
+ /**
9
+ * int32: [-2147483648, 21474836 47]
10
+ */
11
+ exports.int32Format = {
12
+ name: 'int32',
13
+ type: 'number',
14
+ validate: (value) => {
15
+ return (Number.isInteger(value) && value >= -2147483648 && value <= 2147483647);
16
+ },
17
+ async: false,
18
+ };
19
+ /**
20
+ * int64: [-9223372036854775808, 9223372036854775807]
21
+ */
22
+ exports.int64Format = {
23
+ name: 'int64',
24
+ type: 'number',
25
+ validate: (value) => {
26
+ const max = Number.MAX_SAFE_INTEGER; // 9007199254740991
27
+ const min = Number.MIN_SAFE_INTEGER; // -9007199254740991
28
+ return Number.isInteger(value) && value >= min && value <= max;
29
+ },
30
+ async: false,
31
+ };
32
+ /**
33
+ * float: [-2^128, 2^128]
34
+ */
35
+ exports.floatFormat = {
36
+ name: 'float',
37
+ type: 'number',
38
+ validate: (value) => {
39
+ return value >= -Math.pow(2, 128) && value <= Math.pow(2, 128);
40
+ },
41
+ async: false,
42
+ };
43
+ /**
44
+ * double: [-2^1024, 2^1024]
45
+ */
46
+ exports.doubleFormat = {
47
+ name: 'double',
48
+ type: 'number',
49
+ validate: (value) => {
50
+ const max = Number.MAX_VALUE; // 1.7976931348623157e+308
51
+ const min = -Number.MAX_VALUE; // -1.7976931348623157e+308
52
+ return value >= min && value <= max;
53
+ },
54
+ async: false,
55
+ };
56
+ /**
57
+ * Base64 encoded string
58
+ */
59
+ exports.byteFormat = {
60
+ name: 'byte',
61
+ type: 'string',
62
+ validate: (value) => {
63
+ const base64 = Buffer.from(value, 'base64').toString('base64');
64
+ return value === base64;
65
+ },
66
+ async: false,
67
+ };
68
+ /**
69
+ * Binary string
70
+ */
71
+ exports.binaryFormat = {
72
+ name: 'binary',
73
+ type: 'string',
74
+ validate: (value) => true,
75
+ async: false,
76
+ };
77
+ exports.openapiFormats = [
78
+ exports.int32Format,
79
+ exports.int64Format,
80
+ exports.floatFormat,
81
+ exports.doubleFormat,
82
+ exports.byteFormat,
83
+ exports.binaryFormat,
84
+ ];
85
+ //# sourceMappingURL=openapi-formats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi-formats.js","sourceRoot":"","sources":["../../src/validation/openapi-formats.ts"],"names":[],"mappings":";AAAA,iDAAiD;AACjD,8BAA8B;AAC9B,+CAA+C;AAC/C,gEAAgE;;;AAIhE;;GAEG;AACU,QAAA,WAAW,GAAc;IACpC,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;QAC1B,OAAO,CACL,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,IAAI,KAAK,IAAI,UAAU,CACvE,CAAC;IACJ,CAAC;IACD,KAAK,EAAE,KAAK;CACb,CAAC;AAEF;;GAEG;AACU,QAAA,WAAW,GAAc;IACpC,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;QAC1B,MAAM,GAAG,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC,mBAAmB;QACxD,MAAM,GAAG,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB;QACzD,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,CAAC;IACjE,CAAC;IACD,KAAK,EAAE,KAAK;CACb,CAAC;AAEF;;GAEG;AACU,QAAA,WAAW,GAAc;IACpC,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;QAC1B,OAAO,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjE,CAAC;IACD,KAAK,EAAE,KAAK;CACb,CAAC;AAEF;;GAEG;AACU,QAAA,YAAY,GAAc;IACrC,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;QAC1B,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,0BAA0B;QACxD,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,2BAA2B;QAC1D,OAAO,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,CAAC;IACtC,CAAC;IACD,KAAK,EAAE,KAAK;CACb,CAAC;AAEF;;GAEG;AACU,QAAA,UAAU,GAAc;IACnC,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;QAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC/D,OAAO,KAAK,KAAK,MAAM,CAAC;IAC1B,CAAC;IACD,KAAK,EAAE,KAAK;CACb,CAAC;AAEF;;GAEG;AACU,QAAA,YAAY,GAAc;IACrC,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI;IACjC,KAAK,EAAE,KAAK;CACb,CAAC;AAEW,QAAA,cAAc,GAAgB;IACzC,mBAAW;IACX,mBAAW;IACX,mBAAW;IACX,oBAAY;IACZ,kBAAU;IACV,oBAAY;CACb,CAAC"}
@@ -13,10 +13,10 @@ import { ValidationOptions, ValueValidationOptions } from '../types';
13
13
  */
14
14
  export declare function validateRequestBody(body: RequestBody, requestBodySpec?: RequestBodyObject, globalSchemas?: SchemasObject, options?: ValidationOptions): Promise<void>;
15
15
  /**
16
- * Validate the request body data against JSON schema.
17
- * @param body - The request body data.
16
+ * Validate the value against JSON schema.
17
+ * @param value - The data value.
18
18
  * @param schema - The JSON schema used to perform the validation.
19
19
  * @param globalSchemas - Schema references.
20
- * @param options - Request body validation options.
20
+ * @param options - Value validation options.
21
21
  */
22
- export declare function validateValueAgainstSchema(value: any, schema: SchemaObject | ReferenceObject, globalSchemas?: SchemasObject, options?: ValueValidationOptions): Promise<void>;
22
+ export declare function validateValueAgainstSchema(value: any, schema: SchemaObject | ReferenceObject, globalSchemas?: SchemasObject, options?: ValueValidationOptions): Promise<any>;
@@ -8,7 +8,6 @@ exports.validateValueAgainstSchema = exports.validateRequestBody = void 0;
8
8
  const tslib_1 = require("tslib");
9
9
  const openapi_v3_1 = require("@loopback/openapi-v3");
10
10
  const debug_1 = tslib_1.__importDefault(require("debug"));
11
- const lodash_1 = tslib_1.__importDefault(require("lodash"));
12
11
  const util_1 = tslib_1.__importDefault(require("util"));
13
12
  const __1 = require("..");
14
13
  const ajv_factory_provider_1 = require("./ajv-factory.provider");
@@ -86,16 +85,16 @@ function getKeyForOptions(options = ajv_factory_provider_1.DEFAULT_AJV_VALIDATIO
86
85
  return JSON.stringify(ajvOptions);
87
86
  }
88
87
  /**
89
- * Validate the request body data against JSON schema.
90
- * @param body - The request body data.
88
+ * Validate the value against JSON schema.
89
+ * @param value - The data value.
91
90
  * @param schema - The JSON schema used to perform the validation.
92
91
  * @param globalSchemas - Schema references.
93
- * @param options - Request body validation options.
92
+ * @param options - Value validation options.
94
93
  */
95
94
  async function validateValueAgainstSchema(
96
95
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
97
96
  value, schema, globalSchemas = {}, options = {}) {
98
- var _a, _b;
97
+ var _a, _b, _c;
99
98
  let validate;
100
99
  const cache = (_a = options.compiledSchemaCache) !== null && _a !== void 0 ? _a : DEFAULT_COMPILED_SCHEMA_CACHE;
101
100
  const key = getKeyForOptions(options);
@@ -115,11 +114,8 @@ value, schema, globalSchemas = {}, options = {}) {
115
114
  let validationErrors = [];
116
115
  try {
117
116
  const validationResult = await validate(value);
118
- // When value is optional & values is empty / null, ajv returns null
119
- if (validationResult || validationResult === null) {
120
- debug(`Value from ${options.source} passed AJV validation.`);
121
- return;
122
- }
117
+ debug(`Value from ${options.source} passed AJV validation.`, validationResult);
118
+ return validationResult;
123
119
  }
124
120
  catch (error) {
125
121
  validationErrors = error.errors;
@@ -133,24 +129,23 @@ value, schema, globalSchemas = {}, options = {}) {
133
129
  }
134
130
  // Throw invalid request body error
135
131
  if (options.source === 'body') {
136
- const error = __1.RestHttpErrors.invalidRequestBody();
137
- addErrorDetails(error, validationErrors);
132
+ const error = __1.RestHttpErrors.invalidRequestBody(buildErrorDetails(validationErrors));
138
133
  throw error;
139
134
  }
140
135
  // Throw invalid value error
141
- const error = new __1.HttpErrors.BadRequest('Invalid value.');
142
- addErrorDetails(error, validationErrors);
136
+ const error = __1.RestHttpErrors.invalidData(value, (_c = options.name) !== null && _c !== void 0 ? _c : '(unknown)', {
137
+ details: buildErrorDetails(validationErrors),
138
+ });
143
139
  throw error;
144
140
  }
145
141
  exports.validateValueAgainstSchema = validateValueAgainstSchema;
146
- function addErrorDetails(
147
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
148
- error, validationErrors) {
149
- error.details = lodash_1.default.map(validationErrors, e => {
142
+ function buildErrorDetails(validationErrors) {
143
+ return validationErrors.map((e) => {
144
+ var _a;
150
145
  return {
151
146
  path: e.dataPath,
152
147
  code: e.keyword,
153
- message: e.message,
148
+ message: (_a = e.message) !== null && _a !== void 0 ? _a : `must pass validation rule ${e.keyword}`,
154
149
  info: e.params,
155
150
  };
156
151
  });
@@ -1 +1 @@
1
- {"version":3,"file":"request-body.validator.js","sourceRoot":"","sources":["../../src/validation/request-body.validator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"request-body.validator.js","sourceRoot":"","sources":["../../src/validation/request-body.validator.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loopback/rest",
3
- "version": "6.0.0",
3
+ "version": "7.0.1",
4
4
  "description": "Expose controllers as REST endpoints and route REST API requests to controller methods",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -23,21 +23,23 @@
23
23
  "publishConfig": {
24
24
  "access": "public"
25
25
  },
26
+ "peerDependencies": {
27
+ "@loopback/core": "^2.10.1"
28
+ },
26
29
  "dependencies": {
27
- "@loopback/core": "^2.9.3",
28
- "@loopback/express": "^1.3.0",
29
- "@loopback/http-server": "^2.1.11",
30
- "@loopback/openapi-v3": "^3.4.7",
31
- "@openapi-contrib/openapi-schema-to-json-schema": "^3.0.3",
30
+ "@loopback/express": "^2.0.1",
31
+ "@loopback/http-server": "^2.2.2",
32
+ "@loopback/openapi-v3": "^4.0.1",
33
+ "@openapi-contrib/openapi-schema-to-json-schema": "^3.0.4",
32
34
  "@types/body-parser": "^1.19.0",
33
35
  "@types/cors": "^2.8.7",
34
- "@types/express": "^4.17.7",
35
- "@types/express-serve-static-core": "^4.17.9",
36
+ "@types/express": "^4.17.8",
37
+ "@types/express-serve-static-core": "^4.17.12",
36
38
  "@types/http-errors": "^1.8.0",
37
39
  "@types/on-finished": "^2.3.1",
38
40
  "@types/serve-static": "1.13.5",
39
41
  "@types/type-is": "^1.6.3",
40
- "ajv": "^6.12.3",
42
+ "ajv": "^6.12.5",
41
43
  "ajv-errors": "^1.0.1",
42
44
  "ajv-keywords": "^3.5.2",
43
45
  "body-parser": "^1.19.0",
@@ -47,29 +49,30 @@
47
49
  "http-errors": "^1.8.0",
48
50
  "js-yaml": "^3.14.0",
49
51
  "json-schema-compare": "^0.2.2",
50
- "lodash": "^4.17.19",
52
+ "lodash": "^4.17.20",
51
53
  "on-finished": "^2.3.0",
52
54
  "path-to-regexp": "^6.1.0",
53
55
  "qs": "^6.9.4",
54
56
  "strong-error-handler": "^3.5.0",
55
- "tslib": "^2.0.0",
57
+ "tslib": "^2.0.1",
56
58
  "type-is": "^1.6.18",
57
59
  "validator": "^13.1.1"
58
60
  },
59
61
  "devDependencies": {
60
- "@loopback/build": "^6.2.0",
61
- "@loopback/eslint-config": "^9.0.0",
62
- "@loopback/openapi-spec-builder": "^2.1.11",
63
- "@loopback/repository": "^2.11.0",
64
- "@loopback/testlab": "^3.2.2",
62
+ "@loopback/build": "^6.2.4",
63
+ "@loopback/core": "^2.10.1",
64
+ "@loopback/eslint-config": "^10.0.0",
65
+ "@loopback/openapi-spec-builder": "^2.1.15",
66
+ "@loopback/repository": "^3.0.1",
67
+ "@loopback/testlab": "^3.2.6",
65
68
  "@types/debug": "^4.1.5",
66
69
  "@types/js-yaml": "^3.12.5",
67
70
  "@types/json-schema-compare": "^0.2.0",
68
- "@types/lodash": "^4.14.158",
69
- "@types/multer": "^1.4.3",
70
- "@types/node": "^10.17.28",
71
+ "@types/lodash": "^4.14.161",
72
+ "@types/multer": "^1.4.4",
73
+ "@types/node": "^10.17.35",
71
74
  "@types/on-finished": "^2.3.1",
72
- "@types/qs": "^6.9.4",
75
+ "@types/qs": "^6.9.5",
73
76
  "multer": "^1.4.2"
74
77
  },
75
78
  "files": [
@@ -83,5 +86,5 @@
83
86
  "url": "https://github.com/strongloop/loopback-next.git",
84
87
  "directory": "packages/rest"
85
88
  },
86
- "gitHead": "1619bf0c29aa03853a7977212e60028664fca640"
89
+ "gitHead": "79327fd7e68ebb05be0aa689f4986b54e2a99a6b"
87
90
  }
@@ -61,15 +61,18 @@ export class RequestBodyParser {
61
61
  if (customParser) {
62
62
  // Invoke the custom parser
63
63
  const body = await this._invokeCustomParser(customParser, request);
64
+ debug('Parsed request body', body);
64
65
  return Object.assign(requestBody, body);
65
66
  } else {
66
67
  const parser = this._findParser(matchedMediaType);
67
68
  if (parser) {
68
69
  const body = await parser.parse(request);
70
+ debug('Parsed request body', body);
69
71
  return Object.assign(requestBody, body);
70
72
  }
71
73
  }
72
74
  } catch (err) {
75
+ debug('Request body parsing error', err);
73
76
  throw normalizeParsingError(err);
74
77
  }
75
78
 
@@ -13,10 +13,10 @@ import debugModule from 'debug';
13
13
  import {
14
14
  RestHttpErrors,
15
15
  validateValueAgainstSchema,
16
- ValidationOptions,
17
16
  ValueValidationOptions,
18
17
  } from '../';
19
18
  import {parseJson} from '../parse-json';
19
+ import {ValidationOptions} from '../types';
20
20
  import {DEFAULT_AJV_VALIDATION_OPTIONS} from '../validation/ajv-factory.provider';
21
21
  import {
22
22
  DateCoercionOptions,
@@ -61,31 +61,51 @@ export async function coerceParameter(
61
61
  validator.validateParamBeforeCoercion(data);
62
62
  if (data === undefined) return data;
63
63
 
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ let result: any = data;
66
+
64
67
  switch (OAIType) {
65
68
  case 'byte':
66
- return coerceBuffer(data, spec);
69
+ result = coerceBuffer(data, spec);
70
+ break;
67
71
  case 'date':
68
- return coerceDatetime(data, spec, {dateOnly: true});
72
+ result = coerceDatetime(data, spec, {dateOnly: true});
73
+ break;
69
74
  case 'date-time':
70
- return coerceDatetime(data, spec);
75
+ result = coerceDatetime(data, spec);
76
+ break;
71
77
  case 'float':
72
78
  case 'double':
73
79
  case 'number':
74
- return coerceNumber(data, spec);
80
+ result = coerceNumber(data, spec);
81
+ break;
75
82
  case 'long':
76
- return coerceInteger(data, spec, {isLong: true});
83
+ result = coerceInteger(data, spec, {isLong: true});
84
+ break;
77
85
  case 'integer':
78
- return coerceInteger(data, spec);
86
+ result = coerceInteger(data, spec);
87
+ break;
79
88
  case 'boolean':
80
- return coerceBoolean(data, spec);
89
+ result = coerceBoolean(data, spec);
90
+ break;
81
91
  case 'object':
82
- return coerceObject(data, spec, options);
92
+ result = await coerceObject(data, spec);
93
+ break;
83
94
  case 'string':
84
95
  case 'password':
85
- return coerceString(data, spec);
86
- default:
87
- return data;
96
+ result = coerceString(data, spec);
97
+ break;
98
+ }
99
+
100
+ if (result != null) {
101
+ // For date/date-time/byte, we need to pass the raw string value to AJV
102
+ if (OAIType === 'date' || OAIType === 'date-time' || OAIType === 'byte') {
103
+ await validateParam(spec, data, options);
104
+ return result;
105
+ }
106
+ result = await validateParam(spec, result, options);
88
107
  }
108
+ return result;
89
109
  }
90
110
 
91
111
  function coerceString(data: string | object, spec: ParameterObject) {
@@ -165,11 +185,7 @@ function coerceBoolean(data: string | object, spec: ParameterObject) {
165
185
  throw RestHttpErrors.invalidData(data, spec.name);
166
186
  }
167
187
 
168
- async function coerceObject(
169
- input: string | object,
170
- spec: ParameterObject,
171
- options: ValidationOptions = DEFAULT_AJV_VALIDATION_OPTIONS,
172
- ) {
188
+ async function coerceObject(input: string | object, spec: ParameterObject) {
173
189
  const data = parseJsonIfNeeded(input, spec);
174
190
 
175
191
  if (data == null) {
@@ -180,17 +196,25 @@ async function coerceObject(
180
196
  if (typeof data !== 'object' || Array.isArray(data))
181
197
  throw RestHttpErrors.invalidData(input, spec.name);
182
198
 
199
+ return data;
200
+ }
201
+
202
+ function validateParam(
203
+ spec: ParameterObject,
204
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
205
+ data: any,
206
+ options: ValidationOptions = DEFAULT_AJV_VALIDATION_OPTIONS,
207
+ ) {
183
208
  const schema = extractSchemaFromSpec(spec);
184
209
  if (schema) {
185
210
  // Apply coercion based on properties defined by spec.schema
186
- await validateValueAgainstSchema(
211
+ return validateValueAgainstSchema(
187
212
  data,
188
213
  schema,
189
214
  {},
190
- {...options, coerceTypes: true, source: 'parameter'},
215
+ {...options, coerceTypes: true, source: 'parameter', name: spec.name},
191
216
  );
192
217
  }
193
-
194
218
  return data;
195
219
  }
196
220
 
@@ -4,6 +4,7 @@
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
6
  import {Context} from '@loopback/core';
7
+ import {MIDDLEWARE_CONTEXT} from '@loopback/express';
7
8
  import {
8
9
  ComponentsObject,
9
10
  ControllerSpec,
@@ -109,6 +110,11 @@ export class HttpHandler {
109
110
  this._serverConfig,
110
111
  );
111
112
 
113
+ // Set the request context as a property of Express request object so that
114
+ // downstream Express native integration can access `RequestContext`
115
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
116
+ (request as any)[MIDDLEWARE_CONTEXT] = requestContext;
117
+
112
118
  const sequence = await requestContext.get<SequenceHandler>(
113
119
  RestBindings.SEQUENCE,
114
120
  );