@loopback/rest 5.0.1 → 5.2.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.
Files changed (118) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/dist/body-parsers/body-parser.d.ts +1 -1
  3. package/dist/body-parsers/body-parser.helpers.js +1 -1
  4. package/dist/body-parsers/body-parser.js +112 -115
  5. package/dist/body-parsers/body-parser.js.map +1 -1
  6. package/dist/body-parsers/body-parser.json.js +24 -27
  7. package/dist/body-parsers/body-parser.json.js.map +1 -1
  8. package/dist/body-parsers/body-parser.raw.js +19 -22
  9. package/dist/body-parsers/body-parser.raw.js.map +1 -1
  10. package/dist/body-parsers/body-parser.text.js +21 -24
  11. package/dist/body-parsers/body-parser.text.js.map +1 -1
  12. package/dist/body-parsers/body-parser.urlencoded.js +19 -22
  13. package/dist/body-parsers/body-parser.urlencoded.js.map +1 -1
  14. package/dist/body-parsers/index.js +1 -1
  15. package/dist/body-parsers/index.js.map +1 -1
  16. package/dist/coercion/coerce-parameter.d.ts +3 -1
  17. package/dist/coercion/coerce-parameter.js +28 -12
  18. package/dist/coercion/coerce-parameter.js.map +1 -1
  19. package/dist/coercion/validator.js +1 -1
  20. package/dist/http-handler.d.ts +1 -1
  21. package/dist/http-handler.js +1 -1
  22. package/dist/index.d.ts +1 -0
  23. package/dist/index.js +2 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/keys.d.ts +1 -1
  26. package/dist/keys.js +33 -34
  27. package/dist/keys.js.map +1 -1
  28. package/dist/parser.js +1 -1
  29. package/dist/parser.js.map +1 -1
  30. package/dist/providers/find-route.provider.d.ts +1 -1
  31. package/dist/providers/find-route.provider.js +21 -24
  32. package/dist/providers/find-route.provider.js.map +1 -1
  33. package/dist/providers/invoke-method.provider.d.ts +1 -1
  34. package/dist/providers/invoke-method.provider.js +16 -19
  35. package/dist/providers/invoke-method.provider.js.map +1 -1
  36. package/dist/providers/log-error.provider.d.ts +1 -1
  37. package/dist/providers/parse-params.provider.d.ts +1 -1
  38. package/dist/providers/parse-params.provider.js +20 -23
  39. package/dist/providers/parse-params.provider.js.map +1 -1
  40. package/dist/providers/reject.provider.d.ts +1 -1
  41. package/dist/providers/reject.provider.js +25 -28
  42. package/dist/providers/reject.provider.js.map +1 -1
  43. package/dist/providers/send.provider.d.ts +1 -1
  44. package/dist/request-context.d.ts +1 -1
  45. package/dist/rest.application.d.ts +15 -2
  46. package/dist/rest.application.js +14 -1
  47. package/dist/rest.application.js.map +1 -1
  48. package/dist/rest.component.d.ts +1 -1
  49. package/dist/rest.component.js +46 -49
  50. package/dist/rest.component.js.map +1 -1
  51. package/dist/rest.server.d.ts +15 -2
  52. package/dist/rest.server.js +615 -588
  53. package/dist/rest.server.js.map +1 -1
  54. package/dist/router/base-route.d.ts +1 -1
  55. package/dist/router/controller-route.d.ts +1 -1
  56. package/dist/router/controller-route.js +3 -4
  57. package/dist/router/controller-route.js.map +1 -1
  58. package/dist/router/external-express-routes.js +1 -1
  59. package/dist/router/external-express-routes.js.map +1 -1
  60. package/dist/router/handler-route.d.ts +1 -1
  61. package/dist/router/handler-route.js +2 -2
  62. package/dist/router/handler-route.js.map +1 -1
  63. package/dist/router/redirect-route.js +2 -2
  64. package/dist/router/redirect-route.js.map +1 -1
  65. package/dist/router/regexp-router.js +55 -58
  66. package/dist/router/regexp-router.js.map +1 -1
  67. package/dist/router/route-entry.d.ts +1 -1
  68. package/dist/router/trie-router.js +32 -35
  69. package/dist/router/trie-router.js.map +1 -1
  70. package/dist/sequence.d.ts +1 -1
  71. package/dist/sequence.js +74 -77
  72. package/dist/sequence.js.map +1 -1
  73. package/dist/spec-enhancers/consolidate.spec-enhancer.js +89 -92
  74. package/dist/spec-enhancers/consolidate.spec-enhancer.js.map +1 -1
  75. package/dist/spec-enhancers/info.spec-enhancer.js +63 -67
  76. package/dist/spec-enhancers/info.spec-enhancer.js.map +1 -1
  77. package/dist/types.d.ts +10 -0
  78. package/dist/validation/ajv-factory.provider.js +63 -66
  79. package/dist/validation/ajv-factory.provider.js.map +1 -1
  80. package/dist/validation/request-body.validator.d.ts +10 -2
  81. package/dist/validation/request-body.validator.js +25 -9
  82. package/dist/validation/request-body.validator.js.map +1 -1
  83. package/package.json +25 -23
  84. package/src/body-parsers/body-parser.helpers.ts +1 -1
  85. package/src/body-parsers/body-parser.json.ts +1 -1
  86. package/src/body-parsers/body-parser.raw.ts +1 -1
  87. package/src/body-parsers/body-parser.text.ts +1 -1
  88. package/src/body-parsers/body-parser.ts +1 -1
  89. package/src/body-parsers/body-parser.urlencoded.ts +1 -1
  90. package/src/body-parsers/index.ts +1 -1
  91. package/src/coercion/coerce-parameter.ts +55 -15
  92. package/src/coercion/validator.ts +1 -1
  93. package/src/http-handler.ts +2 -2
  94. package/src/index.ts +6 -0
  95. package/src/keys.ts +1 -2
  96. package/src/parser.ts +1 -1
  97. package/src/providers/find-route.provider.ts +1 -1
  98. package/src/providers/invoke-method.provider.ts +1 -1
  99. package/src/providers/log-error.provider.ts +1 -1
  100. package/src/providers/parse-params.provider.ts +1 -1
  101. package/src/providers/reject.provider.ts +1 -1
  102. package/src/providers/send.provider.ts +1 -1
  103. package/src/request-context.ts +1 -1
  104. package/src/rest.application.ts +19 -3
  105. package/src/rest.component.ts +1 -1
  106. package/src/rest.server.ts +35 -3
  107. package/src/router/base-route.ts +1 -1
  108. package/src/router/controller-route.ts +2 -2
  109. package/src/router/external-express-routes.ts +2 -2
  110. package/src/router/handler-route.ts +1 -1
  111. package/src/router/redirect-route.ts +1 -2
  112. package/src/router/regexp-router.ts +1 -1
  113. package/src/router/route-entry.ts +1 -1
  114. package/src/router/trie-router.ts +2 -2
  115. package/src/sequence.ts +1 -1
  116. package/src/spec-enhancers/info.spec-enhancer.ts +3 -2
  117. package/src/types.ts +11 -0
  118. package/src/validation/request-body.validator.ts +35 -12
