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