@loopback/rest 5.1.0 → 5.2.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.
- package/CHANGELOG.md +49 -0
- package/dist/body-parsers/body-parser.d.ts +1 -1
- package/dist/body-parsers/body-parser.js +112 -115
- package/dist/body-parsers/body-parser.js.map +1 -1
- package/dist/body-parsers/body-parser.json.js +24 -27
- package/dist/body-parsers/body-parser.json.js.map +1 -1
- package/dist/body-parsers/body-parser.raw.js +19 -22
- package/dist/body-parsers/body-parser.raw.js.map +1 -1
- package/dist/body-parsers/body-parser.text.js +21 -24
- package/dist/body-parsers/body-parser.text.js.map +1 -1
- package/dist/body-parsers/body-parser.urlencoded.js +19 -22
- package/dist/body-parsers/body-parser.urlencoded.js.map +1 -1
- package/dist/coercion/coerce-parameter.d.ts +3 -1
- package/dist/coercion/coerce-parameter.js +28 -12
- package/dist/coercion/coerce-parameter.js.map +1 -1
- package/dist/http-handler.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/keys.d.ts +1 -1
- package/dist/keys.js +33 -34
- package/dist/keys.js.map +1 -1
- package/dist/parser.js +1 -1
- package/dist/parser.js.map +1 -1
- package/dist/providers/find-route.provider.d.ts +1 -1
- package/dist/providers/find-route.provider.js +21 -24
- package/dist/providers/find-route.provider.js.map +1 -1
- package/dist/providers/invoke-method.provider.d.ts +1 -1
- package/dist/providers/invoke-method.provider.js +16 -19
- package/dist/providers/invoke-method.provider.js.map +1 -1
- package/dist/providers/log-error.provider.d.ts +1 -1
- package/dist/providers/parse-params.provider.d.ts +1 -1
- package/dist/providers/parse-params.provider.js +20 -23
- package/dist/providers/parse-params.provider.js.map +1 -1
- package/dist/providers/reject.provider.d.ts +1 -1
- package/dist/providers/reject.provider.js +25 -28
- package/dist/providers/reject.provider.js.map +1 -1
- package/dist/providers/send.provider.d.ts +1 -1
- package/dist/request-context.d.ts +1 -1
- package/dist/rest.application.d.ts +1 -2
- package/dist/rest.application.js.map +1 -1
- package/dist/rest.component.d.ts +1 -1
- package/dist/rest.component.js +46 -49
- package/dist/rest.component.js.map +1 -1
- package/dist/rest.server.d.ts +1 -2
- package/dist/rest.server.js +618 -621
- package/dist/rest.server.js.map +1 -1
- package/dist/router/base-route.d.ts +1 -1
- package/dist/router/controller-route.d.ts +1 -1
- package/dist/router/controller-route.js +3 -4
- package/dist/router/controller-route.js.map +1 -1
- package/dist/router/handler-route.d.ts +1 -1
- package/dist/router/handler-route.js +2 -2
- package/dist/router/handler-route.js.map +1 -1
- package/dist/router/redirect-route.js +2 -2
- package/dist/router/redirect-route.js.map +1 -1
- package/dist/router/regexp-router.js +55 -58
- package/dist/router/regexp-router.js.map +1 -1
- package/dist/router/route-entry.d.ts +1 -1
- package/dist/router/trie-router.js +31 -34
- package/dist/router/trie-router.js.map +1 -1
- package/dist/sequence.d.ts +1 -1
- package/dist/sequence.js +74 -77
- package/dist/sequence.js.map +1 -1
- package/dist/spec-enhancers/consolidate.spec-enhancer.js +89 -92
- package/dist/spec-enhancers/consolidate.spec-enhancer.js.map +1 -1
- package/dist/spec-enhancers/info.spec-enhancer.js +63 -67
- package/dist/spec-enhancers/info.spec-enhancer.js.map +1 -1
- package/dist/types.d.ts +10 -0
- package/dist/validation/ajv-factory.provider.js +63 -66
- package/dist/validation/ajv-factory.provider.js.map +1 -1
- package/dist/validation/request-body.validator.d.ts +10 -2
- package/dist/validation/request-body.validator.js +25 -9
- package/dist/validation/request-body.validator.js.map +1 -1
- package/package.json +29 -27
- package/src/body-parsers/body-parser.json.ts +1 -1
- package/src/body-parsers/body-parser.raw.ts +1 -1
- package/src/body-parsers/body-parser.text.ts +1 -1
- package/src/body-parsers/body-parser.ts +1 -1
- package/src/body-parsers/body-parser.urlencoded.ts +1 -1
- package/src/coercion/coerce-parameter.ts +55 -15
- package/src/http-handler.ts +1 -1
- package/src/index.ts +6 -0
- package/src/keys.ts +1 -2
- package/src/parser.ts +1 -1
- package/src/providers/find-route.provider.ts +1 -1
- package/src/providers/invoke-method.provider.ts +1 -1
- package/src/providers/log-error.provider.ts +1 -1
- package/src/providers/parse-params.provider.ts +1 -1
- package/src/providers/reject.provider.ts +1 -1
- package/src/providers/send.provider.ts +1 -1
- package/src/request-context.ts +1 -1
- package/src/rest.application.ts +4 -2
- package/src/rest.component.ts +1 -1
- package/src/rest.server.ts +5 -3
- package/src/router/base-route.ts +1 -1
- package/src/router/controller-route.ts +2 -2
- package/src/router/external-express-routes.ts +1 -1
- package/src/router/handler-route.ts +1 -1
- package/src/router/redirect-route.ts +1 -2
- package/src/router/regexp-router.ts +1 -1
- package/src/router/route-entry.ts +1 -1
- package/src/router/trie-router.ts +1 -1
- package/src/sequence.ts +1 -1
- package/src/spec-enhancers/info.spec-enhancer.ts +3 -2
- package/src/types.ts +11 -0
- 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 =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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":";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
|
|
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,
|
|
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
|
-
|
|
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(
|
|
115
|
-
// When
|
|
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(
|
|
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
|
|
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
|
-
|
|
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":";AAAA,sDAAsD;AACtD,8BAA8B;AAC9B,+CAA+C;AAC/C,gEAAgE;;;;AAEhE,qDAM8B;AAE9B,0DAAgC;AAChC,4DAAuB;AACvB,wDAAwB;AACxB,0BAA2D;
|
|
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.1
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "5.2.1",
|
|
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/
|
|
25
|
-
"@loopback/
|
|
26
|
-
"@loopback/
|
|
27
|
-
"@loopback/
|
|
28
|
-
"@
|
|
29
|
-
"@openapi-contrib/openapi-schema-to-json-schema": "^3.0.0",
|
|
27
|
+
"@loopback/core": "^2.9.2",
|
|
28
|
+
"@loopback/express": "^1.2.6",
|
|
29
|
+
"@loopback/http-server": "^2.1.10",
|
|
30
|
+
"@loopback/openapi-v3": "^3.4.6",
|
|
31
|
+
"@openapi-contrib/openapi-schema-to-json-schema": "^3.0.3",
|
|
30
32
|
"@types/body-parser": "^1.19.0",
|
|
31
33
|
"@types/cors": "^2.8.6",
|
|
32
|
-
"@types/express": "^4.17.
|
|
33
|
-
"@types/express-serve-static-core": "^4.17.
|
|
34
|
-
"@types/http-errors": "^1.
|
|
34
|
+
"@types/express": "^4.17.7",
|
|
35
|
+
"@types/express-serve-static-core": "^4.17.8",
|
|
36
|
+
"@types/http-errors": "^1.8.0",
|
|
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
|
-
"ajv": "^6.12.
|
|
40
|
+
"ajv": "^6.12.3",
|
|
39
41
|
"ajv-errors": "^1.0.1",
|
|
40
|
-
"ajv-keywords": "^3.
|
|
42
|
+
"ajv-keywords": "^3.5.1",
|
|
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.
|
|
47
|
+
"http-errors": "^1.8.0",
|
|
46
48
|
"js-yaml": "^3.14.0",
|
|
47
49
|
"json-schema-compare": "^0.2.2",
|
|
48
|
-
"lodash": "^4.17.
|
|
50
|
+
"lodash": "^4.17.19",
|
|
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.
|
|
54
|
+
"strong-error-handler": "^3.5.0",
|
|
53
55
|
"tslib": "^2.0.0",
|
|
54
56
|
"type-is": "^1.6.18",
|
|
55
|
-
"validator": "^13.
|
|
57
|
+
"validator": "^13.1.1"
|
|
56
58
|
},
|
|
57
59
|
"devDependencies": {
|
|
58
|
-
"@loopback/build": "^
|
|
59
|
-
"@loopback/eslint-config": "^8.0.
|
|
60
|
-
"@loopback/openapi-spec-builder": "^2.1.
|
|
61
|
-
"@loopback/repository": "^2.
|
|
62
|
-
"@loopback/testlab": "^3.1
|
|
60
|
+
"@loopback/build": "^6.1.1",
|
|
61
|
+
"@loopback/eslint-config": "^8.0.4",
|
|
62
|
+
"@loopback/openapi-spec-builder": "^2.1.10",
|
|
63
|
+
"@loopback/repository": "^2.10.0",
|
|
64
|
+
"@loopback/testlab": "^3.2.1",
|
|
63
65
|
"@types/debug": "^4.1.5",
|
|
64
|
-
"@types/js-yaml": "^3.12.
|
|
66
|
+
"@types/js-yaml": "^3.12.5",
|
|
65
67
|
"@types/json-schema-compare": "^0.2.0",
|
|
66
|
-
"@types/lodash": "^4.14.
|
|
68
|
+
"@types/lodash": "^4.14.157",
|
|
67
69
|
"@types/multer": "^1.4.3",
|
|
68
|
-
"@types/node": "^10.17.
|
|
70
|
+
"@types/node": "^10.17.27",
|
|
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": "
|
|
86
|
+
"gitHead": "5538896411bb56467ae52670a29d1aec1690be74"
|
|
85
87
|
}
|
|
@@ -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/
|
|
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/
|
|
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/
|
|
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';
|
|
@@ -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/
|
|
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';
|
|
@@ -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 {
|
|
6
|
+
import {
|
|
7
|
+
isReferenceObject,
|
|
8
|
+
ParameterObject,
|
|
9
|
+
ReferenceObject,
|
|
10
|
+
SchemaObject,
|
|
11
|
+
} from '@loopback/openapi-v3';
|
|
7
12
|
import debugModule from 'debug';
|
|
8
|
-
import {
|
|
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
|
-
|
|
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(
|
|
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
|
|
174
|
+
if (data == null) {
|
|
165
175
|
// Skip any further checks and coercions, nothing we can do with `undefined`
|
|
166
|
-
return
|
|
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
|
-
|
|
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/http-handler.ts
CHANGED
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/
|
|
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/
|
|
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/
|
|
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/
|
|
6
|
+
import {Provider} from '@loopback/core';
|
|
7
7
|
import {LogError, Request} from '../types';
|
|
8
8
|
|
|
9
9
|
export class LogErrorProvider implements Provider<LogError> {
|
|
@@ -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, Provider} from '@loopback/
|
|
6
|
+
import {inject, Provider} from '@loopback/core';
|
|
7
7
|
import {RequestBodyParser} from '../body-parsers';
|
|
8
8
|
import {RestBindings} from '../keys';
|
|
9
9
|
import {parseOperationArgs} from '../parser';
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
6
|
import {LogError, Reject, HandlerContext} from '../types';
|
|
7
|
-
import {inject, Provider} from '@loopback/
|
|
7
|
+
import {inject, Provider} from '@loopback/core';
|
|
8
8
|
import {HttpError} from 'http-errors';
|
|
9
9
|
import {RestBindings} from '../keys';
|
|
10
10
|
import {writeErrorToResponse, ErrorWriterOptions} from 'strong-error-handler';
|