@@ -16,72 +16,69 @@ const ajvErrors = require('ajv-errors');
16
16
  /**
17
17
  * A provider class that instantiate an AJV instance
18
18
  */
19
- let AjvFactoryProvider = /** @class */ (() => {
20
- let AjvFactoryProvider = class AjvFactoryProvider {
21
- constructor(options = {}) {
22
- this.options = options;
23
- }
24
- value() {
25
- return options => {
26
- var _a;
27
- let validationOptions = {
28
- ...this.options,
29
- ...options,
30
- };
31
- // See https://github.com/epoberezkin/ajv#options
32
- validationOptions = {
33
- allErrors: true,
34
- jsonPointers: true,
35
- // nullable: support keyword "nullable" from Open API 3 specification.
36
- nullable: true,
37
- // Allow OpenAPI spec binary format
38
- unknownFormats: ['binary'],
39
- ...validationOptions,
40
- };
41
- debug('AJV options', validationOptions);
42
- const ajvInst = new ajv_1.default(validationOptions);
43
- if (validationOptions.ajvKeywords === true) {
44
- ajvKeywords(ajvInst);
45
- }
46
- else if (Array.isArray(validationOptions.ajvKeywords)) {
47
- ajvKeywords(ajvInst, validationOptions.ajvKeywords);
48
- }
49
- if (validationOptions.ajvErrors === true) {
50
- ajvErrors(ajvInst);
51
- }
52
- else if (((_a = validationOptions.ajvErrors) === null || _a === void 0 ? void 0 : _a.constructor) === Object) {
53
- ajvErrors(ajvInst, validationOptions.ajvErrors);
54
- }
55
- if (this.keywords) {
56
- this.keywords.forEach(keyword => {
57
- debug('Adding Ajv keyword %s', keyword.name);
58
- ajvInst.addKeyword(keyword.name, keyword);
59
- });
60
- }
61
- if (this.formats) {
62
- this.formats.forEach(format => {
63
- debug('Adding Ajv format %s', format.name);
64
- ajvInst.addFormat(format.name, format);
65
- });
66
- }
67
- return ajvInst;
19
+ let AjvFactoryProvider = class AjvFactoryProvider {
20
+ constructor(options = {}) {
21
+ this.options = options;
22
+ }
23
+ value() {
24
+ return options => {
25
+ var _a;
26
+ let validationOptions = {
27
+ ...this.options,
28
+ ...options,
68
29
  };
69
- }
70
- };
71
- tslib_1.__decorate([
72
- core_1.inject(core_1.filterByTag(keys_1.RestTags.AJV_KEYWORD)),
73
- tslib_1.__metadata("design:type", Array)
74
- ], AjvFactoryProvider.prototype, "keywords", void 0);
75
- tslib_1.__decorate([
76
- core_1.inject(core_1.filterByTag(keys_1.RestTags.AJV_FORMAT)),
77
- tslib_1.__metadata("design:type", Array)
78
- ], AjvFactoryProvider.prototype, "formats", void 0);
79
- AjvFactoryProvider = tslib_1.__decorate([
80
- core_1.bind({ scope: core_1.BindingScope.SINGLETON }),
81
- tslib_1.__param(0, core_1.inject(keys_1.RestBindings.REQUEST_BODY_PARSER_OPTIONS.deepProperty('validation'), { optional: true })),
82
- tslib_1.__metadata("design:paramtypes", [Object])
83
- ], AjvFactoryProvider);
84
- return AjvFactoryProvider;
85
- })();
30
+ // See https://github.com/epoberezkin/ajv#options
31
+ validationOptions = {
32
+ allErrors: true,
33
+ jsonPointers: true,
34
+ // nullable: support keyword "nullable" from Open API 3 specification.
35
+ nullable: true,
36
+ // Allow OpenAPI spec binary format
37
+ unknownFormats: ['binary'],
38
+ ...validationOptions,
39
+ };
40
+ debug('AJV options', validationOptions);
41
+ const ajvInst = new ajv_1.default(validationOptions);
42
+ if (validationOptions.ajvKeywords === true) {
43
+ ajvKeywords(ajvInst);
44
+ }
45
+ else if (Array.isArray(validationOptions.ajvKeywords)) {
46
+ ajvKeywords(ajvInst, validationOptions.ajvKeywords);
47
+ }
48
+ if (validationOptions.ajvErrors === true) {
49
+ ajvErrors(ajvInst);
50
+ }
51
+ else if (((_a = validationOptions.ajvErrors) === null || _a === void 0 ? void 0 : _a.constructor) === Object) {
52
+ ajvErrors(ajvInst, validationOptions.ajvErrors);
53
+ }
54
+ if (this.keywords) {
55
+ this.keywords.forEach(keyword => {
56
+ debug('Adding Ajv keyword %s', keyword.name);
57
+ ajvInst.addKeyword(keyword.name, keyword);
58
+ });
59
+ }
60
+ if (this.formats) {
61
+ this.formats.forEach(format => {
62
+ debug('Adding Ajv format %s', format.name);
63
+ ajvInst.addFormat(format.name, format);
64
+ });
65
+ }
66
+ return ajvInst;
67
+ };
68
+ }
69
+ };
70
+ tslib_1.__decorate([
71
+ core_1.inject(core_1.filterByTag(keys_1.RestTags.AJV_KEYWORD)),
72
+ tslib_1.__metadata("design:type", Array)
73
+ ], AjvFactoryProvider.prototype, "keywords", void 0);
74
+ tslib_1.__decorate([
75
+ core_1.inject(core_1.filterByTag(keys_1.RestTags.AJV_FORMAT)),
76
+ tslib_1.__metadata("design:type", Array)
77
+ ], AjvFactoryProvider.prototype, "formats", void 0);
78
+ AjvFactoryProvider = tslib_1.__decorate([
79
+ core_1.bind({ scope: core_1.BindingScope.SINGLETON }),
80
+ tslib_1.__param(0, core_1.inject(keys_1.RestBindings.REQUEST_BODY_PARSER_OPTIONS.deepProperty('validation'), { optional: true })),
81
+ tslib_1.__metadata("design:paramtypes", [Object])
82
+ ], AjvFactoryProvider);
86
83
  exports.AjvFactoryProvider = AjvFactoryProvider;
87
84
  //# sourceMappingURL=ajv-factory.provider.js.map
@@ -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":";AAAA,iDAAiD;AACjD,8BAA8B;AAC9B,+CAA+C;AAC/C,gEAAgE;;;;AAEhE,yCAMwB;AACxB,sDAA0B;AAC1B,0DAAgC;AAChC,kCAA+C;AAO/C,MAAM,KAAK,GAAG,eAAW,CAAC,mBAAmB,CAAC,CAAC;AAE/C,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;AAC5C,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAExC;;GAEG;AAEH,IAAa,kBAAkB,GAA/B,MAAa,kBAAkB;IAC7B,YAKU,UAAwC,EAAE;QAA1C,YAAO,GAAP,OAAO,CAAmC;IACjD,CAAC;IAQJ,KAAK;QACH,OAAO,OAAO,CAAC,EAAE;;YACf,IAAI,iBAAiB,GAAiC;gBACpD,GAAG,IAAI,CAAC,OAAO;gBACf,GAAG,OAAO;aACX,CAAC;YACF,iDAAiD;YACjD,iBAAiB,GAAG;gBAClB,SAAS,EAAE,IAAI;gBACf,YAAY,EAAE,IAAI;gBAClB,sEAAsE;gBACtE,QAAQ,EAAE,IAAI;gBACd,mCAAmC;gBACnC,cAAc,EAAE,CAAC,QAAQ,CAAC;gBAC1B,GAAG,iBAAiB;aACrB,CAAC;YAEF,KAAK,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;YACxC,MAAM,OAAO,GAAG,IAAI,aAAO,CAAC,iBAAiB,CAAC,CAAC;YAE/C,IAAI,iBAAiB,CAAC,WAAW,KAAK,IAAI,EAAE;gBAC1C,WAAW,CAAC,OAAO,CAAC,CAAC;aACtB;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE;gBACvD,WAAW,CAAC,OAAO,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;aACrD;YAED,IAAI,iBAAiB,CAAC,SAAS,KAAK,IAAI,EAAE;gBACxC,SAAS,CAAC,OAAO,CAAC,CAAC;aACpB;iBAAM,IAAI,OAAA,iBAAiB,CAAC,SAAS,0CAAE,WAAW,MAAK,MAAM,EAAE;gBAC9D,SAAS,CAAC,OAAO,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;aACjD;YAED,IAAI,IAAI,CAAC,QAAQ,EAAE;gBACjB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;oBAC9B,KAAK,CAAC,uBAAuB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;oBAC7C,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBAC5C,CAAC,CAAC,CAAC;aACJ;YAED,IAAI,IAAI,CAAC,OAAO,EAAE;gBAChB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;oBAC5B,KAAK,CAAC,sBAAsB,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;oBAC3C,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACzC,CAAC,CAAC,CAAC;aACJ;YACD,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC;IACJ,CAAC;CACF,CAAA;AArDC;IADC,aAAM,CAAC,kBAAW,CAAC,eAAQ,CAAC,WAAW,CAAC,CAAC;;oDACX;AAG/B;IADC,aAAM,CAAC,kBAAW,CAAC,eAAQ,CAAC,UAAU,CAAC,CAAC;;mDACZ;AAblB,kBAAkB;IAD9B,WAAI,CAAC,EAAC,KAAK,EAAE,mBAAY,CAAC,SAAS,EAAC,CAAC;IAGjC,mBAAA,aAAM,CACL,mBAAY,CAAC,2BAA2B,CAAC,YAAY,CAAC,YAAY,CAAC,EACnE,EAAC,QAAQ,EAAE,IAAI,EAAC,CACjB,CAAA;;GALQ,kBAAkB,CA+D9B;AA/DY,gDAAkB"}
@@ -1,6 +1,6 @@
1
- import { RequestBodyObject, SchemasObject } from '@loopback/openapi-v3';
1
+ import { ReferenceObject, RequestBodyObject, SchemaObject, SchemasObject } from '@loopback/openapi-v3';
2
2
  import { RequestBody } from '..';
3
- import { RequestBodyValidationOptions } from '../types';
3
+ import { RequestBodyValidationOptions, ValueValidationOptions } from '../types';
4
4
  /**
5
5
  * Check whether the request body is valid according to the provided OpenAPI schema.
6
6
  * The JSON schema is generated from the OpenAPI schema which is typically defined
@@ -12,3 +12,11 @@ import { RequestBodyValidationOptions } from '../types';
12
12
  * @param options - Request body validation options for AJV
13
13
  */
14
14
  export declare function validateRequestBody(body: RequestBody, requestBodySpec?: RequestBodyObject, globalSchemas?: SchemasObject, options?: RequestBodyValidationOptions): Promise<void>;
15
+ /**
16
+ * Validate the request body data against JSON schema.
17
+ * @param body - The request body data.
18
+ * @param schema - The JSON schema used to perform the validation.
19
+ * @param globalSchemas - Schema references.
20
+ * @param options - Request body validation options.
21
+ */
22
+ export declare function validateValueAgainstSchema(value: any, schema: SchemaObject | ReferenceObject, globalSchemas?: SchemasObject, options?: ValueValidationOptions): Promise<void>;
@@ -4,7 +4,7 @@
4
4
  // This file is licensed under the MIT License.
5
5
  // License text available at https://opensource.org/licenses/MIT
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.validateRequestBody = void 0;
7
+ 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"));
@@ -47,7 +47,10 @@ async function validateRequestBody(body, requestBodySpec, globalSchemas = {}, op
47
47
  if (!schema)
48
48
  return;
49
49
  options = { coerceTypes: !!body.coercionRequired, ...options };
50
- await validateValueAgainstSchema(body.value, schema, globalSchemas, options);
50
+ await validateValueAgainstSchema(body.value, schema, globalSchemas, {
51
+ ...options,
52
+ source: 'body',
53
+ });
51
54
  }
52
55
  exports.validateRequestBody = validateRequestBody;
53
56
  /**
@@ -91,7 +94,7 @@ function getKeyForOptions(options) {
91
94
  */
92
95
  async function validateValueAgainstSchema(
93
96
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
- body, schema, globalSchemas = {}, options = {}) {
97
+ value, schema, globalSchemas = {}, options = {}) {
95
98
  var _a, _b;
96
99
  let validate;
97
100
  const cache = (_a = options.compiledSchemaCache) !== null && _a !== void 0 ? _a : DEFAULT_COMPILED_SCHEMA_CACHE;
@@ -111,10 +114,10 @@ body, schema, globalSchemas = {}, options = {}) {
111
114
  }
112
115
  let validationErrors = [];
113
116
  try {
114
- const validationResult = await validate(body);
115
- // When body is optional & values is empty / null, ajv returns null
117
+ const validationResult = await validate(value);
118
+ // When value is optional & values is empty / null, ajv returns null
116
119
  if (validationResult || validationResult === null) {
117
- debug('Request body passed AJV validation.');
120
+ debug(`Value from ${options.source} passed AJV validation.`);
118
121
  return;
119
122
  }
120
123
  }
@@ -123,12 +126,26 @@ body, schema, globalSchemas = {}, options = {}) {
123
126
  }
