@rjsf/utils 5.10.0 → 5.11.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/dist/index.d.ts +1 -0
- package/dist/utils.cjs.development.js +775 -971
- package/dist/utils.cjs.development.js.map +1 -1
- package/dist/utils.cjs.production.min.js +1 -1
- package/dist/utils.cjs.production.min.js.map +1 -1
- package/dist/utils.esm.js +774 -970
- package/dist/utils.esm.js.map +1 -1
- package/dist/utils.umd.development.js +778 -974
- package/dist/utils.umd.development.js.map +1 -1
- package/dist/utils.umd.production.min.js +1 -1
- package/dist/utils.umd.production.min.js.map +1 -1
- package/package.json +8 -8
package/dist/utils.esm.js
CHANGED
|
@@ -10,6 +10,7 @@ import isString from 'lodash-es/isString';
|
|
|
10
10
|
import reduce from 'lodash-es/reduce';
|
|
11
11
|
import times from 'lodash-es/times';
|
|
12
12
|
import set from 'lodash-es/set';
|
|
13
|
+
import forEach from 'lodash-es/forEach';
|
|
13
14
|
import mergeAllOf from 'json-schema-merge-allof';
|
|
14
15
|
import union from 'lodash-es/union';
|
|
15
16
|
import isEqual from 'lodash-es/isEqual';
|
|
@@ -19,7 +20,6 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
19
20
|
import { createElement } from 'react';
|
|
20
21
|
import ReactIs from 'react-is';
|
|
21
22
|
import toPath from 'lodash-es/toPath';
|
|
22
|
-
import forEach from 'lodash-es/forEach';
|
|
23
23
|
|
|
24
24
|
/** Determines whether a `thing` is an object for the purposes of RSJF. In this case, `thing` is an object if it has
|
|
25
25
|
* the type `object` but is NOT null, an array or a File.
|
|
@@ -81,103 +81,42 @@ function asNumber(value) {
|
|
|
81
81
|
// specific precision or number of significant digits)
|
|
82
82
|
return value;
|
|
83
83
|
}
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
const n = Number(value);
|
|
85
|
+
const valid = typeof n === 'number' && !Number.isNaN(n);
|
|
86
86
|
return valid ? n : value;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
function _defineProperties(target, props) {
|
|
90
|
-
for (var i = 0; i < props.length; i++) {
|
|
91
|
-
var descriptor = props[i];
|
|
92
|
-
descriptor.enumerable = descriptor.enumerable || false;
|
|
93
|
-
descriptor.configurable = true;
|
|
94
|
-
if ("value" in descriptor) descriptor.writable = true;
|
|
95
|
-
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
function _createClass(Constructor, protoProps, staticProps) {
|
|
99
|
-
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
100
|
-
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
101
|
-
Object.defineProperty(Constructor, "prototype", {
|
|
102
|
-
writable: false
|
|
103
|
-
});
|
|
104
|
-
return Constructor;
|
|
105
|
-
}
|
|
106
|
-
function _extends() {
|
|
107
|
-
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
108
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
109
|
-
var source = arguments[i];
|
|
110
|
-
for (var key in source) {
|
|
111
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
112
|
-
target[key] = source[key];
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return target;
|
|
117
|
-
};
|
|
118
|
-
return _extends.apply(this, arguments);
|
|
119
|
-
}
|
|
120
|
-
function _objectDestructuringEmpty(obj) {
|
|
121
|
-
if (obj == null) throw new TypeError("Cannot destructure " + obj);
|
|
122
|
-
}
|
|
123
|
-
function _objectWithoutPropertiesLoose(source, excluded) {
|
|
124
|
-
if (source == null) return {};
|
|
125
|
-
var target = {};
|
|
126
|
-
var sourceKeys = Object.keys(source);
|
|
127
|
-
var key, i;
|
|
128
|
-
for (i = 0; i < sourceKeys.length; i++) {
|
|
129
|
-
key = sourceKeys[i];
|
|
130
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
131
|
-
target[key] = source[key];
|
|
132
|
-
}
|
|
133
|
-
return target;
|
|
134
|
-
}
|
|
135
|
-
function _toPrimitive(input, hint) {
|
|
136
|
-
if (typeof input !== "object" || input === null) return input;
|
|
137
|
-
var prim = input[Symbol.toPrimitive];
|
|
138
|
-
if (prim !== undefined) {
|
|
139
|
-
var res = prim.call(input, hint || "default");
|
|
140
|
-
if (typeof res !== "object") return res;
|
|
141
|
-
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
142
|
-
}
|
|
143
|
-
return (hint === "string" ? String : Number)(input);
|
|
144
|
-
}
|
|
145
|
-
function _toPropertyKey(arg) {
|
|
146
|
-
var key = _toPrimitive(arg, "string");
|
|
147
|
-
return typeof key === "symbol" ? key : String(key);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
89
|
/** Below are the list of all the keys into various elements of a RJSFSchema or UiSchema that are used by the various
|
|
151
90
|
* utility functions. In addition to those keys, there are the special `ADDITIONAL_PROPERTY_FLAG` and
|
|
152
91
|
* `RJSF_ADDITONAL_PROPERTIES_FLAG` flags that is added to a schema under certain conditions by the `retrieveSchema()`
|
|
153
92
|
* utility.
|
|
154
93
|
*/
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
94
|
+
const ADDITIONAL_PROPERTY_FLAG = '__additional_property';
|
|
95
|
+
const ADDITIONAL_PROPERTIES_KEY = 'additionalProperties';
|
|
96
|
+
const ALL_OF_KEY = 'allOf';
|
|
97
|
+
const ANY_OF_KEY = 'anyOf';
|
|
98
|
+
const CONST_KEY = 'const';
|
|
99
|
+
const DEFAULT_KEY = 'default';
|
|
100
|
+
const DEFINITIONS_KEY = 'definitions';
|
|
101
|
+
const DEPENDENCIES_KEY = 'dependencies';
|
|
102
|
+
const ENUM_KEY = 'enum';
|
|
103
|
+
const ERRORS_KEY = '__errors';
|
|
104
|
+
const ID_KEY = '$id';
|
|
105
|
+
const IF_KEY = 'if';
|
|
106
|
+
const ITEMS_KEY = 'items';
|
|
107
|
+
const JUNK_OPTION_ID = '_$junk_option_schema_id$_';
|
|
108
|
+
const NAME_KEY = '$name';
|
|
109
|
+
const ONE_OF_KEY = 'oneOf';
|
|
110
|
+
const PROPERTIES_KEY = 'properties';
|
|
111
|
+
const REQUIRED_KEY = 'required';
|
|
112
|
+
const SUBMIT_BTN_OPTIONS_KEY = 'submitButtonOptions';
|
|
113
|
+
const REF_KEY = '$ref';
|
|
114
|
+
const RJSF_ADDITONAL_PROPERTIES_FLAG = '__rjsf_additionalProperties';
|
|
115
|
+
const ROOT_SCHEMA_PREFIX = '__rjsf_rootSchema';
|
|
116
|
+
const UI_FIELD_KEY = 'ui:field';
|
|
117
|
+
const UI_WIDGET_KEY = 'ui:widget';
|
|
118
|
+
const UI_OPTIONS_KEY = 'ui:options';
|
|
119
|
+
const UI_GLOBAL_OPTIONS_KEY = 'ui:globalOptions';
|
|
181
120
|
|
|
182
121
|
/** Get all passed options from ui:options, and ui:<optionName>, returning them in an object with the `ui:`
|
|
183
122
|
* stripped off. Any `globalOptions` will always be returned, unless they are overridden by options in the `uiSchema`.
|
|
@@ -186,27 +125,26 @@ var UI_GLOBAL_OPTIONS_KEY = 'ui:globalOptions';
|
|
|
186
125
|
* @param [globalOptions={}] - The optional Global UI Schema from which to get any fallback `xxx` options
|
|
187
126
|
* @returns - An object containing all the `ui:xxx` options with the `ui:` stripped off along with all `globalOptions`
|
|
188
127
|
*/
|
|
189
|
-
function getUiOptions(uiSchema, globalOptions) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
if (globalOptions === void 0) {
|
|
194
|
-
globalOptions = {};
|
|
195
|
-
}
|
|
196
|
-
return Object.keys(uiSchema).filter(function (key) {
|
|
197
|
-
return key.indexOf('ui:') === 0;
|
|
198
|
-
}).reduce(function (options, key) {
|
|
199
|
-
var _extends2;
|
|
200
|
-
var value = uiSchema[key];
|
|
128
|
+
function getUiOptions(uiSchema = {}, globalOptions = {}) {
|
|
129
|
+
return Object.keys(uiSchema).filter(key => key.indexOf('ui:') === 0).reduce((options, key) => {
|
|
130
|
+
const value = uiSchema[key];
|
|
201
131
|
if (key === UI_WIDGET_KEY && isObject(value)) {
|
|
202
132
|
console.error('Setting options via ui:widget object is no longer supported, use ui:options instead');
|
|
203
133
|
return options;
|
|
204
134
|
}
|
|
205
135
|
if (key === UI_OPTIONS_KEY && isObject(value)) {
|
|
206
|
-
return
|
|
136
|
+
return {
|
|
137
|
+
...options,
|
|
138
|
+
...value
|
|
139
|
+
};
|
|
207
140
|
}
|
|
208
|
-
return
|
|
209
|
-
|
|
141
|
+
return {
|
|
142
|
+
...options,
|
|
143
|
+
[key.substring(3)]: value
|
|
144
|
+
};
|
|
145
|
+
}, {
|
|
146
|
+
...globalOptions
|
|
147
|
+
});
|
|
210
148
|
}
|
|
211
149
|
|
|
212
150
|
/** Checks whether the field described by `schema`, having the `uiSchema` and `formData` supports expanding. The UI for
|
|
@@ -218,16 +156,13 @@ function getUiOptions(uiSchema, globalOptions) {
|
|
|
218
156
|
* @param [formData] - The formData for the field
|
|
219
157
|
* @returns - True if the schema element has additionalProperties, is expandable, and not at the maxProperties limit
|
|
220
158
|
*/
|
|
221
|
-
function canExpand(schema, uiSchema, formData) {
|
|
222
|
-
if (uiSchema === void 0) {
|
|
223
|
-
uiSchema = {};
|
|
224
|
-
}
|
|
159
|
+
function canExpand(schema, uiSchema = {}, formData) {
|
|
225
160
|
if (!schema.additionalProperties) {
|
|
226
161
|
return false;
|
|
227
162
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
163
|
+
const {
|
|
164
|
+
expandable = true
|
|
165
|
+
} = getUiOptions(uiSchema);
|
|
231
166
|
if (expandable === false) {
|
|
232
167
|
return expandable;
|
|
233
168
|
}
|
|
@@ -245,21 +180,30 @@ function canExpand(schema, uiSchema, formData) {
|
|
|
245
180
|
* @returns - A `FormValidation` object based on the `formData` structure
|
|
246
181
|
*/
|
|
247
182
|
function createErrorHandler(formData) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
183
|
+
const handler = {
|
|
184
|
+
// We store the list of errors for this node in a property named __errors
|
|
185
|
+
// to avoid name collision with a possible sub schema field named
|
|
186
|
+
// 'errors' (see `utils.toErrorSchema`).
|
|
187
|
+
[ERRORS_KEY]: [],
|
|
188
|
+
addError(message) {
|
|
189
|
+
this[ERRORS_KEY].push(message);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
252
192
|
if (Array.isArray(formData)) {
|
|
253
|
-
return formData.reduce(
|
|
254
|
-
|
|
255
|
-
|
|
193
|
+
return formData.reduce((acc, value, key) => {
|
|
194
|
+
return {
|
|
195
|
+
...acc,
|
|
196
|
+
[key]: createErrorHandler(value)
|
|
197
|
+
};
|
|
256
198
|
}, handler);
|
|
257
199
|
}
|
|
258
200
|
if (isPlainObject(formData)) {
|
|
259
|
-
|
|
260
|
-
return Object.keys(formObject).reduce(
|
|
261
|
-
|
|
262
|
-
|
|
201
|
+
const formObject = formData;
|
|
202
|
+
return Object.keys(formObject).reduce((acc, key) => {
|
|
203
|
+
return {
|
|
204
|
+
...acc,
|
|
205
|
+
[key]: createErrorHandler(formObject[key])
|
|
206
|
+
};
|
|
263
207
|
}, handler);
|
|
264
208
|
}
|
|
265
209
|
return handler;
|
|
@@ -273,7 +217,7 @@ function createErrorHandler(formData) {
|
|
|
273
217
|
* @returns - True if the `a` and `b` are deeply equal, false otherwise
|
|
274
218
|
*/
|
|
275
219
|
function deepEquals(a, b) {
|
|
276
|
-
return isEqualWith(a, b,
|
|
220
|
+
return isEqualWith(a, b, (obj, other) => {
|
|
277
221
|
if (typeof obj === 'function' && typeof other === 'function') {
|
|
278
222
|
// Assume all functions are equivalent
|
|
279
223
|
// see https://github.com/rjsf-team/react-jsonschema-form/issues/255
|
|
@@ -292,8 +236,8 @@ function deepEquals(a, b) {
|
|
|
292
236
|
* value from `object[key]`
|
|
293
237
|
*/
|
|
294
238
|
function splitKeyElementFromObject(key, object) {
|
|
295
|
-
|
|
296
|
-
|
|
239
|
+
const value = object[key];
|
|
240
|
+
const remaining = omit(object, [key]);
|
|
297
241
|
return [remaining, value];
|
|
298
242
|
}
|
|
299
243
|
/** Given the name of a `$ref` from within a schema, using the `rootSchema`, look up and return the sub-schema using the
|
|
@@ -305,28 +249,26 @@ function splitKeyElementFromObject(key, object) {
|
|
|
305
249
|
* @returns - The sub-schema within the `rootSchema` which matches the `$ref` if it exists
|
|
306
250
|
* @throws - Error indicating that no schema for that reference exists
|
|
307
251
|
*/
|
|
308
|
-
function findSchemaDefinition($ref, rootSchema) {
|
|
309
|
-
|
|
310
|
-
rootSchema = {};
|
|
311
|
-
}
|
|
312
|
-
var ref = $ref || '';
|
|
252
|
+
function findSchemaDefinition($ref, rootSchema = {}) {
|
|
253
|
+
let ref = $ref || '';
|
|
313
254
|
if (ref.startsWith('#')) {
|
|
314
255
|
// Decode URI fragment representation.
|
|
315
256
|
ref = decodeURIComponent(ref.substring(1));
|
|
316
257
|
} else {
|
|
317
|
-
throw new Error(
|
|
258
|
+
throw new Error(`Could not find a definition for ${$ref}.`);
|
|
318
259
|
}
|
|
319
|
-
|
|
260
|
+
const current = jsonpointer.get(rootSchema, ref);
|
|
320
261
|
if (current === undefined) {
|
|
321
|
-
throw new Error(
|
|
262
|
+
throw new Error(`Could not find a definition for ${$ref}.`);
|
|
322
263
|
}
|
|
323
264
|
if (current[REF_KEY]) {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
theRef = _splitKeyElementFromO[1];
|
|
327
|
-
var subSchema = findSchemaDefinition(theRef, rootSchema);
|
|
265
|
+
const [remaining, theRef] = splitKeyElementFromObject(REF_KEY, current);
|
|
266
|
+
const subSchema = findSchemaDefinition(theRef, rootSchema);
|
|
328
267
|
if (Object.keys(remaining).length > 0) {
|
|
329
|
-
return
|
|
268
|
+
return {
|
|
269
|
+
...remaining,
|
|
270
|
+
...subSchema
|
|
271
|
+
};
|
|
330
272
|
}
|
|
331
273
|
return subSchema;
|
|
332
274
|
}
|
|
@@ -351,12 +293,12 @@ function getMatchingOption(validator, formData, options, rootSchema, discriminat
|
|
|
351
293
|
if (formData === undefined) {
|
|
352
294
|
return 0;
|
|
353
295
|
}
|
|
354
|
-
for (
|
|
355
|
-
|
|
296
|
+
for (let i = 0; i < options.length; i++) {
|
|
297
|
+
const option = options[i];
|
|
356
298
|
// If we have a discriminator field, then we will use this to make the determination
|
|
357
299
|
if (discriminatorField && has(option, [PROPERTIES_KEY, discriminatorField])) {
|
|
358
|
-
|
|
359
|
-
|
|
300
|
+
const value = get(formData, discriminatorField);
|
|
301
|
+
const discriminator = get(option, [PROPERTIES_KEY, discriminatorField], {});
|
|
360
302
|
if (validator.isValid(discriminator, value, rootSchema)) {
|
|
361
303
|
return i;
|
|
362
304
|
}
|
|
@@ -371,18 +313,18 @@ function getMatchingOption(validator, formData, options, rootSchema, discriminat
|
|
|
371
313
|
//
|
|
372
314
|
// Create an "anyOf" schema that requires at least one of the keys in the
|
|
373
315
|
// "properties" object
|
|
374
|
-
|
|
375
|
-
anyOf: Object.keys(option[PROPERTIES_KEY]).map(
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
};
|
|
379
|
-
})
|
|
316
|
+
const requiresAnyOf = {
|
|
317
|
+
anyOf: Object.keys(option[PROPERTIES_KEY]).map(key => ({
|
|
318
|
+
required: [key]
|
|
319
|
+
}))
|
|
380
320
|
};
|
|
381
|
-
|
|
321
|
+
let augmentedSchema;
|
|
382
322
|
// If the "anyOf" keyword already exists, wrap the augmentation in an "allOf"
|
|
383
323
|
if (option.anyOf) {
|
|
384
324
|
// Create a shallow clone of the option
|
|
385
|
-
|
|
325
|
+
const {
|
|
326
|
+
...shallowClone
|
|
327
|
+
} = option;
|
|
386
328
|
if (!shallowClone.allOf) {
|
|
387
329
|
shallowClone.allOf = [];
|
|
388
330
|
} else {
|
|
@@ -429,12 +371,12 @@ function getFirstMatchingOption(validator, formData, options, rootSchema, discri
|
|
|
429
371
|
* @returns - The `discriminator.propertyName` if it exists in the schema, otherwise `undefined`
|
|
430
372
|
*/
|
|
431
373
|
function getDiscriminatorFieldFromSchema(schema) {
|
|
432
|
-
|
|
433
|
-
|
|
374
|
+
let discriminator;
|
|
375
|
+
const maybeString = get(schema, 'discriminator.propertyName', undefined);
|
|
434
376
|
if (isString(maybeString)) {
|
|
435
377
|
discriminator = maybeString;
|
|
436
378
|
} else if (maybeString !== undefined) {
|
|
437
|
-
console.warn(
|
|
379
|
+
console.warn(`Expecting discriminator to be a string, got "${typeof maybeString}" instead`);
|
|
438
380
|
}
|
|
439
381
|
return discriminator;
|
|
440
382
|
}
|
|
@@ -480,20 +422,20 @@ function guessType(value) {
|
|
|
480
422
|
* @returns - The type of the schema
|
|
481
423
|
*/
|
|
482
424
|
function getSchemaType(schema) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
425
|
+
let {
|
|
426
|
+
type
|
|
427
|
+
} = schema;
|
|
428
|
+
if (!type && schema.const) {
|
|
429
|
+
return guessType(schema.const);
|
|
486
430
|
}
|
|
487
|
-
if (!type && schema
|
|
431
|
+
if (!type && schema.enum) {
|
|
488
432
|
return 'string';
|
|
489
433
|
}
|
|
490
434
|
if (!type && (schema.properties || schema.additionalProperties)) {
|
|
491
435
|
return 'object';
|
|
492
436
|
}
|
|
493
437
|
if (Array.isArray(type) && type.length === 2 && type.includes('null')) {
|
|
494
|
-
type = type.find(
|
|
495
|
-
return type !== 'null';
|
|
496
|
-
});
|
|
438
|
+
type = type.find(type => type !== 'null');
|
|
497
439
|
}
|
|
498
440
|
return type;
|
|
499
441
|
}
|
|
@@ -507,9 +449,9 @@ function getSchemaType(schema) {
|
|
|
507
449
|
* @returns - The merged schema object
|
|
508
450
|
*/
|
|
509
451
|
function mergeSchemas(obj1, obj2) {
|
|
510
|
-
|
|
511
|
-
return Object.keys(obj2).reduce(
|
|
512
|
-
|
|
452
|
+
const acc = Object.assign({}, obj1); // Prevent mutation of source object.
|
|
453
|
+
return Object.keys(obj2).reduce((acc, key) => {
|
|
454
|
+
const left = obj1 ? obj1[key] : {},
|
|
513
455
|
right = obj2[key];
|
|
514
456
|
if (obj1 && key in obj1 && isObject(right)) {
|
|
515
457
|
acc[key] = mergeSchemas(left, right);
|
|
@@ -523,12 +465,6 @@ function mergeSchemas(obj1, obj2) {
|
|
|
523
465
|
}, acc);
|
|
524
466
|
}
|
|
525
467
|
|
|
526
|
-
var _excluded$2 = ["if", "then", "else"],
|
|
527
|
-
_excluded2$1 = ["$ref"],
|
|
528
|
-
_excluded3 = ["allOf"],
|
|
529
|
-
_excluded4 = ["oneOf", "anyOf"],
|
|
530
|
-
_excluded5 = ["dependencies"],
|
|
531
|
-
_excluded6 = ["oneOf"];
|
|
532
468
|
/** Retrieves an expanded schema that has had all of its conditions, additional properties, references and dependencies
|
|
533
469
|
* resolved and merged into the `schema` given a `validator`, `rootSchema` and `rawFormData` that is used to do the
|
|
534
470
|
* potentially recursive resolution.
|
|
@@ -539,10 +475,7 @@ var _excluded$2 = ["if", "then", "else"],
|
|
|
539
475
|
* @param [rawFormData] - The current formData, if any, to assist retrieving a schema
|
|
540
476
|
* @returns - The schema having its conditions, additional properties, references and dependencies resolved
|
|
541
477
|
*/
|
|
542
|
-
function retrieveSchema(validator, schema, rootSchema, rawFormData) {
|
|
543
|
-
if (rootSchema === void 0) {
|
|
544
|
-
rootSchema = {};
|
|
545
|
-
}
|
|
478
|
+
function retrieveSchema(validator, schema, rootSchema = {}, rawFormData) {
|
|
546
479
|
return retrieveSchemaInternal(validator, schema, rootSchema, rawFormData)[0];
|
|
547
480
|
}
|
|
548
481
|
/** Resolves a conditional block (if/else/then) by removing the condition and merging the appropriate conditional branch
|
|
@@ -558,13 +491,15 @@ function retrieveSchema(validator, schema, rootSchema, rawFormData) {
|
|
|
558
491
|
* @returns - A list of schemas with the appropriate conditions resolved, possibly with all branches expanded
|
|
559
492
|
*/
|
|
560
493
|
function resolveCondition(validator, schema, rootSchema, expandAllBranches, formData) {
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
494
|
+
const {
|
|
495
|
+
if: expression,
|
|
496
|
+
then,
|
|
497
|
+
else: otherwise,
|
|
498
|
+
...resolvedSchemaLessConditional
|
|
499
|
+
} = schema;
|
|
500
|
+
const conditionValue = validator.isValid(expression, formData || {}, rootSchema);
|
|
501
|
+
let resolvedSchemas = [resolvedSchemaLessConditional];
|
|
502
|
+
let schemas = [];
|
|
568
503
|
if (expandAllBranches) {
|
|
569
504
|
if (then && typeof then !== 'boolean') {
|
|
570
505
|
schemas = schemas.concat(retrieveSchemaInternal(validator, then, rootSchema, formData, expandAllBranches));
|
|
@@ -573,19 +508,15 @@ function resolveCondition(validator, schema, rootSchema, expandAllBranches, form
|
|
|
573
508
|
schemas = schemas.concat(retrieveSchemaInternal(validator, otherwise, rootSchema, formData, expandAllBranches));
|
|
574
509
|
}
|
|
575
510
|
} else {
|
|
576
|
-
|
|
511
|
+
const conditionalSchema = conditionValue ? then : otherwise;
|
|
577
512
|
if (conditionalSchema && typeof conditionalSchema !== 'boolean') {
|
|
578
513
|
schemas = schemas.concat(retrieveSchemaInternal(validator, conditionalSchema, rootSchema, formData, expandAllBranches));
|
|
579
514
|
}
|
|
580
515
|
}
|
|
581
516
|
if (schemas.length) {
|
|
582
|
-
resolvedSchemas = schemas.map(
|
|
583
|
-
return mergeSchemas(resolvedSchemaLessConditional, s);
|
|
584
|
-
});
|
|
517
|
+
resolvedSchemas = schemas.map(s => mergeSchemas(resolvedSchemaLessConditional, s));
|
|
585
518
|
}
|
|
586
|
-
return resolvedSchemas.flatMap(
|
|
587
|
-
return retrieveSchemaInternal(validator, s, rootSchema, formData, expandAllBranches);
|
|
588
|
-
});
|
|
519
|
+
return resolvedSchemas.flatMap(s => retrieveSchemaInternal(validator, s, rootSchema, formData, expandAllBranches));
|
|
589
520
|
}
|
|
590
521
|
/** Given a list of lists of allOf, anyOf or oneOf values, create a list of lists of all permutations of the values. The
|
|
591
522
|
* `listOfLists` is expected to be all resolved values of the 1st...nth schemas within an `allOf`, `anyOf` or `oneOf`.
|
|
@@ -602,19 +533,13 @@ function resolveCondition(validator, schema, rootSchema, expandAllBranches, form
|
|
|
602
533
|
* @returns - The list of all permutations of schemas for a set of `xxxOf`s
|
|
603
534
|
*/
|
|
604
535
|
function getAllPermutationsOfXxxOf(listOfLists) {
|
|
605
|
-
|
|
536
|
+
const allPermutations = listOfLists.reduce((permutations, list) => {
|
|
606
537
|
// When there are more than one set of schemas for a row, duplicate the set of permutations and add in the values
|
|
607
538
|
if (list.length > 1) {
|
|
608
|
-
return list.flatMap(
|
|
609
|
-
return times(permutations.length, function (i) {
|
|
610
|
-
return [].concat(permutations[i]).concat(element);
|
|
611
|
-
});
|
|
612
|
-
});
|
|
539
|
+
return list.flatMap(element => times(permutations.length, i => [...permutations[i]].concat(element)));
|
|
613
540
|
}
|
|
614
541
|
// Otherwise just push in the single value into the current set of permutations
|
|
615
|
-
permutations.forEach(
|
|
616
|
-
return permutation.push(list[0]);
|
|
617
|
-
});
|
|
542
|
+
permutations.forEach(permutation => permutation.push(list[0]));
|
|
618
543
|
return permutations;
|
|
619
544
|
}, [[]] // Start with an empty list
|
|
620
545
|
);
|
|
@@ -638,21 +563,18 @@ function resolveSchema(validator, schema, rootSchema, expandAllBranches, formDat
|
|
|
638
563
|
return resolveReference(validator, schema, rootSchema, expandAllBranches, formData);
|
|
639
564
|
}
|
|
640
565
|
if (DEPENDENCIES_KEY in schema) {
|
|
641
|
-
|
|
642
|
-
return resolvedSchemas.flatMap(
|
|
566
|
+
const resolvedSchemas = resolveDependencies(validator, schema, rootSchema, expandAllBranches, formData);
|
|
567
|
+
return resolvedSchemas.flatMap(s => {
|
|
643
568
|
return retrieveSchemaInternal(validator, s, rootSchema, formData, expandAllBranches);
|
|
644
569
|
});
|
|
645
570
|
}
|
|
646
571
|
if (ALL_OF_KEY in schema && Array.isArray(schema.allOf)) {
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
allOf: permutation
|
|
654
|
-
});
|
|
655
|
-
});
|
|
572
|
+
const allOfSchemaElements = schema.allOf.map(allOfSubschema => retrieveSchemaInternal(validator, allOfSubschema, rootSchema, formData, expandAllBranches));
|
|
573
|
+
const allPermutations = getAllPermutationsOfXxxOf(allOfSchemaElements);
|
|
574
|
+
return allPermutations.map(permutation => ({
|
|
575
|
+
...schema,
|
|
576
|
+
allOf: permutation
|
|
577
|
+
}));
|
|
656
578
|
}
|
|
657
579
|
// No $ref or dependencies or allOf attribute was found, returning the original schema.
|
|
658
580
|
return [schema];
|
|
@@ -670,12 +592,48 @@ function resolveSchema(validator, schema, rootSchema, expandAllBranches, formDat
|
|
|
670
592
|
*/
|
|
671
593
|
function resolveReference(validator, schema, rootSchema, expandAllBranches, formData) {
|
|
672
594
|
// Drop the $ref property of the source schema.
|
|
673
|
-
|
|
674
|
-
|
|
595
|
+
const {
|
|
596
|
+
$ref,
|
|
597
|
+
...localSchema
|
|
598
|
+
} = schema;
|
|
675
599
|
// Retrieve the referenced schema definition.
|
|
676
|
-
|
|
600
|
+
const refSchema = findSchemaDefinition($ref, rootSchema);
|
|
677
601
|
// Update referenced schema definition with local schema properties.
|
|
678
|
-
return retrieveSchemaInternal(validator,
|
|
602
|
+
return retrieveSchemaInternal(validator, {
|
|
603
|
+
...refSchema,
|
|
604
|
+
...localSchema
|
|
605
|
+
}, rootSchema, formData, expandAllBranches);
|
|
606
|
+
}
|
|
607
|
+
/** Resolves all references within a schema's properties and array items.
|
|
608
|
+
*
|
|
609
|
+
* @param schema - The schema for which resolving all references is desired
|
|
610
|
+
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
611
|
+
* @returns - given schema will all references resolved
|
|
612
|
+
*/
|
|
613
|
+
function resolveAllReferences(schema, rootSchema) {
|
|
614
|
+
let resolvedSchema = schema;
|
|
615
|
+
// resolve top level ref
|
|
616
|
+
if (REF_KEY in resolvedSchema) {
|
|
617
|
+
const {
|
|
618
|
+
$ref,
|
|
619
|
+
...localSchema
|
|
620
|
+
} = resolvedSchema;
|
|
621
|
+
// Retrieve the referenced schema definition.
|
|
622
|
+
const refSchema = findSchemaDefinition($ref, rootSchema);
|
|
623
|
+
resolvedSchema = {
|
|
624
|
+
...refSchema,
|
|
625
|
+
...localSchema
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
if (PROPERTIES_KEY in resolvedSchema) {
|
|
629
|
+
forEach(resolvedSchema[PROPERTIES_KEY], (value, key) => {
|
|
630
|
+
resolvedSchema[PROPERTIES_KEY][key] = resolveAllReferences(value, rootSchema);
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
if (ITEMS_KEY in resolvedSchema && !Array.isArray(resolvedSchema.items) && typeof resolvedSchema.items !== 'boolean') {
|
|
634
|
+
resolvedSchema.items = resolveAllReferences(resolvedSchema.items, rootSchema);
|
|
635
|
+
}
|
|
636
|
+
return resolvedSchema;
|
|
679
637
|
}
|
|
680
638
|
/** Creates new 'properties' items for each key in the `formData`
|
|
681
639
|
*
|
|
@@ -687,28 +645,34 @@ function resolveReference(validator, schema, rootSchema, expandAllBranches, form
|
|
|
687
645
|
*/
|
|
688
646
|
function stubExistingAdditionalProperties(validator, theSchema, rootSchema, aFormData) {
|
|
689
647
|
// Clone the schema so that we don't ruin the consumer's original
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
648
|
+
const schema = {
|
|
649
|
+
...theSchema,
|
|
650
|
+
properties: {
|
|
651
|
+
...theSchema.properties
|
|
652
|
+
}
|
|
653
|
+
};
|
|
693
654
|
// make sure formData is an object
|
|
694
|
-
|
|
695
|
-
Object.keys(formData).forEach(
|
|
655
|
+
const formData = aFormData && isObject(aFormData) ? aFormData : {};
|
|
656
|
+
Object.keys(formData).forEach(key => {
|
|
696
657
|
if (key in schema.properties) {
|
|
697
658
|
// No need to stub, our schema already has the property
|
|
698
659
|
return;
|
|
699
660
|
}
|
|
700
|
-
|
|
661
|
+
let additionalProperties = {};
|
|
701
662
|
if (typeof schema.additionalProperties !== 'boolean') {
|
|
702
663
|
if (REF_KEY in schema.additionalProperties) {
|
|
703
664
|
additionalProperties = retrieveSchema(validator, {
|
|
704
665
|
$ref: get(schema.additionalProperties, [REF_KEY])
|
|
705
666
|
}, rootSchema, formData);
|
|
706
667
|
} else if ('type' in schema.additionalProperties) {
|
|
707
|
-
additionalProperties =
|
|
668
|
+
additionalProperties = {
|
|
669
|
+
...schema.additionalProperties
|
|
670
|
+
};
|
|
708
671
|
} else if (ANY_OF_KEY in schema.additionalProperties || ONE_OF_KEY in schema.additionalProperties) {
|
|
709
|
-
additionalProperties =
|
|
710
|
-
type: 'object'
|
|
711
|
-
|
|
672
|
+
additionalProperties = {
|
|
673
|
+
type: 'object',
|
|
674
|
+
...schema.additionalProperties
|
|
675
|
+
};
|
|
712
676
|
} else {
|
|
713
677
|
additionalProperties = {
|
|
714
678
|
type: guessType(get(formData, [key]))
|
|
@@ -740,36 +704,35 @@ function stubExistingAdditionalProperties(validator, theSchema, rootSchema, aFor
|
|
|
740
704
|
* @returns - The schema(s) resulting from having its conditions, additional properties, references and dependencies
|
|
741
705
|
* resolved. Multiple schemas may be returned if `expandAllBranches` is true.
|
|
742
706
|
*/
|
|
743
|
-
function retrieveSchemaInternal(validator, schema, rootSchema, rawFormData, expandAllBranches) {
|
|
744
|
-
if (expandAllBranches === void 0) {
|
|
745
|
-
expandAllBranches = false;
|
|
746
|
-
}
|
|
707
|
+
function retrieveSchemaInternal(validator, schema, rootSchema, rawFormData, expandAllBranches = false) {
|
|
747
708
|
if (!isObject(schema)) {
|
|
748
709
|
return [{}];
|
|
749
710
|
}
|
|
750
|
-
|
|
751
|
-
return resolvedSchemas.flatMap(
|
|
752
|
-
|
|
711
|
+
const resolvedSchemas = resolveSchema(validator, schema, rootSchema, expandAllBranches, rawFormData);
|
|
712
|
+
return resolvedSchemas.flatMap(s => {
|
|
713
|
+
let resolvedSchema = s;
|
|
753
714
|
if (IF_KEY in resolvedSchema) {
|
|
754
715
|
return resolveCondition(validator, resolvedSchema, rootSchema, expandAllBranches, rawFormData);
|
|
755
716
|
}
|
|
756
717
|
if (ALL_OF_KEY in resolvedSchema) {
|
|
718
|
+
// resolve allOf schemas
|
|
719
|
+
if (expandAllBranches) {
|
|
720
|
+
return [...resolvedSchema.allOf];
|
|
721
|
+
}
|
|
757
722
|
try {
|
|
758
723
|
resolvedSchema = mergeAllOf(resolvedSchema, {
|
|
759
724
|
deep: false
|
|
760
725
|
});
|
|
761
726
|
} catch (e) {
|
|
762
727
|
console.warn('could not merge subschemas in allOf:\n', e);
|
|
763
|
-
|
|
764
|
-
allOf
|
|
765
|
-
resolvedSchemaWithoutAllOf
|
|
766
|
-
|
|
767
|
-
return [resolvedSchemaWithoutAllOf].concat(allOf);
|
|
768
|
-
}
|
|
728
|
+
const {
|
|
729
|
+
allOf,
|
|
730
|
+
...resolvedSchemaWithoutAllOf
|
|
731
|
+
} = resolvedSchema;
|
|
769
732
|
return resolvedSchemaWithoutAllOf;
|
|
770
733
|
}
|
|
771
734
|
}
|
|
772
|
-
|
|
735
|
+
const hasAdditionalProperties = ADDITIONAL_PROPERTIES_KEY in resolvedSchema && resolvedSchema.additionalProperties !== false;
|
|
773
736
|
if (hasAdditionalProperties) {
|
|
774
737
|
return stubExistingAdditionalProperties(validator, resolvedSchema, rootSchema, rawFormData);
|
|
775
738
|
}
|
|
@@ -789,11 +752,12 @@ function retrieveSchemaInternal(validator, schema, rootSchema, rawFormData, expa
|
|
|
789
752
|
* @returns - Either an array containing the best matching option or all options if `expandAllBranches` is true
|
|
790
753
|
*/
|
|
791
754
|
function resolveAnyOrOneOfSchemas(validator, schema, rootSchema, expandAllBranches, rawFormData) {
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
oneOf
|
|
795
|
-
anyOf
|
|
796
|
-
remaining
|
|
755
|
+
let anyOrOneOf;
|
|
756
|
+
const {
|
|
757
|
+
oneOf,
|
|
758
|
+
anyOf,
|
|
759
|
+
...remaining
|
|
760
|
+
} = schema;
|
|
797
761
|
if (Array.isArray(oneOf)) {
|
|
798
762
|
anyOrOneOf = oneOf;
|
|
799
763
|
} else if (Array.isArray(anyOf)) {
|
|
@@ -801,23 +765,17 @@ function resolveAnyOrOneOfSchemas(validator, schema, rootSchema, expandAllBranch
|
|
|
801
765
|
}
|
|
802
766
|
if (anyOrOneOf) {
|
|
803
767
|
// Ensure that during expand all branches we pass an object rather than undefined so that all options are interrogated
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
anyOrOneOf = anyOrOneOf.map(
|
|
807
|
-
|
|
808
|
-
// For this ref situation, don't expand all branches and just pick the first/only schema result
|
|
809
|
-
return resolveReference(validator, s, rootSchema, false, formData)[0];
|
|
810
|
-
}
|
|
811
|
-
return s;
|
|
768
|
+
const formData = rawFormData === undefined && expandAllBranches ? {} : rawFormData;
|
|
769
|
+
const discriminator = getDiscriminatorFieldFromSchema(schema);
|
|
770
|
+
anyOrOneOf = anyOrOneOf.map(s => {
|
|
771
|
+
return resolveAllReferences(s, rootSchema);
|
|
812
772
|
});
|
|
813
773
|
// Call this to trigger the set of isValid() calls that the schema parser will need
|
|
814
|
-
|
|
774
|
+
const option = getFirstMatchingOption(validator, formData, anyOrOneOf, rootSchema, discriminator);
|
|
815
775
|
if (expandAllBranches) {
|
|
816
|
-
return anyOrOneOf.map(
|
|
817
|
-
return _extends({}, remaining, item);
|
|
818
|
-
});
|
|
776
|
+
return anyOrOneOf.map(item => mergeSchemas(remaining, item));
|
|
819
777
|
}
|
|
820
|
-
schema =
|
|
778
|
+
schema = mergeSchemas(remaining, anyOrOneOf[option]);
|
|
821
779
|
}
|
|
822
780
|
return [schema];
|
|
823
781
|
}
|
|
@@ -834,12 +792,12 @@ function resolveAnyOrOneOfSchemas(validator, schema, rootSchema, expandAllBranch
|
|
|
834
792
|
*/
|
|
835
793
|
function resolveDependencies(validator, schema, rootSchema, expandAllBranches, formData) {
|
|
836
794
|
// Drop the dependencies from the source schema.
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
795
|
+
const {
|
|
796
|
+
dependencies,
|
|
797
|
+
...remainingSchema
|
|
798
|
+
} = schema;
|
|
799
|
+
const resolvedSchemas = resolveAnyOrOneOfSchemas(validator, remainingSchema, rootSchema, expandAllBranches, formData);
|
|
800
|
+
return resolvedSchemas.flatMap(resolvedSchema => processDependencies(validator, dependencies, resolvedSchema, rootSchema, expandAllBranches, formData));
|
|
843
801
|
}
|
|
844
802
|
/** Processes all the `dependencies` recursively into the list of `resolvedSchema`s as needed. Passes the
|
|
845
803
|
* `expandAllBranches` flag down to the `withDependentSchema()` and the recursive `processDependencies()` helper calls.
|
|
@@ -854,35 +812,24 @@ function resolveDependencies(validator, schema, rootSchema, expandAllBranches, f
|
|
|
854
812
|
* @returns - The schema with the `dependencies` resolved into it
|
|
855
813
|
*/
|
|
856
814
|
function processDependencies(validator, dependencies, resolvedSchema, rootSchema, expandAllBranches, formData) {
|
|
857
|
-
|
|
815
|
+
let schemas = [resolvedSchema];
|
|
858
816
|
// Process dependencies updating the local schema properties as appropriate.
|
|
859
|
-
|
|
817
|
+
for (const dependencyKey in dependencies) {
|
|
860
818
|
// Skip this dependency if its trigger property is not present.
|
|
861
819
|
if (!expandAllBranches && get(formData, [dependencyKey]) === undefined) {
|
|
862
|
-
|
|
820
|
+
continue;
|
|
863
821
|
}
|
|
864
822
|
// Skip this dependency if it is not included in the schema (such as when dependencyKey is itself a hidden dependency.)
|
|
865
823
|
if (resolvedSchema.properties && !(dependencyKey in resolvedSchema.properties)) {
|
|
866
|
-
|
|
824
|
+
continue;
|
|
867
825
|
}
|
|
868
|
-
|
|
869
|
-
remainingDependencies = _splitKeyElementFromO[0],
|
|
870
|
-
dependencyValue = _splitKeyElementFromO[1];
|
|
826
|
+
const [remainingDependencies, dependencyValue] = splitKeyElementFromObject(dependencyKey, dependencies);
|
|
871
827
|
if (Array.isArray(dependencyValue)) {
|
|
872
828
|
schemas[0] = withDependentProperties(resolvedSchema, dependencyValue);
|
|
873
829
|
} else if (isObject(dependencyValue)) {
|
|
874
830
|
schemas = withDependentSchema(validator, resolvedSchema, rootSchema, dependencyKey, dependencyValue, expandAllBranches, formData);
|
|
875
831
|
}
|
|
876
|
-
return
|
|
877
|
-
v: schemas.flatMap(function (schema) {
|
|
878
|
-
return processDependencies(validator, remainingDependencies, schema, rootSchema, expandAllBranches, formData);
|
|
879
|
-
})
|
|
880
|
-
};
|
|
881
|
-
};
|
|
882
|
-
for (var dependencyKey in dependencies) {
|
|
883
|
-
var _ret = _loop();
|
|
884
|
-
if (_ret === "continue") continue;
|
|
885
|
-
if (typeof _ret === "object") return _ret.v;
|
|
832
|
+
return schemas.flatMap(schema => processDependencies(validator, remainingDependencies, schema, rootSchema, expandAllBranches, formData));
|
|
886
833
|
}
|
|
887
834
|
return schemas;
|
|
888
835
|
}
|
|
@@ -896,10 +843,11 @@ function withDependentProperties(schema, additionallyRequired) {
|
|
|
896
843
|
if (!additionallyRequired) {
|
|
897
844
|
return schema;
|
|
898
845
|
}
|
|
899
|
-
|
|
900
|
-
return
|
|
846
|
+
const required = Array.isArray(schema.required) ? Array.from(new Set([...schema.required, ...additionallyRequired])) : additionallyRequired;
|
|
847
|
+
return {
|
|
848
|
+
...schema,
|
|
901
849
|
required: required
|
|
902
|
-
}
|
|
850
|
+
};
|
|
903
851
|
}
|
|
904
852
|
/** Merges a dependent schema into the `schema` dealing with oneOfs and references. Passes the `expandAllBranches` flag
|
|
905
853
|
* down to the `retrieveSchemaInternal()`, `resolveReference()` and `withExactlyOneSubschema()` helper calls.
|
|
@@ -915,26 +863,26 @@ function withDependentProperties(schema, additionallyRequired) {
|
|
|
915
863
|
* @returns - The list of schemas with the dependent schema resolved into them
|
|
916
864
|
*/
|
|
917
865
|
function withDependentSchema(validator, schema, rootSchema, dependencyKey, dependencyValue, expandAllBranches, formData) {
|
|
918
|
-
|
|
919
|
-
return dependentSchemas.flatMap(
|
|
920
|
-
|
|
921
|
-
|
|
866
|
+
const dependentSchemas = retrieveSchemaInternal(validator, dependencyValue, rootSchema, formData, expandAllBranches);
|
|
867
|
+
return dependentSchemas.flatMap(dependent => {
|
|
868
|
+
const {
|
|
869
|
+
oneOf,
|
|
870
|
+
...dependentSchema
|
|
871
|
+
} = dependent;
|
|
922
872
|
schema = mergeSchemas(schema, dependentSchema);
|
|
923
873
|
// Since it does not contain oneOf, we return the original schema.
|
|
924
874
|
if (oneOf === undefined) {
|
|
925
875
|
return schema;
|
|
926
876
|
}
|
|
927
877
|
// Resolve $refs inside oneOf.
|
|
928
|
-
|
|
878
|
+
const resolvedOneOfs = oneOf.map(subschema => {
|
|
929
879
|
if (typeof subschema === 'boolean' || !(REF_KEY in subschema)) {
|
|
930
880
|
return [subschema];
|
|
931
881
|
}
|
|
932
882
|
return resolveReference(validator, subschema, rootSchema, expandAllBranches, formData);
|
|
933
883
|
});
|
|
934
|
-
|
|
935
|
-
return allPermutations.flatMap(
|
|
936
|
-
return withExactlyOneSubschema(validator, schema, rootSchema, dependencyKey, resolvedOneOf, expandAllBranches, formData);
|
|
937
|
-
});
|
|
884
|
+
const allPermutations = getAllPermutationsOfXxxOf(resolvedOneOfs);
|
|
885
|
+
return allPermutations.flatMap(resolvedOneOf => withExactlyOneSubschema(validator, schema, rootSchema, dependencyKey, resolvedOneOf, expandAllBranches, formData));
|
|
938
886
|
});
|
|
939
887
|
}
|
|
940
888
|
/** Returns a list of `schema`s with the best choice from the `oneOf` options merged into it. If `expandAllBranches` is
|
|
@@ -952,16 +900,19 @@ function withDependentSchema(validator, schema, rootSchema, dependencyKey, depen
|
|
|
952
900
|
* @returns - Either an array containing the best matching option or all options if `expandAllBranches` is true
|
|
953
901
|
*/
|
|
954
902
|
function withExactlyOneSubschema(validator, schema, rootSchema, dependencyKey, oneOf, expandAllBranches, formData) {
|
|
955
|
-
|
|
903
|
+
const validSubschemas = oneOf.filter(subschema => {
|
|
956
904
|
if (typeof subschema === 'boolean' || !subschema || !subschema.properties) {
|
|
957
905
|
return false;
|
|
958
906
|
}
|
|
959
|
-
|
|
907
|
+
const {
|
|
908
|
+
[dependencyKey]: conditionPropertySchema
|
|
909
|
+
} = subschema.properties;
|
|
960
910
|
if (conditionPropertySchema) {
|
|
961
|
-
|
|
962
|
-
var conditionSchema = {
|
|
911
|
+
const conditionSchema = {
|
|
963
912
|
type: 'object',
|
|
964
|
-
properties:
|
|
913
|
+
properties: {
|
|
914
|
+
[dependencyKey]: conditionPropertySchema
|
|
915
|
+
}
|
|
965
916
|
};
|
|
966
917
|
return validator.isValid(conditionSchema, formData, rootSchema) || expandAllBranches;
|
|
967
918
|
}
|
|
@@ -971,24 +922,22 @@ function withExactlyOneSubschema(validator, schema, rootSchema, dependencyKey, o
|
|
|
971
922
|
console.warn("ignoring oneOf in dependencies because there isn't exactly one subschema that is valid");
|
|
972
923
|
return [schema];
|
|
973
924
|
}
|
|
974
|
-
return validSubschemas.flatMap(
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
925
|
+
return validSubschemas.flatMap(s => {
|
|
926
|
+
const subschema = s;
|
|
927
|
+
const [dependentSubschema] = splitKeyElementFromObject(dependencyKey, subschema.properties);
|
|
928
|
+
const dependentSchema = {
|
|
929
|
+
...subschema,
|
|
979
930
|
properties: dependentSubschema
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
return schemas.map(
|
|
983
|
-
return mergeSchemas(schema, s);
|
|
984
|
-
});
|
|
931
|
+
};
|
|
932
|
+
const schemas = retrieveSchemaInternal(validator, dependentSchema, rootSchema, formData, expandAllBranches);
|
|
933
|
+
return schemas.map(s => mergeSchemas(schema, s));
|
|
985
934
|
});
|
|
986
935
|
}
|
|
987
936
|
|
|
988
937
|
/** A junk option used to determine when the getFirstMatchingOption call really matches an option rather than returning
|
|
989
938
|
* the first item
|
|
990
939
|
*/
|
|
991
|
-
|
|
940
|
+
const JUNK_OPTION = {
|
|
992
941
|
type: 'object',
|
|
993
942
|
$id: JUNK_OPTION_ID,
|
|
994
943
|
properties: {
|
|
@@ -1017,41 +966,38 @@ var JUNK_OPTION = {
|
|
|
1017
966
|
* @param formData - The form data associated with the schema, used to calculate the score
|
|
1018
967
|
* @returns - The score a schema against the formData
|
|
1019
968
|
*/
|
|
1020
|
-
function calculateIndexScore(validator, rootSchema, schema, formData) {
|
|
1021
|
-
|
|
1022
|
-
formData = {};
|
|
1023
|
-
}
|
|
1024
|
-
var totalScore = 0;
|
|
969
|
+
function calculateIndexScore(validator, rootSchema, schema, formData = {}) {
|
|
970
|
+
let totalScore = 0;
|
|
1025
971
|
if (schema) {
|
|
1026
972
|
if (isObject$1(schema.properties)) {
|
|
1027
|
-
totalScore += reduce(schema.properties,
|
|
1028
|
-
|
|
973
|
+
totalScore += reduce(schema.properties, (score, value, key) => {
|
|
974
|
+
const formValue = get(formData, key);
|
|
1029
975
|
if (typeof value === 'boolean') {
|
|
1030
976
|
return score;
|
|
1031
977
|
}
|
|
1032
978
|
if (has(value, REF_KEY)) {
|
|
1033
|
-
|
|
979
|
+
const newSchema = retrieveSchema(validator, value, rootSchema, formValue);
|
|
1034
980
|
return score + calculateIndexScore(validator, rootSchema, newSchema, formValue || {});
|
|
1035
981
|
}
|
|
1036
982
|
if ((has(value, ONE_OF_KEY) || has(value, ANY_OF_KEY)) && formValue) {
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
return score + getClosestMatchingOption(validator, rootSchema, formValue, get(value,
|
|
983
|
+
const key = has(value, ONE_OF_KEY) ? ONE_OF_KEY : ANY_OF_KEY;
|
|
984
|
+
const discriminator = getDiscriminatorFieldFromSchema(value);
|
|
985
|
+
return score + getClosestMatchingOption(validator, rootSchema, formValue, get(value, key), -1, discriminator);
|
|
1040
986
|
}
|
|
1041
987
|
if (value.type === 'object') {
|
|
1042
988
|
return score + calculateIndexScore(validator, rootSchema, value, formValue || {});
|
|
1043
989
|
}
|
|
1044
990
|
if (value.type === guessType(formValue)) {
|
|
1045
991
|
// If the types match, then we bump the score by one
|
|
1046
|
-
|
|
1047
|
-
if (value
|
|
992
|
+
let newScore = score + 1;
|
|
993
|
+
if (value.default) {
|
|
1048
994
|
// If the schema contains a readonly default value score the value that matches the default higher and
|
|
1049
995
|
// any non-matching value lower
|
|
1050
|
-
newScore += formValue === value
|
|
1051
|
-
} else if (value
|
|
996
|
+
newScore += formValue === value.default ? 1 : -1;
|
|
997
|
+
} else if (value.const) {
|
|
1052
998
|
// If the schema contains a const value score the value that matches the default higher and
|
|
1053
999
|
// any non-matching value lower
|
|
1054
|
-
newScore += formValue === value
|
|
1000
|
+
newScore += formValue === value.const ? 1 : -1;
|
|
1055
1001
|
}
|
|
1056
1002
|
// TODO eventually, deal with enums/arrays
|
|
1057
1003
|
return newScore;
|
|
@@ -1086,21 +1032,15 @@ function calculateIndexScore(validator, rootSchema, schema, formData) {
|
|
|
1086
1032
|
* determine which option is selected
|
|
1087
1033
|
* @returns - The index of the option that is the closest match to the `formData` or the `selectedOption` if no match
|
|
1088
1034
|
*/
|
|
1089
|
-
function getClosestMatchingOption(validator, rootSchema, formData, options, selectedOption, discriminatorField) {
|
|
1090
|
-
if (selectedOption === void 0) {
|
|
1091
|
-
selectedOption = -1;
|
|
1092
|
-
}
|
|
1035
|
+
function getClosestMatchingOption(validator, rootSchema, formData, options, selectedOption = -1, discriminatorField) {
|
|
1093
1036
|
// First resolve any refs in the options
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
return retrieveSchema(validator, option, rootSchema, formData);
|
|
1097
|
-
}
|
|
1098
|
-
return option;
|
|
1037
|
+
const resolvedOptions = options.map(option => {
|
|
1038
|
+
return resolveAllReferences(option, rootSchema);
|
|
1099
1039
|
});
|
|
1100
1040
|
// Reduce the array of options down to a list of the indexes that are considered matching options
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1041
|
+
const allValidIndexes = resolvedOptions.reduce((validList, option, index) => {
|
|
1042
|
+
const testOptions = [JUNK_OPTION, option];
|
|
1043
|
+
const match = getFirstMatchingOption(validator, formData, testOptions, rootSchema, discriminatorField);
|
|
1104
1044
|
// The match is the real option, so add its index to list of valid indexes
|
|
1105
1045
|
if (match === 1) {
|
|
1106
1046
|
validList.push(index);
|
|
@@ -1113,29 +1053,30 @@ function getClosestMatchingOption(validator, rootSchema, formData, options, sele
|
|
|
1113
1053
|
}
|
|
1114
1054
|
if (!allValidIndexes.length) {
|
|
1115
1055
|
// No indexes were valid, so we'll score all the options, add all the indexes
|
|
1116
|
-
times(resolvedOptions.length,
|
|
1117
|
-
return allValidIndexes.push(i);
|
|
1118
|
-
});
|
|
1056
|
+
times(resolvedOptions.length, i => allValidIndexes.push(i));
|
|
1119
1057
|
}
|
|
1120
|
-
|
|
1058
|
+
const scoreCount = new Set();
|
|
1121
1059
|
// Score all the options in the list of valid indexes and return the index with the best score
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1060
|
+
const {
|
|
1061
|
+
bestIndex
|
|
1062
|
+
} = allValidIndexes.reduce((scoreData, index) => {
|
|
1063
|
+
const {
|
|
1064
|
+
bestScore
|
|
1065
|
+
} = scoreData;
|
|
1066
|
+
const option = resolvedOptions[index];
|
|
1067
|
+
const score = calculateIndexScore(validator, rootSchema, option, formData);
|
|
1068
|
+
scoreCount.add(score);
|
|
1069
|
+
if (score > bestScore) {
|
|
1070
|
+
return {
|
|
1071
|
+
bestIndex: index,
|
|
1072
|
+
bestScore: score
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1075
|
+
return scoreData;
|
|
1076
|
+
}, {
|
|
1077
|
+
bestIndex: selectedOption,
|
|
1078
|
+
bestScore: 0
|
|
1079
|
+
});
|
|
1139
1080
|
// if all scores are the same go with selectedOption
|
|
1140
1081
|
if (scoreCount.size === 1 && selectedOption >= 0) {
|
|
1141
1082
|
return selectedOption;
|
|
@@ -1150,9 +1091,7 @@ function getClosestMatchingOption(validator, rootSchema, formData, options, sele
|
|
|
1150
1091
|
* @returns - True if there are fixed items in the schema, false otherwise
|
|
1151
1092
|
*/
|
|
1152
1093
|
function isFixedItems(schema) {
|
|
1153
|
-
return Array.isArray(schema.items) && schema.items.length > 0 && schema.items.every(
|
|
1154
|
-
return isObject(item);
|
|
1155
|
-
});
|
|
1094
|
+
return Array.isArray(schema.items) && schema.items.length > 0 && schema.items.every(item => isObject(item));
|
|
1156
1095
|
}
|
|
1157
1096
|
|
|
1158
1097
|
/** Merges the `defaults` object of type `T` into the `formData` of type `T`
|
|
@@ -1171,13 +1110,10 @@ function isFixedItems(schema) {
|
|
|
1171
1110
|
* @param [mergeExtraArrayDefaults=false] - If true, any additional default array entries are appended onto the formData
|
|
1172
1111
|
* @returns - The resulting merged form data with defaults
|
|
1173
1112
|
*/
|
|
1174
|
-
function mergeDefaultsWithFormData(defaults, formData, mergeExtraArrayDefaults) {
|
|
1175
|
-
if (mergeExtraArrayDefaults === void 0) {
|
|
1176
|
-
mergeExtraArrayDefaults = false;
|
|
1177
|
-
}
|
|
1113
|
+
function mergeDefaultsWithFormData(defaults, formData, mergeExtraArrayDefaults = false) {
|
|
1178
1114
|
if (Array.isArray(formData)) {
|
|
1179
|
-
|
|
1180
|
-
|
|
1115
|
+
const defaultsArray = Array.isArray(defaults) ? defaults : [];
|
|
1116
|
+
const mapped = formData.map((value, idx) => {
|
|
1181
1117
|
if (defaultsArray[idx]) {
|
|
1182
1118
|
return mergeDefaultsWithFormData(defaultsArray[idx], value, mergeExtraArrayDefaults);
|
|
1183
1119
|
}
|
|
@@ -1185,13 +1121,13 @@ function mergeDefaultsWithFormData(defaults, formData, mergeExtraArrayDefaults)
|
|
|
1185
1121
|
});
|
|
1186
1122
|
// Merge any extra defaults when mergeExtraArrayDefaults is true
|
|
1187
1123
|
if (mergeExtraArrayDefaults && mapped.length < defaultsArray.length) {
|
|
1188
|
-
mapped.push
|
|
1124
|
+
mapped.push(...defaultsArray.slice(mapped.length));
|
|
1189
1125
|
}
|
|
1190
1126
|
return mapped;
|
|
1191
1127
|
}
|
|
1192
1128
|
if (isObject(formData)) {
|
|
1193
|
-
|
|
1194
|
-
return Object.keys(formData).reduce(
|
|
1129
|
+
const acc = Object.assign({}, defaults); // Prevent mutation of source object.
|
|
1130
|
+
return Object.keys(formData).reduce((acc, key) => {
|
|
1195
1131
|
acc[key] = mergeDefaultsWithFormData(defaults ? get(defaults, key) : {}, get(formData, key), mergeExtraArrayDefaults);
|
|
1196
1132
|
return acc;
|
|
1197
1133
|
}, acc);
|
|
@@ -1208,19 +1144,16 @@ function mergeDefaultsWithFormData(defaults, formData, mergeExtraArrayDefaults)
|
|
|
1208
1144
|
* NOTE: Uses shallow comparison for the duplicate checking.
|
|
1209
1145
|
* @returns - A new object that is the merge of the two given objects
|
|
1210
1146
|
*/
|
|
1211
|
-
function mergeObjects(obj1, obj2, concatArrays) {
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
}
|
|
1215
|
-
return Object.keys(obj2).reduce(function (acc, key) {
|
|
1216
|
-
var left = obj1 ? obj1[key] : {},
|
|
1147
|
+
function mergeObjects(obj1, obj2, concatArrays = false) {
|
|
1148
|
+
return Object.keys(obj2).reduce((acc, key) => {
|
|
1149
|
+
const left = obj1 ? obj1[key] : {},
|
|
1217
1150
|
right = obj2[key];
|
|
1218
1151
|
if (obj1 && key in obj1 && isObject(right)) {
|
|
1219
1152
|
acc[key] = mergeObjects(left, right, concatArrays);
|
|
1220
1153
|
} else if (concatArrays && Array.isArray(left) && Array.isArray(right)) {
|
|
1221
|
-
|
|
1154
|
+
let toMerge = right;
|
|
1222
1155
|
if (concatArrays === 'preventDuplicates') {
|
|
1223
|
-
toMerge = right.reduce(
|
|
1156
|
+
toMerge = right.reduce((result, value) => {
|
|
1224
1157
|
if (!left.includes(value)) {
|
|
1225
1158
|
result.push(value);
|
|
1226
1159
|
}
|
|
@@ -1242,7 +1175,7 @@ function mergeObjects(obj1, obj2, concatArrays) {
|
|
|
1242
1175
|
* @returns - True if the `schema` has a single constant value, false otherwise
|
|
1243
1176
|
*/
|
|
1244
1177
|
function isConstant(schema) {
|
|
1245
|
-
return Array.isArray(schema
|
|
1178
|
+
return Array.isArray(schema.enum) && schema.enum.length === 1 || CONST_KEY in schema;
|
|
1246
1179
|
}
|
|
1247
1180
|
|
|
1248
1181
|
/** Checks to see if the `schema` combination represents a select
|
|
@@ -1252,19 +1185,14 @@ function isConstant(schema) {
|
|
|
1252
1185
|
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1253
1186
|
* @returns - True if schema contains a select, otherwise false
|
|
1254
1187
|
*/
|
|
1255
|
-
function isSelect(validator, theSchema, rootSchema) {
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
var schema = retrieveSchema(validator, theSchema, rootSchema, undefined);
|
|
1260
|
-
var altSchemas = schema.oneOf || schema.anyOf;
|
|
1261
|
-
if (Array.isArray(schema["enum"])) {
|
|
1188
|
+
function isSelect(validator, theSchema, rootSchema = {}) {
|
|
1189
|
+
const schema = retrieveSchema(validator, theSchema, rootSchema, undefined);
|
|
1190
|
+
const altSchemas = schema.oneOf || schema.anyOf;
|
|
1191
|
+
if (Array.isArray(schema.enum)) {
|
|
1262
1192
|
return true;
|
|
1263
1193
|
}
|
|
1264
1194
|
if (Array.isArray(altSchemas)) {
|
|
1265
|
-
return altSchemas.every(
|
|
1266
|
-
return typeof altSchemas !== 'boolean' && isConstant(altSchemas);
|
|
1267
|
-
});
|
|
1195
|
+
return altSchemas.every(altSchemas => typeof altSchemas !== 'boolean' && isConstant(altSchemas));
|
|
1268
1196
|
}
|
|
1269
1197
|
return false;
|
|
1270
1198
|
}
|
|
@@ -1283,8 +1211,6 @@ function isMultiSelect(validator, schema, rootSchema) {
|
|
|
1283
1211
|
return isSelect(validator, schema.items, rootSchema);
|
|
1284
1212
|
}
|
|
1285
1213
|
|
|
1286
|
-
var _excluded$1 = ["oneOf"],
|
|
1287
|
-
_excluded2 = ["anyOf"];
|
|
1288
1214
|
/** Enum that indicates how `schema.additionalItems` should be handled by the `getInnerSchemaForArrayItem()` function.
|
|
1289
1215
|
*/
|
|
1290
1216
|
var AdditionalItemsHandling;
|
|
@@ -1308,16 +1234,10 @@ var AdditionalItemsHandling;
|
|
|
1308
1234
|
* @param [idx=-1] - Index, if non-negative, will be used to return the idx-th element in a `schema.items` array
|
|
1309
1235
|
* @returns - The best fit schema object from the `schema` given the `additionalItems` and `idx` modifiers
|
|
1310
1236
|
*/
|
|
1311
|
-
function getInnerSchemaForArrayItem(schema, additionalItems, idx) {
|
|
1312
|
-
if (additionalItems === void 0) {
|
|
1313
|
-
additionalItems = AdditionalItemsHandling.Ignore;
|
|
1314
|
-
}
|
|
1315
|
-
if (idx === void 0) {
|
|
1316
|
-
idx = -1;
|
|
1317
|
-
}
|
|
1237
|
+
function getInnerSchemaForArrayItem(schema, additionalItems = AdditionalItemsHandling.Ignore, idx = -1) {
|
|
1318
1238
|
if (idx >= 0) {
|
|
1319
1239
|
if (Array.isArray(schema.items) && idx < schema.items.length) {
|
|
1320
|
-
|
|
1240
|
+
const item = schema.items[idx];
|
|
1321
1241
|
if (typeof item !== 'boolean') {
|
|
1322
1242
|
return item;
|
|
1323
1243
|
}
|
|
@@ -1349,23 +1269,17 @@ function getInnerSchemaForArrayItem(schema, additionalItems, idx) {
|
|
|
1349
1269
|
* @param experimental_defaultFormStateBehavior - Optional configuration object, if provided, allows users to override
|
|
1350
1270
|
* default form state behavior
|
|
1351
1271
|
*/
|
|
1352
|
-
function maybeAddDefaultToObject(obj, key, computedDefault, includeUndefinedValues, isParentRequired, requiredFields, experimental_defaultFormStateBehavior) {
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
}
|
|
1356
|
-
if (experimental_defaultFormStateBehavior === void 0) {
|
|
1357
|
-
experimental_defaultFormStateBehavior = {};
|
|
1358
|
-
}
|
|
1359
|
-
var _experimental_default = experimental_defaultFormStateBehavior,
|
|
1360
|
-
_experimental_default2 = _experimental_default.emptyObjectFields,
|
|
1361
|
-
emptyObjectFields = _experimental_default2 === void 0 ? 'populateAllDefaults' : _experimental_default2;
|
|
1272
|
+
function maybeAddDefaultToObject(obj, key, computedDefault, includeUndefinedValues, isParentRequired, requiredFields = [], experimental_defaultFormStateBehavior = {}) {
|
|
1273
|
+
const {
|
|
1274
|
+
emptyObjectFields = 'populateAllDefaults'
|
|
1275
|
+
} = experimental_defaultFormStateBehavior;
|
|
1362
1276
|
if (includeUndefinedValues) {
|
|
1363
1277
|
obj[key] = computedDefault;
|
|
1364
1278
|
} else if (emptyObjectFields !== 'skipDefaults') {
|
|
1365
1279
|
if (isObject(computedDefault)) {
|
|
1366
1280
|
// If isParentRequired is undefined, then we are at the root level of the schema so defer to the requiredness of
|
|
1367
1281
|
// the field key itself in the `requiredField` list
|
|
1368
|
-
|
|
1282
|
+
const isSelfOrParentRequired = isParentRequired === undefined ? requiredFields.includes(key) : isParentRequired;
|
|
1369
1283
|
// Store computedDefault if it's a non-empty object(e.g. not {}) and satisfies certain conditions
|
|
1370
1284
|
// Condition 1: If computedDefault is not empty or if the key is a required field
|
|
1371
1285
|
// Condition 2: If the parent object is required or emptyObjectFields is not 'populateRequiredDefaults'
|
|
@@ -1398,100 +1312,98 @@ function maybeAddDefaultToObject(obj, key, computedDefault, includeUndefinedValu
|
|
|
1398
1312
|
* @param [props.required] - Optional flag, if true, indicates this schema was required in the parent schema.
|
|
1399
1313
|
* @returns - The resulting `formData` with all the defaults provided
|
|
1400
1314
|
*/
|
|
1401
|
-
function computeDefaults(validator, rawSchema,
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
experimental_defaultFormStateBehavior = _ref$experimental_def === void 0 ? undefined : _ref$experimental_def,
|
|
1413
|
-
required = _ref.required;
|
|
1414
|
-
var formData = isObject(rawFormData) ? rawFormData : {};
|
|
1415
|
-
var schema = isObject(rawSchema) ? rawSchema : {};
|
|
1315
|
+
function computeDefaults(validator, rawSchema, {
|
|
1316
|
+
parentDefaults,
|
|
1317
|
+
rawFormData,
|
|
1318
|
+
rootSchema = {},
|
|
1319
|
+
includeUndefinedValues = false,
|
|
1320
|
+
_recurseList = [],
|
|
1321
|
+
experimental_defaultFormStateBehavior = undefined,
|
|
1322
|
+
required
|
|
1323
|
+
} = {}) {
|
|
1324
|
+
const formData = isObject(rawFormData) ? rawFormData : {};
|
|
1325
|
+
const schema = isObject(rawSchema) ? rawSchema : {};
|
|
1416
1326
|
// Compute the defaults recursively: give highest priority to deepest nodes.
|
|
1417
|
-
|
|
1327
|
+
let defaults = parentDefaults;
|
|
1418
1328
|
// If we get a new schema, then we need to recompute defaults again for the new schema found.
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
if (isObject(defaults) && isObject(schema
|
|
1329
|
+
let schemaToCompute = null;
|
|
1330
|
+
let updatedRecurseList = _recurseList;
|
|
1331
|
+
if (isObject(defaults) && isObject(schema.default)) {
|
|
1422
1332
|
// For object defaults, only override parent defaults that are defined in
|
|
1423
1333
|
// schema.default.
|
|
1424
|
-
defaults = mergeObjects(defaults, schema
|
|
1334
|
+
defaults = mergeObjects(defaults, schema.default);
|
|
1425
1335
|
} else if (DEFAULT_KEY in schema) {
|
|
1426
|
-
defaults = schema
|
|
1336
|
+
defaults = schema.default;
|
|
1427
1337
|
} else if (REF_KEY in schema) {
|
|
1428
|
-
|
|
1338
|
+
const refName = schema[REF_KEY];
|
|
1429
1339
|
// Use referenced schema defaults for this node.
|
|
1430
1340
|
if (!_recurseList.includes(refName)) {
|
|
1431
1341
|
updatedRecurseList = _recurseList.concat(refName);
|
|
1432
1342
|
schemaToCompute = findSchemaDefinition(refName, rootSchema);
|
|
1433
1343
|
}
|
|
1434
1344
|
} else if (DEPENDENCIES_KEY in schema) {
|
|
1435
|
-
|
|
1345
|
+
const resolvedSchema = resolveDependencies(validator, schema, rootSchema, false, formData);
|
|
1436
1346
|
schemaToCompute = resolvedSchema[0]; // pick the first element from resolve dependencies
|
|
1437
1347
|
} else if (isFixedItems(schema)) {
|
|
1438
|
-
defaults = schema.items.map(
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
});
|
|
1448
|
-
});
|
|
1348
|
+
defaults = schema.items.map((itemSchema, idx) => computeDefaults(validator, itemSchema, {
|
|
1349
|
+
rootSchema,
|
|
1350
|
+
includeUndefinedValues,
|
|
1351
|
+
_recurseList,
|
|
1352
|
+
experimental_defaultFormStateBehavior,
|
|
1353
|
+
parentDefaults: Array.isArray(parentDefaults) ? parentDefaults[idx] : undefined,
|
|
1354
|
+
rawFormData: formData,
|
|
1355
|
+
required
|
|
1356
|
+
}));
|
|
1449
1357
|
} else if (ONE_OF_KEY in schema) {
|
|
1450
|
-
|
|
1451
|
-
|
|
1358
|
+
const {
|
|
1359
|
+
oneOf,
|
|
1360
|
+
...remaining
|
|
1361
|
+
} = schema;
|
|
1452
1362
|
if (oneOf.length === 0) {
|
|
1453
1363
|
return undefined;
|
|
1454
1364
|
}
|
|
1455
|
-
|
|
1365
|
+
const discriminator = getDiscriminatorFieldFromSchema(schema);
|
|
1456
1366
|
schemaToCompute = oneOf[getClosestMatchingOption(validator, rootSchema, isEmpty(formData) ? undefined : formData, oneOf, 0, discriminator)];
|
|
1457
|
-
schemaToCompute =
|
|
1367
|
+
schemaToCompute = mergeSchemas(remaining, schemaToCompute);
|
|
1458
1368
|
} else if (ANY_OF_KEY in schema) {
|
|
1459
|
-
|
|
1460
|
-
|
|
1369
|
+
const {
|
|
1370
|
+
anyOf,
|
|
1371
|
+
...remaining
|
|
1372
|
+
} = schema;
|
|
1461
1373
|
if (anyOf.length === 0) {
|
|
1462
1374
|
return undefined;
|
|
1463
1375
|
}
|
|
1464
|
-
|
|
1465
|
-
schemaToCompute = anyOf[getClosestMatchingOption(validator, rootSchema, isEmpty(formData) ? undefined : formData, anyOf, 0,
|
|
1466
|
-
schemaToCompute =
|
|
1376
|
+
const discriminator = getDiscriminatorFieldFromSchema(schema);
|
|
1377
|
+
schemaToCompute = anyOf[getClosestMatchingOption(validator, rootSchema, isEmpty(formData) ? undefined : formData, anyOf, 0, discriminator)];
|
|
1378
|
+
schemaToCompute = mergeSchemas(remaining, schemaToCompute);
|
|
1467
1379
|
}
|
|
1468
1380
|
if (schemaToCompute) {
|
|
1469
1381
|
return computeDefaults(validator, schemaToCompute, {
|
|
1470
|
-
rootSchema
|
|
1471
|
-
includeUndefinedValues
|
|
1382
|
+
rootSchema,
|
|
1383
|
+
includeUndefinedValues,
|
|
1472
1384
|
_recurseList: updatedRecurseList,
|
|
1473
|
-
experimental_defaultFormStateBehavior
|
|
1385
|
+
experimental_defaultFormStateBehavior,
|
|
1474
1386
|
parentDefaults: defaults,
|
|
1475
1387
|
rawFormData: formData,
|
|
1476
|
-
required
|
|
1388
|
+
required
|
|
1477
1389
|
});
|
|
1478
1390
|
}
|
|
1479
1391
|
// No defaults defined for this node, fallback to generic typed ones.
|
|
1480
1392
|
if (defaults === undefined) {
|
|
1481
|
-
defaults = schema
|
|
1393
|
+
defaults = schema.default;
|
|
1482
1394
|
}
|
|
1483
1395
|
switch (getSchemaType(schema)) {
|
|
1484
1396
|
// We need to recurse for object schema inner default values.
|
|
1485
1397
|
case 'object':
|
|
1486
1398
|
{
|
|
1487
|
-
|
|
1399
|
+
const objectDefaults = Object.keys(schema.properties || {}).reduce((acc, key) => {
|
|
1488
1400
|
var _schema$required;
|
|
1489
1401
|
// Compute the defaults for this node, with the parent defaults we might
|
|
1490
1402
|
// have from a previous run: defaults[key].
|
|
1491
|
-
|
|
1492
|
-
rootSchema
|
|
1493
|
-
_recurseList
|
|
1494
|
-
experimental_defaultFormStateBehavior
|
|
1403
|
+
const computedDefault = computeDefaults(validator, get(schema, [PROPERTIES_KEY, key]), {
|
|
1404
|
+
rootSchema,
|
|
1405
|
+
_recurseList,
|
|
1406
|
+
experimental_defaultFormStateBehavior,
|
|
1495
1407
|
includeUndefinedValues: includeUndefinedValues === true,
|
|
1496
1408
|
parentDefaults: get(defaults, [key]),
|
|
1497
1409
|
rawFormData: get(formData, [key]),
|
|
@@ -1502,31 +1414,25 @@ function computeDefaults(validator, rawSchema, _temp) {
|
|
|
1502
1414
|
}, {});
|
|
1503
1415
|
if (schema.additionalProperties) {
|
|
1504
1416
|
// as per spec additionalProperties may be either schema or boolean
|
|
1505
|
-
|
|
1506
|
-
|
|
1417
|
+
const additionalPropertiesSchema = isObject(schema.additionalProperties) ? schema.additionalProperties : {};
|
|
1418
|
+
const keys = new Set();
|
|
1507
1419
|
if (isObject(defaults)) {
|
|
1508
|
-
Object.keys(defaults).filter(
|
|
1509
|
-
return !schema.properties || !schema.properties[key];
|
|
1510
|
-
}).forEach(function (key) {
|
|
1511
|
-
return keys.add(key);
|
|
1512
|
-
});
|
|
1420
|
+
Object.keys(defaults).filter(key => !schema.properties || !schema.properties[key]).forEach(key => keys.add(key));
|
|
1513
1421
|
}
|
|
1514
|
-
|
|
1422
|
+
let formDataRequired;
|
|
1515
1423
|
if (isObject(formData)) {
|
|
1516
1424
|
formDataRequired = [];
|
|
1517
|
-
Object.keys(formData).filter(
|
|
1518
|
-
return !schema.properties || !schema.properties[key];
|
|
1519
|
-
}).forEach(function (key) {
|
|
1425
|
+
Object.keys(formData).filter(key => !schema.properties || !schema.properties[key]).forEach(key => {
|
|
1520
1426
|
keys.add(key);
|
|
1521
1427
|
formDataRequired.push(key);
|
|
1522
1428
|
});
|
|
1523
1429
|
}
|
|
1524
|
-
keys.forEach(
|
|
1430
|
+
keys.forEach(key => {
|
|
1525
1431
|
var _schema$required2;
|
|
1526
|
-
|
|
1527
|
-
rootSchema
|
|
1528
|
-
_recurseList
|
|
1529
|
-
experimental_defaultFormStateBehavior
|
|
1432
|
+
const computedDefault = computeDefaults(validator, additionalPropertiesSchema, {
|
|
1433
|
+
rootSchema,
|
|
1434
|
+
_recurseList,
|
|
1435
|
+
experimental_defaultFormStateBehavior,
|
|
1530
1436
|
includeUndefinedValues: includeUndefinedValues === true,
|
|
1531
1437
|
parentDefaults: get(defaults, [key]),
|
|
1532
1438
|
rawFormData: get(formData, [key]),
|
|
@@ -1540,54 +1446,54 @@ function computeDefaults(validator, rawSchema, _temp) {
|
|
|
1540
1446
|
}
|
|
1541
1447
|
case 'array':
|
|
1542
1448
|
{
|
|
1543
|
-
var
|
|
1449
|
+
var _experimental_default;
|
|
1544
1450
|
// Inject defaults into existing array defaults
|
|
1545
1451
|
if (Array.isArray(defaults)) {
|
|
1546
|
-
defaults = defaults.map(
|
|
1547
|
-
|
|
1452
|
+
defaults = defaults.map((item, idx) => {
|
|
1453
|
+
const schemaItem = getInnerSchemaForArrayItem(schema, AdditionalItemsHandling.Fallback, idx);
|
|
1548
1454
|
return computeDefaults(validator, schemaItem, {
|
|
1549
|
-
rootSchema
|
|
1550
|
-
_recurseList
|
|
1551
|
-
experimental_defaultFormStateBehavior
|
|
1455
|
+
rootSchema,
|
|
1456
|
+
_recurseList,
|
|
1457
|
+
experimental_defaultFormStateBehavior,
|
|
1552
1458
|
parentDefaults: item,
|
|
1553
|
-
required
|
|
1459
|
+
required
|
|
1554
1460
|
});
|
|
1555
1461
|
});
|
|
1556
1462
|
}
|
|
1557
1463
|
// Deeply inject defaults into already existing form data
|
|
1558
1464
|
if (Array.isArray(rawFormData)) {
|
|
1559
|
-
|
|
1560
|
-
defaults = rawFormData.map(
|
|
1465
|
+
const schemaItem = getInnerSchemaForArrayItem(schema);
|
|
1466
|
+
defaults = rawFormData.map((item, idx) => {
|
|
1561
1467
|
return computeDefaults(validator, schemaItem, {
|
|
1562
|
-
rootSchema
|
|
1563
|
-
_recurseList
|
|
1564
|
-
experimental_defaultFormStateBehavior
|
|
1468
|
+
rootSchema,
|
|
1469
|
+
_recurseList,
|
|
1470
|
+
experimental_defaultFormStateBehavior,
|
|
1565
1471
|
rawFormData: item,
|
|
1566
1472
|
parentDefaults: get(defaults, [idx]),
|
|
1567
|
-
required
|
|
1473
|
+
required
|
|
1568
1474
|
});
|
|
1569
1475
|
});
|
|
1570
1476
|
}
|
|
1571
|
-
|
|
1477
|
+
const ignoreMinItemsFlagSet = (experimental_defaultFormStateBehavior === null || experimental_defaultFormStateBehavior === void 0 ? void 0 : (_experimental_default = experimental_defaultFormStateBehavior.arrayMinItems) === null || _experimental_default === void 0 ? void 0 : _experimental_default.populate) === 'requiredOnly';
|
|
1572
1478
|
if (ignoreMinItemsFlagSet && !required) {
|
|
1573
1479
|
// If no form data exists or defaults are set leave the field empty/non-existent, otherwise
|
|
1574
1480
|
// return form data/defaults
|
|
1575
1481
|
return defaults ? defaults : undefined;
|
|
1576
1482
|
}
|
|
1577
|
-
|
|
1483
|
+
const defaultsLength = Array.isArray(defaults) ? defaults.length : 0;
|
|
1578
1484
|
if (!schema.minItems || isMultiSelect(validator, schema, rootSchema) || schema.minItems <= defaultsLength) {
|
|
1579
1485
|
return defaults ? defaults : [];
|
|
1580
1486
|
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1487
|
+
const defaultEntries = defaults || [];
|
|
1488
|
+
const fillerSchema = getInnerSchemaForArrayItem(schema, AdditionalItemsHandling.Invert);
|
|
1489
|
+
const fillerDefault = fillerSchema.default;
|
|
1584
1490
|
// Calculate filler entries for remaining items (minItems - existing raw data/defaults)
|
|
1585
|
-
|
|
1491
|
+
const fillerEntries = new Array(schema.minItems - defaultsLength).fill(computeDefaults(validator, fillerSchema, {
|
|
1586
1492
|
parentDefaults: fillerDefault,
|
|
1587
|
-
rootSchema
|
|
1588
|
-
_recurseList
|
|
1589
|
-
experimental_defaultFormStateBehavior
|
|
1590
|
-
required
|
|
1493
|
+
rootSchema,
|
|
1494
|
+
_recurseList,
|
|
1495
|
+
experimental_defaultFormStateBehavior,
|
|
1496
|
+
required
|
|
1591
1497
|
}));
|
|
1592
1498
|
// then fill up the rest with either the item default or empty, up to minItems
|
|
1593
1499
|
return defaultEntries.concat(fillerEntries);
|
|
@@ -1608,26 +1514,24 @@ function computeDefaults(validator, rawSchema, _temp) {
|
|
|
1608
1514
|
* @param [experimental_defaultFormStateBehavior] Optional configuration object, if provided, allows users to override default form state behavior
|
|
1609
1515
|
* @returns - The resulting `formData` with all the defaults provided
|
|
1610
1516
|
*/
|
|
1611
|
-
function getDefaultFormState(validator, theSchema, formData, rootSchema, includeUndefinedValues, experimental_defaultFormStateBehavior) {
|
|
1612
|
-
if (includeUndefinedValues === void 0) {
|
|
1613
|
-
includeUndefinedValues = false;
|
|
1614
|
-
}
|
|
1517
|
+
function getDefaultFormState(validator, theSchema, formData, rootSchema, includeUndefinedValues = false, experimental_defaultFormStateBehavior) {
|
|
1615
1518
|
if (!isObject(theSchema)) {
|
|
1616
1519
|
throw new Error('Invalid schema: ' + theSchema);
|
|
1617
1520
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
rootSchema
|
|
1621
|
-
includeUndefinedValues
|
|
1622
|
-
experimental_defaultFormStateBehavior
|
|
1521
|
+
const schema = retrieveSchema(validator, theSchema, rootSchema, formData);
|
|
1522
|
+
const defaults = computeDefaults(validator, schema, {
|
|
1523
|
+
rootSchema,
|
|
1524
|
+
includeUndefinedValues,
|
|
1525
|
+
experimental_defaultFormStateBehavior,
|
|
1623
1526
|
rawFormData: formData
|
|
1624
1527
|
});
|
|
1625
1528
|
if (formData === undefined || formData === null || typeof formData === 'number' && isNaN(formData)) {
|
|
1626
1529
|
// No form data? Use schema defaults.
|
|
1627
1530
|
return defaults;
|
|
1628
1531
|
}
|
|
1629
|
-
|
|
1630
|
-
mergeExtraDefaults
|
|
1532
|
+
const {
|
|
1533
|
+
mergeExtraDefaults
|
|
1534
|
+
} = (experimental_defaultFormStateBehavior === null || experimental_defaultFormStateBehavior === void 0 ? void 0 : experimental_defaultFormStateBehavior.arrayMinItems) || {};
|
|
1631
1535
|
if (isObject(formData)) {
|
|
1632
1536
|
return mergeDefaultsWithFormData(defaults, formData, mergeExtraDefaults);
|
|
1633
1537
|
}
|
|
@@ -1642,10 +1546,7 @@ function getDefaultFormState(validator, theSchema, formData, rootSchema, include
|
|
|
1642
1546
|
* @param uiSchema - The UI Schema from which to detect if it is customized
|
|
1643
1547
|
* @returns - True if the `uiSchema` describes a custom widget, false otherwise
|
|
1644
1548
|
*/
|
|
1645
|
-
function isCustomWidget(uiSchema) {
|
|
1646
|
-
if (uiSchema === void 0) {
|
|
1647
|
-
uiSchema = {};
|
|
1648
|
-
}
|
|
1549
|
+
function isCustomWidget(uiSchema = {}) {
|
|
1649
1550
|
return (
|
|
1650
1551
|
// TODO: Remove the `&& uiSchema['ui:widget'] !== 'hidden'` once we support hidden widgets for arrays.
|
|
1651
1552
|
// https://rjsf-team.github.io/react-jsonschema-form/docs/usage/widgets/#hidden-widgets
|
|
@@ -1661,15 +1562,12 @@ function isCustomWidget(uiSchema) {
|
|
|
1661
1562
|
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1662
1563
|
* @returns - True if schema/uiSchema contains an array of files, otherwise false
|
|
1663
1564
|
*/
|
|
1664
|
-
function isFilesArray(validator, schema, uiSchema, rootSchema) {
|
|
1665
|
-
if (uiSchema === void 0) {
|
|
1666
|
-
uiSchema = {};
|
|
1667
|
-
}
|
|
1565
|
+
function isFilesArray(validator, schema, uiSchema = {}, rootSchema) {
|
|
1668
1566
|
if (uiSchema[UI_WIDGET_KEY] === 'files') {
|
|
1669
1567
|
return true;
|
|
1670
1568
|
}
|
|
1671
1569
|
if (schema.items) {
|
|
1672
|
-
|
|
1570
|
+
const itemsSchema = retrieveSchema(validator, schema.items, rootSchema);
|
|
1673
1571
|
return itemsSchema.type === 'string' && itemsSchema.format === 'data-url';
|
|
1674
1572
|
}
|
|
1675
1573
|
return false;
|
|
@@ -1685,15 +1583,13 @@ function isFilesArray(validator, schema, uiSchema, rootSchema) {
|
|
|
1685
1583
|
* @param [globalOptions={}] - The optional Global UI Schema from which to get any fallback `xxx` options
|
|
1686
1584
|
* @returns - True if the label should be displayed or false if it should not
|
|
1687
1585
|
*/
|
|
1688
|
-
function getDisplayLabel(validator, schema, uiSchema, rootSchema, globalOptions) {
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
var displayLabel = !!label;
|
|
1696
|
-
var schemaType = getSchemaType(schema);
|
|
1586
|
+
function getDisplayLabel(validator, schema, uiSchema = {}, rootSchema, globalOptions) {
|
|
1587
|
+
const uiOptions = getUiOptions(uiSchema, globalOptions);
|
|
1588
|
+
const {
|
|
1589
|
+
label = true
|
|
1590
|
+
} = uiOptions;
|
|
1591
|
+
let displayLabel = !!label;
|
|
1592
|
+
const schemaType = getSchemaType(schema);
|
|
1697
1593
|
if (schemaType === 'array') {
|
|
1698
1594
|
displayLabel = isMultiSelect(validator, schema, rootSchema) || isFilesArray(validator, schema, uiSchema, rootSchema) || isCustomWidget(uiSchema);
|
|
1699
1595
|
}
|
|
@@ -1725,21 +1621,23 @@ function mergeValidationData(validator, validationData, additionalErrorSchema) {
|
|
|
1725
1621
|
if (!additionalErrorSchema) {
|
|
1726
1622
|
return validationData;
|
|
1727
1623
|
}
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1624
|
+
const {
|
|
1625
|
+
errors: oldErrors,
|
|
1626
|
+
errorSchema: oldErrorSchema
|
|
1627
|
+
} = validationData;
|
|
1628
|
+
let errors = validator.toErrorList(additionalErrorSchema);
|
|
1629
|
+
let errorSchema = additionalErrorSchema;
|
|
1732
1630
|
if (!isEmpty(oldErrorSchema)) {
|
|
1733
1631
|
errorSchema = mergeObjects(oldErrorSchema, additionalErrorSchema, true);
|
|
1734
|
-
errors = [].concat(
|
|
1632
|
+
errors = [...oldErrors].concat(errors);
|
|
1735
1633
|
}
|
|
1736
1634
|
return {
|
|
1737
|
-
errorSchema
|
|
1738
|
-
errors
|
|
1635
|
+
errorSchema,
|
|
1636
|
+
errors
|
|
1739
1637
|
};
|
|
1740
1638
|
}
|
|
1741
1639
|
|
|
1742
|
-
|
|
1640
|
+
const NO_VALUE = /*#__PURE__*/Symbol('no Value');
|
|
1743
1641
|
/** Sanitize the `data` associated with the `oldSchema` so it is considered appropriate for the `newSchema`. If the new
|
|
1744
1642
|
* schema does not contain any properties, then `undefined` is returned to clear all the form data. Due to the nature
|
|
1745
1643
|
* of schemas, this sanitization happens recursively for nested objects of data. Also, any properties in the old schema
|
|
@@ -1787,31 +1685,28 @@ var NO_VALUE = /*#__PURE__*/Symbol('no Value');
|
|
|
1787
1685
|
* @returns - The new form data, with all the fields uniquely associated with the old schema set
|
|
1788
1686
|
* to `undefined`. Will return `undefined` if the new schema is not an object containing properties.
|
|
1789
1687
|
*/
|
|
1790
|
-
function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, data) {
|
|
1791
|
-
if (data === void 0) {
|
|
1792
|
-
data = {};
|
|
1793
|
-
}
|
|
1688
|
+
function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, data = {}) {
|
|
1794
1689
|
// By default, we will clear the form data
|
|
1795
|
-
|
|
1690
|
+
let newFormData;
|
|
1796
1691
|
// If the new schema is of type object and that object contains a list of properties
|
|
1797
1692
|
if (has(newSchema, PROPERTIES_KEY)) {
|
|
1798
1693
|
// Create an object containing root-level keys in the old schema, setting each key to undefined to remove the data
|
|
1799
|
-
|
|
1694
|
+
const removeOldSchemaData = {};
|
|
1800
1695
|
if (has(oldSchema, PROPERTIES_KEY)) {
|
|
1801
|
-
|
|
1802
|
-
Object.keys(properties).forEach(
|
|
1696
|
+
const properties = get(oldSchema, PROPERTIES_KEY, {});
|
|
1697
|
+
Object.keys(properties).forEach(key => {
|
|
1803
1698
|
if (has(data, key)) {
|
|
1804
1699
|
removeOldSchemaData[key] = undefined;
|
|
1805
1700
|
}
|
|
1806
1701
|
});
|
|
1807
1702
|
}
|
|
1808
|
-
|
|
1703
|
+
const keys = Object.keys(get(newSchema, PROPERTIES_KEY, {}));
|
|
1809
1704
|
// Create a place to store nested data that will be a side-effect of the filter
|
|
1810
|
-
|
|
1811
|
-
keys.forEach(
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1705
|
+
const nestedData = {};
|
|
1706
|
+
keys.forEach(key => {
|
|
1707
|
+
const formValue = get(data, key);
|
|
1708
|
+
let oldKeyedSchema = get(oldSchema, [PROPERTIES_KEY, key], {});
|
|
1709
|
+
let newKeyedSchema = get(newSchema, [PROPERTIES_KEY, key], {});
|
|
1815
1710
|
// Resolve the refs if they exist
|
|
1816
1711
|
if (has(oldKeyedSchema, REF_KEY)) {
|
|
1817
1712
|
oldKeyedSchema = retrieveSchema(validator, oldKeyedSchema, rootSchema, formValue);
|
|
@@ -1820,8 +1715,8 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
|
|
|
1820
1715
|
newKeyedSchema = retrieveSchema(validator, newKeyedSchema, rootSchema, formValue);
|
|
1821
1716
|
}
|
|
1822
1717
|
// Now get types and see if they are the same
|
|
1823
|
-
|
|
1824
|
-
|
|
1718
|
+
const oldSchemaTypeForKey = get(oldKeyedSchema, 'type');
|
|
1719
|
+
const newSchemaTypeForKey = get(newKeyedSchema, 'type');
|
|
1825
1720
|
// Check if the old option has the same key with the same type
|
|
1826
1721
|
if (!oldSchemaTypeForKey || oldSchemaTypeForKey === newSchemaTypeForKey) {
|
|
1827
1722
|
if (has(removeOldSchemaData, key)) {
|
|
@@ -1831,7 +1726,7 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
|
|
|
1831
1726
|
// If it is an object, we'll recurse and store the resulting sanitized data for the key
|
|
1832
1727
|
if (newSchemaTypeForKey === 'object' || newSchemaTypeForKey === 'array' && Array.isArray(formValue)) {
|
|
1833
1728
|
// SIDE-EFFECT: process the new schema type of object recursively to save iterations
|
|
1834
|
-
|
|
1729
|
+
const itemData = sanitizeDataForNewSchema(validator, rootSchema, newKeyedSchema, oldKeyedSchema, formValue);
|
|
1835
1730
|
if (itemData !== undefined || newSchemaTypeForKey === 'array') {
|
|
1836
1731
|
// only put undefined values for the array type and not the object type
|
|
1837
1732
|
nestedData[key] = itemData;
|
|
@@ -1840,8 +1735,8 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
|
|
|
1840
1735
|
// Ok, the non-object types match, let's make sure that a default or a const of a different value is replaced
|
|
1841
1736
|
// with the new default or const. This allows the case where two schemas differ that only by the default/const
|
|
1842
1737
|
// value to be properly selected
|
|
1843
|
-
|
|
1844
|
-
|
|
1738
|
+
const newOptionDefault = get(newKeyedSchema, 'default', NO_VALUE);
|
|
1739
|
+
const oldOptionDefault = get(oldKeyedSchema, 'default', NO_VALUE);
|
|
1845
1740
|
if (newOptionDefault !== NO_VALUE && newOptionDefault !== formValue) {
|
|
1846
1741
|
if (oldOptionDefault === formValue) {
|
|
1847
1742
|
// If the old default matches the formValue, we'll update the new value to match the new default
|
|
@@ -1851,8 +1746,8 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
|
|
|
1851
1746
|
removeOldSchemaData[key] = undefined;
|
|
1852
1747
|
}
|
|
1853
1748
|
}
|
|
1854
|
-
|
|
1855
|
-
|
|
1749
|
+
const newOptionConst = get(newKeyedSchema, 'const', NO_VALUE);
|
|
1750
|
+
const oldOptionConst = get(oldKeyedSchema, 'const', NO_VALUE);
|
|
1856
1751
|
if (newOptionConst !== NO_VALUE && newOptionConst !== formValue) {
|
|
1857
1752
|
// Since this is a const, if the old value matches, replace the value with the new const otherwise clear it
|
|
1858
1753
|
removeOldSchemaData[key] = oldOptionConst === formValue ? newOptionConst : undefined;
|
|
@@ -1860,11 +1755,15 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
|
|
|
1860
1755
|
}
|
|
1861
1756
|
}
|
|
1862
1757
|
});
|
|
1863
|
-
newFormData =
|
|
1758
|
+
newFormData = {
|
|
1759
|
+
...data,
|
|
1760
|
+
...removeOldSchemaData,
|
|
1761
|
+
...nestedData
|
|
1762
|
+
};
|
|
1864
1763
|
// First apply removing the old schema data, then apply the nested data, then apply the old data keys to keep
|
|
1865
1764
|
} else if (get(oldSchema, 'type') === 'array' && get(newSchema, 'type') === 'array' && Array.isArray(data)) {
|
|
1866
|
-
|
|
1867
|
-
|
|
1765
|
+
let oldSchemaItems = get(oldSchema, 'items');
|
|
1766
|
+
let newSchemaItems = get(newSchema, 'items');
|
|
1868
1767
|
// If any of the array types `items` are arrays (remember arrays are objects) then we'll just drop the data
|
|
1869
1768
|
// Eventually, we may want to deal with when either of the `items` are arrays since those tuple validations
|
|
1870
1769
|
if (typeof oldSchemaItems === 'object' && typeof newSchemaItems === 'object' && !Array.isArray(oldSchemaItems) && !Array.isArray(newSchemaItems)) {
|
|
@@ -1875,14 +1774,14 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
|
|
|
1875
1774
|
newSchemaItems = retrieveSchema(validator, newSchemaItems, rootSchema, data);
|
|
1876
1775
|
}
|
|
1877
1776
|
// Now get types and see if they are the same
|
|
1878
|
-
|
|
1879
|
-
|
|
1777
|
+
const oldSchemaType = get(oldSchemaItems, 'type');
|
|
1778
|
+
const newSchemaType = get(newSchemaItems, 'type');
|
|
1880
1779
|
// Check if the old option has the same key with the same type
|
|
1881
1780
|
if (!oldSchemaType || oldSchemaType === newSchemaType) {
|
|
1882
|
-
|
|
1781
|
+
const maxItems = get(newSchema, 'maxItems', -1);
|
|
1883
1782
|
if (newSchemaType === 'object') {
|
|
1884
|
-
newFormData = data.reduce(
|
|
1885
|
-
|
|
1783
|
+
newFormData = data.reduce((newValue, aValue) => {
|
|
1784
|
+
const itemValue = sanitizeDataForNewSchema(validator, rootSchema, newSchemaItems, oldSchemaItems, aValue);
|
|
1886
1785
|
if (itemValue !== undefined && (maxItems < 0 || newValue.length < maxItems)) {
|
|
1887
1786
|
newValue.push(itemValue);
|
|
1888
1787
|
}
|
|
@@ -1915,15 +1814,10 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
|
|
|
1915
1814
|
* @param [_recurseList=[]] - The list of retrieved schemas currently being recursed, used to prevent infinite recursion
|
|
1916
1815
|
* @returns - The `IdSchema` object for the `schema`
|
|
1917
1816
|
*/
|
|
1918
|
-
function toIdSchemaInternal(validator, schema, idPrefix, idSeparator, id, rootSchema, formData, _recurseList) {
|
|
1919
|
-
if (_recurseList === void 0) {
|
|
1920
|
-
_recurseList = [];
|
|
1921
|
-
}
|
|
1817
|
+
function toIdSchemaInternal(validator, schema, idPrefix, idSeparator, id, rootSchema, formData, _recurseList = []) {
|
|
1922
1818
|
if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
return isEqual(item, _schema);
|
|
1926
|
-
});
|
|
1819
|
+
const _schema = retrieveSchema(validator, schema, rootSchema, formData);
|
|
1820
|
+
const sameSchemaIndex = _recurseList.findIndex(item => isEqual(item, _schema));
|
|
1927
1821
|
if (sameSchemaIndex === -1) {
|
|
1928
1822
|
return toIdSchemaInternal(validator, _schema, idPrefix, idSeparator, id, rootSchema, formData, _recurseList.concat(_schema));
|
|
1929
1823
|
}
|
|
@@ -1931,14 +1825,14 @@ function toIdSchemaInternal(validator, schema, idPrefix, idSeparator, id, rootSc
|
|
|
1931
1825
|
if (ITEMS_KEY in schema && !get(schema, [ITEMS_KEY, REF_KEY])) {
|
|
1932
1826
|
return toIdSchemaInternal(validator, get(schema, ITEMS_KEY), idPrefix, idSeparator, id, rootSchema, formData, _recurseList);
|
|
1933
1827
|
}
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
$id
|
|
1828
|
+
const $id = id || idPrefix;
|
|
1829
|
+
const idSchema = {
|
|
1830
|
+
$id
|
|
1937
1831
|
};
|
|
1938
1832
|
if (getSchemaType(schema) === 'object' && PROPERTIES_KEY in schema) {
|
|
1939
|
-
for (
|
|
1940
|
-
|
|
1941
|
-
|
|
1833
|
+
for (const name in schema.properties) {
|
|
1834
|
+
const field = get(schema, [PROPERTIES_KEY, name]);
|
|
1835
|
+
const fieldId = idSchema[ID_KEY] + idSeparator + name;
|
|
1942
1836
|
idSchema[name] = toIdSchemaInternal(validator, isObject(field) ? field : {}, idPrefix, idSeparator, fieldId, rootSchema,
|
|
1943
1837
|
// It's possible that formData is not an object -- this can happen if an
|
|
1944
1838
|
// array item has just been added, but not populated with data yet
|
|
@@ -1958,13 +1852,7 @@ function toIdSchemaInternal(validator, schema, idPrefix, idSeparator, id, rootSc
|
|
|
1958
1852
|
* @param [idSeparator='_'] - The separator to use for the path segments in the id
|
|
1959
1853
|
* @returns - The `IdSchema` object for the `schema`
|
|
1960
1854
|
*/
|
|
1961
|
-
function toIdSchema(validator, schema, id, rootSchema, formData, idPrefix, idSeparator) {
|
|
1962
|
-
if (idPrefix === void 0) {
|
|
1963
|
-
idPrefix = 'root';
|
|
1964
|
-
}
|
|
1965
|
-
if (idSeparator === void 0) {
|
|
1966
|
-
idSeparator = '_';
|
|
1967
|
-
}
|
|
1855
|
+
function toIdSchema(validator, schema, id, rootSchema, formData, idPrefix = 'root', idSeparator = '_') {
|
|
1968
1856
|
return toIdSchemaInternal(validator, schema, idPrefix, idSeparator, id, rootSchema, formData);
|
|
1969
1857
|
}
|
|
1970
1858
|
|
|
@@ -1979,39 +1867,38 @@ function toIdSchema(validator, schema, id, rootSchema, formData, idPrefix, idSep
|
|
|
1979
1867
|
* @param [_recurseList=[]] - The list of retrieved schemas currently being recursed, used to prevent infinite recursion
|
|
1980
1868
|
* @returns - The `PathSchema` object for the `schema`
|
|
1981
1869
|
*/
|
|
1982
|
-
function toPathSchemaInternal(validator, schema, name, rootSchema, formData, _recurseList) {
|
|
1983
|
-
var _pathSchema;
|
|
1984
|
-
if (_recurseList === void 0) {
|
|
1985
|
-
_recurseList = [];
|
|
1986
|
-
}
|
|
1870
|
+
function toPathSchemaInternal(validator, schema, name, rootSchema, formData, _recurseList = []) {
|
|
1987
1871
|
if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
return isEqual(item, _schema);
|
|
1991
|
-
});
|
|
1872
|
+
const _schema = retrieveSchema(validator, schema, rootSchema, formData);
|
|
1873
|
+
const sameSchemaIndex = _recurseList.findIndex(item => isEqual(item, _schema));
|
|
1992
1874
|
if (sameSchemaIndex === -1) {
|
|
1993
1875
|
return toPathSchemaInternal(validator, _schema, name, rootSchema, formData, _recurseList.concat(_schema));
|
|
1994
1876
|
}
|
|
1995
1877
|
}
|
|
1996
|
-
|
|
1878
|
+
let pathSchema = {
|
|
1879
|
+
[NAME_KEY]: name.replace(/^\./, '')
|
|
1880
|
+
};
|
|
1997
1881
|
if (ONE_OF_KEY in schema || ANY_OF_KEY in schema) {
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
pathSchema =
|
|
1882
|
+
const xxxOf = ONE_OF_KEY in schema ? schema.oneOf : schema.anyOf;
|
|
1883
|
+
const discriminator = getDiscriminatorFieldFromSchema(schema);
|
|
1884
|
+
const index = getClosestMatchingOption(validator, rootSchema, formData, xxxOf, 0, discriminator);
|
|
1885
|
+
const _schema = xxxOf[index];
|
|
1886
|
+
pathSchema = {
|
|
1887
|
+
...pathSchema,
|
|
1888
|
+
...toPathSchemaInternal(validator, _schema, name, rootSchema, formData, _recurseList)
|
|
1889
|
+
};
|
|
2003
1890
|
}
|
|
2004
1891
|
if (ADDITIONAL_PROPERTIES_KEY in schema && schema[ADDITIONAL_PROPERTIES_KEY] !== false) {
|
|
2005
1892
|
set(pathSchema, RJSF_ADDITONAL_PROPERTIES_FLAG, true);
|
|
2006
1893
|
}
|
|
2007
1894
|
if (ITEMS_KEY in schema && Array.isArray(formData)) {
|
|
2008
|
-
formData.forEach(
|
|
2009
|
-
pathSchema[i] = toPathSchemaInternal(validator, schema.items, name
|
|
1895
|
+
formData.forEach((element, i) => {
|
|
1896
|
+
pathSchema[i] = toPathSchemaInternal(validator, schema.items, `${name}.${i}`, rootSchema, element, _recurseList);
|
|
2010
1897
|
});
|
|
2011
1898
|
} else if (PROPERTIES_KEY in schema) {
|
|
2012
|
-
for (
|
|
2013
|
-
|
|
2014
|
-
pathSchema[property] = toPathSchemaInternal(validator, field, name
|
|
1899
|
+
for (const property in schema.properties) {
|
|
1900
|
+
const field = get(schema, [PROPERTIES_KEY, property]);
|
|
1901
|
+
pathSchema[property] = toPathSchemaInternal(validator, field, `${name}.${property}`, rootSchema,
|
|
2015
1902
|
// It's possible that formData is not an object -- this can happen if an
|
|
2016
1903
|
// array item has just been added, but not populated with data yet
|
|
2017
1904
|
get(formData, [property]), _recurseList);
|
|
@@ -2028,10 +1915,7 @@ function toPathSchemaInternal(validator, schema, name, rootSchema, formData, _re
|
|
|
2028
1915
|
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
2029
1916
|
* @returns - The `PathSchema` object for the `schema`
|
|
2030
1917
|
*/
|
|
2031
|
-
function toPathSchema(validator, schema, name, rootSchema, formData) {
|
|
2032
|
-
if (name === void 0) {
|
|
2033
|
-
name = '';
|
|
2034
|
-
}
|
|
1918
|
+
function toPathSchema(validator, schema, name = '', rootSchema, formData) {
|
|
2035
1919
|
return toPathSchemaInternal(validator, schema, name, rootSchema, formData);
|
|
2036
1920
|
}
|
|
2037
1921
|
|
|
@@ -2040,14 +1924,14 @@ function toPathSchema(validator, schema, name, rootSchema, formData) {
|
|
|
2040
1924
|
* Since these generally do not change across a `Form`, this allows for providing a simplified set of APIs to the
|
|
2041
1925
|
* `@rjsf/core` components and the various themes as well. This class implements the `SchemaUtilsType` interface.
|
|
2042
1926
|
*/
|
|
2043
|
-
|
|
1927
|
+
class SchemaUtils {
|
|
2044
1928
|
/** Constructs the `SchemaUtils` instance with the given `validator` and `rootSchema` stored as instance variables
|
|
2045
1929
|
*
|
|
2046
1930
|
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
2047
1931
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
2048
1932
|
* @param experimental_defaultFormStateBehavior - Configuration flags to allow users to override default form state behavior
|
|
2049
1933
|
*/
|
|
2050
|
-
|
|
1934
|
+
constructor(validator, rootSchema, experimental_defaultFormStateBehavior) {
|
|
2051
1935
|
this.rootSchema = void 0;
|
|
2052
1936
|
this.validator = void 0;
|
|
2053
1937
|
this.experimental_defaultFormStateBehavior = void 0;
|
|
@@ -2059,8 +1943,7 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2059
1943
|
*
|
|
2060
1944
|
* @returns - The `ValidatorType`
|
|
2061
1945
|
*/
|
|
2062
|
-
|
|
2063
|
-
_proto.getValidator = function getValidator() {
|
|
1946
|
+
getValidator() {
|
|
2064
1947
|
return this.validator;
|
|
2065
1948
|
}
|
|
2066
1949
|
/** Determines whether either the `validator` and `rootSchema` differ from the ones associated with this instance of
|
|
@@ -2071,11 +1954,8 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2071
1954
|
* @param rootSchema - The root schema that will be compared against the current one
|
|
2072
1955
|
* @param [experimental_defaultFormStateBehavior] Optional configuration object, if provided, allows users to override default form state behavior
|
|
2073
1956
|
* @returns - True if the `SchemaUtilsType` differs from the given `validator` or `rootSchema`
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
if (experimental_defaultFormStateBehavior === void 0) {
|
|
2077
|
-
experimental_defaultFormStateBehavior = {};
|
|
2078
|
-
}
|
|
1957
|
+
*/
|
|
1958
|
+
doesSchemaUtilsDiffer(validator, rootSchema, experimental_defaultFormStateBehavior = {}) {
|
|
2079
1959
|
if (!validator || !rootSchema) {
|
|
2080
1960
|
return false;
|
|
2081
1961
|
}
|
|
@@ -2090,11 +1970,8 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2090
1970
|
* If "excludeObjectChildren", pass `includeUndefinedValues` as false when computing defaults for any nested
|
|
2091
1971
|
* object properties.
|
|
2092
1972
|
* @returns - The resulting `formData` with all the defaults provided
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
if (includeUndefinedValues === void 0) {
|
|
2096
|
-
includeUndefinedValues = false;
|
|
2097
|
-
}
|
|
1973
|
+
*/
|
|
1974
|
+
getDefaultFormState(schema, formData, includeUndefinedValues = false) {
|
|
2098
1975
|
return getDefaultFormState(this.validator, schema, formData, this.rootSchema, includeUndefinedValues, this.experimental_defaultFormStateBehavior);
|
|
2099
1976
|
}
|
|
2100
1977
|
/** Determines whether the combination of `schema` and `uiSchema` properties indicates that the label for the `schema`
|
|
@@ -2104,8 +1981,8 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2104
1981
|
* @param [uiSchema] - The UI schema from which to derive potentially displayable information
|
|
2105
1982
|
* @param [globalOptions={}] - The optional Global UI Schema from which to get any fallback `xxx` options
|
|
2106
1983
|
* @returns - True if the label should be displayed or false if it should not
|
|
2107
|
-
|
|
2108
|
-
|
|
1984
|
+
*/
|
|
1985
|
+
getDisplayLabel(schema, uiSchema, globalOptions) {
|
|
2109
1986
|
return getDisplayLabel(this.validator, schema, uiSchema, this.rootSchema, globalOptions);
|
|
2110
1987
|
}
|
|
2111
1988
|
/** Determines which of the given `options` provided most closely matches the `formData`.
|
|
@@ -2120,8 +1997,8 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2120
1997
|
* @param [discriminatorField] - The optional name of the field within the options object whose value is used to
|
|
2121
1998
|
* determine which option is selected
|
|
2122
1999
|
* @returns - The index of the option that is the closest match to the `formData` or the `selectedOption` if no match
|
|
2123
|
-
|
|
2124
|
-
|
|
2000
|
+
*/
|
|
2001
|
+
getClosestMatchingOption(formData, options, selectedOption, discriminatorField) {
|
|
2125
2002
|
return getClosestMatchingOption(this.validator, this.rootSchema, formData, options, selectedOption, discriminatorField);
|
|
2126
2003
|
}
|
|
2127
2004
|
/** Given the `formData` and list of `options`, attempts to find the index of the first option that matches the data.
|
|
@@ -2132,8 +2009,8 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2132
2009
|
* @param [discriminatorField] - The optional name of the field within the options object whose value is used to
|
|
2133
2010
|
* determine which option is selected
|
|
2134
2011
|
* @returns - The firstindex of the matched option or 0 if none is available
|
|
2135
|
-
|
|
2136
|
-
|
|
2012
|
+
*/
|
|
2013
|
+
getFirstMatchingOption(formData, options, discriminatorField) {
|
|
2137
2014
|
return getFirstMatchingOption(this.validator, formData, options, this.rootSchema, discriminatorField);
|
|
2138
2015
|
}
|
|
2139
2016
|
/** Given the `formData` and list of `options`, attempts to find the index of the option that best matches the data.
|
|
@@ -2145,8 +2022,8 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2145
2022
|
* determine which option is selected
|
|
2146
2023
|
* @returns - The index of the matched option or 0 if none is available
|
|
2147
2024
|
* @deprecated
|
|
2148
|
-
|
|
2149
|
-
|
|
2025
|
+
*/
|
|
2026
|
+
getMatchingOption(formData, options, discriminatorField) {
|
|
2150
2027
|
return getMatchingOption(this.validator, formData, options, this.rootSchema, discriminatorField);
|
|
2151
2028
|
}
|
|
2152
2029
|
/** Checks to see if the `schema` and `uiSchema` combination represents an array of files
|
|
@@ -2154,24 +2031,24 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2154
2031
|
* @param schema - The schema for which check for array of files flag is desired
|
|
2155
2032
|
* @param [uiSchema] - The UI schema from which to check the widget
|
|
2156
2033
|
* @returns - True if schema/uiSchema contains an array of files, otherwise false
|
|
2157
|
-
|
|
2158
|
-
|
|
2034
|
+
*/
|
|
2035
|
+
isFilesArray(schema, uiSchema) {
|
|
2159
2036
|
return isFilesArray(this.validator, schema, uiSchema, this.rootSchema);
|
|
2160
2037
|
}
|
|
2161
2038
|
/** Checks to see if the `schema` combination represents a multi-select
|
|
2162
2039
|
*
|
|
2163
2040
|
* @param schema - The schema for which check for a multi-select flag is desired
|
|
2164
2041
|
* @returns - True if schema contains a multi-select, otherwise false
|
|
2165
|
-
|
|
2166
|
-
|
|
2042
|
+
*/
|
|
2043
|
+
isMultiSelect(schema) {
|
|
2167
2044
|
return isMultiSelect(this.validator, schema, this.rootSchema);
|
|
2168
2045
|
}
|
|
2169
2046
|
/** Checks to see if the `schema` combination represents a select
|
|
2170
2047
|
*
|
|
2171
2048
|
* @param schema - The schema for which check for a select flag is desired
|
|
2172
2049
|
* @returns - True if schema contains a select, otherwise false
|
|
2173
|
-
|
|
2174
|
-
|
|
2050
|
+
*/
|
|
2051
|
+
isSelect(schema) {
|
|
2175
2052
|
return isSelect(this.validator, schema, this.rootSchema);
|
|
2176
2053
|
}
|
|
2177
2054
|
/** Merges the errors in `additionalErrorSchema` into the existing `validationData` by combining the hierarchies in
|
|
@@ -2184,8 +2061,8 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2184
2061
|
* @returns - The `validationData` with the additional errors from `additionalErrorSchema` merged into it, if provided.
|
|
2185
2062
|
* @deprecated - Use the `validationDataMerge()` function exported from `@rjsf/utils` instead. This function will be
|
|
2186
2063
|
* removed in the next major release.
|
|
2187
|
-
|
|
2188
|
-
|
|
2064
|
+
*/
|
|
2065
|
+
mergeValidationData(validationData, additionalErrorSchema) {
|
|
2189
2066
|
return mergeValidationData(this.validator, validationData, additionalErrorSchema);
|
|
2190
2067
|
}
|
|
2191
2068
|
/** Retrieves an expanded schema that has had all of its conditions, additional properties, references and
|
|
@@ -2195,8 +2072,8 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2195
2072
|
* @param schema - The schema for which retrieving a schema is desired
|
|
2196
2073
|
* @param [rawFormData] - The current formData, if any, to assist retrieving a schema
|
|
2197
2074
|
* @returns - The schema having its conditions, additional properties, references and dependencies resolved
|
|
2198
|
-
|
|
2199
|
-
|
|
2075
|
+
*/
|
|
2076
|
+
retrieveSchema(schema, rawFormData) {
|
|
2200
2077
|
return retrieveSchema(this.validator, schema, this.rootSchema, rawFormData);
|
|
2201
2078
|
}
|
|
2202
2079
|
/** Sanitize the `data` associated with the `oldSchema` so it is considered appropriate for the `newSchema`. If the
|
|
@@ -2209,8 +2086,8 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2209
2086
|
* @param [data={}] - The form data associated with the schema, defaulting to an empty object when undefined
|
|
2210
2087
|
* @returns - The new form data, with all the fields uniquely associated with the old schema set
|
|
2211
2088
|
* to `undefined`. Will return `undefined` if the new schema is not an object containing properties.
|
|
2212
|
-
|
|
2213
|
-
|
|
2089
|
+
*/
|
|
2090
|
+
sanitizeDataForNewSchema(newSchema, oldSchema, data) {
|
|
2214
2091
|
return sanitizeDataForNewSchema(this.validator, this.rootSchema, newSchema, oldSchema, data);
|
|
2215
2092
|
}
|
|
2216
2093
|
/** Generates an `IdSchema` object for the `schema`, recursively
|
|
@@ -2221,14 +2098,8 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2221
2098
|
* @param [idPrefix='root'] - The prefix to use for the id
|
|
2222
2099
|
* @param [idSeparator='_'] - The separator to use for the path segments in the id
|
|
2223
2100
|
* @returns - The `IdSchema` object for the `schema`
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
if (idPrefix === void 0) {
|
|
2227
|
-
idPrefix = 'root';
|
|
2228
|
-
}
|
|
2229
|
-
if (idSeparator === void 0) {
|
|
2230
|
-
idSeparator = '_';
|
|
2231
|
-
}
|
|
2101
|
+
*/
|
|
2102
|
+
toIdSchema(schema, id, formData, idPrefix = 'root', idSeparator = '_') {
|
|
2232
2103
|
return toIdSchema(this.validator, schema, id, this.rootSchema, formData, idPrefix, idSeparator);
|
|
2233
2104
|
}
|
|
2234
2105
|
/** Generates an `PathSchema` object for the `schema`, recursively
|
|
@@ -2237,12 +2108,11 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2237
2108
|
* @param [name] - The base name for the schema
|
|
2238
2109
|
* @param [formData] - The current formData, if any, onto which to provide any missing defaults
|
|
2239
2110
|
* @returns - The `PathSchema` object for the `schema`
|
|
2240
|
-
|
|
2241
|
-
|
|
2111
|
+
*/
|
|
2112
|
+
toPathSchema(schema, name, formData) {
|
|
2242
2113
|
return toPathSchema(this.validator, schema, name, this.rootSchema, formData);
|
|
2243
|
-
}
|
|
2244
|
-
|
|
2245
|
-
}();
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2246
2116
|
/** Creates a `SchemaUtilsType` interface that is based around the given `validator` and `rootSchema` parameters. The
|
|
2247
2117
|
* resulting interface implementation will forward the `validator` and `rootSchema` to all the wrapped APIs.
|
|
2248
2118
|
*
|
|
@@ -2251,10 +2121,7 @@ var SchemaUtils = /*#__PURE__*/function () {
|
|
|
2251
2121
|
* @param [experimental_defaultFormStateBehavior] Optional configuration object, if provided, allows users to override default form state behavior
|
|
2252
2122
|
* @returns - An implementation of a `SchemaUtilsType` interface
|
|
2253
2123
|
*/
|
|
2254
|
-
function createSchemaUtils(validator, rootSchema, experimental_defaultFormStateBehavior) {
|
|
2255
|
-
if (experimental_defaultFormStateBehavior === void 0) {
|
|
2256
|
-
experimental_defaultFormStateBehavior = {};
|
|
2257
|
-
}
|
|
2124
|
+
function createSchemaUtils(validator, rootSchema, experimental_defaultFormStateBehavior = {}) {
|
|
2258
2125
|
return new SchemaUtils(validator, rootSchema, experimental_defaultFormStateBehavior);
|
|
2259
2126
|
}
|
|
2260
2127
|
|
|
@@ -2266,17 +2133,17 @@ function createSchemaUtils(validator, rootSchema, experimental_defaultFormStateB
|
|
|
2266
2133
|
*/
|
|
2267
2134
|
function dataURItoBlob(dataURI) {
|
|
2268
2135
|
// Split metadata from data
|
|
2269
|
-
|
|
2136
|
+
const splitted = dataURI.split(',');
|
|
2270
2137
|
// Split params
|
|
2271
|
-
|
|
2138
|
+
const params = splitted[0].split(';');
|
|
2272
2139
|
// Get mime-type from params
|
|
2273
|
-
|
|
2140
|
+
const type = params[0].replace('data:', '');
|
|
2274
2141
|
// Filter the name property from params
|
|
2275
|
-
|
|
2142
|
+
const properties = params.filter(param => {
|
|
2276
2143
|
return param.split('=')[0] === 'name';
|
|
2277
2144
|
});
|
|
2278
2145
|
// Look for the name and use unknown if no name property.
|
|
2279
|
-
|
|
2146
|
+
let name;
|
|
2280
2147
|
if (properties.length !== 1) {
|
|
2281
2148
|
name = 'unknown';
|
|
2282
2149
|
} else {
|
|
@@ -2286,18 +2153,18 @@ function dataURItoBlob(dataURI) {
|
|
|
2286
2153
|
}
|
|
2287
2154
|
// Built the Uint8Array Blob parameter from the base64 string.
|
|
2288
2155
|
try {
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
for (
|
|
2156
|
+
const binary = atob(splitted[1]);
|
|
2157
|
+
const array = [];
|
|
2158
|
+
for (let i = 0; i < binary.length; i++) {
|
|
2292
2159
|
array.push(binary.charCodeAt(i));
|
|
2293
2160
|
}
|
|
2294
2161
|
// Create the blob object
|
|
2295
|
-
|
|
2296
|
-
type
|
|
2162
|
+
const blob = new window.Blob([new Uint8Array(array)], {
|
|
2163
|
+
type
|
|
2297
2164
|
});
|
|
2298
2165
|
return {
|
|
2299
|
-
blob
|
|
2300
|
-
name
|
|
2166
|
+
blob,
|
|
2167
|
+
name
|
|
2301
2168
|
};
|
|
2302
2169
|
} catch (error) {
|
|
2303
2170
|
return {
|
|
@@ -2319,13 +2186,11 @@ function dataURItoBlob(dataURI) {
|
|
|
2319
2186
|
* @returns - The updated string with any replacement specifiers replaced
|
|
2320
2187
|
*/
|
|
2321
2188
|
function replaceStringParameters(inputString, params) {
|
|
2322
|
-
|
|
2189
|
+
let output = inputString;
|
|
2323
2190
|
if (Array.isArray(params)) {
|
|
2324
|
-
|
|
2325
|
-
params.forEach(
|
|
2326
|
-
|
|
2327
|
-
return part === "%" + (index + 1);
|
|
2328
|
-
});
|
|
2191
|
+
const parts = output.split(/(%\d)/);
|
|
2192
|
+
params.forEach((param, index) => {
|
|
2193
|
+
const partIndex = parts.findIndex(part => part === `%${index + 1}`);
|
|
2329
2194
|
if (partIndex >= 0) {
|
|
2330
2195
|
parts[partIndex] = param;
|
|
2331
2196
|
}
|
|
@@ -2358,20 +2223,13 @@ function englishStringTranslator(stringToTranslate, params) {
|
|
|
2358
2223
|
* @returns - The single or list of values specified by the single or list of indexes if they are valid. Otherwise,
|
|
2359
2224
|
* `emptyValue` or an empty list.
|
|
2360
2225
|
*/
|
|
2361
|
-
function enumOptionsValueForIndex(valueIndex, allEnumOptions, emptyValue) {
|
|
2362
|
-
if (allEnumOptions === void 0) {
|
|
2363
|
-
allEnumOptions = [];
|
|
2364
|
-
}
|
|
2226
|
+
function enumOptionsValueForIndex(valueIndex, allEnumOptions = [], emptyValue) {
|
|
2365
2227
|
if (Array.isArray(valueIndex)) {
|
|
2366
|
-
return valueIndex.map(
|
|
2367
|
-
return enumOptionsValueForIndex(index, allEnumOptions);
|
|
2368
|
-
}).filter(function (val) {
|
|
2369
|
-
return val;
|
|
2370
|
-
});
|
|
2228
|
+
return valueIndex.map(index => enumOptionsValueForIndex(index, allEnumOptions)).filter(val => val);
|
|
2371
2229
|
}
|
|
2372
2230
|
// So Number(null) and Number('') both return 0, so use emptyValue for those two values
|
|
2373
|
-
|
|
2374
|
-
|
|
2231
|
+
const index = valueIndex === '' || valueIndex === null ? -1 : Number(valueIndex);
|
|
2232
|
+
const option = allEnumOptions[index];
|
|
2375
2233
|
return option ? option.value : emptyValue;
|
|
2376
2234
|
}
|
|
2377
2235
|
|
|
@@ -2387,15 +2245,10 @@ function enumOptionsValueForIndex(valueIndex, allEnumOptions, emptyValue) {
|
|
|
2387
2245
|
* unless `selected` is a single value. In that case, if the `valueIndex` value matches `selected`, returns
|
|
2388
2246
|
* undefined, otherwise `selected`.
|
|
2389
2247
|
*/
|
|
2390
|
-
function enumOptionsDeselectValue(valueIndex, selected, allEnumOptions) {
|
|
2391
|
-
|
|
2392
|
-
allEnumOptions = [];
|
|
2393
|
-
}
|
|
2394
|
-
var value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
|
|
2248
|
+
function enumOptionsDeselectValue(valueIndex, selected, allEnumOptions = []) {
|
|
2249
|
+
const value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
|
|
2395
2250
|
if (Array.isArray(selected)) {
|
|
2396
|
-
return selected.filter(
|
|
2397
|
-
return !isEqual(v, value);
|
|
2398
|
-
});
|
|
2251
|
+
return selected.filter(v => !isEqual(v, value));
|
|
2399
2252
|
}
|
|
2400
2253
|
return isEqual(value, selected) ? undefined : selected;
|
|
2401
2254
|
}
|
|
@@ -2408,9 +2261,7 @@ function enumOptionsDeselectValue(valueIndex, selected, allEnumOptions) {
|
|
|
2408
2261
|
*/
|
|
2409
2262
|
function enumOptionsIsSelected(value, selected) {
|
|
2410
2263
|
if (Array.isArray(selected)) {
|
|
2411
|
-
return selected.some(
|
|
2412
|
-
return isEqual(sel, value);
|
|
2413
|
-
});
|
|
2264
|
+
return selected.some(sel => isEqual(sel, value));
|
|
2414
2265
|
}
|
|
2415
2266
|
return isEqual(selected, value);
|
|
2416
2267
|
}
|
|
@@ -2426,18 +2277,8 @@ function enumOptionsIsSelected(value, selected) {
|
|
|
2426
2277
|
* @returns - A single string index for the first `value` in `allEnumOptions`, if not `multiple`. Otherwise, the list
|
|
2427
2278
|
* of indexes for (each of) the value(s) in `value`.
|
|
2428
2279
|
*/
|
|
2429
|
-
function enumOptionsIndexForValue(value, allEnumOptions, multiple) {
|
|
2430
|
-
|
|
2431
|
-
allEnumOptions = [];
|
|
2432
|
-
}
|
|
2433
|
-
if (multiple === void 0) {
|
|
2434
|
-
multiple = false;
|
|
2435
|
-
}
|
|
2436
|
-
var selectedIndexes = allEnumOptions.map(function (opt, index) {
|
|
2437
|
-
return enumOptionsIsSelected(opt.value, value) ? String(index) : undefined;
|
|
2438
|
-
}).filter(function (opt) {
|
|
2439
|
-
return typeof opt !== 'undefined';
|
|
2440
|
-
});
|
|
2280
|
+
function enumOptionsIndexForValue(value, allEnumOptions = [], multiple = false) {
|
|
2281
|
+
const selectedIndexes = allEnumOptions.map((opt, index) => enumOptionsIsSelected(opt.value, value) ? String(index) : undefined).filter(opt => typeof opt !== 'undefined');
|
|
2441
2282
|
if (!multiple) {
|
|
2442
2283
|
return selectedIndexes[0];
|
|
2443
2284
|
}
|
|
@@ -2452,25 +2293,17 @@ function enumOptionsIndexForValue(value, allEnumOptions, multiple) {
|
|
|
2452
2293
|
* @param [allEnumOptions=[]] - The list of all the known enumOptions
|
|
2453
2294
|
* @returns - The updated list of selected enum values with enum value at the `valueIndex` added to it
|
|
2454
2295
|
*/
|
|
2455
|
-
function enumOptionsSelectValue(valueIndex, selected, allEnumOptions) {
|
|
2456
|
-
|
|
2457
|
-
allEnumOptions = [];
|
|
2458
|
-
}
|
|
2459
|
-
var value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
|
|
2296
|
+
function enumOptionsSelectValue(valueIndex, selected, allEnumOptions = []) {
|
|
2297
|
+
const value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
|
|
2460
2298
|
if (!isNil(value)) {
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
return val;
|
|
2467
|
-
});
|
|
2468
|
-
var updated = selected.slice(0, index).concat(value, selected.slice(index));
|
|
2299
|
+
const index = allEnumOptions.findIndex(opt => value === opt.value);
|
|
2300
|
+
const all = allEnumOptions.map(({
|
|
2301
|
+
value: val
|
|
2302
|
+
}) => val);
|
|
2303
|
+
const updated = selected.slice(0, index).concat(value, selected.slice(index));
|
|
2469
2304
|
// As inserting values at predefined index positions doesn't work with empty
|
|
2470
2305
|
// arrays, we need to reorder the updated selection to match the initial order
|
|
2471
|
-
return updated.sort(
|
|
2472
|
-
return Number(all.indexOf(a) > all.indexOf(b));
|
|
2473
|
-
});
|
|
2306
|
+
return updated.sort((a, b) => Number(all.indexOf(a) > all.indexOf(b)));
|
|
2474
2307
|
}
|
|
2475
2308
|
return selected;
|
|
2476
2309
|
}
|
|
@@ -2480,12 +2313,12 @@ function enumOptionsSelectValue(valueIndex, selected, allEnumOptions) {
|
|
|
2480
2313
|
* schema by using either dotted path or an array of path names. Once you are done building the `ErrorSchema`, you can
|
|
2481
2314
|
* get the result and/or reset all the errors back to an initial set and start again.
|
|
2482
2315
|
*/
|
|
2483
|
-
|
|
2316
|
+
class ErrorSchemaBuilder {
|
|
2484
2317
|
/** Construct an `ErrorSchemaBuilder` with an optional initial set of errors in an `ErrorSchema`.
|
|
2485
2318
|
*
|
|
2486
2319
|
* @param [initialSchema] - The optional set of initial errors, that will be cloned into the class
|
|
2487
2320
|
*/
|
|
2488
|
-
|
|
2321
|
+
constructor(initialSchema) {
|
|
2489
2322
|
/** The error schema being built
|
|
2490
2323
|
*
|
|
2491
2324
|
* @private
|
|
@@ -2495,16 +2328,18 @@ var ErrorSchemaBuilder = /*#__PURE__*/function () {
|
|
|
2495
2328
|
}
|
|
2496
2329
|
/** Returns the `ErrorSchema` that has been updated by the methods of the `ErrorSchemaBuilder`
|
|
2497
2330
|
*/
|
|
2498
|
-
|
|
2331
|
+
get ErrorSchema() {
|
|
2332
|
+
return this.errorSchema;
|
|
2333
|
+
}
|
|
2499
2334
|
/** Will get an existing `ErrorSchema` at the specified `pathOfError` or create and return one.
|
|
2500
2335
|
*
|
|
2501
2336
|
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to add the error(s)
|
|
2502
2337
|
* @returns - The error block for the given `pathOfError` or the root if not provided
|
|
2503
2338
|
* @private
|
|
2504
2339
|
*/
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2340
|
+
getOrCreateErrorBlock(pathOfError) {
|
|
2341
|
+
const hasPath = Array.isArray(pathOfError) && pathOfError.length > 0 || typeof pathOfError === 'string';
|
|
2342
|
+
let errorBlock = hasPath ? get(this.errorSchema, pathOfError) : this.errorSchema;
|
|
2508
2343
|
if (!errorBlock && pathOfError) {
|
|
2509
2344
|
errorBlock = {};
|
|
2510
2345
|
set(this.errorSchema, pathOfError, errorBlock);
|
|
@@ -2515,8 +2350,8 @@ var ErrorSchemaBuilder = /*#__PURE__*/function () {
|
|
|
2515
2350
|
*
|
|
2516
2351
|
* @param [initialSchema] - The optional set of initial errors, that will be cloned into the class
|
|
2517
2352
|
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
2518
|
-
|
|
2519
|
-
|
|
2353
|
+
*/
|
|
2354
|
+
resetAllErrors(initialSchema) {
|
|
2520
2355
|
this.errorSchema = initialSchema ? cloneDeep(initialSchema) : {};
|
|
2521
2356
|
return this;
|
|
2522
2357
|
}
|
|
@@ -2527,17 +2362,16 @@ var ErrorSchemaBuilder = /*#__PURE__*/function () {
|
|
|
2527
2362
|
* @param errorOrList - The error or list of errors to add into the `ErrorSchema`
|
|
2528
2363
|
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to add the error(s)
|
|
2529
2364
|
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2365
|
+
*/
|
|
2366
|
+
addErrors(errorOrList, pathOfError) {
|
|
2367
|
+
const errorBlock = this.getOrCreateErrorBlock(pathOfError);
|
|
2368
|
+
let errorsList = get(errorBlock, ERRORS_KEY);
|
|
2534
2369
|
if (!Array.isArray(errorsList)) {
|
|
2535
2370
|
errorsList = [];
|
|
2536
2371
|
errorBlock[ERRORS_KEY] = errorsList;
|
|
2537
2372
|
}
|
|
2538
2373
|
if (Array.isArray(errorOrList)) {
|
|
2539
|
-
|
|
2540
|
-
(_errorsList = errorsList).push.apply(_errorsList, errorOrList);
|
|
2374
|
+
errorsList.push(...errorOrList);
|
|
2541
2375
|
} else {
|
|
2542
2376
|
errorsList.push(errorOrList);
|
|
2543
2377
|
}
|
|
@@ -2550,11 +2384,11 @@ var ErrorSchemaBuilder = /*#__PURE__*/function () {
|
|
|
2550
2384
|
* @param errorOrList - The error or list of errors to set into the `ErrorSchema`
|
|
2551
2385
|
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to set the error(s)
|
|
2552
2386
|
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2387
|
+
*/
|
|
2388
|
+
setErrors(errorOrList, pathOfError) {
|
|
2389
|
+
const errorBlock = this.getOrCreateErrorBlock(pathOfError);
|
|
2556
2390
|
// Effectively clone the array being given to prevent accidental outside manipulation of the given list
|
|
2557
|
-
|
|
2391
|
+
const listToAdd = Array.isArray(errorOrList) ? [...errorOrList] : [errorOrList];
|
|
2558
2392
|
set(errorBlock, ERRORS_KEY, listToAdd);
|
|
2559
2393
|
return this;
|
|
2560
2394
|
}
|
|
@@ -2564,20 +2398,13 @@ var ErrorSchemaBuilder = /*#__PURE__*/function () {
|
|
|
2564
2398
|
*
|
|
2565
2399
|
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to clear the error(s)
|
|
2566
2400
|
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2401
|
+
*/
|
|
2402
|
+
clearErrors(pathOfError) {
|
|
2403
|
+
const errorBlock = this.getOrCreateErrorBlock(pathOfError);
|
|
2570
2404
|
set(errorBlock, ERRORS_KEY, []);
|
|
2571
2405
|
return this;
|
|
2572
|
-
}
|
|
2573
|
-
|
|
2574
|
-
key: "ErrorSchema",
|
|
2575
|
-
get: function get() {
|
|
2576
|
-
return this.errorSchema;
|
|
2577
|
-
}
|
|
2578
|
-
}]);
|
|
2579
|
-
return ErrorSchemaBuilder;
|
|
2580
|
-
}();
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2581
2408
|
|
|
2582
2409
|
/** Extracts the range spec information `{ step?: number, min?: number, max?: number }` that can be spread onto an HTML
|
|
2583
2410
|
* input from the range analog in the schema `{ multipleOf?: number, minimum?: number, maximum?: number }`.
|
|
@@ -2586,7 +2413,7 @@ var ErrorSchemaBuilder = /*#__PURE__*/function () {
|
|
|
2586
2413
|
* @returns - A range specification from the schema
|
|
2587
2414
|
*/
|
|
2588
2415
|
function rangeSpec(schema) {
|
|
2589
|
-
|
|
2416
|
+
const spec = {};
|
|
2590
2417
|
if (schema.multipleOf) {
|
|
2591
2418
|
spec.step = schema.multipleOf;
|
|
2592
2419
|
}
|
|
@@ -2607,16 +2434,11 @@ function rangeSpec(schema) {
|
|
|
2607
2434
|
* @param [autoDefaultStepAny=true] - Determines whether to auto-default step=any when the type is number and no step
|
|
2608
2435
|
* @returns - The extracted `InputPropsType` object
|
|
2609
2436
|
*/
|
|
2610
|
-
function getInputProps(schema, defaultType, options, autoDefaultStepAny) {
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
autoDefaultStepAny = true;
|
|
2616
|
-
}
|
|
2617
|
-
var inputProps = _extends({
|
|
2618
|
-
type: defaultType || 'text'
|
|
2619
|
-
}, rangeSpec(schema));
|
|
2437
|
+
function getInputProps(schema, defaultType, options = {}, autoDefaultStepAny = true) {
|
|
2438
|
+
const inputProps = {
|
|
2439
|
+
type: defaultType || 'text',
|
|
2440
|
+
...rangeSpec(schema)
|
|
2441
|
+
};
|
|
2620
2442
|
// If options.inputType is set use that as the input type
|
|
2621
2443
|
if (options.inputType) {
|
|
2622
2444
|
inputProps.type = options.inputType;
|
|
@@ -2647,7 +2469,7 @@ function getInputProps(schema, defaultType, options, autoDefaultStepAny) {
|
|
|
2647
2469
|
|
|
2648
2470
|
/** The default submit button options, exported for testing purposes
|
|
2649
2471
|
*/
|
|
2650
|
-
|
|
2472
|
+
const DEFAULT_OPTIONS = {
|
|
2651
2473
|
props: {
|
|
2652
2474
|
disabled: false
|
|
2653
2475
|
},
|
|
@@ -2659,14 +2481,14 @@ var DEFAULT_OPTIONS = {
|
|
|
2659
2481
|
* @param [uiSchema={}] - the UI Schema from which to extract submit button props
|
|
2660
2482
|
* @returns - The merging of the `DEFAULT_OPTIONS` with any custom ones
|
|
2661
2483
|
*/
|
|
2662
|
-
function getSubmitButtonOptions(uiSchema) {
|
|
2663
|
-
|
|
2664
|
-
uiSchema = {};
|
|
2665
|
-
}
|
|
2666
|
-
var uiOptions = getUiOptions(uiSchema);
|
|
2484
|
+
function getSubmitButtonOptions(uiSchema = {}) {
|
|
2485
|
+
const uiOptions = getUiOptions(uiSchema);
|
|
2667
2486
|
if (uiOptions && uiOptions[SUBMIT_BTN_OPTIONS_KEY]) {
|
|
2668
|
-
|
|
2669
|
-
return
|
|
2487
|
+
const options = uiOptions[SUBMIT_BTN_OPTIONS_KEY];
|
|
2488
|
+
return {
|
|
2489
|
+
...DEFAULT_OPTIONS,
|
|
2490
|
+
...options
|
|
2491
|
+
};
|
|
2670
2492
|
}
|
|
2671
2493
|
return DEFAULT_OPTIONS;
|
|
2672
2494
|
}
|
|
@@ -2679,11 +2501,10 @@ function getSubmitButtonOptions(uiSchema) {
|
|
|
2679
2501
|
* @param [uiOptions={}] - The `UIOptionsType` from which to read an alternate template
|
|
2680
2502
|
* @returns - The template from either the `uiSchema` or `registry` for the `name`
|
|
2681
2503
|
*/
|
|
2682
|
-
function getTemplate(name, registry, uiOptions) {
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
}
|
|
2686
|
-
var templates = registry.templates;
|
|
2504
|
+
function getTemplate(name, registry, uiOptions = {}) {
|
|
2505
|
+
const {
|
|
2506
|
+
templates
|
|
2507
|
+
} = registry;
|
|
2687
2508
|
if (name === 'ButtonTemplates') {
|
|
2688
2509
|
return templates[name];
|
|
2689
2510
|
}
|
|
@@ -2694,11 +2515,10 @@ function getTemplate(name, registry, uiOptions) {
|
|
|
2694
2515
|
);
|
|
2695
2516
|
}
|
|
2696
2517
|
|
|
2697
|
-
var _excluded = ["options"];
|
|
2698
2518
|
/** The map of schema types to widget type to widget name
|
|
2699
2519
|
*/
|
|
2700
|
-
|
|
2701
|
-
|
|
2520
|
+
const widgetMap = {
|
|
2521
|
+
boolean: {
|
|
2702
2522
|
checkbox: 'CheckboxWidget',
|
|
2703
2523
|
radio: 'RadioWidget',
|
|
2704
2524
|
select: 'SelectWidget',
|
|
@@ -2757,16 +2577,21 @@ var widgetMap = {
|
|
|
2757
2577
|
* @returns - The wrapper widget
|
|
2758
2578
|
*/
|
|
2759
2579
|
function mergeWidgetOptions(AWidget) {
|
|
2760
|
-
|
|
2580
|
+
let MergedWidget = get(AWidget, 'MergedWidget');
|
|
2761
2581
|
// cache return value as property of widget for proper react reconciliation
|
|
2762
2582
|
if (!MergedWidget) {
|
|
2763
|
-
|
|
2764
|
-
MergedWidget =
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2583
|
+
const defaultOptions = AWidget.defaultProps && AWidget.defaultProps.options || {};
|
|
2584
|
+
MergedWidget = ({
|
|
2585
|
+
options,
|
|
2586
|
+
...props
|
|
2587
|
+
}) => {
|
|
2588
|
+
return jsx(AWidget, {
|
|
2589
|
+
options: {
|
|
2590
|
+
...defaultOptions,
|
|
2591
|
+
...options
|
|
2592
|
+
},
|
|
2593
|
+
...props
|
|
2594
|
+
});
|
|
2770
2595
|
};
|
|
2771
2596
|
set(AWidget, 'MergedWidget', MergedWidget);
|
|
2772
2597
|
}
|
|
@@ -2783,31 +2608,28 @@ function mergeWidgetOptions(AWidget) {
|
|
|
2783
2608
|
* @returns - The `Widget` component to use
|
|
2784
2609
|
* @throws - An error if there is no `Widget` component that can be returned
|
|
2785
2610
|
*/
|
|
2786
|
-
function getWidget(schema, widget, registeredWidgets) {
|
|
2787
|
-
|
|
2788
|
-
registeredWidgets = {};
|
|
2789
|
-
}
|
|
2790
|
-
var type = getSchemaType(schema);
|
|
2611
|
+
function getWidget(schema, widget, registeredWidgets = {}) {
|
|
2612
|
+
const type = getSchemaType(schema);
|
|
2791
2613
|
if (typeof widget === 'function' || widget && ReactIs.isForwardRef( /*#__PURE__*/createElement(widget)) || ReactIs.isMemo(widget)) {
|
|
2792
2614
|
return mergeWidgetOptions(widget);
|
|
2793
2615
|
}
|
|
2794
2616
|
if (typeof widget !== 'string') {
|
|
2795
|
-
throw new Error(
|
|
2617
|
+
throw new Error(`Unsupported widget definition: ${typeof widget}`);
|
|
2796
2618
|
}
|
|
2797
2619
|
if (widget in registeredWidgets) {
|
|
2798
|
-
|
|
2620
|
+
const registeredWidget = registeredWidgets[widget];
|
|
2799
2621
|
return getWidget(schema, registeredWidget, registeredWidgets);
|
|
2800
2622
|
}
|
|
2801
2623
|
if (typeof type === 'string') {
|
|
2802
2624
|
if (!(type in widgetMap)) {
|
|
2803
|
-
throw new Error(
|
|
2625
|
+
throw new Error(`No widget for type '${type}'`);
|
|
2804
2626
|
}
|
|
2805
2627
|
if (widget in widgetMap[type]) {
|
|
2806
|
-
|
|
2807
|
-
return getWidget(schema,
|
|
2628
|
+
const registeredWidget = registeredWidgets[widgetMap[type][widget]];
|
|
2629
|
+
return getWidget(schema, registeredWidget, registeredWidgets);
|
|
2808
2630
|
}
|
|
2809
2631
|
}
|
|
2810
|
-
throw new Error(
|
|
2632
|
+
throw new Error(`No widget '${widget}' for type '${type}'`);
|
|
2811
2633
|
}
|
|
2812
2634
|
|
|
2813
2635
|
/** JS has no built-in hashing function, so rolling our own
|
|
@@ -2818,9 +2640,9 @@ function getWidget(schema, widget, registeredWidgets) {
|
|
|
2818
2640
|
* @returns - The resulting hash of the string in hex format
|
|
2819
2641
|
*/
|
|
2820
2642
|
function hashString(string) {
|
|
2821
|
-
|
|
2822
|
-
for (
|
|
2823
|
-
|
|
2643
|
+
let hash = 0;
|
|
2644
|
+
for (let i = 0; i < string.length; i += 1) {
|
|
2645
|
+
const chr = string.charCodeAt(i);
|
|
2824
2646
|
hash = (hash << 5) - hash + chr;
|
|
2825
2647
|
hash = hash & hash; // Convert to 32bit integer
|
|
2826
2648
|
}
|
|
@@ -2834,11 +2656,9 @@ function hashString(string) {
|
|
|
2834
2656
|
* @returns - The string obtained from the hash of the stringified schema
|
|
2835
2657
|
*/
|
|
2836
2658
|
function hashForSchema(schema) {
|
|
2837
|
-
|
|
2659
|
+
const allKeys = new Set();
|
|
2838
2660
|
// solution source: https://stackoverflow.com/questions/16167581/sort-object-properties-and-json-stringify/53593328#53593328
|
|
2839
|
-
JSON.stringify(schema,
|
|
2840
|
-
return allKeys.add(key), value;
|
|
2841
|
-
});
|
|
2661
|
+
JSON.stringify(schema, (key, value) => (allKeys.add(key), value));
|
|
2842
2662
|
return hashString(JSON.stringify(schema, Array.from(allKeys).sort()));
|
|
2843
2663
|
}
|
|
2844
2664
|
|
|
@@ -2850,15 +2670,12 @@ function hashForSchema(schema) {
|
|
|
2850
2670
|
* @param [registeredWidgets={}] - A registry of widget name to `Widget` implementation
|
|
2851
2671
|
* @returns - True if the widget exists, false otherwise
|
|
2852
2672
|
*/
|
|
2853
|
-
function hasWidget(schema, widget, registeredWidgets) {
|
|
2854
|
-
if (registeredWidgets === void 0) {
|
|
2855
|
-
registeredWidgets = {};
|
|
2856
|
-
}
|
|
2673
|
+
function hasWidget(schema, widget, registeredWidgets = {}) {
|
|
2857
2674
|
try {
|
|
2858
2675
|
getWidget(schema, widget, registeredWidgets);
|
|
2859
2676
|
return true;
|
|
2860
2677
|
} catch (e) {
|
|
2861
|
-
|
|
2678
|
+
const err = e;
|
|
2862
2679
|
if (err.message && (err.message.startsWith('No widget') || err.message.startsWith('Unsupported widget'))) {
|
|
2863
2680
|
return false;
|
|
2864
2681
|
}
|
|
@@ -2872,8 +2689,8 @@ function hasWidget(schema, widget, registeredWidgets) {
|
|
|
2872
2689
|
* @param suffix - The suffix to append to the id
|
|
2873
2690
|
*/
|
|
2874
2691
|
function idGenerator(id, suffix) {
|
|
2875
|
-
|
|
2876
|
-
return theId
|
|
2692
|
+
const theId = isString(id) ? id : id[ID_KEY];
|
|
2693
|
+
return `${theId}__${suffix}`;
|
|
2877
2694
|
}
|
|
2878
2695
|
/** Return a consistent `id` for the field description element
|
|
2879
2696
|
*
|
|
@@ -2923,12 +2740,9 @@ function titleId(id) {
|
|
|
2923
2740
|
* @param [includeExamples=false] - Optional flag, if true, will add the `examplesId` into the list
|
|
2924
2741
|
* @returns - The string containing the list of ids for use in an `aria-describedBy` attribute
|
|
2925
2742
|
*/
|
|
2926
|
-
function ariaDescribedByIds(id, includeExamples) {
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
}
|
|
2930
|
-
var examples = includeExamples ? " " + examplesId(id) : '';
|
|
2931
|
-
return errorId(id) + " " + descriptionId(id) + " " + helpId(id) + examples;
|
|
2743
|
+
function ariaDescribedByIds(id, includeExamples = false) {
|
|
2744
|
+
const examples = includeExamples ? ` ${examplesId(id)}` : '';
|
|
2745
|
+
return `${errorId(id)} ${descriptionId(id)} ${helpId(id)}${examples}`;
|
|
2932
2746
|
}
|
|
2933
2747
|
/** Return a consistent `id` for the `optionIndex`s of a `Radio` or `Checkboxes` widget
|
|
2934
2748
|
*
|
|
@@ -2937,7 +2751,7 @@ function ariaDescribedByIds(id, includeExamples) {
|
|
|
2937
2751
|
* @returns - An id for the option index based on the parent `id`
|
|
2938
2752
|
*/
|
|
2939
2753
|
function optionId(id, optionIndex) {
|
|
2940
|
-
return id
|
|
2754
|
+
return `${id}-${optionIndex}`;
|
|
2941
2755
|
}
|
|
2942
2756
|
|
|
2943
2757
|
function labelValue(label, hideLabel, fallback) {
|
|
@@ -2961,11 +2775,11 @@ function localToUTC(dateString) {
|
|
|
2961
2775
|
* @throws - Error when the schema does not have a constant value
|
|
2962
2776
|
*/
|
|
2963
2777
|
function toConstant(schema) {
|
|
2964
|
-
if (ENUM_KEY in schema && Array.isArray(schema
|
|
2965
|
-
return schema
|
|
2778
|
+
if (ENUM_KEY in schema && Array.isArray(schema.enum) && schema.enum.length === 1) {
|
|
2779
|
+
return schema.enum[0];
|
|
2966
2780
|
}
|
|
2967
2781
|
if (CONST_KEY in schema) {
|
|
2968
|
-
return schema
|
|
2782
|
+
return schema.const;
|
|
2969
2783
|
}
|
|
2970
2784
|
throw new Error('schema cannot be inferred as a constant');
|
|
2971
2785
|
}
|
|
@@ -2981,28 +2795,28 @@ function toConstant(schema) {
|
|
|
2981
2795
|
function optionsList(schema) {
|
|
2982
2796
|
// enumNames was deprecated in v5 and is intentionally omitted from the RJSFSchema type.
|
|
2983
2797
|
// Cast the type to include enumNames so the feature still works.
|
|
2984
|
-
|
|
2798
|
+
const schemaWithEnumNames = schema;
|
|
2985
2799
|
if (schemaWithEnumNames.enumNames && process.env.NODE_ENV !== 'production') {
|
|
2986
2800
|
console.warn('The enumNames property is deprecated and may be removed in a future major release.');
|
|
2987
2801
|
}
|
|
2988
|
-
if (schema
|
|
2989
|
-
return schema
|
|
2990
|
-
|
|
2802
|
+
if (schema.enum) {
|
|
2803
|
+
return schema.enum.map((value, i) => {
|
|
2804
|
+
const label = schemaWithEnumNames.enumNames && schemaWithEnumNames.enumNames[i] || String(value);
|
|
2991
2805
|
return {
|
|
2992
|
-
label
|
|
2993
|
-
value
|
|
2806
|
+
label,
|
|
2807
|
+
value
|
|
2994
2808
|
};
|
|
2995
2809
|
});
|
|
2996
2810
|
}
|
|
2997
|
-
|
|
2998
|
-
return altSchemas && altSchemas.map(
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
2811
|
+
const altSchemas = schema.oneOf || schema.anyOf;
|
|
2812
|
+
return altSchemas && altSchemas.map(aSchemaDef => {
|
|
2813
|
+
const aSchema = aSchemaDef;
|
|
2814
|
+
const value = toConstant(aSchema);
|
|
2815
|
+
const label = aSchema.title || String(value);
|
|
3002
2816
|
return {
|
|
3003
2817
|
schema: aSchema,
|
|
3004
|
-
label
|
|
3005
|
-
value
|
|
2818
|
+
label,
|
|
2819
|
+
value
|
|
3006
2820
|
};
|
|
3007
2821
|
});
|
|
3008
2822
|
}
|
|
@@ -3021,35 +2835,27 @@ function orderProperties(properties, order) {
|
|
|
3021
2835
|
if (!Array.isArray(order)) {
|
|
3022
2836
|
return properties;
|
|
3023
2837
|
}
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
var orderFiltered = order.filter(function (prop) {
|
|
3035
|
-
return prop === '*' || propertyHash[prop];
|
|
3036
|
-
});
|
|
3037
|
-
var orderHash = arrayToHash(orderFiltered);
|
|
3038
|
-
var rest = properties.filter(function (prop) {
|
|
3039
|
-
return !orderHash[prop];
|
|
3040
|
-
});
|
|
3041
|
-
var restIndex = orderFiltered.indexOf('*');
|
|
2838
|
+
const arrayToHash = arr => arr.reduce((prev, curr) => {
|
|
2839
|
+
prev[curr] = true;
|
|
2840
|
+
return prev;
|
|
2841
|
+
}, {});
|
|
2842
|
+
const errorPropList = arr => arr.length > 1 ? `properties '${arr.join("', '")}'` : `property '${arr[0]}'`;
|
|
2843
|
+
const propertyHash = arrayToHash(properties);
|
|
2844
|
+
const orderFiltered = order.filter(prop => prop === '*' || propertyHash[prop]);
|
|
2845
|
+
const orderHash = arrayToHash(orderFiltered);
|
|
2846
|
+
const rest = properties.filter(prop => !orderHash[prop]);
|
|
2847
|
+
const restIndex = orderFiltered.indexOf('*');
|
|
3042
2848
|
if (restIndex === -1) {
|
|
3043
2849
|
if (rest.length) {
|
|
3044
|
-
throw new Error(
|
|
2850
|
+
throw new Error(`uiSchema order list does not contain ${errorPropList(rest)}`);
|
|
3045
2851
|
}
|
|
3046
2852
|
return orderFiltered;
|
|
3047
2853
|
}
|
|
3048
2854
|
if (restIndex !== orderFiltered.lastIndexOf('*')) {
|
|
3049
2855
|
throw new Error('uiSchema order list contains more than one wildcard item');
|
|
3050
2856
|
}
|
|
3051
|
-
|
|
3052
|
-
complete.splice
|
|
2857
|
+
const complete = [...orderFiltered];
|
|
2858
|
+
complete.splice(restIndex, 1, ...rest);
|
|
3053
2859
|
return complete;
|
|
3054
2860
|
}
|
|
3055
2861
|
|
|
@@ -3060,7 +2866,7 @@ function orderProperties(properties, order) {
|
|
|
3060
2866
|
* @returns - The number converted to a string with leading zero padding if the number of digits is less than `width`
|
|
3061
2867
|
*/
|
|
3062
2868
|
function pad(num, width) {
|
|
3063
|
-
|
|
2869
|
+
let s = String(num);
|
|
3064
2870
|
while (s.length < width) {
|
|
3065
2871
|
s = '0' + s;
|
|
3066
2872
|
}
|
|
@@ -3074,10 +2880,7 @@ function pad(num, width) {
|
|
|
3074
2880
|
* @returns - The date string converted to a `DateObject`
|
|
3075
2881
|
* @throws - Error when the date cannot be parsed from the string
|
|
3076
2882
|
*/
|
|
3077
|
-
function parseDateString(dateString, includeTime) {
|
|
3078
|
-
if (includeTime === void 0) {
|
|
3079
|
-
includeTime = true;
|
|
3080
|
-
}
|
|
2883
|
+
function parseDateString(dateString, includeTime = true) {
|
|
3081
2884
|
if (!dateString) {
|
|
3082
2885
|
return {
|
|
3083
2886
|
year: -1,
|
|
@@ -3088,7 +2891,7 @@ function parseDateString(dateString, includeTime) {
|
|
|
3088
2891
|
second: includeTime ? -1 : 0
|
|
3089
2892
|
};
|
|
3090
2893
|
}
|
|
3091
|
-
|
|
2894
|
+
const date = new Date(dateString);
|
|
3092
2895
|
if (Number.isNaN(date.getTime())) {
|
|
3093
2896
|
throw new Error('Unable to parse date ' + dateString);
|
|
3094
2897
|
}
|
|
@@ -3113,11 +2916,11 @@ function parseDateString(dateString, includeTime) {
|
|
|
3113
2916
|
*/
|
|
3114
2917
|
function schemaRequiresTrueValue(schema) {
|
|
3115
2918
|
// Check if const is a truthy value
|
|
3116
|
-
if (schema
|
|
2919
|
+
if (schema.const) {
|
|
3117
2920
|
return true;
|
|
3118
2921
|
}
|
|
3119
2922
|
// Check if an enum has a single value of true
|
|
3120
|
-
if (schema
|
|
2923
|
+
if (schema.enum && schema.enum.length === 1 && schema.enum[0] === true) {
|
|
3121
2924
|
return true;
|
|
3122
2925
|
}
|
|
3123
2926
|
// If anyOf has a single value, evaluate the subschema
|
|
@@ -3130,9 +2933,7 @@ function schemaRequiresTrueValue(schema) {
|
|
|
3130
2933
|
}
|
|
3131
2934
|
// Evaluate each subschema in allOf, to see if one of them requires a true value
|
|
3132
2935
|
if (schema.allOf) {
|
|
3133
|
-
|
|
3134
|
-
return schemaRequiresTrueValue(subSchema);
|
|
3135
|
-
};
|
|
2936
|
+
const schemaSome = subSchema => schemaRequiresTrueValue(subSchema);
|
|
3136
2937
|
return schema.allOf.some(schemaSome);
|
|
3137
2938
|
}
|
|
3138
2939
|
return false;
|
|
@@ -3147,8 +2948,10 @@ function schemaRequiresTrueValue(schema) {
|
|
|
3147
2948
|
* @returns - True if the component should be re-rendered, false otherwise
|
|
3148
2949
|
*/
|
|
3149
2950
|
function shouldRender(component, nextProps, nextState) {
|
|
3150
|
-
|
|
3151
|
-
|
|
2951
|
+
const {
|
|
2952
|
+
props,
|
|
2953
|
+
state
|
|
2954
|
+
} = component;
|
|
3152
2955
|
return !deepEquals(props, nextProps) || !deepEquals(state, nextState);
|
|
3153
2956
|
}
|
|
3154
2957
|
|
|
@@ -3159,21 +2962,17 @@ function shouldRender(component, nextProps, nextState) {
|
|
|
3159
2962
|
* @param [time=true] - Optional flag used to remove the time portion of the date string if false
|
|
3160
2963
|
* @returns - The UTC date string
|
|
3161
2964
|
*/
|
|
3162
|
-
function toDateString(dateObject, time) {
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
_dateObject$second = dateObject.second,
|
|
3174
|
-
second = _dateObject$second === void 0 ? 0 : _dateObject$second;
|
|
3175
|
-
var utcTime = Date.UTC(year, month - 1, day, hour, minute, second);
|
|
3176
|
-
var datetime = new Date(utcTime).toJSON();
|
|
2965
|
+
function toDateString(dateObject, time = true) {
|
|
2966
|
+
const {
|
|
2967
|
+
year,
|
|
2968
|
+
month,
|
|
2969
|
+
day,
|
|
2970
|
+
hour = 0,
|
|
2971
|
+
minute = 0,
|
|
2972
|
+
second = 0
|
|
2973
|
+
} = dateObject;
|
|
2974
|
+
const utcTime = Date.UTC(year, month - 1, day, hour, minute, second);
|
|
2975
|
+
const datetime = new Date(utcTime).toJSON();
|
|
3177
2976
|
return time ? datetime : datetime.slice(0, 10);
|
|
3178
2977
|
}
|
|
3179
2978
|
|
|
@@ -3183,29 +2982,26 @@ function toDateString(dateObject, time) {
|
|
|
3183
2982
|
* @param [fieldPath=[]] - The current field path, defaults to [] if not specified
|
|
3184
2983
|
* @returns - The list of `RJSFValidationErrors` extracted from the `errorSchema`
|
|
3185
2984
|
*/
|
|
3186
|
-
function toErrorList(errorSchema, fieldPath) {
|
|
3187
|
-
if (fieldPath === void 0) {
|
|
3188
|
-
fieldPath = [];
|
|
3189
|
-
}
|
|
2985
|
+
function toErrorList(errorSchema, fieldPath = []) {
|
|
3190
2986
|
if (!errorSchema) {
|
|
3191
2987
|
return [];
|
|
3192
2988
|
}
|
|
3193
|
-
|
|
2989
|
+
let errorList = [];
|
|
3194
2990
|
if (ERRORS_KEY in errorSchema) {
|
|
3195
|
-
errorList = errorList.concat(errorSchema[ERRORS_KEY].map(
|
|
3196
|
-
|
|
2991
|
+
errorList = errorList.concat(errorSchema[ERRORS_KEY].map(message => {
|
|
2992
|
+
const property = `.${fieldPath.join('.')}`;
|
|
3197
2993
|
return {
|
|
3198
|
-
property
|
|
3199
|
-
message
|
|
3200
|
-
stack: property
|
|
2994
|
+
property,
|
|
2995
|
+
message,
|
|
2996
|
+
stack: `${property} ${message}`
|
|
3201
2997
|
};
|
|
3202
2998
|
}));
|
|
3203
2999
|
}
|
|
3204
|
-
return Object.keys(errorSchema).reduce(
|
|
3000
|
+
return Object.keys(errorSchema).reduce((acc, key) => {
|
|
3205
3001
|
if (key !== ERRORS_KEY) {
|
|
3206
|
-
|
|
3002
|
+
const childSchema = errorSchema[key];
|
|
3207
3003
|
if (isPlainObject(childSchema)) {
|
|
3208
|
-
acc = acc.concat(toErrorList(childSchema, [
|
|
3004
|
+
acc = acc.concat(toErrorList(childSchema, [...fieldPath, key]));
|
|
3209
3005
|
}
|
|
3210
3006
|
}
|
|
3211
3007
|
return acc;
|
|
@@ -3232,13 +3028,15 @@ function toErrorList(errorSchema, fieldPath) {
|
|
|
3232
3028
|
* @returns - The `ErrorSchema` built from the list of `RJSFValidationErrors`
|
|
3233
3029
|
*/
|
|
3234
3030
|
function toErrorSchema(errors) {
|
|
3235
|
-
|
|
3031
|
+
const builder = new ErrorSchemaBuilder();
|
|
3236
3032
|
if (errors.length) {
|
|
3237
|
-
errors.forEach(
|
|
3238
|
-
|
|
3239
|
-
|
|
3033
|
+
errors.forEach(error => {
|
|
3034
|
+
const {
|
|
3035
|
+
property,
|
|
3036
|
+
message
|
|
3037
|
+
} = error;
|
|
3240
3038
|
// When the property is the root element, just use an empty array for the path
|
|
3241
|
-
|
|
3039
|
+
const path = property === '.' ? [] : toPath(property);
|
|
3242
3040
|
// If the property is at the root (.level1) then toPath creates
|
|
3243
3041
|
// an empty array element at the first index. Remove it.
|
|
3244
3042
|
if (path.length > 0 && path[0] === '') {
|
|
@@ -3258,17 +3056,21 @@ function toErrorSchema(errors) {
|
|
|
3258
3056
|
* @returns - The `ErrorSchema` resulting from the stripping of the `addError()` function
|
|
3259
3057
|
*/
|
|
3260
3058
|
function unwrapErrorHandler(errorHandler) {
|
|
3261
|
-
return Object.keys(errorHandler).reduce(
|
|
3059
|
+
return Object.keys(errorHandler).reduce((acc, key) => {
|
|
3262
3060
|
if (key === 'addError') {
|
|
3263
3061
|
return acc;
|
|
3264
3062
|
} else {
|
|
3265
|
-
|
|
3266
|
-
var childSchema = errorHandler[key];
|
|
3063
|
+
const childSchema = errorHandler[key];
|
|
3267
3064
|
if (isPlainObject(childSchema)) {
|
|
3268
|
-
|
|
3269
|
-
|
|
3065
|
+
return {
|
|
3066
|
+
...acc,
|
|
3067
|
+
[key]: unwrapErrorHandler(childSchema)
|
|
3068
|
+
};
|
|
3270
3069
|
}
|
|
3271
|
-
return
|
|
3070
|
+
return {
|
|
3071
|
+
...acc,
|
|
3072
|
+
[key]: childSchema
|
|
3073
|
+
};
|
|
3272
3074
|
}
|
|
3273
3075
|
}, {});
|
|
3274
3076
|
}
|
|
@@ -3287,15 +3089,15 @@ function utcToLocal(jsonDate) {
|
|
|
3287
3089
|
// > should be a _valid local date and time string_ (not GMT)
|
|
3288
3090
|
// Note - date constructor passed local ISO-8601 does not correctly
|
|
3289
3091
|
// change time to UTC in node pre-8
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
return yyyy
|
|
3092
|
+
const date = new Date(jsonDate);
|
|
3093
|
+
const yyyy = pad(date.getFullYear(), 4);
|
|
3094
|
+
const MM = pad(date.getMonth() + 1, 2);
|
|
3095
|
+
const dd = pad(date.getDate(), 2);
|
|
3096
|
+
const hh = pad(date.getHours(), 2);
|
|
3097
|
+
const mm = pad(date.getMinutes(), 2);
|
|
3098
|
+
const ss = pad(date.getSeconds(), 2);
|
|
3099
|
+
const SSS = pad(date.getMilliseconds(), 3);
|
|
3100
|
+
return `${yyyy}-${MM}-${dd}T${hh}:${mm}:${ss}.${SSS}`;
|
|
3299
3101
|
}
|
|
3300
3102
|
|
|
3301
3103
|
/** Merges the errors in `additionalErrorSchema` into the existing `validationData` by combining the hierarchies in the
|
|
@@ -3311,17 +3113,19 @@ function validationDataMerge(validationData, additionalErrorSchema) {
|
|
|
3311
3113
|
if (!additionalErrorSchema) {
|
|
3312
3114
|
return validationData;
|
|
3313
3115
|
}
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3116
|
+
const {
|
|
3117
|
+
errors: oldErrors,
|
|
3118
|
+
errorSchema: oldErrorSchema
|
|
3119
|
+
} = validationData;
|
|
3120
|
+
let errors = toErrorList(additionalErrorSchema);
|
|
3121
|
+
let errorSchema = additionalErrorSchema;
|
|
3318
3122
|
if (!isEmpty(oldErrorSchema)) {
|
|
3319
3123
|
errorSchema = mergeObjects(oldErrorSchema, additionalErrorSchema, true);
|
|
3320
|
-
errors = [].concat(
|
|
3124
|
+
errors = [...oldErrors].concat(errors);
|
|
3321
3125
|
}
|
|
3322
3126
|
return {
|
|
3323
|
-
errorSchema
|
|
3324
|
-
errors
|
|
3127
|
+
errorSchema,
|
|
3128
|
+
errors
|
|
3325
3129
|
};
|
|
3326
3130
|
}
|
|
3327
3131
|
|
|
@@ -3331,9 +3135,9 @@ function validationDataMerge(validationData, additionalErrorSchema) {
|
|
|
3331
3135
|
* @param node - The object node to which a ROOT_SCHEMA_PREFIX is added when a REF_KEY is part of it
|
|
3332
3136
|
*/
|
|
3333
3137
|
function withIdRefPrefixObject(node) {
|
|
3334
|
-
for (
|
|
3335
|
-
|
|
3336
|
-
|
|
3138
|
+
for (const key in node) {
|
|
3139
|
+
const realObj = node;
|
|
3140
|
+
const value = realObj[key];
|
|
3337
3141
|
if (key === REF_KEY && typeof value === 'string' && value.startsWith('#')) {
|
|
3338
3142
|
realObj[key] = ROOT_SCHEMA_PREFIX + value;
|
|
3339
3143
|
} else {
|
|
@@ -3348,7 +3152,7 @@ function withIdRefPrefixObject(node) {
|
|
|
3348
3152
|
* @param node - The list of object nodes to which a ROOT_SCHEMA_PREFIX is added when a REF_KEY is part of it
|
|
3349
3153
|
*/
|
|
3350
3154
|
function withIdRefPrefixArray(node) {
|
|
3351
|
-
for (
|
|
3155
|
+
for (let i = 0; i < node.length; i++) {
|
|
3352
3156
|
node[i] = withIdRefPrefix(node[i]);
|
|
3353
3157
|
}
|
|
3354
3158
|
return node;
|
|
@@ -3360,11 +3164,13 @@ function withIdRefPrefixArray(node) {
|
|
|
3360
3164
|
* @returns - A copy of the `schemaNode` with updated `$ref`s
|
|
3361
3165
|
*/
|
|
3362
3166
|
function withIdRefPrefix(schemaNode) {
|
|
3363
|
-
if (schemaNode.constructor === Object) {
|
|
3364
|
-
return withIdRefPrefixObject(_extends({}, schemaNode));
|
|
3365
|
-
}
|
|
3366
3167
|
if (Array.isArray(schemaNode)) {
|
|
3367
|
-
return withIdRefPrefixArray([]
|
|
3168
|
+
return withIdRefPrefixArray([...schemaNode]);
|
|
3169
|
+
}
|
|
3170
|
+
if (isObject$1(schemaNode)) {
|
|
3171
|
+
return withIdRefPrefixObject({
|
|
3172
|
+
...schemaNode
|
|
3173
|
+
});
|
|
3368
3174
|
}
|
|
3369
3175
|
return schemaNode;
|
|
3370
3176
|
}
|
|
@@ -3452,13 +3258,13 @@ var TranslatableString;
|
|
|
3452
3258
|
* the hashed value of the schema. NOTE: After hashing the schema, an $id with the hash value is added to the
|
|
3453
3259
|
* schema IF that schema doesn't already have an $id, prior to putting the schema into the map.
|
|
3454
3260
|
*/
|
|
3455
|
-
|
|
3261
|
+
class ParserValidator {
|
|
3456
3262
|
/** Construct the ParserValidator for the given `rootSchema`. This `rootSchema` will be stashed in the `schemaMap`
|
|
3457
3263
|
* first.
|
|
3458
3264
|
*
|
|
3459
3265
|
* @param rootSchema - The root schema against which this validator will be executed
|
|
3460
3266
|
*/
|
|
3461
|
-
|
|
3267
|
+
constructor(rootSchema) {
|
|
3462
3268
|
/** The rootSchema provided during construction of the class */
|
|
3463
3269
|
this.rootSchema = void 0;
|
|
3464
3270
|
/** The map of schemas encountered by the ParserValidator */
|
|
@@ -3473,23 +3279,24 @@ var ParserValidator = /*#__PURE__*/function () {
|
|
|
3473
3279
|
* @param schema - The schema which is to be added to the map
|
|
3474
3280
|
* @param hash - The hash value at which to map the schema
|
|
3475
3281
|
*/
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3282
|
+
addSchema(schema, hash) {
|
|
3283
|
+
const key = get(schema, ID_KEY, hash);
|
|
3284
|
+
const identifiedSchema = {
|
|
3285
|
+
...schema,
|
|
3286
|
+
[ID_KEY]: key
|
|
3287
|
+
};
|
|
3288
|
+
const existing = this.schemaMap[key];
|
|
3482
3289
|
if (!existing) {
|
|
3483
3290
|
this.schemaMap[key] = identifiedSchema;
|
|
3484
3291
|
} else if (!isEqual(existing, identifiedSchema)) {
|
|
3485
3292
|
console.error('existing schema:', JSON.stringify(existing, null, 2));
|
|
3486
3293
|
console.error('new schema:', JSON.stringify(identifiedSchema, null, 2));
|
|
3487
|
-
throw new Error(
|
|
3294
|
+
throw new Error(`Two different schemas exist with the same key ${key}! What a bad coincidence. If possible, try adding an $id to one of the schemas`);
|
|
3488
3295
|
}
|
|
3489
3296
|
}
|
|
3490
3297
|
/** Returns the current `schemaMap` to the caller
|
|
3491
|
-
|
|
3492
|
-
|
|
3298
|
+
*/
|
|
3299
|
+
getSchemaMap() {
|
|
3493
3300
|
return this.schemaMap;
|
|
3494
3301
|
}
|
|
3495
3302
|
/** Implements the `ValidatorType` `isValid()` method to capture the `schema` in the `schemaMap`. Throws an error when
|
|
@@ -3499,8 +3306,8 @@ var ParserValidator = /*#__PURE__*/function () {
|
|
|
3499
3306
|
* @param _formData - The formData parameter that is ignored
|
|
3500
3307
|
* @param rootSchema - The root schema associated with the schema
|
|
3501
3308
|
* @throws - Error when the given `rootSchema` differs from the root schema provided during construction
|
|
3502
|
-
|
|
3503
|
-
|
|
3309
|
+
*/
|
|
3310
|
+
isValid(schema, _formData, rootSchema) {
|
|
3504
3311
|
if (!isEqual(rootSchema, this.rootSchema)) {
|
|
3505
3312
|
throw new Error('Unexpectedly calling isValid() with a rootSchema that differs from the construction rootSchema');
|
|
3506
3313
|
}
|
|
@@ -3511,16 +3318,16 @@ var ParserValidator = /*#__PURE__*/function () {
|
|
|
3511
3318
|
*
|
|
3512
3319
|
* @param _schema - The schema parameter that is ignored
|
|
3513
3320
|
* @param _formData - The formData parameter that is ignored
|
|
3514
|
-
|
|
3515
|
-
|
|
3321
|
+
*/
|
|
3322
|
+
rawValidation(_schema, _formData) {
|
|
3516
3323
|
throw new Error('Unexpectedly calling the `rawValidation()` method during schema parsing');
|
|
3517
3324
|
}
|
|
3518
3325
|
/** Implements the `ValidatorType` `toErrorList()` method to throw an error since it is never supposed to be called
|
|
3519
3326
|
*
|
|
3520
3327
|
* @param _errorSchema - The error schema parameter that is ignored
|
|
3521
3328
|
* @param _fieldPath - The field path parameter that is ignored
|
|
3522
|
-
|
|
3523
|
-
|
|
3329
|
+
*/
|
|
3330
|
+
toErrorList(_errorSchema, _fieldPath) {
|
|
3524
3331
|
throw new Error('Unexpectedly calling the `toErrorList()` method during schema parsing');
|
|
3525
3332
|
}
|
|
3526
3333
|
/** Implements the `ValidatorType` `validateFormData()` method to throw an error since it is never supposed to be
|
|
@@ -3531,12 +3338,11 @@ var ParserValidator = /*#__PURE__*/function () {
|
|
|
3531
3338
|
* @param _customValidate - The customValidate parameter that is ignored
|
|
3532
3339
|
* @param _transformErrors - The transformErrors parameter that is ignored
|
|
3533
3340
|
* @param _uiSchema - The uiSchema parameter that is ignored
|
|
3534
|
-
|
|
3535
|
-
|
|
3341
|
+
*/
|
|
3342
|
+
validateFormData(_formData, _schema, _customValidate, _transformErrors, _uiSchema) {
|
|
3536
3343
|
throw new Error('Unexpectedly calling the `validateFormData()` method during schema parsing');
|
|
3537
|
-
}
|
|
3538
|
-
|
|
3539
|
-
}();
|
|
3344
|
+
}
|
|
3345
|
+
}
|
|
3540
3346
|
|
|
3541
3347
|
/** Recursive function used to parse the given `schema` belonging to the `rootSchema`. The `validator` is used to
|
|
3542
3348
|
* capture the sub-schemas that the `isValid()` function is called with. For each schema returned by the
|
|
@@ -3549,17 +3355,15 @@ var ParserValidator = /*#__PURE__*/function () {
|
|
|
3549
3355
|
* @param schema - The current schema element being parsed
|
|
3550
3356
|
*/
|
|
3551
3357
|
function parseSchema(validator, recurseList, rootSchema, schema) {
|
|
3552
|
-
|
|
3553
|
-
schemas.forEach(
|
|
3554
|
-
|
|
3555
|
-
return isEqual(item, schema);
|
|
3556
|
-
});
|
|
3358
|
+
const schemas = retrieveSchemaInternal(validator, schema, rootSchema, undefined, true);
|
|
3359
|
+
schemas.forEach(schema => {
|
|
3360
|
+
const sameSchemaIndex = recurseList.findIndex(item => isEqual(item, schema));
|
|
3557
3361
|
if (sameSchemaIndex === -1) {
|
|
3558
3362
|
recurseList.push(schema);
|
|
3559
|
-
|
|
3560
|
-
allOptions.forEach(
|
|
3363
|
+
const allOptions = resolveAnyOrOneOfSchemas(validator, schema, rootSchema, true);
|
|
3364
|
+
allOptions.forEach(s => {
|
|
3561
3365
|
if (PROPERTIES_KEY in s && s[PROPERTIES_KEY]) {
|
|
3562
|
-
forEach(schema[PROPERTIES_KEY],
|
|
3366
|
+
forEach(schema[PROPERTIES_KEY], value => {
|
|
3563
3367
|
parseSchema(validator, recurseList, rootSchema, value);
|
|
3564
3368
|
});
|
|
3565
3369
|
}
|
|
@@ -3577,8 +3381,8 @@ function parseSchema(validator, recurseList, rootSchema, schema) {
|
|
|
3577
3381
|
* @returns - The `SchemaMap` of all schemas that were parsed
|
|
3578
3382
|
*/
|
|
3579
3383
|
function schemaParser(rootSchema) {
|
|
3580
|
-
|
|
3581
|
-
|
|
3384
|
+
const validator = new ParserValidator(rootSchema);
|
|
3385
|
+
const recurseList = [];
|
|
3582
3386
|
parseSchema(validator, recurseList, rootSchema, rootSchema);
|
|
3583
3387
|
return validator.getSchemaMap();
|
|
3584
3388
|
}
|