@jskit-ai/kernel 0.1.55 → 0.1.56
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/package.json +3 -2
- package/server/actions/ActionRuntimeServiceProvider.test.js +23 -15
- package/server/http/lib/kernel.test.js +447 -0
- package/server/http/lib/routeRegistration.js +236 -15
- package/server/http/lib/routeTransport.js +126 -0
- package/server/http/lib/routeValidator.js +133 -198
- package/server/http/lib/routeValidator.test.js +385 -278
- package/server/http/lib/router.js +17 -2
- package/server/platform/providerRuntime.test.js +7 -7
- package/server/runtime/bootBootstrapRoutes.js +2 -18
- package/server/runtime/bootBootstrapRoutes.test.js +5 -14
- package/server/runtime/fastifyBootstrap.js +119 -0
- package/server/runtime/fastifyBootstrap.test.js +119 -1
- package/server/runtime/moduleConfig.js +32 -62
- package/server/runtime/moduleConfig.test.js +48 -24
- package/server/support/pageTargets.js +15 -9
- package/server/support/pageTargets.test.js +1 -1
- package/shared/actions/actionContributorHelpers.js +5 -11
- package/shared/actions/actionDefinitions.js +37 -150
- package/shared/actions/actionDefinitions.test.js +117 -136
- package/shared/actions/policies.js +25 -169
- package/shared/actions/policies.test.js +76 -87
- package/shared/actions/registry.test.js +24 -50
- package/shared/support/crudFieldContract.js +322 -0
- package/shared/support/crudFieldContract.test.js +67 -0
- package/shared/support/crudListFilters.js +582 -38
- package/shared/support/crudListFilters.test.js +178 -8
- package/shared/support/crudLookup.js +14 -7
- package/shared/support/crudLookup.test.js +91 -66
- package/shared/support/shellLayoutTargets.test.js +1 -1
- package/shared/validators/composeSchemaDefinitions.js +53 -0
- package/shared/validators/composeSchemaDefinitions.test.js +156 -0
- package/shared/validators/createCursorListValidator.js +22 -35
- package/shared/validators/createCursorListValidator.test.js +22 -23
- package/shared/validators/cursorPaginationQueryValidator.js +14 -24
- package/shared/validators/cursorPaginationQueryValidator.test.js +18 -8
- package/shared/validators/htmlTimeSchemas.js +6 -4
- package/shared/validators/index.js +15 -7
- package/shared/validators/jsonRestSchemaSupport.js +139 -0
- package/shared/validators/mergeObjectSchemas.js +44 -6
- package/shared/validators/mergeObjectSchemas.test.js +60 -35
- package/shared/validators/recordIdParamsValidator.js +19 -52
- package/shared/validators/recordIdParamsValidator.test.js +13 -8
- package/shared/validators/resourceRequiredMetadata.js +3 -3
- package/shared/validators/resourceRequiredMetadata.test.js +29 -16
- package/shared/validators/schemaDefinitions.js +126 -0
- package/shared/validators/schemaDefinitions.test.js +51 -0
- package/shared/validators/schemaPayloadValidation.js +65 -0
- package/test/barrelExposure.test.js +30 -0
- package/test/routeInputContractGuard.test.js +10 -6
- package/shared/validators/mergeValidators.js +0 -89
- package/shared/validators/mergeValidators.test.js +0 -116
- package/shared/validators/nestValidator.js +0 -53
- package/shared/validators/nestValidator.test.js +0 -60
- package/shared/validators/settingsFieldNormalization.js +0 -40
|
@@ -1,125 +1,65 @@
|
|
|
1
1
|
import { normalizeObject, normalizeText } from "../../../shared/support/normalize.js";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
normalizeSchemaDefinition,
|
|
4
|
+
resolveSchemaTransportSchemaDefinition,
|
|
5
|
+
validateSchemaPayload
|
|
6
|
+
} from "../../../shared/validators/index.js";
|
|
3
7
|
import { RouteDefinitionError } from "./errors.js";
|
|
4
8
|
import { resolveRouteLabel } from "./routeSupport.js";
|
|
5
9
|
|
|
6
10
|
const ROUTE_VALIDATOR_SYMBOL = "@jskit-ai/kernel/http/routeValidator";
|
|
11
|
+
const JSON_REST_TRANSPORT_EXTENSION_KEY = "x-json-rest-schema";
|
|
7
12
|
const VALIDATOR_OPTION_KEYS = Object.freeze([
|
|
8
13
|
"meta",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
14
|
+
"body",
|
|
15
|
+
"query",
|
|
16
|
+
"params",
|
|
17
|
+
"responses",
|
|
13
18
|
"advanced"
|
|
14
19
|
]);
|
|
20
|
+
const ADVANCED_VALIDATOR_OPTION_KEYS = Object.freeze([
|
|
21
|
+
"fastifySchema"
|
|
22
|
+
]);
|
|
23
|
+
const UNSUPPORTED_ROUTE_VALIDATOR_KEYS = Object.freeze([
|
|
24
|
+
"schema",
|
|
25
|
+
"input",
|
|
26
|
+
"validator"
|
|
27
|
+
]);
|
|
15
28
|
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
function normalizeOptionalValidatorTransformer(source, normalized, { context = "route validator" } = {}) {
|
|
21
|
-
if (!Object.prototype.hasOwnProperty.call(source, "normalize")) {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const normalize = source.normalize;
|
|
26
|
-
if (normalize != null && typeof normalize !== "function") {
|
|
27
|
-
throw new RouteDefinitionError(`${context}.normalize must be a function.`);
|
|
28
|
-
}
|
|
29
|
-
if (typeof normalize === "function") {
|
|
30
|
-
normalized.normalize = normalize;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function normalizeSingleRouteValidator(value, { context = "route validator" } = {}) {
|
|
35
|
-
if (value == null) {
|
|
36
|
-
return Object.freeze({});
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
40
|
-
throw new RouteDefinitionError(`${context} must be an object.`);
|
|
29
|
+
function stripJsonRestTransportExtensions(value) {
|
|
30
|
+
if (Array.isArray(value)) {
|
|
31
|
+
return value.map((entry) => stripJsonRestTransportExtensions(entry));
|
|
41
32
|
}
|
|
42
33
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (Object.prototype.hasOwnProperty.call(source, "schema")) {
|
|
47
|
-
normalized.schema = source.schema;
|
|
34
|
+
if (!value || typeof value !== "object") {
|
|
35
|
+
return value;
|
|
48
36
|
}
|
|
49
37
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return Object.freeze(normalized);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function mergeNormalizedRouteValidators(validators, { context = "route validator" } = {}) {
|
|
56
|
-
return mergeValidators(validators, {
|
|
57
|
-
context,
|
|
58
|
-
allowAsyncNormalize: false,
|
|
59
|
-
createError(message) {
|
|
60
|
-
return new RouteDefinitionError(message);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
38
|
+
const sanitized = {};
|
|
64
39
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (Array.isArray(value)) {
|
|
71
|
-
if (!allowArray) {
|
|
72
|
-
throw new RouteDefinitionError(`${context} does not support arrays.`);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (value.length === 0) {
|
|
76
|
-
return Object.freeze({});
|
|
40
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
41
|
+
if (key === JSON_REST_TRANSPORT_EXTENSION_KEY) {
|
|
42
|
+
continue;
|
|
77
43
|
}
|
|
78
44
|
|
|
79
|
-
|
|
80
|
-
const validator = normalizeSingleRouteValidator(entry, {
|
|
81
|
-
context: `${context}[${index}]`
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
if (
|
|
85
|
-
!Object.prototype.hasOwnProperty.call(validator, "schema") &&
|
|
86
|
-
!Object.prototype.hasOwnProperty.call(validator, "normalize")
|
|
87
|
-
) {
|
|
88
|
-
throw new RouteDefinitionError(`${context}[${index}] must define schema and/or normalize.`);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return validator;
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
return mergeNormalizedRouteValidators(validators, {
|
|
95
|
-
context
|
|
96
|
-
});
|
|
45
|
+
sanitized[key] = stripJsonRestTransportExtensions(entry);
|
|
97
46
|
}
|
|
98
47
|
|
|
99
|
-
return
|
|
100
|
-
context
|
|
101
|
-
});
|
|
48
|
+
return sanitized;
|
|
102
49
|
}
|
|
103
50
|
|
|
104
|
-
function
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (!Object.prototype.hasOwnProperty.call(source, "schema")) {
|
|
113
|
-
throw new RouteDefinitionError(`${context}.schema is required when using a response validator object.`);
|
|
51
|
+
function normalizeRouteSchemaSection(value, { context = "route section", defaultMode = "patch" } = {}) {
|
|
52
|
+
try {
|
|
53
|
+
return normalizeSchemaDefinition(value, {
|
|
54
|
+
context,
|
|
55
|
+
defaultMode
|
|
56
|
+
});
|
|
57
|
+
} catch (error) {
|
|
58
|
+
throw new RouteDefinitionError(error?.message || `${context} is invalid.`);
|
|
114
59
|
}
|
|
115
|
-
normalized.schema = source.schema;
|
|
116
|
-
|
|
117
|
-
normalizeOptionalValidatorTransformer(source, normalized, { context });
|
|
118
|
-
|
|
119
|
-
return Object.freeze(normalized);
|
|
120
60
|
}
|
|
121
61
|
|
|
122
|
-
function
|
|
62
|
+
function normalizeResponseDefinition(value, { context = "route responses" } = {}) {
|
|
123
63
|
if (value == null) {
|
|
124
64
|
return undefined;
|
|
125
65
|
}
|
|
@@ -132,8 +72,24 @@ function normalizeResponseValidatorDefinition(value, { context = "route validato
|
|
|
132
72
|
const normalized = {};
|
|
133
73
|
|
|
134
74
|
for (const [statusCode, entry] of Object.entries(source)) {
|
|
135
|
-
|
|
136
|
-
|
|
75
|
+
const entryContext = `${context}.${statusCode}`;
|
|
76
|
+
if (
|
|
77
|
+
entry &&
|
|
78
|
+
typeof entry === "object" &&
|
|
79
|
+
!Array.isArray(entry) &&
|
|
80
|
+
Object.prototype.hasOwnProperty.call(entry, "transportSchema")
|
|
81
|
+
) {
|
|
82
|
+
normalized[statusCode] = Object.freeze({
|
|
83
|
+
transportSchema: normalizeObject(entry.transportSchema, {
|
|
84
|
+
fallback: {}
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
normalized[statusCode] = normalizeRouteSchemaSection(entry, {
|
|
91
|
+
context: entryContext,
|
|
92
|
+
defaultMode: "replace"
|
|
137
93
|
});
|
|
138
94
|
}
|
|
139
95
|
|
|
@@ -155,46 +111,6 @@ function normalizeAdvancedFastifySchema(value, { context = "route validator" } =
|
|
|
155
111
|
});
|
|
156
112
|
}
|
|
157
113
|
|
|
158
|
-
function normalizeAdvancedJskitInput(value, { context = "route validator" } = {}) {
|
|
159
|
-
if (!Object.prototype.hasOwnProperty.call(value, "jskitInput")) {
|
|
160
|
-
return undefined;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const jskitInput = value.jskitInput;
|
|
164
|
-
if (!jskitInput || typeof jskitInput !== "object" || Array.isArray(jskitInput)) {
|
|
165
|
-
throw new RouteDefinitionError(`${context}.advanced.jskitInput must be an object.`);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const supportedKeys = new Set(["body", "query", "params"]);
|
|
169
|
-
for (const key of Object.keys(jskitInput)) {
|
|
170
|
-
if (!supportedKeys.has(key)) {
|
|
171
|
-
throw new RouteDefinitionError(
|
|
172
|
-
`${context}.advanced.jskitInput.${key} is not supported. Use body, query, or params.`
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const normalized = {};
|
|
178
|
-
for (const key of ["body", "query", "params"]) {
|
|
179
|
-
if (!Object.prototype.hasOwnProperty.call(jskitInput, key)) {
|
|
180
|
-
continue;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const transform = jskitInput[key];
|
|
184
|
-
if (transform == null) {
|
|
185
|
-
continue;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (typeof transform !== "function") {
|
|
189
|
-
throw new RouteDefinitionError(`${context}.advanced.jskitInput.${key} must be a function.`);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
normalized[key] = transform;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return Object.freeze(normalized);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
114
|
function normalizeRouteValidatorMeta(value, { context = "route validator" } = {}) {
|
|
199
115
|
if (value == null) {
|
|
200
116
|
return Object.freeze({});
|
|
@@ -243,32 +159,23 @@ function normalizeRouteValidatorDefinition(sourceDefinition, { context = "route
|
|
|
243
159
|
throw new RouteDefinitionError(`${context} must be an object.`);
|
|
244
160
|
}
|
|
245
161
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (Object.prototype.hasOwnProperty.call(definition, "query")) {
|
|
250
|
-
throw new RouteDefinitionError(`${context}.query is not supported. Use ${context}.queryValidator.`);
|
|
251
|
-
}
|
|
252
|
-
if (Object.prototype.hasOwnProperty.call(definition, "params")) {
|
|
253
|
-
throw new RouteDefinitionError(`${context}.params is not supported. Use ${context}.paramsValidator.`);
|
|
254
|
-
}
|
|
255
|
-
if (Object.prototype.hasOwnProperty.call(definition, "response")) {
|
|
256
|
-
throw new RouteDefinitionError(`${context}.response is not supported. Use ${context}.responseValidators.`);
|
|
162
|
+
const unsupportedKeys = Object.keys(definition).filter((key) => !VALIDATOR_OPTION_KEYS.includes(key));
|
|
163
|
+
if (unsupportedKeys.length > 0) {
|
|
164
|
+
throw new RouteDefinitionError(`${context}.${unsupportedKeys[0]} is not supported.`);
|
|
257
165
|
}
|
|
258
166
|
|
|
259
167
|
const meta = normalizeRouteValidatorMeta(definition.meta, {
|
|
260
168
|
context
|
|
261
169
|
});
|
|
262
|
-
const
|
|
263
|
-
context: `${context}.
|
|
170
|
+
const body = normalizeRouteSchemaSection(definition.body, {
|
|
171
|
+
context: `${context}.body`,
|
|
172
|
+
defaultMode: "patch"
|
|
264
173
|
});
|
|
265
|
-
const
|
|
266
|
-
context: `${context}.
|
|
267
|
-
allowArray: true
|
|
174
|
+
const query = normalizeRouteSchemaSection(definition.query, {
|
|
175
|
+
context: `${context}.query`
|
|
268
176
|
});
|
|
269
|
-
const
|
|
270
|
-
context: `${context}.
|
|
271
|
-
allowArray: true
|
|
177
|
+
const params = normalizeRouteSchemaSection(definition.params, {
|
|
178
|
+
context: `${context}.params`
|
|
272
179
|
});
|
|
273
180
|
|
|
274
181
|
const advancedSource =
|
|
@@ -282,16 +189,23 @@ function normalizeRouteValidatorDefinition(sourceDefinition, { context = "route
|
|
|
282
189
|
throw new RouteDefinitionError(`${context}.advanced must be an object.`);
|
|
283
190
|
}
|
|
284
191
|
|
|
192
|
+
const unsupportedAdvancedKeys = Object.keys(advancedSource).filter(
|
|
193
|
+
(key) => !ADVANCED_VALIDATOR_OPTION_KEYS.includes(key)
|
|
194
|
+
);
|
|
195
|
+
if (unsupportedAdvancedKeys.length > 0) {
|
|
196
|
+
throw new RouteDefinitionError(`${context}.advanced.${unsupportedAdvancedKeys[0]} is not supported.`);
|
|
197
|
+
}
|
|
198
|
+
|
|
285
199
|
const normalized = {
|
|
286
200
|
meta,
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
201
|
+
body,
|
|
202
|
+
query,
|
|
203
|
+
params
|
|
290
204
|
};
|
|
291
205
|
|
|
292
|
-
if (Object.prototype.hasOwnProperty.call(definition, "
|
|
293
|
-
normalized.
|
|
294
|
-
context: `${context}.
|
|
206
|
+
if (Object.prototype.hasOwnProperty.call(definition, "responses")) {
|
|
207
|
+
normalized.responses = normalizeResponseDefinition(definition.responses, {
|
|
208
|
+
context: `${context}.responses`
|
|
295
209
|
});
|
|
296
210
|
}
|
|
297
211
|
|
|
@@ -302,13 +216,6 @@ function normalizeRouteValidatorDefinition(sourceDefinition, { context = "route
|
|
|
302
216
|
normalized.fastifySchema = fastifySchema;
|
|
303
217
|
}
|
|
304
218
|
|
|
305
|
-
const jskitInput = normalizeAdvancedJskitInput(advancedSource, {
|
|
306
|
-
context
|
|
307
|
-
});
|
|
308
|
-
if (jskitInput) {
|
|
309
|
-
normalized.jskitInput = jskitInput;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
219
|
return Object.freeze(normalized);
|
|
313
220
|
}
|
|
314
221
|
|
|
@@ -316,6 +223,14 @@ function compileNormalizedRouteValidator(normalizedValidator) {
|
|
|
316
223
|
const schema = {};
|
|
317
224
|
const input = {};
|
|
318
225
|
|
|
226
|
+
function createJsonRestSchemaInputTransform(definition, { defaultMode = "patch", context = "route validator" } = {}) {
|
|
227
|
+
return (payload) => validateSchemaPayload(definition, payload, {
|
|
228
|
+
phase: defaultMode === "replace" ? "output" : "input",
|
|
229
|
+
context,
|
|
230
|
+
statusCode: 400
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
319
234
|
if (Array.isArray(normalizedValidator.meta?.tags) && normalizedValidator.meta.tags.length > 0) {
|
|
320
235
|
schema.tags = [...normalizedValidator.meta.tags];
|
|
321
236
|
}
|
|
@@ -323,32 +238,50 @@ function compileNormalizedRouteValidator(normalizedValidator) {
|
|
|
323
238
|
schema.summary = normalizedValidator.meta.summary;
|
|
324
239
|
}
|
|
325
240
|
|
|
326
|
-
if (
|
|
327
|
-
schema.body = normalizedValidator.
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
241
|
+
if (normalizedValidator.body) {
|
|
242
|
+
schema.body = resolveSchemaTransportSchemaDefinition(normalizedValidator.body, {
|
|
243
|
+
defaultMode: "patch",
|
|
244
|
+
context: "route validator.body"
|
|
245
|
+
});
|
|
246
|
+
input.body = createJsonRestSchemaInputTransform(normalizedValidator.body, {
|
|
247
|
+
defaultMode: "patch",
|
|
248
|
+
context: "route validator.body"
|
|
249
|
+
});
|
|
331
250
|
}
|
|
332
251
|
|
|
333
|
-
if (
|
|
334
|
-
schema.querystring = normalizedValidator.
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
252
|
+
if (normalizedValidator.query) {
|
|
253
|
+
schema.querystring = resolveSchemaTransportSchemaDefinition(normalizedValidator.query, {
|
|
254
|
+
defaultMode: "patch",
|
|
255
|
+
context: "route validator.query"
|
|
256
|
+
});
|
|
257
|
+
input.query = createJsonRestSchemaInputTransform(normalizedValidator.query, {
|
|
258
|
+
defaultMode: "patch",
|
|
259
|
+
context: "route validator.query"
|
|
260
|
+
});
|
|
338
261
|
}
|
|
339
262
|
|
|
340
|
-
if (
|
|
341
|
-
schema.params = normalizedValidator.
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
263
|
+
if (normalizedValidator.params) {
|
|
264
|
+
schema.params = resolveSchemaTransportSchemaDefinition(normalizedValidator.params, {
|
|
265
|
+
defaultMode: "patch",
|
|
266
|
+
context: "route validator.params"
|
|
267
|
+
});
|
|
268
|
+
input.params = createJsonRestSchemaInputTransform(normalizedValidator.params, {
|
|
269
|
+
defaultMode: "patch",
|
|
270
|
+
context: "route validator.params"
|
|
271
|
+
});
|
|
345
272
|
}
|
|
346
273
|
|
|
347
|
-
if (Object.prototype.hasOwnProperty.call(normalizedValidator, "
|
|
274
|
+
if (Object.prototype.hasOwnProperty.call(normalizedValidator, "responses")) {
|
|
348
275
|
const responseSchema = {};
|
|
349
276
|
|
|
350
|
-
for (const [statusCode, entry] of Object.entries(normalizedValidator.
|
|
351
|
-
responseSchema[statusCode] =
|
|
277
|
+
for (const [statusCode, entry] of Object.entries(normalizedValidator.responses || {})) {
|
|
278
|
+
responseSchema[statusCode] =
|
|
279
|
+
entry && typeof entry === "object" && !Array.isArray(entry) && Object.prototype.hasOwnProperty.call(entry, "transportSchema")
|
|
280
|
+
? entry.transportSchema
|
|
281
|
+
: resolveSchemaTransportSchemaDefinition(entry, {
|
|
282
|
+
defaultMode: "replace",
|
|
283
|
+
context: `route validator.responses.${statusCode}`
|
|
284
|
+
});
|
|
352
285
|
}
|
|
353
286
|
|
|
354
287
|
schema.response = responseSchema;
|
|
@@ -358,14 +291,10 @@ function compileNormalizedRouteValidator(normalizedValidator) {
|
|
|
358
291
|
Object.assign(schema, normalizedValidator.fastifySchema);
|
|
359
292
|
}
|
|
360
293
|
|
|
361
|
-
if (normalizedValidator.jskitInput) {
|
|
362
|
-
Object.assign(input, normalizedValidator.jskitInput);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
294
|
const compiled = {};
|
|
366
295
|
if (Object.keys(schema).length > 0) {
|
|
367
296
|
compiled.schema = Object.freeze({
|
|
368
|
-
...schema
|
|
297
|
+
...stripJsonRestTransportExtensions(schema)
|
|
369
298
|
});
|
|
370
299
|
}
|
|
371
300
|
if (Object.keys(input).length > 0) {
|
|
@@ -433,14 +362,20 @@ function resolveRouteValidatorOptions({
|
|
|
433
362
|
path
|
|
434
363
|
});
|
|
435
364
|
|
|
365
|
+
const unsupportedRouteKeys = UNSUPPORTED_ROUTE_VALIDATOR_KEYS.filter((key) =>
|
|
366
|
+
Object.prototype.hasOwnProperty.call(normalizedOptions, key)
|
|
367
|
+
);
|
|
368
|
+
if (unsupportedRouteKeys.length > 0) {
|
|
369
|
+
throw new RouteDefinitionError(
|
|
370
|
+
`Route ${routeLabel} uses unsupported validator options: ${unsupportedRouteKeys.join(", ")}.`
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
|
|
436
374
|
const hasInlineValidatorShape = VALIDATOR_OPTION_KEYS.some((key) => Object.prototype.hasOwnProperty.call(normalizedOptions, key));
|
|
437
375
|
|
|
438
376
|
const remainingOptions = {
|
|
439
377
|
...normalizedOptions
|
|
440
378
|
};
|
|
441
|
-
delete remainingOptions.schema;
|
|
442
|
-
delete remainingOptions.input;
|
|
443
|
-
delete remainingOptions.validator;
|
|
444
379
|
|
|
445
380
|
if (!hasInlineValidatorShape) {
|
|
446
381
|
return remainingOptions;
|