124
127
  /* istanbul ignore if */
125
128
  if (debug.enabled) {
126
- debug('Invalid request body: %s. Errors: %s', util_1.default.inspect(body, { depth: null }), util_1.default.inspect(validationErrors));
129
+ debug('Invalid value: %s. Errors: %s', util_1.default.inspect(value, { depth: null }), util_1.default.inspect(validationErrors));
127
130
  }
128
131
  if (typeof options.ajvErrorTransformer === 'function') {
129
132
  validationErrors = options.ajvErrorTransformer(validationErrors);
130
133
  }
131
- const error = __1.RestHttpErrors.invalidRequestBody();
134
+ // Throw invalid request body error
135
+ if (options.source === 'body') {
136
+ const error = __1.RestHttpErrors.invalidRequestBody();
137
+ addErrorDetails(error, validationErrors);
138
+ throw error;
139
+ }
140
+ // Throw invalid value error
141
+ const error = new __1.HttpErrors.BadRequest('Invalid value.');
142
+ addErrorDetails(error, validationErrors);
143
+ throw error;
144
+ }
145
+ exports.validateValueAgainstSchema = validateValueAgainstSchema;
146
+ function addErrorDetails(
147
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
148
+ error, validationErrors) {
132
149
  error.details = lodash_1.default.map(validationErrors, e => {
133
150
  return {
134
151
  path: e.dataPath,
@@ -137,7 +154,6 @@ body, schema, globalSchemas = {}, options = {}) {
137
154
  info: e.params,
138
155
  };
139
156
  });
140
- throw error;
141
157
  }
