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