@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
|
@@ -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
|
@@ -4,13 +4,15 @@
|
|
|
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,
|
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 {
|
|
@@ -178,7 +180,7 @@ export class RestServer extends BaseMiddlewareRegistry
|
|
|
178
180
|
* will be 'http://localhost:3000' regardless of the `basePath`.
|
|
179
181
|
*/
|
|
180
182
|
get rootUrl(): string | undefined {
|
|
181
|
-
return this._httpServer
|
|
183
|
+
return this._httpServer?.url;
|
|
182
184
|
}
|
|
183
185
|
|
|
184
186
|
/**
|
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';
|
|
@@ -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 {
|
|
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
|
|
|
@@ -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 {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
|
/**
|