142
158
  /**
143
159
  * Create a validate function for the given schema
@@ -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,11 +1,11 @@
1
1
  {
2
2
  "name": "@loopback/rest",
3
- "version": "5.0.1",
4
- "description": "",
3
+ "version": "5.2.0",
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",
7
7
  "engines": {
8
- "node": ">=10"
8
+ "node": ">=10.16"
9
9
  },
10
10
  "scripts": {
11
11
  "acceptance": "lb-mocha \"dist/__tests__/acceptance/**/*.js\"",
@@ -20,52 +20,54 @@
20
20
  "author": "IBM Corp.",
21
21
  "copyright.owner": "IBM Corp.",
22
22
  "license": "MIT",
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
23
26
  "dependencies": {
24
- "@loopback/context": "^3.8.1",
25
- "@loopback/core": "^2.7.0",
26
- "@loopback/express": "^1.2.1",
27
- "@loopback/http-server": "^2.1.5",
28
- "@loopback/openapi-v3": "^3.4.1",
27
+ "@loopback/core": "^2.9.1",
28
+ "@loopback/express": "^1.2.5",
29
+ "@loopback/http-server": "^2.1.9",
30
+ "@loopback/openapi-v3": "^3.4.5",
29
31
  "@openapi-contrib/openapi-schema-to-json-schema": "^3.0.0",
30
32
  "@types/body-parser": "^1.19.0",
31
33
  "@types/cors": "^2.8.6",
32
34
  "@types/express": "^4.17.6",
33
- "@types/express-serve-static-core": "^4.17.6",
35
+ "@types/express-serve-static-core": "^4.17.8",
34
36
  "@types/http-errors": "^1.6.3",
35
37
  "@types/on-finished": "^2.3.1",
36
38
  "@types/serve-static": "1.13.4",
37
39
  "@types/type-is": "^1.6.3",
38
40
  "ajv": "^6.12.2",
39
41
  "ajv-errors": "^1.0.1",
40
- "ajv-keywords": "^3.4.1",
42
+ "ajv-keywords": "^3.5.0",
41
43
  "body-parser": "^1.19.0",
42
44
  "cors": "^2.8.5",
43
45
  "debug": "^4.1.1",
44
46
  "express": "^4.17.1",
45
- "http-errors": "^1.7.3",
46
- "js-yaml": "^3.13.1",
47
+ "http-errors": "^1.8.0",
48
+ "js-yaml": "^3.14.0",
47
49
  "json-schema-compare": "^0.2.2",
48
50
  "lodash": "^4.17.15",
49
51
  "on-finished": "^2.3.0",
50
52
  "path-to-regexp": "^6.1.0",
51
53
  "qs": "^6.9.4",
52
- "strong-error-handler": "^3.4.0",
54
+ "strong-error-handler": "^3.5.0",
53
55
  "tslib": "^2.0.0",
54
56
  "type-is": "^1.6.18",
55
- "validator": "^13.0.0"
57
+ "validator": "^13.1.1"
56
58
  },
