@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.
- package/CHANGELOG.md +47 -0
- package/dist/body-parsers/body-parser.d.ts +1 -1
- package/dist/body-parsers/body-parser.helpers.js +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/body-parsers/index.js +1 -1
- package/dist/body-parsers/index.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/coercion/validator.js +1 -1
- package/dist/http-handler.d.ts +1 -1
- package/dist/http-handler.js +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 +15 -2
- package/dist/rest.application.js +14 -1
- 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 +15 -2
- package/dist/rest.server.js +615 -588
- 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/external-express-routes.js +1 -1
- package/dist/router/external-express-routes.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 +32 -35
- 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 +25 -23
- package/src/body-parsers/body-parser.helpers.ts +1 -1
- 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/body-parsers/index.ts +1 -1
- package/src/coercion/coerce-parameter.ts +55 -15
- package/src/coercion/validator.ts +1 -1
- package/src/http-handler.ts +2 -2
- 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 +19 -3
- package/src/rest.component.ts +1 -1
- package/src/rest.server.ts +35 -3
- package/src/router/base-route.ts +1 -1
- package/src/router/controller-route.ts +2 -2
- package/src/router/external-express-routes.ts +2 -2
- 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 +2 -2
- 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
|
@@ -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';
|
|
@@ -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, BoundValue} from '@loopback/
|
|
6
|
+
import {Provider, BoundValue} from '@loopback/core';
|
|
7
7
|
import {writeResultToResponse} from '../writer';
|
|
8
8
|
/**
|
|
9
9
|
* Provides the function that populates the response object with
|
package/src/request-context.ts
CHANGED
package/src/rest.application.ts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
// Copyright IBM Corp. 2018,
|
|
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
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
+
Application,
|
|
8
|
+
ApplicationConfig,
|
|
7
9
|
Binding,
|
|
8
10
|
BindingAddress,
|
|
9
11
|
Constructor,
|
|
10
12
|
Context,
|
|
11
13
|
Provider,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
Server,
|
|
15
|
+
} from '@loopback/core';
|
|
14
16
|
import {
|
|
15
17
|
ExpressMiddlewareFactory,
|
|
16
18
|
ExpressRequestHandler,
|
|
@@ -387,4 +389,18 @@ export class RestApplication extends Application implements HttpServerLike {
|
|
|
387
389
|
): void {
|
|
388
390
|
this.restServer.mountExpressRouter(basePath, router, spec);
|
|
389
391
|
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Export the OpenAPI spec to the given json or yaml file
|
|
395
|
+
* @param outFile - File name for the spec. The extension of the file
|
|
396
|
+
* determines the format of the file.
|
|
397
|
+
* - `yaml` or `yml`: YAML
|
|
398
|
+
* - `json` or other: JSON
|
|
399
|
+
* If the outFile is not provided or its value is `''` or `'-'`, the spec is
|
|
400
|
+
* written to the console using the `log` function.
|
|
401
|
+
* @param log - Log function, default to `console.log`
|
|
402
|
+
*/
|
|
403
|
+
async exportOpenApiSpec(outFile = '', log = console.log): Promise<void> {
|
|
404
|
+
return this.restServer.exportOpenApiSpec(outFile, log);
|
|
405
|
+
}
|
|
390
406
|
}
|
package/src/rest.component.ts
CHANGED
package/src/rest.server.ts
CHANGED
|
@@ -4,18 +4,20 @@
|
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
+
Application,
|
|
7
8
|
Binding,
|
|
8
9
|
BindingAddress,
|
|
9
10
|
BindingScope,
|
|
10
11
|
Constructor,
|
|
11
12
|
ContextObserver,
|
|
13
|
+
CoreBindings,
|
|
12
14
|
createBindingFromClass,
|
|
13
15
|
filterByKey,
|
|
14
16
|
filterByTag,
|
|
15
17
|
inject,
|
|
18
|
+
Server,
|
|
16
19
|
Subscription,
|
|
17
|
-
} from '@loopback/
|
|
18
|
-
import {Application, CoreBindings, Server} from '@loopback/core';
|
|
20
|
+
} from '@loopback/core';
|
|
19
21
|
import {BaseMiddlewareRegistry, ExpressRequestHandler} from '@loopback/express';
|
|
20
22
|
import {HttpServer, HttpServerOptions} from '@loopback/http-server';
|
|
21
23
|
import {
|
|
@@ -32,6 +34,7 @@ import cors from 'cors';
|
|
|
32
34
|
import debugFactory from 'debug';
|
|
33
35
|
import express, {ErrorRequestHandler} from 'express';
|
|
34
36
|
import {PathParams} from 'express-serve-static-core';
|
|
37
|
+
import fs from 'fs';
|
|
35
38
|
import {IncomingMessage, ServerResponse} from 'http';
|
|
36
39
|
import {ServerOptions} from 'https';
|
|
37
40
|
import {safeDump} from 'js-yaml';
|
|
@@ -124,6 +127,7 @@ export class RestServer extends BaseMiddlewareRegistry
|
|
|
124
127
|
*/
|
|
125
128
|
|
|
126
129
|
protected _OASEnhancer: OASEnhancerService;
|
|
130
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
127
131
|
public get OASEnhancer(): OASEnhancerService {
|
|
128
132
|
this._setupOASEnhancerIfNeeded();
|
|
129
133
|
return this._OASEnhancer;
|
|
@@ -176,7 +180,7 @@ export class RestServer extends BaseMiddlewareRegistry
|
|
|
176
180
|
* will be 'http://localhost:3000' regardless of the `basePath`.
|
|
177
181
|
*/
|
|
178
182
|
get rootUrl(): string | undefined {
|
|
179
|
-
return this._httpServer
|
|
183
|
+
return this._httpServer?.url;
|
|
180
184
|
}
|
|
181
185
|
|
|
182
186
|
/**
|
|
@@ -987,6 +991,34 @@ export class RestServer extends BaseMiddlewareRegistry
|
|
|
987
991
|
): void {
|
|
988
992
|
this._externalRoutes.mountRouter(basePath, router, spec);
|
|
989
993
|
}
|
|
994
|
+
|
|
995
|
+
/**
|
|
996
|
+
* Export the OpenAPI spec to the given json or yaml file
|
|
997
|
+
* @param outFile - File name for the spec. The extension of the file
|
|
998
|
+
* determines the format of the file.
|
|
999
|
+
* - `yaml` or `yml`: YAML
|
|
1000
|
+
* - `json` or other: JSON
|
|
1001
|
+
* If the outFile is not provided or its value is `''` or `'-'`, the spec is
|
|
1002
|
+
* written to the console using the `log` function.
|
|
1003
|
+
* @param log - Log function, default to `console.log`
|
|
1004
|
+
*/
|
|
1005
|
+
async exportOpenApiSpec(outFile = '', log = console.log): Promise<void> {
|
|
1006
|
+
const spec = await this.getApiSpec();
|
|
1007
|
+
if (outFile === '-' || outFile === '') {
|
|
1008
|
+
const json = JSON.stringify(spec, null, 2);
|
|
1009
|
+
log('%s', json);
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
const fileName = outFile.toLowerCase();
|
|
1013
|
+
if (fileName.endsWith('.yaml') || fileName.endsWith('.yml')) {
|
|
1014
|
+
const yaml = safeDump(spec);
|
|
1015
|
+
fs.writeFileSync(outFile, yaml, 'utf-8');
|
|
1016
|
+
} else {
|
|
1017
|
+
const json = JSON.stringify(spec, null, 2);
|
|
1018
|
+
fs.writeFileSync(outFile, json, 'utf-8');
|
|
1019
|
+
}
|
|
1020
|
+
log('The OpenAPI spec has been saved to %s.', outFile);
|
|
1021
|
+
}
|
|
990
1022
|
}
|
|
991
1023
|
|
|
992
1024
|
/**
|
package/src/router/base-route.ts
CHANGED
|
@@ -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, InvocationSource} from '@loopback/
|
|
6
|
+
import {Context, InvocationSource} from '@loopback/core';
|
|
7
7
|
import {OperationObject} from '@loopback/openapi-v3';
|
|
8
8
|
import {OperationArgs, OperationRetval} from '../types';
|
|
9
9
|
import {RouteEntry} from './route-entry';
|
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
BindingScope,
|
|
8
8
|
Constructor,
|
|
9
9
|
Context,
|
|
10
|
+
CoreBindings,
|
|
10
11
|
instantiateClass,
|
|
11
12
|
invokeMethod,
|
|
12
13
|
ValueOrPromise,
|
|
13
|
-
} from '@loopback/
|
|
14
|
-
import {CoreBindings} from '@loopback/core';
|
|
14
|
+
} from '@loopback/core';
|
|
15
15
|
import {ControllerSpec, OperationObject} from '@loopback/openapi-v3';
|
|
16
16
|
import assert from 'assert';
|
|
17
17
|
import debugFactory from 'debug';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
// Copyright IBM Corp. 2019. All Rights Reserved.
|
|
1
|
+
// Copyright IBM Corp. 2019,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/
|
|
6
|
+
import {Context} from '@loopback/core';
|
|
7
7
|
import {
|
|
8
8
|
executeExpressRequestHandler,
|
|
9
9
|
ExpressRequestHandler,
|
|
@@ -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, invokeMethodWithInterceptors} from '@loopback/
|
|
6
|
+
import {Context, invokeMethodWithInterceptors} from '@loopback/core';
|
|
7
7
|
import {OperationObject} from '@loopback/openapi-v3';
|
|
8
8
|
import {RestBindings} from '../keys';
|
|
9
9
|
import {OperationArgs, OperationRetval} from '../types';
|
|
@@ -54,8 +54,7 @@ export class RedirectRoute implements RouteEntry, ResolvedRoute {
|
|
|
54
54
|
const redirectOptions = obj as RedirectRoute;
|
|
55
55
|
if (
|
|
56
56
|
redirectOptions?.targetLocation &&
|
|
57
|
-
redirectOptions.spec
|
|
58
|
-
redirectOptions.spec.description === 'LoopBack Redirect route'
|
|
57
|
+
redirectOptions.spec?.description === 'LoopBack Redirect route'
|
|
59
58
|
) {
|
|
60
59
|
return true;
|
|
61
60
|
}
|
|
@@ -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 {inspect} from 'util';
|
|
8
8
|
import {RestBindings} from '../keys';
|
|
9
9
|
import {PathParameterValues} from '../types';
|
|
@@ -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} from '@loopback/
|
|
6
|
+
import {Context} from '@loopback/core';
|
|
7
7
|
import {OperationObject, SchemasObject} from '@loopback/openapi-v3';
|
|
8
8
|
import {OperationArgs, OperationRetval, PathParameterValues} from '../types';
|
|
9
9
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
// Copyright IBM Corp. 2018,
|
|
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
|
|
5
5
|
|
|
6
|
-
import {inject} from '@loopback/
|
|
6
|
+
import {inject} from '@loopback/core';
|
|
7
7
|
import {inspect} from 'util';
|
|
8
8
|
import {RestBindings} from '../keys';
|
|
9
9
|
import {RestRouterOptions} from './rest-router';
|
package/src/sequence.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
6
|
const debug = require('debug')('loopback:rest:sequence');
|
|
7
|
-
import {inject, ValueOrPromise} from '@loopback/
|
|
7
|
+
import {inject, ValueOrPromise} from '@loopback/core';
|
|
8
8
|
import {InvokeMiddleware} from '@loopback/express';
|
|
9
9
|
import {RestBindings} from './keys';
|
|
10
10
|
import {RequestContext} from './request-context';
|
|
@@ -4,13 +4,14 @@
|
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
+
ApplicationMetadata,
|
|
7
8
|
bind,
|
|
8
9
|
BindingScope,
|
|
10
|
+
CoreBindings,
|
|
9
11
|
inject,
|
|
10
12
|
JSONObject,
|
|
11
13
|
JSONValue,
|
|
12
|
-
} from '@loopback/
|
|
13
|
-
import {ApplicationMetadata, CoreBindings} from '@loopback/core';
|
|
14
|
+
} from '@loopback/core';
|
|
14
15
|
import {
|
|
15
16
|
asSpecEnhancer,
|
|
16
17
|
ContactObject,
|
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 {
|
|
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,
|
|
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
|
-
|
|
127
|
+
value: any,
|
|
121
128
|
schema: SchemaObject | ReferenceObject,
|
|
122
129
|
globalSchemas: SchemasObject = {},
|
|
123
|
-
options:
|
|
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(
|
|
149
|
-
// When
|
|
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(
|
|
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
|
|
162
|
-
util.inspect(
|
|
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
|
-
|
|
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
|
/**
|