@loopback/rest 5.1.2 → 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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,23 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [5.2.0](https://github.com/strongloop/loopback-next/compare/@loopback/rest@5.1.2...@loopback/rest@5.2.0) (2020-06-30)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **rest:** fix typing to be compatible with latest @types/js-yaml ([5ac39e4](https://github.com/strongloop/loopback-next/commit/5ac39e44827ef74c9d2bccb1797a9da125c249e3))
12
+
13
+
14
+ ### Features
15
+
16
+ * coerce query object with schema ([ccea25f](https://github.com/strongloop/loopback-next/commit/ccea25fc382457f9436adfc0d8f6ce3a2d029c5e))
17
+ * **rest:** expose types from strong-error-handler ([b6f5595](https://github.com/strongloop/loopback-next/commit/b6f559549518c839a2898f1b968fc6a7901a6c6b))
18
+
19
+
20
+
21
+
22
+
6
23
  ## [5.1.2](https://github.com/strongloop/loopback-next/compare/@loopback/rest@5.1.1...@loopback/rest@5.1.2) (2020-06-23)
7
24
 
8
25
 
@@ -1,9 +1,11 @@
1
1
  import { ParameterObject } from '@loopback/openapi-v3';
2
+ import { ValueValidationOptions } from '../';
2
3
  /**
3
4
  * Coerce the http raw data to a JavaScript type data of a parameter
4
5
  * according to its OpenAPI schema specification.
5
6
  *
6
7
  * @param data - The raw data get from http request
7
8
  * @param schema - The parameter's schema defined in OpenAPI specification
9
+ * @param options - The ajv validation options
8
10
  */
9
- export declare function coerceParameter(data: string | undefined | object, spec: ParameterObject): string | number | boolean | object | undefined;
11
+ export declare function coerceParameter(data: string | undefined | object, spec: ParameterObject, options?: ValueValidationOptions): Promise<string | number | boolean | object | undefined>;
@@ -20,14 +20,10 @@ const debug = debug_1.default('loopback:rest:coercion');
20
20
  *
21
21
  * @param data - The raw data get from http request
22
22
  * @param schema - The parameter's schema defined in OpenAPI specification
23
+ * @param options - The ajv validation options
23
24
  */
24
- function coerceParameter(data, spec) {
25
- let schema = spec.schema;
26
- // If a query parameter is a url encoded Json object, the schema is defined under content['application/json']
27
- if (!schema && spec.in === 'query' && spec.content) {
28
- const jsonSpec = spec.content['application/json'];
29
- schema = jsonSpec.schema;
30
- }
25
+ async function coerceParameter(data, spec, options) {
26
+ const schema = extractSchemaFromSpec(spec);
31
27
  if (!schema || openapi_v3_1.isReferenceObject(schema)) {
32
28
  debug('The parameter with schema %s is not coerced since schema' +
33
29
  'dereference is not supported yet.', schema);
@@ -56,7 +52,7 @@ function coerceParameter(data, spec) {
56
52
  case 'boolean':
57
53
  return coerceBoolean(data, spec);
58
54
  case 'object':
59
- return coerceObject(data, spec);
55
+ return coerceObject(data, spec, options);
60
56
  case 'string':
61
57
  case 'password':
62
58
  return coerceString(data, spec);
@@ -127,17 +123,37 @@ function coerceBoolean(data, spec) {
127
123
  return false;
128
124
  throw __1.RestHttpErrors.invalidData(data, spec.name);
129
125
  }
130
- function coerceObject(input, spec) {
126
+ async function coerceObject(input, spec, options) {
131
127
  const data = parseJsonIfNeeded(input, spec);
132
- if (data === undefined) {
128
+ if (data == null) {
133
129
  // Skip any further checks and coercions, nothing we can do with `undefined`
134
- return undefined;
130
+ return data;
135
131
  }
136
132
  if (typeof data !== 'object' || Array.isArray(data))
137
133
  throw __1.RestHttpErrors.invalidData(input, spec.name);
138
- // TODO(bajtos) apply coercion based on properties defined by spec.schema
134
+ const schema = extractSchemaFromSpec(spec);
135
+ if (schema) {
136
+ // Apply coercion based on properties defined by spec.schema
137
+ await __1.validateValueAgainstSchema(data, schema, {}, { ...options, coerceTypes: true, source: 'parameter' });
138
+ }
139
139
  return data;
140
140
  }
141
+ /**
142
+ * Extract the schema from an OpenAPI parameter specification. If the root level
143
+ * one not found, search from media type 'application/json'.
144
+ *
145
+ * @param spec The parameter specification
146
+ */
147
+ function extractSchemaFromSpec(spec) {
148
+ var _a, _b;
149
+ let schema = spec.schema;
150
+ // If a query parameter is a url encoded Json object,
151
+ // the schema is defined under content['application/json']
152
+ if (!schema && spec.in === 'query') {
153
+ schema = (_b = (_a = spec.content) === null || _a === void 0 ? void 0 : _a['application/json']) === null || _b === void 0 ? void 0 : _b.schema;
154
+ }
155
+ return schema;
156
+ }
141
157
  function parseJsonIfNeeded(data, spec) {
142
158
  if (typeof data !== 'string')
143
159
  return data;
@@ -1 +1 @@
1
- {"version":3,"file":"coerce-parameter.js","sourceRoot":"","sources":["../../src/coercion/coerce-parameter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"coerce-parameter.js","sourceRoot":"","sources":["../../src/coercion/coerce-parameter.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -15,6 +15,7 @@
15
15
  * @packageDocumentation
16
16
  */
17
17
  export * from '@loopback/openapi-v3';
18
+ export { ErrorHandlerOptions, ErrorWriterOptions, StrongErrorHandler, writeErrorToResponse, } from 'strong-error-handler';
18
19
  export * from './body-parsers';
19
20
  export * from './http-handler';
20
21
  export * from './keys';
package/dist/index.js CHANGED
@@ -23,6 +23,8 @@ const tslib_1 = require("tslib");
23
23
  * @packageDocumentation
24
24
  */
25
25
  tslib_1.__exportStar(require("@loopback/openapi-v3"), exports);
26
+ var strong_error_handler_1 = require("strong-error-handler");
27
+ Object.defineProperty(exports, "writeErrorToResponse", { enumerable: true, get: function () { return strong_error_handler_1.writeErrorToResponse; } });
26
28
  tslib_1.__exportStar(require("./body-parsers"), exports);
27
29
  tslib_1.__exportStar(require("./http-handler"), exports);
28
30
  tslib_1.__exportStar(require("./keys"), exports);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,sDAAsD;AACtD,8BAA8B;AAC9B,+CAA+C;AAC/C,gEAAgE;;;;AAEhE;;;;;;;;;;;;;;;GAeG;AAEH,+DAAqC;AACrC,yDAA+B;AAC/B,yDAA+B;AAC/B,iDAAuB;AACvB,uDAA6B;AAC7B,mDAAyB;AACzB,sDAA4B;AAC5B,4DAAkC;AAClC,4DAAkC;AAClC,6DAAmC;AACnC,2DAAiC;AACjC,wDAA8B;AAC9B,mDAAyB;AACzB,qDAA2B;AAC3B,8EAAoD;AACpD,kDAAwB;AACxB,8EAAoD;AACpD,mDAAyB;AAGzB,sDAAsD;AACtD,sEAAqC;AAH7B,qBAGD,qBAAU,CAHC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,sDAAsD;AACtD,8BAA8B;AAC9B,+CAA+C;AAC/C,gEAAgE;;;;AAEhE;;;;;;;;;;;;;;;GAeG;AAEH,+DAAqC;AACrC,6DAK8B;AAD5B,4HAAA,oBAAoB,OAAA;AAEtB,yDAA+B;AAC/B,yDAA+B;AAC/B,iDAAuB;AACvB,uDAA6B;AAC7B,mDAAyB;AACzB,sDAA4B;AAC5B,4DAAkC;AAClC,4DAAkC;AAClC,6DAAmC;AACnC,2DAAiC;AACjC,wDAA8B;AAC9B,mDAAyB;AACzB,qDAA2B;AAC3B,8EAAoD;AACpD,kDAAwB;AACxB,8EAAoD;AACpD,mDAAyB;AAGzB,sDAAsD;AACtD,sEAAqC;AAH7B,qBAGD,qBAAU,CAHC"}
package/dist/parser.js CHANGED
@@ -49,7 +49,7 @@ async function buildOperationArguments(operationSpec, request, pathParams, body,
49
49
  }
50
50
  const spec = paramSpec;
51
51
  const rawValue = getParamFromRequest(spec, request, pathParams);
52
- const coercedValue = coerce_parameter_1.coerceParameter(rawValue, spec);
52
+ const coercedValue = await coerce_parameter_1.coerceParameter(rawValue, spec);
53
53
  paramArgs.push(coercedValue);
54
54
  }
55
55
  debug('Validating request body - value %j', body);
@@ -1 +1 @@
1
- {"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -77,6 +77,16 @@ export declare type AjvKeyword = KeywordDefinition & {
77
77
  export declare type AjvFormat = FormatDefinition & {
78
78
  name: string;
79
79
  };
80
+ /**
81
+ * Options for any value validation using AJV
82
+ */
83
+ export interface ValueValidationOptions extends RequestBodyValidationOptions {
84
+ /**
85
+ * Where the data comes from. It can be 'body', 'path', 'header',
86
+ * 'query', 'cookie', etc...
87
+ */
88
+ source?: string;
89
+ }
80
90
  /**
81
91
  * Options for request body validation using AJV
82
92
  */
@@ -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,6 +1,6 @@
1
1
  {
2
2
  "name": "@loopback/rest",
3
- "version": "5.1.2",
3
+ "version": "5.2.0",
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",
@@ -24,15 +24,15 @@
24
24
  "access": "public"
25
25
  },
26
26
  "dependencies": {
27
- "@loopback/core": "^2.9.0",
28
- "@loopback/express": "^1.2.4",
29
- "@loopback/http-server": "^2.1.8",
30
- "@loopback/openapi-v3": "^3.4.4",
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",
31
31
  "@openapi-contrib/openapi-schema-to-json-schema": "^3.0.0",
32
32
  "@types/body-parser": "^1.19.0",
33
33
  "@types/cors": "^2.8.6",
34
34
  "@types/express": "^4.17.6",
35
- "@types/express-serve-static-core": "^4.17.6",
35
+ "@types/express-serve-static-core": "^4.17.8",
36
36
  "@types/http-errors": "^1.6.3",
37
37
  "@types/on-finished": "^2.3.1",
38
38
  "@types/serve-static": "1.13.4",
@@ -44,28 +44,28 @@
44
44
  "cors": "^2.8.5",
45
45
  "debug": "^4.1.1",
46
46
  "express": "^4.17.1",
47
- "http-errors": "^1.7.3",
47
+ "http-errors": "^1.8.0",
48
48
  "js-yaml": "^3.14.0",
49
49
  "json-schema-compare": "^0.2.2",
50
50
  "lodash": "^4.17.15",
51
51
  "on-finished": "^2.3.0",
52
52
  "path-to-regexp": "^6.1.0",
53
53
  "qs": "^6.9.4",
54
- "strong-error-handler": "^3.4.0",
54
+ "strong-error-handler": "^3.5.0",
55
55
  "tslib": "^2.0.0",
56
56
  "type-is": "^1.6.18",
57
57
  "validator": "^13.1.1"
58
58
  },
59
59
  "devDependencies": {
60
- "@loopback/build": "^6.0.0",
61
- "@loopback/eslint-config": "^8.0.2",
62
- "@loopback/openapi-spec-builder": "^2.1.8",
63
- "@loopback/repository": "^2.8.0",
64
- "@loopback/testlab": "^3.1.8",
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",
65
65
  "@types/debug": "^4.1.5",
66
- "@types/js-yaml": "^3.12.4",
66
+ "@types/js-yaml": "^3.12.5",
67
67
  "@types/json-schema-compare": "^0.2.0",
68
- "@types/lodash": "^4.14.156",
68
+ "@types/lodash": "^4.14.157",
69
69
  "@types/multer": "^1.4.3",
70
70
  "@types/node": "^10.17.26",
71
71
  "@types/on-finished": "^2.3.1",
@@ -83,5 +83,5 @@
83
83
  "url": "https://github.com/strongloop/loopback-next.git",
84
84
  "directory": "packages/rest"
85
85
  },
86
- "gitHead": "9ccb0b7ae75727ec9b90c5bba18885edb3f93a92"
86
+ "gitHead": "b89db3d3b8be6a36e63e91c2331d217fda7538de"
87
87
  }
@@ -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,
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/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
 
package/src/types.ts CHANGED
@@ -108,6 +108,17 @@ export type AjvKeyword = KeywordDefinition & {name: string};
108
108
  */
109
109
  export type AjvFormat = FormatDefinition & {name: string};
110
110
 
111
+ /**
112
+ * Options for any value validation using AJV
113
+ */
114
+ export interface ValueValidationOptions extends RequestBodyValidationOptions {
115
+ /**
116
+ * Where the data comes from. It can be 'body', 'path', 'header',
117
+ * 'query', 'cookie', etc...
118
+ */
119
+ source?: string;
120
+ }
121
+
111
122
  /**
112
123
  * Options for request body validation using AJV
113
124
  */
@@ -15,7 +15,11 @@ import debugModule from 'debug';
15
15
  import _ from 'lodash';
16
16
  import util from 'util';
17
17
  import {HttpErrors, RequestBody, RestHttpErrors} from '..';
18
- import {RequestBodyValidationOptions, SchemaValidatorCache} from '../types';
18
+ import {
19
+ RequestBodyValidationOptions,
20
+ SchemaValidatorCache,
21
+ ValueValidationOptions,
22
+ } from '../types';
19
23
  import {AjvFactoryProvider} from './ajv-factory.provider';
20
24
 
21
25
  const toJsonSchema = require('@openapi-contrib/openapi-schema-to-json-schema');
@@ -66,7 +70,10 @@ export async function validateRequestBody(
66
70
  if (!schema) return;
67
71
 
68
72
  options = {coerceTypes: !!body.coercionRequired, ...options};
69
- await validateValueAgainstSchema(body.value, schema, globalSchemas, options);
73
+ await validateValueAgainstSchema(body.value, schema, globalSchemas, {
74
+ ...options,
75
+ source: 'body',
76
+ });
70
77
  }
71
78
 
72
79
  /**
@@ -115,12 +122,12 @@ function getKeyForOptions(options: RequestBodyValidationOptions) {
115
122
  * @param globalSchemas - Schema references.
116
123
  * @param options - Request body validation options.
117
124
  */
118
- async function validateValueAgainstSchema(
125
+ export async function validateValueAgainstSchema(
119
126
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
120
- body: any,
127
+ value: any,
121
128
  schema: SchemaObject | ReferenceObject,
122
129
  globalSchemas: SchemasObject = {},
123
- options: RequestBodyValidationOptions = {},
130
+ options: ValueValidationOptions = {},
124
131
  ) {
125
132
  let validate: ajv.ValidateFunction | undefined;
126
133
 
@@ -145,10 +152,10 @@ async function validateValueAgainstSchema(
145
152
 
146
153
  let validationErrors: ajv.ErrorObject[] = [];
147
154
  try {
148
- const validationResult = await validate(body);
149
- // When body is optional & values is empty / null, ajv returns null
155
+ const validationResult = await validate(value);
156
+ // When value is optional & values is empty / null, ajv returns null
150
157
  if (validationResult || validationResult === null) {
151
- debug('Request body passed AJV validation.');
158
+ debug(`Value from ${options.source} passed AJV validation.`);
152
159
  return;
153
160
  }
154
161
  } catch (error) {
@@ -158,8 +165,8 @@ async function validateValueAgainstSchema(
158
165
  /* istanbul ignore if */
159
166
  if (debug.enabled) {
160
167
  debug(
161
- 'Invalid request body: %s. Errors: %s',
162
- util.inspect(body, {depth: null}),
168
+ 'Invalid value: %s. Errors: %s',
169
+ util.inspect(value, {depth: null}),
163
170
  util.inspect(validationErrors),
164
171
  );
165
172
  }
@@ -168,7 +175,24 @@ async function validateValueAgainstSchema(
168
175
  validationErrors = options.ajvErrorTransformer(validationErrors);
169
176
  }
170
177
 
171
- const error = RestHttpErrors.invalidRequestBody();
178
+ // Throw invalid request body error
179
+ if (options.source === 'body') {
180
+ const error = RestHttpErrors.invalidRequestBody();
181
+ addErrorDetails(error, validationErrors);
182
+ throw error;
183
+ }
184
+
185
+ // Throw invalid value error
186
+ const error = new HttpErrors.BadRequest('Invalid value.');
187
+ addErrorDetails(error, validationErrors);
188
+ throw error;
189
+ }
190
+
191
+ function addErrorDetails(
192
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
193
+ error: any,
194
+ validationErrors: ajv.ErrorObject[],
195
+ ) {
172
196
  error.details = _.map(validationErrors, e => {
173
197
  return {
174
198
  path: e.dataPath,
@@ -177,7 +201,6 @@ async function validateValueAgainstSchema(
177
201
  info: e.params,
178
202
  };
179
203
  });
180
- throw error;
181
204
  }
182
205
 
183
206
  /**