57
59
  "devDependencies": {
58
- "@loopback/build": "^5.4.1",
59
- "@loopback/eslint-config": "^7.0.1",
60
- "@loopback/openapi-spec-builder": "^2.1.5",
61
- "@loopback/repository": "^2.5.1",
62
- "@loopback/testlab": "^3.1.5",
60
+ "@loopback/build": "^6.1.0",
61
+ "@loopback/eslint-config": "^8.0.3",
62
+ "@loopback/openapi-spec-builder": "^2.1.9",
63
+ "@loopback/repository": "^2.9.0",
64
+ "@loopback/testlab": "^3.2.0",
63
65
  "@types/debug": "^4.1.5",
64
- "@types/js-yaml": "^3.12.4",
66
+ "@types/js-yaml": "^3.12.5",
65
67
  "@types/json-schema-compare": "^0.2.0",
66
- "@types/lodash": "^4.14.152",
68
+ "@types/lodash": "^4.14.157",
67
69
  "@types/multer": "^1.4.3",
68
- "@types/node": "^10.17.24",
70
+ "@types/node": "^10.17.26",
69
71
  "@types/on-finished": "^2.3.1",
70
72
  "@types/qs": "^6.9.3",
71
73
  "multer": "^1.4.2"
@@ -81,5 +83,5 @@
81
83
  "url": "https://github.com/strongloop/loopback-next.git",
82
84
  "directory": "packages/rest"
83
85
  },
