@loopback/rest 6.1.0 → 8.0.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 +109 -0
- package/dist/body-parsers/body-parser.js +3 -0
- package/dist/body-parsers/body-parser.js.map +1 -1
- package/dist/coercion/coerce-parameter.d.ts +1 -1
- package/dist/coercion/coerce-parameter.js +36 -13
- package/dist/coercion/coerce-parameter.js.map +1 -1
- package/dist/coercion/utils.d.ts +1 -1
- package/dist/http-handler.js +5 -0
- package/dist/http-handler.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/providers/find-route.provider.d.ts +0 -2
- package/dist/providers/find-route.provider.js +11 -8
- package/dist/providers/find-route.provider.js.map +1 -1
- package/dist/providers/invoke-method.provider.d.ts +0 -2
- package/dist/providers/invoke-method.provider.js +21 -10
- package/dist/providers/invoke-method.provider.js.map +1 -1
- package/dist/providers/log-error.provider.js +7 -2
- package/dist/providers/log-error.provider.js.map +1 -1
- package/dist/providers/parse-params.provider.d.ts +0 -2
- package/dist/providers/parse-params.provider.js +16 -8
- 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 +2 -1
- package/dist/providers/reject.provider.js.map +1 -1
- package/dist/providers/send.provider.d.ts +1 -4
- package/dist/providers/send.provider.js +11 -13
- package/dist/providers/send.provider.js.map +1 -1
- package/dist/request-context.js.map +1 -1
- package/dist/rest.application.js +1 -1
- package/dist/rest.application.js.map +1 -1
- package/dist/rest.server.d.ts +1 -0
- package/dist/rest.server.js +5 -4
- package/dist/rest.server.js.map +1 -1
- package/dist/router/base-route.js +3 -3
- package/dist/router/base-route.js.map +1 -1
- package/dist/router/controller-route.js +1 -1
- package/dist/router/controller-route.js.map +1 -1
- package/dist/router/handler-route.js +1 -1
- package/dist/router/handler-route.js.map +1 -1
- package/dist/router/redirect-route.js +1 -1
- package/dist/router/redirect-route.js.map +1 -1
- package/dist/sequence.js +1 -1
- package/dist/sequence.js.map +1 -1
- package/dist/spec-enhancers/consolidate.spec-enhancer.js +1 -1
- package/dist/spec-enhancers/consolidate.spec-enhancer.js.map +1 -1
- package/dist/spec-enhancers/info.spec-enhancer.js +13 -5
- package/dist/spec-enhancers/info.spec-enhancer.js.map +1 -1
- package/dist/validation/ajv-factory.provider.js +5 -3
- package/dist/validation/ajv-factory.provider.js.map +1 -1
- package/dist/validation/openapi-formats.d.ts +26 -0
- package/dist/validation/openapi-formats.js +85 -0
- package/dist/validation/openapi-formats.js.map +1 -0
- package/dist/validation/request-body.validator.d.ts +4 -4
- package/dist/validation/request-body.validator.js +5 -8
- package/dist/validation/request-body.validator.js.map +1 -1
- package/package.json +25 -22
- package/src/body-parsers/body-parser.ts +3 -0
- package/src/coercion/coerce-parameter.ts +43 -19
- package/src/http-handler.ts +6 -0
- package/src/providers/find-route.provider.ts +24 -8
- package/src/providers/invoke-method.provider.ts +28 -10
- package/src/providers/log-error.provider.ts +2 -1
- package/src/providers/parse-params.provider.ts +28 -8
- package/src/providers/reject.provider.ts +4 -3
- package/src/providers/send.provider.ts +9 -12
- package/src/request-context.ts +2 -1
- package/src/rest.application.ts +1 -1
- package/src/rest.server.ts +8 -5
- package/src/router/base-route.ts +3 -3
- package/src/router/controller-route.ts +1 -1
- package/src/router/handler-route.ts +3 -1
- package/src/router/redirect-route.ts +1 -1
- package/src/sequence.ts +2 -2
- package/src/spec-enhancers/consolidate.spec-enhancer.ts +2 -2
- package/src/spec-enhancers/info.spec-enhancer.ts +15 -6
- package/src/validation/ajv-factory.provider.ts +8 -4
- package/src/validation/openapi-formats.ts +92 -0
- package/src/validation/request-body.validator.ts +8 -8
|
@@ -3,11 +3,11 @@
|
|
|
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 {BindingScope, injectable, Provider} from '@loopback/core';
|
|
7
7
|
import {asMiddleware, Middleware} from '@loopback/express';
|
|
8
8
|
import {RestBindings, RestTags} from '../keys';
|
|
9
9
|
import {RestMiddlewareGroups} from '../sequence';
|
|
10
|
-
import {
|
|
10
|
+
import {Send} from '../types';
|
|
11
11
|
import {writeResultToResponse} from '../writer';
|
|
12
12
|
/**
|
|
13
13
|
* Provides the function that populates the response object with
|
|
@@ -16,13 +16,14 @@ import {writeResultToResponse} from '../writer';
|
|
|
16
16
|
* @returns The handler function that will populate the
|
|
17
17
|
* response with operation results.
|
|
18
18
|
*/
|
|
19
|
+
@injectable({scope: BindingScope.SINGLETON})
|
|
19
20
|
export class SendProvider implements Provider<Send> {
|
|
20
21
|
value() {
|
|
21
22
|
return writeResultToResponse;
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
@
|
|
26
|
+
@injectable(
|
|
26
27
|
asMiddleware({
|
|
27
28
|
group: RestMiddlewareGroups.SEND_RESPONSE,
|
|
28
29
|
downstreamGroups: [
|
|
@@ -31,17 +32,13 @@ export class SendProvider implements Provider<Send> {
|
|
|
31
32
|
],
|
|
32
33
|
chain: RestTags.REST_MIDDLEWARE_CHAIN,
|
|
33
34
|
}),
|
|
35
|
+
{scope: BindingScope.SINGLETON},
|
|
34
36
|
)
|
|
35
37
|
export class SendResponseMiddlewareProvider implements Provider<Middleware> {
|
|
36
|
-
constructor(
|
|
37
|
-
@inject(RestBindings.SequenceActions.SEND)
|
|
38
|
-
protected send: Send,
|
|
39
|
-
@inject(RestBindings.SequenceActions.REJECT)
|
|
40
|
-
protected reject: Reject,
|
|
41
|
-
) {}
|
|
42
|
-
|
|
43
38
|
value(): Middleware {
|
|
44
39
|
return async (ctx, next) => {
|
|
40
|
+
const send = await ctx.get(RestBindings.SequenceActions.SEND);
|
|
41
|
+
const reject = await ctx.get(RestBindings.SequenceActions.REJECT);
|
|
45
42
|
try {
|
|
46
43
|
/**
|
|
47
44
|
* Invoke downstream middleware to produce the result
|
|
@@ -50,12 +47,12 @@ export class SendResponseMiddlewareProvider implements Provider<Middleware> {
|
|
|
50
47
|
/**
|
|
51
48
|
* Write the result to HTTP response
|
|
52
49
|
*/
|
|
53
|
-
|
|
50
|
+
send(ctx.response, result);
|
|
54
51
|
} catch (err) {
|
|
55
52
|
/**
|
|
56
53
|
* Write the error to HTTP response
|
|
57
54
|
*/
|
|
58
|
-
|
|
55
|
+
reject(ctx, err);
|
|
59
56
|
}
|
|
60
57
|
};
|
|
61
58
|
}
|
package/src/request-context.ts
CHANGED
|
@@ -17,7 +17,8 @@ import {RestServerResolvedConfig} from './rest.server';
|
|
|
17
17
|
* A per-request Context combining an IoC container with handler context
|
|
18
18
|
* (request, response, etc.).
|
|
19
19
|
*/
|
|
20
|
-
export class RequestContext
|
|
20
|
+
export class RequestContext
|
|
21
|
+
extends MiddlewareContext
|
|
21
22
|
implements HandlerContext {
|
|
22
23
|
/**
|
|
23
24
|
* Get the protocol used by the client to make the request.
|
package/src/rest.application.ts
CHANGED
|
@@ -368,7 +368,7 @@ export class RestApplication extends Application implements HttpServerLike {
|
|
|
368
368
|
* @returns Binding for the api spec
|
|
369
369
|
*/
|
|
370
370
|
api(spec: OpenApiSpec): Binding {
|
|
371
|
-
return this.bind(RestBindings.API_SPEC).to(spec);
|
|
371
|
+
return this.restServer.bind(RestBindings.API_SPEC).to(spec);
|
|
372
372
|
}
|
|
373
373
|
|
|
374
374
|
/**
|
package/src/rest.server.ts
CHANGED
|
@@ -111,7 +111,8 @@ const SequenceActions = RestBindings.SequenceActions;
|
|
|
111
111
|
* const server = await app.get('servers.foo');
|
|
112
112
|
* ```
|
|
113
113
|
*/
|
|
114
|
-
export class RestServer
|
|
114
|
+
export class RestServer
|
|
115
|
+
extends BaseMiddlewareRegistry
|
|
115
116
|
implements Server, HttpServerLike {
|
|
116
117
|
/**
|
|
117
118
|
* Handle incoming HTTP(S) request by invoking the corresponding
|
|
@@ -170,6 +171,10 @@ export class RestServer extends BaseMiddlewareRegistry
|
|
|
170
171
|
return this._httpServer ? this._httpServer.listening : false;
|
|
171
172
|
}
|
|
172
173
|
|
|
174
|
+
get httpServer(): HttpServer | undefined {
|
|
175
|
+
return this._httpServer;
|
|
176
|
+
}
|
|
177
|
+
|
|
173
178
|
/**
|
|
174
179
|
* The base url for the server, including the basePath if set. For example,
|
|
175
180
|
* the value will be 'http://localhost:3000/api' if `basePath` is set to
|
|
@@ -206,6 +211,7 @@ export class RestServer extends BaseMiddlewareRegistry
|
|
|
206
211
|
config: RestServerConfig = {},
|
|
207
212
|
) {
|
|
208
213
|
super(app);
|
|
214
|
+
this.scope = BindingScope.SERVER;
|
|
209
215
|
|
|
210
216
|
this.config = resolveRestServerConfig(config);
|
|
211
217
|
|
|
@@ -978,10 +984,7 @@ export class RestServer extends BaseMiddlewareRegistry
|
|
|
978
984
|
return;
|
|
979
985
|
}
|
|
980
986
|
|
|
981
|
-
const serverOptions = {};
|
|
982
|
-
if (protocol === 'https') Object.assign(serverOptions, httpsOptions);
|
|
983
|
-
Object.assign(serverOptions, {port, host, protocol, path});
|
|
984
|
-
|
|
987
|
+
const serverOptions = {...httpsOptions, port, host, protocol, path};
|
|
985
988
|
this._httpServer = new HttpServer(this.requestHandler, serverOptions);
|
|
986
989
|
|
|
987
990
|
await this._httpServer.start();
|
package/src/router/base-route.ts
CHANGED
|
@@ -36,11 +36,11 @@ export abstract class BaseRoute implements RouteEntry {
|
|
|
36
36
|
): Promise<OperationRetval>;
|
|
37
37
|
|
|
38
38
|
describe(): string {
|
|
39
|
-
return
|
|
39
|
+
return `${this.verb} ${this.path}`;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
toString() {
|
|
43
|
-
return `${this.constructor.name} - ${this.
|
|
43
|
+
return `${this.constructor.name} - ${this.describe()}`;
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -48,6 +48,6 @@ export class RouteSource implements InvocationSource<RouteEntry> {
|
|
|
48
48
|
type = 'route';
|
|
49
49
|
constructor(readonly value: RouteEntry) {}
|
|
50
50
|
toString() {
|
|
51
|
-
return
|
|
51
|
+
return this.value.toString();
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -101,7 +101,7 @@ export class ControllerRoute<T> extends BaseRoute {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
describe(): string {
|
|
104
|
-
return `${this._controllerName}.${this._methodName}`;
|
|
104
|
+
return `${super.describe()} => ${this._controllerName}.${this._methodName}`;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
updateBindings(requestContext: Context) {
|
|
@@ -20,7 +20,9 @@ export class Route extends BaseRoute {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
describe(): string {
|
|
23
|
-
return
|
|
23
|
+
return `${super.describe()} => ${
|
|
24
|
+
this._handler.name || this._handler.toString()
|
|
25
|
+
}`;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
updateBindings(requestContext: Context) {
|
|
@@ -42,7 +42,7 @@ export class RedirectRoute implements RouteEntry, ResolvedRoute {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
describe(): string {
|
|
45
|
-
return `
|
|
45
|
+
return `Redirect: "${this.sourcePath}" => "${this.targetLocation}"`;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/**
|
package/src/sequence.ts
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
-
bind,
|
|
8
7
|
BindingScope,
|
|
9
8
|
config,
|
|
10
9
|
Context,
|
|
11
10
|
inject,
|
|
11
|
+
injectable,
|
|
12
12
|
ValueOrPromise,
|
|
13
13
|
} from '@loopback/core';
|
|
14
14
|
import {
|
|
@@ -185,7 +185,7 @@ export namespace RestMiddlewareGroups {
|
|
|
185
185
|
/**
|
|
186
186
|
* A sequence implementation using middleware chains
|
|
187
187
|
*/
|
|
188
|
-
@
|
|
188
|
+
@injectable({scope: BindingScope.SINGLETON})
|
|
189
189
|
export class MiddlewareSequence implements SequenceHandler {
|
|
190
190
|
private middlewareView: MiddlewareView;
|
|
191
191
|
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
ApplicationConfig,
|
|
8
|
-
bind,
|
|
9
8
|
BindingScope,
|
|
10
9
|
CoreBindings,
|
|
11
10
|
inject,
|
|
11
|
+
injectable,
|
|
12
12
|
} from '@loopback/core';
|
|
13
13
|
import {
|
|
14
14
|
asSpecEnhancer,
|
|
@@ -58,7 +58,7 @@ const debug = debugFactory('loopback:openapi:spec-enhancer:consolidate');
|
|
|
58
58
|
* When comparing schemas to avoid naming collisions, the description field
|
|
59
59
|
* is ignored.
|
|
60
60
|
*/
|
|
61
|
-
@
|
|
61
|
+
@injectable(asSpecEnhancer, {scope: BindingScope.SINGLETON})
|
|
62
62
|
export class ConsolidationEnhancer implements OASEnhancer {
|
|
63
63
|
name = 'consolidate';
|
|
64
64
|
disabled: boolean;
|
|
@@ -5,16 +5,17 @@
|
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
ApplicationMetadata,
|
|
8
|
-
bind,
|
|
9
8
|
BindingScope,
|
|
10
9
|
CoreBindings,
|
|
11
10
|
inject,
|
|
11
|
+
injectable,
|
|
12
12
|
JSONObject,
|
|
13
13
|
JSONValue,
|
|
14
14
|
} from '@loopback/core';
|
|
15
15
|
import {
|
|
16
16
|
asSpecEnhancer,
|
|
17
17
|
ContactObject,
|
|
18
|
+
DEFAULT_OPENAPI_SPEC_INFO,
|
|
18
19
|
mergeOpenAPISpec,
|
|
19
20
|
OASEnhancer,
|
|
20
21
|
OpenApiSpec,
|
|
@@ -27,7 +28,7 @@ const debug = debugFactory('loopback:openapi:spec-enhancer:info');
|
|
|
27
28
|
* An OpenAPI spec enhancer to populate `info` with application metadata
|
|
28
29
|
* (package.json).
|
|
29
30
|
*/
|
|
30
|
-
@
|
|
31
|
+
@injectable(asSpecEnhancer, {scope: BindingScope.SINGLETON})
|
|
31
32
|
export class InfoSpecEnhancer implements OASEnhancer {
|
|
32
33
|
name = 'info';
|
|
33
34
|
|
|
@@ -44,12 +45,20 @@ export class InfoSpecEnhancer implements OASEnhancer {
|
|
|
44
45
|
const contact: ContactObject = InfoSpecEnhancer.parseAuthor(
|
|
45
46
|
this.pkg.author,
|
|
46
47
|
);
|
|
48
|
+
// Only override `info` if the `spec.info` is not customized
|
|
49
|
+
const overrideInfo =
|
|
50
|
+
spec.info.title === DEFAULT_OPENAPI_SPEC_INFO.title &&
|
|
51
|
+
spec.info.version === DEFAULT_OPENAPI_SPEC_INFO.version;
|
|
47
52
|
const patchSpec = {
|
|
48
53
|
info: {
|
|
49
|
-
title: this.pkg.name,
|
|
50
|
-
description:
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
title: overrideInfo ? this.pkg.name : spec.info.title ?? this.pkg.name,
|
|
55
|
+
description: overrideInfo
|
|
56
|
+
? this.pkg.description
|
|
57
|
+
: spec.info.description ?? this.pkg.description,
|
|
58
|
+
version: overrideInfo
|
|
59
|
+
? this.pkg.version
|
|
60
|
+
: spec.info.version ?? this.pkg.version,
|
|
61
|
+
contact: overrideInfo ? contact : spec.info.contact ?? contact,
|
|
53
62
|
},
|
|
54
63
|
};
|
|
55
64
|
debug('Enhancing OpenAPI spec with %j', patchSpec);
|
|
@@ -4,16 +4,17 @@
|
|
|
4
4
|
// License text available at https://opensource.org/licenses/MIT
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
-
bind,
|
|
8
7
|
BindingScope,
|
|
9
8
|
filterByTag,
|
|
10
9
|
inject,
|
|
10
|
+
injectable,
|
|
11
11
|
Provider,
|
|
12
12
|
} from '@loopback/core';
|
|
13
13
|
import AjvCtor from 'ajv';
|
|
14
14
|
import debugModule from 'debug';
|
|
15
15
|
import {RestBindings, RestTags} from '../keys';
|
|
16
16
|
import {AjvFactory, AjvFormat, AjvKeyword, ValidationOptions} from '../types';
|
|
17
|
+
import {openapiFormats} from './openapi-formats';
|
|
17
18
|
|
|
18
19
|
const debug = debugModule('loopback:rest:ajv');
|
|
19
20
|
|
|
@@ -29,7 +30,7 @@ export const DEFAULT_AJV_VALIDATION_OPTIONS: ValidationOptions = {
|
|
|
29
30
|
/**
|
|
30
31
|
* A provider class that instantiate an AJV instance
|
|
31
32
|
*/
|
|
32
|
-
@
|
|
33
|
+
@injectable({scope: BindingScope.SINGLETON})
|
|
33
34
|
export class AjvFactoryProvider implements Provider<AjvFactory> {
|
|
34
35
|
constructor(
|
|
35
36
|
@inject(
|
|
@@ -57,8 +58,6 @@ export class AjvFactoryProvider implements Provider<AjvFactory> {
|
|
|
57
58
|
jsonPointers: true,
|
|
58
59
|
// nullable: support keyword "nullable" from Open API 3 specification.
|
|
59
60
|
nullable: true,
|
|
60
|
-
// Allow OpenAPI spec binary format
|
|
61
|
-
unknownFormats: ['binary'],
|
|
62
61
|
...validationOptions,
|
|
63
62
|
};
|
|
64
63
|
|
|
@@ -84,12 +83,17 @@ export class AjvFactoryProvider implements Provider<AjvFactory> {
|
|
|
84
83
|
});
|
|
85
84
|
}
|
|
86
85
|
|
|
86
|
+
for (const format of openapiFormats) {
|
|
87
|
+
ajvInst.addFormat(format.name, format);
|
|
88
|
+
}
|
|
89
|
+
|
|
87
90
|
if (this.formats) {
|
|
88
91
|
this.formats.forEach(format => {
|
|
89
92
|
debug('Adding Ajv format %s', format.name);
|
|
90
93
|
ajvInst.addFormat(format.name, format);
|
|
91
94
|
});
|
|
92
95
|
}
|
|
96
|
+
|
|
93
97
|
return ajvInst;
|
|
94
98
|
};
|
|
95
99
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Copyright IBM Corp. 2020. All Rights Reserved.
|
|
2
|
+
// Node module: @loopback/rest
|
|
3
|
+
// This file is licensed under the MIT License.
|
|
4
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
+
|
|
6
|
+
import {AjvFormat} from '../types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* int32: [-2147483648, 21474836 47]
|
|
10
|
+
*/
|
|
11
|
+
export const int32Format: AjvFormat = {
|
|
12
|
+
name: 'int32',
|
|
13
|
+
type: 'number',
|
|
14
|
+
validate: (value: number) => {
|
|
15
|
+
return (
|
|
16
|
+
Number.isInteger(value) && value >= -2147483648 && value <= 2147483647
|
|
17
|
+
);
|
|
18
|
+
},
|
|
19
|
+
async: false,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* int64: [-9223372036854775808, 9223372036854775807]
|
|
24
|
+
*/
|
|
25
|
+
export const int64Format: AjvFormat = {
|
|
26
|
+
name: 'int64',
|
|
27
|
+
type: 'number',
|
|
28
|
+
validate: (value: number) => {
|
|
29
|
+
const max = Number.MAX_SAFE_INTEGER; // 9007199254740991
|
|
30
|
+
const min = Number.MIN_SAFE_INTEGER; // -9007199254740991
|
|
31
|
+
return Number.isInteger(value) && value >= min && value <= max;
|
|
32
|
+
},
|
|
33
|
+
async: false,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* float: [-2^128, 2^128]
|
|
38
|
+
*/
|
|
39
|
+
export const floatFormat: AjvFormat = {
|
|
40
|
+
name: 'float',
|
|
41
|
+
type: 'number',
|
|
42
|
+
validate: (value: number) => {
|
|
43
|
+
return value >= -Math.pow(2, 128) && value <= Math.pow(2, 128);
|
|
44
|
+
},
|
|
45
|
+
async: false,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* double: [-2^1024, 2^1024]
|
|
50
|
+
*/
|
|
51
|
+
export const doubleFormat: AjvFormat = {
|
|
52
|
+
name: 'double',
|
|
53
|
+
type: 'number',
|
|
54
|
+
validate: (value: number) => {
|
|
55
|
+
const max = Number.MAX_VALUE; // 1.7976931348623157e+308
|
|
56
|
+
const min = -Number.MAX_VALUE; // -1.7976931348623157e+308
|
|
57
|
+
return value >= min && value <= max;
|
|
58
|
+
},
|
|
59
|
+
async: false,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Base64 encoded string
|
|
64
|
+
*/
|
|
65
|
+
export const byteFormat: AjvFormat = {
|
|
66
|
+
name: 'byte',
|
|
67
|
+
type: 'string',
|
|
68
|
+
validate: (value: string) => {
|
|
69
|
+
const base64 = Buffer.from(value, 'base64').toString('base64');
|
|
70
|
+
return value === base64;
|
|
71
|
+
},
|
|
72
|
+
async: false,
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Binary string
|
|
77
|
+
*/
|
|
78
|
+
export const binaryFormat: AjvFormat = {
|
|
79
|
+
name: 'binary',
|
|
80
|
+
type: 'string',
|
|
81
|
+
validate: (value: string) => true,
|
|
82
|
+
async: false,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const openapiFormats: AjvFormat[] = [
|
|
86
|
+
int32Format,
|
|
87
|
+
int64Format,
|
|
88
|
+
floatFormat,
|
|
89
|
+
doubleFormat,
|
|
90
|
+
byteFormat,
|
|
91
|
+
binaryFormat,
|
|
92
|
+
];
|
|
@@ -118,11 +118,11 @@ function getKeyForOptions(
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
/**
|
|
121
|
-
* Validate the
|
|
122
|
-
* @param
|
|
121
|
+
* Validate the value against JSON schema.
|
|
122
|
+
* @param value - The data value.
|
|
123
123
|
* @param schema - The JSON schema used to perform the validation.
|
|
124
124
|
* @param globalSchemas - Schema references.
|
|
125
|
-
* @param options -
|
|
125
|
+
* @param options - Value validation options.
|
|
126
126
|
*/
|
|
127
127
|
export async function validateValueAgainstSchema(
|
|
128
128
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -155,11 +155,11 @@ export async function validateValueAgainstSchema(
|
|
|
155
155
|
let validationErrors: ajv.ErrorObject[] = [];
|
|
156
156
|
try {
|
|
157
157
|
const validationResult = await validate(value);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
158
|
+
debug(
|
|
159
|
+
`Value from ${options.source} passed AJV validation.`,
|
|
160
|
+
validationResult,
|
|
161
|
+
);
|
|
162
|
+
return validationResult;
|
|
163
163
|
} catch (error) {
|
|
164
164
|
validationErrors = error.errors;
|
|
165
165
|
}
|