84
- "gitHead": "62aea854bf85c5a5995b59e6908fe5409f7eea96"
86
+ "gitHead": "b89db3d3b8be6a36e63e91c2331d217fda7538de"
85
87
  }
@@ -1,4 +1,4 @@
1
- // Copyright IBM Corp. 2018,2019. All Rights Reserved.
1
+ // Copyright IBM Corp. 2018,2020. All Rights Reserved.
2
2
  // Node module: @loopback/rest
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
@@ -3,7 +3,7 @@
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
- import {inject} from '@loopback/context';
6
+ import {inject} from '@loopback/core';
7
7
  import {json} from 'body-parser';
8
8
  import {is} from 'type-is';
9
9
  import {RestBindings} from '../keys';
@@ -3,7 +3,7 @@
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
- import {inject} from '@loopback/context';
6
+ import {inject} from '@loopback/core';
7
7
  import {raw} from 'body-parser';
8
8
  import {is} from 'type-is';
9
9
  import {RestBindings} from '../keys';
@@ -3,7 +3,7 @@
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
- import {inject} from '@loopback/context';
6
+ import {inject} from '@loopback/core';
7
7
  import {text} from 'body-parser';
8
8
  import {is} from 'type-is';
9
9
  import {RestBindings} from '../keys';
@@ -10,7 +10,7 @@ import {
10
10
  filterByTag,
11
11
  inject,
12
12
  instantiateClass,
13
- } from '@loopback/context';
13
+ } from '@loopback/core';
14
14
  import {isReferenceObject, OperationObject} from '@loopback/openapi-v3';
15
15
  import debugModule from 'debug';
16
16
  import {is} from 'type-is';
@@ -3,7 +3,7 @@
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
- import {inject} from '@loopback/context';
6
+ import {inject} from '@loopback/core';
7
7
  import {urlencoded} from 'body-parser';
8
8
  import {is} from 'type-is';
9
9
  import {RestBindings} from '../keys';
@@ -1,4 +1,4 @@
1
- // Copyright IBM Corp. 2018. All Rights Reserved.
1
+ // Copyright IBM Corp. 2018,2020. All Rights Reserved.
2
2
  // Node module: @loopback/rest
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
@@ -3,9 +3,19 @@
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
- import {isReferenceObject, ParameterObject} from '@loopback/openapi-v3';
6
+ import {
7
+ isReferenceObject,
8
+ ParameterObject,
9
+ ReferenceObject,
10
+ SchemaObject,
11
+ } from '@loopback/openapi-v3';
7
12
  import debugModule from 'debug';
8
- import {RestHttpErrors} from '../';
13
+ import {
14
+ RequestBodyValidationOptions,
15
+ RestHttpErrors,
16
+ validateValueAgainstSchema,
17
+ ValueValidationOptions,
18
+ } from '../';
9
19
  import {parseJson} from '../parse-json';
10
20
  import {
11
21
  DateCoercionOptions,
@@ -27,18 +37,14 @@ const debug = debugModule('loopback:rest:coercion');
27
37
  *
28
38
  * @param data - The raw data get from http request
29
39
  * @param schema - The parameter's schema defined in OpenAPI specification
40
+ * @param options - The ajv validation options
30
41
  */
31
- export function coerceParameter(
42
+ export async function coerceParameter(
32
43
  data: string | undefined | object,
33
44
  spec: ParameterObject,
45
+ options?: ValueValidationOptions,
34
46
  ) {
35
- let schema = spec.schema;
36
-
37
- // If a query parameter is a url encoded Json object, the schema is defined under content['application/json']
38
- if (!schema && spec.in === 'query' && spec.content) {
39
- const jsonSpec = spec.content['application/json'];
40
- schema = jsonSpec.schema;
41
- }
47
+ const schema = extractSchemaFromSpec(spec);
42
48
 
43
49
  if (!schema || isReferenceObject(schema)) {
44
50
  debug(
@@ -72,7 +78,7 @@ export function coerceParameter(
72
78
  case 'boolean':
73
79
  return coerceBoolean(data, spec);
74
80
  case 'object':
75
- return coerceObject(data, spec);
81
+ return coerceObject(data, spec, options);
76
82
  case 'string':
77
83
  case 'password':
78
84
  return coerceString(data, spec);
@@ -158,21 +164,55 @@ function coerceBoolean(data: string | object, spec: ParameterObject) {
158
164
  throw RestHttpErrors.invalidData(data, spec.name);
159
165
  }
160
166
 
161
- function coerceObject(input: string | object, spec: ParameterObject) {
167
+ async function coerceObject(
168
+ input: string | object,
169
+ spec: ParameterObject,
170
+ options?: RequestBodyValidationOptions,
171
+ ) {
162
172
  const data = parseJsonIfNeeded(input, spec);
163
173
 
164
- if (data === undefined) {
174
+ if (data == null) {
165
175
  // Skip any further checks and coercions, nothing we can do with `undefined`
166
- return undefined;
176
+ return data;
167
177
  }
168
178
 
169
179
  if (typeof data !== 'object' || Array.isArray(data))
170
180
  throw RestHttpErrors.invalidData(input, spec.name);
171
181
 
172
- // TODO(bajtos) apply coercion based on properties defined by spec.schema
182
+ const schema = extractSchemaFromSpec(spec);
183
+ if (schema) {
184
+ // Apply coercion based on properties defined by spec.schema
185
+ await validateValueAgainstSchema(
186
+ data,
187
+ schema,
188
+ {},
189
+ {...options, coerceTypes: true, source: 'parameter'},
190
+ );
191
+ }
192
+
173
193
  return data;
174
194
  }
175
195
 
196
+ /**
197
+ * Extract the schema from an OpenAPI parameter specification. If the root level
198
+ * one not found, search from media type 'application/json'.
199
+ *
200
+ * @param spec The parameter specification
201
+ */
202
+ function extractSchemaFromSpec(
203
+ spec: ParameterObject,
204
+ ): SchemaObject | ReferenceObject | undefined {
205
+ let schema = spec.schema;
206
+
207
+ // If a query parameter is a url encoded Json object,
208
+ // the schema is defined under content['application/json']
209
+ if (!schema && spec.in === 'query') {
210
+ schema = spec.content?.['application/json']?.schema;
211
+ }
212
+
213
+ return schema;
214
+ }
215
+
176
216
  function parseJsonIfNeeded(
177
217
  data: string | object,
178
218
  spec: ParameterObject,
@@ -1,4 +1,4 @@
1
- // Copyright IBM Corp. 2018,2019. All Rights Reserved.
1
+ // Copyright IBM Corp. 2018,2020. All Rights Reserved.
2
2
  // Node module: @loopback/rest
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
@@ -1,9 +1,9 @@
1
- // Copyright IBM Corp. 2017,2019. All Rights Reserved.
1
+ // Copyright IBM Corp. 2017,2020. All Rights Reserved.
2
2
  // Node module: @loopback/rest
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
- import {Context} from '@loopback/context';
6
+ import {Context} from '@loopback/core';
7
7
  import {
8
8
  ComponentsObject,
9
9
  ControllerSpec,
package/src/index.ts CHANGED
@@ -21,6 +21,12 @@
21
21
  */
22
22
 
23
23
  export * from '@loopback/openapi-v3';
24
+ export {
25
+ ErrorHandlerOptions,
26
+ ErrorWriterOptions,
27
+ StrongErrorHandler,
28
+ writeErrorToResponse,
29
+ } from 'strong-error-handler';
24
30
  export * from './body-parsers';
25
31
  export * from './http-handler';
26
32
  export * from './keys';
package/src/keys.ts CHANGED
@@ -3,8 +3,7 @@
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
- import {BindingKey, Context} from '@loopback/context';
7
- import {CoreBindings} from '@loopback/core';
6
+ import {BindingKey, Context, CoreBindings} from '@loopback/core';
8
7
  import {InvokeMiddleware} from '@loopback/express';
9
8
  import {HttpProtocol} from '@loopback/http-server';
10
9
  import {OpenApiSpec, OperationObject} from '@loopback/openapi-v3';
package/src/parser.ts CHANGED
@@ -83,7 +83,7 @@ async function buildOperationArguments(
83
83
  }
84
84
  const spec = paramSpec as ParameterObject;
85
85
  const rawValue = getParamFromRequest(spec, request, pathParams);
86
- const coercedValue = coerceParameter(rawValue, spec);
86
+ const coercedValue = await coerceParameter(rawValue, spec);
87
87
  paramArgs.push(coercedValue);
88
88
  }
89
89
 
@@ -3,7 +3,7 @@
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
- import {Context, inject, Provider} from '@loopback/context';
6
+ import {Context, inject, Provider} from '@loopback/core';
7
7
  import {FindRoute, Request} from '../types';
8
8
  import {HttpHandler} from '../http-handler';
9
9
  import {RestBindings} from '../keys';
@@ -3,7 +3,7 @@
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
- import {Context, inject, Provider} from '@loopback/context';
6
+ import {Context, inject, Provider} from '@loopback/core';
7
7
  import {InvokeMethod, OperationArgs, OperationRetval} from '../types';
8
8
  import {RestBindings} from '../keys';
9
9
  import {RouteEntry} from '../router';
@@ -3,7 +3,7 @@
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
- import {Provider} from '@loopback/context';
6
+ import {Provider} from '@loopback/core';
7
7
  import {LogError, Request} from '../types';
8
8
 
9
9
  export class LogErrorProvider implements Provider<LogError> {