@rjsf/utils 5.0.0-beta.8 → 5.0.0
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 +528 -197
- package/dist/utils.cjs.development.js +1285 -827
- 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 +1263 -827
- package/dist/utils.esm.js.map +1 -1
- package/dist/utils.umd.development.js +1282 -831
- 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 +12 -12
package/dist/utils.esm.js
CHANGED
|
@@ -3,9 +3,16 @@ import get from 'lodash-es/get';
|
|
|
3
3
|
import isEmpty from 'lodash-es/isEmpty';
|
|
4
4
|
import jsonpointer from 'jsonpointer';
|
|
5
5
|
import omit from 'lodash-es/omit';
|
|
6
|
+
import has from 'lodash-es/has';
|
|
7
|
+
import isObject$1 from 'lodash-es/isObject';
|
|
8
|
+
import isString from 'lodash-es/isString';
|
|
9
|
+
import reduce from 'lodash-es/reduce';
|
|
10
|
+
import times from 'lodash-es/times';
|
|
6
11
|
import set from 'lodash-es/set';
|
|
7
12
|
import mergeAllOf from 'json-schema-merge-allof';
|
|
8
13
|
import union from 'lodash-es/union';
|
|
14
|
+
import isEqual from 'lodash-es/isEqual';
|
|
15
|
+
import cloneDeep from 'lodash-es/cloneDeep';
|
|
9
16
|
import React from 'react';
|
|
10
17
|
import ReactIs from 'react-is';
|
|
11
18
|
|
|
@@ -19,7 +26,9 @@ function isObject(thing) {
|
|
|
19
26
|
if (typeof File !== "undefined" && thing instanceof File) {
|
|
20
27
|
return false;
|
|
21
28
|
}
|
|
22
|
-
|
|
29
|
+
if (typeof Date !== "undefined" && thing instanceof Date) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
23
32
|
return typeof thing === "object" && thing !== null && !Array.isArray(thing);
|
|
24
33
|
}
|
|
25
34
|
|
|
@@ -29,12 +38,10 @@ function isObject(thing) {
|
|
|
29
38
|
* @param schema - The schema object to check
|
|
30
39
|
* @returns - True if additional items is allowed, otherwise false
|
|
31
40
|
*/
|
|
32
|
-
|
|
33
41
|
function allowAdditionalItems(schema) {
|
|
34
42
|
if (schema.additionalItems === true) {
|
|
35
43
|
console.warn("additionalItems=true is currently not supported");
|
|
36
44
|
}
|
|
37
|
-
|
|
38
45
|
return isObject(schema.additionalItems);
|
|
39
46
|
}
|
|
40
47
|
|
|
@@ -51,91 +58,141 @@ function asNumber(value) {
|
|
|
51
58
|
if (value === "") {
|
|
52
59
|
return undefined;
|
|
53
60
|
}
|
|
54
|
-
|
|
55
61
|
if (value === null) {
|
|
56
62
|
return null;
|
|
57
63
|
}
|
|
58
|
-
|
|
59
64
|
if (/\.$/.test(value)) {
|
|
60
65
|
// '3.' can't really be considered a number even if it parses in js. The
|
|
61
66
|
// user is most likely entering a float.
|
|
62
67
|
return value;
|
|
63
68
|
}
|
|
64
|
-
|
|
65
69
|
if (/\.0$/.test(value)) {
|
|
66
70
|
// we need to return this as a string here, to allow for input like 3.07
|
|
67
71
|
return value;
|
|
68
72
|
}
|
|
69
|
-
|
|
70
73
|
if (/\.\d*0$/.test(value)) {
|
|
71
74
|
// It's a number, that's cool - but we need it as a string so it doesn't screw
|
|
72
75
|
// with the user when entering dollar amounts or other values (such as those with
|
|
73
76
|
// specific precision or number of significant digits)
|
|
74
77
|
return value;
|
|
75
78
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const valid = typeof n === "number" && !Number.isNaN(n);
|
|
79
|
+
var n = Number(value);
|
|
80
|
+
var valid = typeof n === "number" && !Number.isNaN(n);
|
|
79
81
|
return valid ? n : value;
|
|
80
82
|
}
|
|
81
83
|
|
|
84
|
+
function _defineProperties(target, props) {
|
|
85
|
+
for (var i = 0; i < props.length; i++) {
|
|
86
|
+
var descriptor = props[i];
|
|
87
|
+
descriptor.enumerable = descriptor.enumerable || false;
|
|
88
|
+
descriptor.configurable = true;
|
|
89
|
+
if ("value" in descriptor) descriptor.writable = true;
|
|
90
|
+
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function _createClass(Constructor, protoProps, staticProps) {
|
|
94
|
+
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
95
|
+
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
96
|
+
Object.defineProperty(Constructor, "prototype", {
|
|
97
|
+
writable: false
|
|
98
|
+
});
|
|
99
|
+
return Constructor;
|
|
100
|
+
}
|
|
101
|
+
function _extends() {
|
|
102
|
+
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
103
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
104
|
+
var source = arguments[i];
|
|
105
|
+
for (var key in source) {
|
|
106
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
107
|
+
target[key] = source[key];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return target;
|
|
112
|
+
};
|
|
113
|
+
return _extends.apply(this, arguments);
|
|
114
|
+
}
|
|
115
|
+
function _objectDestructuringEmpty(obj) {
|
|
116
|
+
if (obj == null) throw new TypeError("Cannot destructure " + obj);
|
|
117
|
+
}
|
|
118
|
+
function _objectWithoutPropertiesLoose(source, excluded) {
|
|
119
|
+
if (source == null) return {};
|
|
120
|
+
var target = {};
|
|
121
|
+
var sourceKeys = Object.keys(source);
|
|
122
|
+
var key, i;
|
|
123
|
+
for (i = 0; i < sourceKeys.length; i++) {
|
|
124
|
+
key = sourceKeys[i];
|
|
125
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
126
|
+
target[key] = source[key];
|
|
127
|
+
}
|
|
128
|
+
return target;
|
|
129
|
+
}
|
|
130
|
+
function _toPrimitive(input, hint) {
|
|
131
|
+
if (typeof input !== "object" || input === null) return input;
|
|
132
|
+
var prim = input[Symbol.toPrimitive];
|
|
133
|
+
if (prim !== undefined) {
|
|
134
|
+
var res = prim.call(input, hint || "default");
|
|
135
|
+
if (typeof res !== "object") return res;
|
|
136
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
137
|
+
}
|
|
138
|
+
return (hint === "string" ? String : Number)(input);
|
|
139
|
+
}
|
|
140
|
+
function _toPropertyKey(arg) {
|
|
141
|
+
var key = _toPrimitive(arg, "string");
|
|
142
|
+
return typeof key === "symbol" ? key : String(key);
|
|
143
|
+
}
|
|
144
|
+
|
|
82
145
|
/** Below are the list of all the keys into various elements of a RJSFSchema or UiSchema that are used by the various
|
|
83
146
|
* utility functions. In addition to those keys, there are the special `ADDITIONAL_PROPERTY_FLAG` and
|
|
84
147
|
* `RJSF_ADDITONAL_PROPERTIES_FLAG` flags that is added to a schema under certain conditions by the `retrieveSchema()`
|
|
85
148
|
* utility.
|
|
86
149
|
*/
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
150
|
+
var ADDITIONAL_PROPERTY_FLAG = "__additional_property";
|
|
151
|
+
var ADDITIONAL_PROPERTIES_KEY = "additionalProperties";
|
|
152
|
+
var ALL_OF_KEY = "allOf";
|
|
153
|
+
var ANY_OF_KEY = "anyOf";
|
|
154
|
+
var CONST_KEY = "const";
|
|
155
|
+
var DEFAULT_KEY = "default";
|
|
156
|
+
var DEFINITIONS_KEY = "definitions";
|
|
157
|
+
var DEPENDENCIES_KEY = "dependencies";
|
|
158
|
+
var ENUM_KEY = "enum";
|
|
159
|
+
var ERRORS_KEY = "__errors";
|
|
160
|
+
var ID_KEY = "$id";
|
|
161
|
+
var ITEMS_KEY = "items";
|
|
162
|
+
var NAME_KEY = "$name";
|
|
163
|
+
var ONE_OF_KEY = "oneOf";
|
|
164
|
+
var PROPERTIES_KEY = "properties";
|
|
165
|
+
var REQUIRED_KEY = "required";
|
|
166
|
+
var SUBMIT_BTN_OPTIONS_KEY = "submitButtonOptions";
|
|
167
|
+
var REF_KEY = "$ref";
|
|
168
|
+
var RJSF_ADDITONAL_PROPERTIES_FLAG = "__rjsf_additionalProperties";
|
|
169
|
+
var UI_FIELD_KEY = "ui:field";
|
|
170
|
+
var UI_WIDGET_KEY = "ui:widget";
|
|
171
|
+
var UI_OPTIONS_KEY = "ui:options";
|
|
109
172
|
|
|
110
173
|
/** Get all passed options from ui:options, and ui:<optionName>, returning them in an object with the `ui:`
|
|
111
174
|
* stripped off.
|
|
112
175
|
*
|
|
113
176
|
* @param [uiSchema={}] - The UI Schema from which to get any `ui:xxx` options
|
|
114
|
-
* @returns - An object containing all
|
|
177
|
+
* @returns - An object containing all the `ui:xxx` options with the stripped off
|
|
115
178
|
*/
|
|
116
|
-
|
|
117
179
|
function getUiOptions(uiSchema) {
|
|
118
180
|
if (uiSchema === void 0) {
|
|
119
181
|
uiSchema = {};
|
|
120
182
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
183
|
+
return Object.keys(uiSchema).filter(function (key) {
|
|
184
|
+
return key.indexOf("ui:") === 0;
|
|
185
|
+
}).reduce(function (options, key) {
|
|
186
|
+
var _extends2;
|
|
187
|
+
var value = uiSchema[key];
|
|
125
188
|
if (key === UI_WIDGET_KEY && isObject(value)) {
|
|
126
189
|
console.error("Setting options via ui:widget object is no longer supported, use ui:options instead");
|
|
127
190
|
return options;
|
|
128
191
|
}
|
|
129
|
-
|
|
130
192
|
if (key === UI_OPTIONS_KEY && isObject(value)) {
|
|
131
|
-
return {
|
|
132
|
-
...value
|
|
133
|
-
};
|
|
193
|
+
return _extends({}, options, value);
|
|
134
194
|
}
|
|
135
|
-
|
|
136
|
-
return { ...options,
|
|
137
|
-
[key.substring(3)]: value
|
|
138
|
-
};
|
|
195
|
+
return _extends({}, options, (_extends2 = {}, _extends2[key.substring(3)] = value, _extends2));
|
|
139
196
|
}, {});
|
|
140
197
|
}
|
|
141
198
|
|
|
@@ -148,30 +205,24 @@ function getUiOptions(uiSchema) {
|
|
|
148
205
|
* @param [formData] - The formData for the field
|
|
149
206
|
* @returns - True if the schema element has additionalProperties, is expandable, and not at the maxProperties limit
|
|
150
207
|
*/
|
|
151
|
-
|
|
152
208
|
function canExpand(schema, uiSchema, formData) {
|
|
153
209
|
if (uiSchema === void 0) {
|
|
154
210
|
uiSchema = {};
|
|
155
211
|
}
|
|
156
|
-
|
|
157
212
|
if (!schema.additionalProperties) {
|
|
158
213
|
return false;
|
|
159
214
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
expandable = true
|
|
163
|
-
} = getUiOptions(uiSchema);
|
|
164
|
-
|
|
215
|
+
var _getUiOptions = getUiOptions(uiSchema),
|
|
216
|
+
_getUiOptions$expanda = _getUiOptions.expandable,
|
|
217
|
+
expandable = _getUiOptions$expanda === void 0 ? true : _getUiOptions$expanda;
|
|
165
218
|
if (expandable === false) {
|
|
166
219
|
return expandable;
|
|
167
|
-
}
|
|
220
|
+
}
|
|
221
|
+
// if ui:options.expandable was not explicitly set to false, we can add
|
|
168
222
|
// another property if we have not exceeded maxProperties yet
|
|
169
|
-
|
|
170
|
-
|
|
171
223
|
if (schema.maxProperties !== undefined && formData) {
|
|
172
224
|
return Object.keys(formData).length < schema.maxProperties;
|
|
173
225
|
}
|
|
174
|
-
|
|
175
226
|
return true;
|
|
176
227
|
}
|
|
177
228
|
|
|
@@ -182,15 +233,13 @@ function canExpand(schema, uiSchema, formData) {
|
|
|
182
233
|
* @param b - The second element to compare
|
|
183
234
|
* @returns - True if the `a` and `b` are deeply equal, false otherwise
|
|
184
235
|
*/
|
|
185
|
-
|
|
186
236
|
function deepEquals(a, b) {
|
|
187
|
-
return isEqualWith(a, b, (obj, other)
|
|
237
|
+
return isEqualWith(a, b, function (obj, other) {
|
|
188
238
|
if (typeof obj === "function" && typeof other === "function") {
|
|
189
239
|
// Assume all functions are equivalent
|
|
190
240
|
// see https://github.com/rjsf-team/react-jsonschema-form/issues/255
|
|
191
241
|
return true;
|
|
192
242
|
}
|
|
193
|
-
|
|
194
243
|
return undefined; // fallback to default isEquals behavior
|
|
195
244
|
});
|
|
196
245
|
}
|
|
@@ -203,10 +252,9 @@ function deepEquals(a, b) {
|
|
|
203
252
|
* @returns - An array with the first value being the object minus the `key` element and the second element being the
|
|
204
253
|
* value from `object[key]`
|
|
205
254
|
*/
|
|
206
|
-
|
|
207
255
|
function splitKeyElementFromObject(key, object) {
|
|
208
|
-
|
|
209
|
-
|
|
256
|
+
var value = object[key];
|
|
257
|
+
var remaining = omit(object, [key]);
|
|
210
258
|
return [remaining, value];
|
|
211
259
|
}
|
|
212
260
|
/** Given the name of a `$ref` from within a schema, using the `rootSchema`, look up and return the sub-schema using the
|
|
@@ -218,50 +266,43 @@ function splitKeyElementFromObject(key, object) {
|
|
|
218
266
|
* @returns - The sub-schema within the `rootSchema` which matches the `$ref` if it exists
|
|
219
267
|
* @throws - Error indicating that no schema for that reference exists
|
|
220
268
|
*/
|
|
221
|
-
|
|
222
269
|
function findSchemaDefinition($ref, rootSchema) {
|
|
223
270
|
if (rootSchema === void 0) {
|
|
224
271
|
rootSchema = {};
|
|
225
272
|
}
|
|
226
|
-
|
|
227
|
-
let ref = $ref || "";
|
|
228
|
-
|
|
273
|
+
var ref = $ref || "";
|
|
229
274
|
if (ref.startsWith("#")) {
|
|
230
275
|
// Decode URI fragment representation.
|
|
231
276
|
ref = decodeURIComponent(ref.substring(1));
|
|
232
277
|
} else {
|
|
233
278
|
throw new Error("Could not find a definition for " + $ref + ".");
|
|
234
279
|
}
|
|
235
|
-
|
|
236
|
-
const current = jsonpointer.get(rootSchema, ref);
|
|
237
|
-
|
|
280
|
+
var current = jsonpointer.get(rootSchema, ref);
|
|
238
281
|
if (current === undefined) {
|
|
239
282
|
throw new Error("Could not find a definition for " + $ref + ".");
|
|
240
283
|
}
|
|
241
|
-
|
|
242
284
|
if (current[REF_KEY]) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
285
|
+
var _splitKeyElementFromO = splitKeyElementFromObject(REF_KEY, current),
|
|
286
|
+
remaining = _splitKeyElementFromO[0],
|
|
287
|
+
theRef = _splitKeyElementFromO[1];
|
|
288
|
+
var subSchema = findSchemaDefinition(theRef, rootSchema);
|
|
246
289
|
if (Object.keys(remaining).length > 0) {
|
|
247
|
-
return {
|
|
248
|
-
...subSchema
|
|
249
|
-
};
|
|
290
|
+
return _extends({}, remaining, subSchema);
|
|
250
291
|
}
|
|
251
|
-
|
|
252
292
|
return subSchema;
|
|
253
293
|
}
|
|
254
|
-
|
|
255
294
|
return current;
|
|
256
295
|
}
|
|
257
296
|
|
|
258
297
|
/** Given the `formData` and list of `options`, attempts to find the index of the option that best matches the data.
|
|
298
|
+
* Deprecated, use `getFirstMatchingOption()` instead.
|
|
259
299
|
*
|
|
260
300
|
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
261
301
|
* @param formData - The current formData, if any, used to figure out a match
|
|
262
302
|
* @param options - The list of options to find a matching options from
|
|
263
303
|
* @param rootSchema - The root schema, used to primarily to look up `$ref`s
|
|
264
304
|
* @returns - The index of the matched option or 0 if none is available
|
|
305
|
+
* @deprecated
|
|
265
306
|
*/
|
|
266
307
|
function getMatchingOption(validator, formData, options, rootSchema) {
|
|
267
308
|
// For performance, skip validating subschemas if formData is undefined. We just
|
|
@@ -269,48 +310,44 @@ function getMatchingOption(validator, formData, options, rootSchema) {
|
|
|
269
310
|
if (formData === undefined) {
|
|
270
311
|
return 0;
|
|
271
312
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
313
|
+
for (var i = 0; i < options.length; i++) {
|
|
314
|
+
var option = options[i];
|
|
315
|
+
// If the schema describes an object then we need to add slightly more
|
|
275
316
|
// strict matching to the schema, because unless the schema uses the
|
|
276
317
|
// "requires" keyword, an object will match the schema as long as it
|
|
277
318
|
// doesn't have matching keys with a conflicting type. To do this we use an
|
|
278
319
|
// "anyOf" with an array of requires. This augmentation expresses that the
|
|
279
320
|
// schema should match if any of the keys in the schema are present on the
|
|
280
321
|
// object and pass validation.
|
|
281
|
-
|
|
282
322
|
if (option.properties) {
|
|
283
323
|
// Create an "anyOf" schema that requires at least one of the keys in the
|
|
284
324
|
// "properties" object
|
|
285
|
-
|
|
286
|
-
anyOf: Object.keys(option.properties).map(key
|
|
287
|
-
|
|
288
|
-
|
|
325
|
+
var requiresAnyOf = {
|
|
326
|
+
anyOf: Object.keys(option.properties).map(function (key) {
|
|
327
|
+
return {
|
|
328
|
+
required: [key]
|
|
329
|
+
};
|
|
330
|
+
})
|
|
289
331
|
};
|
|
290
|
-
|
|
291
|
-
|
|
332
|
+
var augmentedSchema = void 0;
|
|
333
|
+
// If the "anyOf" keyword already exists, wrap the augmentation in an "allOf"
|
|
292
334
|
if (option.anyOf) {
|
|
293
335
|
// Create a shallow clone of the option
|
|
294
|
-
|
|
295
|
-
} = option;
|
|
296
|
-
|
|
336
|
+
var shallowClone = _extends({}, (_objectDestructuringEmpty(option), option));
|
|
297
337
|
if (!shallowClone.allOf) {
|
|
298
338
|
shallowClone.allOf = [];
|
|
299
339
|
} else {
|
|
300
340
|
// If "allOf" already exists, shallow clone the array
|
|
301
341
|
shallowClone.allOf = shallowClone.allOf.slice();
|
|
302
342
|
}
|
|
303
|
-
|
|
304
343
|
shallowClone.allOf.push(requiresAnyOf);
|
|
305
344
|
augmentedSchema = shallowClone;
|
|
306
345
|
} else {
|
|
307
346
|
augmentedSchema = Object.assign({}, option, requiresAnyOf);
|
|
308
|
-
}
|
|
347
|
+
}
|
|
348
|
+
// Remove the "required" field as it's likely that not all fields have
|
|
309
349
|
// been filled in yet, which will mean that the schema is not valid
|
|
310
|
-
|
|
311
|
-
|
|
312
350
|
delete augmentedSchema.required;
|
|
313
|
-
|
|
314
351
|
if (validator.isValid(augmentedSchema, formData, rootSchema)) {
|
|
315
352
|
return i;
|
|
316
353
|
}
|
|
@@ -318,10 +355,22 @@ function getMatchingOption(validator, formData, options, rootSchema) {
|
|
|
318
355
|
return i;
|
|
319
356
|
}
|
|
320
357
|
}
|
|
321
|
-
|
|
322
358
|
return 0;
|
|
323
359
|
}
|
|
324
360
|
|
|
361
|
+
/** Given the `formData` and list of `options`, attempts to find the index of the first option that matches the data.
|
|
362
|
+
* Always returns the first option if there is nothing that matches.
|
|
363
|
+
*
|
|
364
|
+
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
365
|
+
* @param formData - The current formData, if any, used to figure out a match
|
|
366
|
+
* @param options - The list of options to find a matching options from
|
|
367
|
+
* @param rootSchema - The root schema, used to primarily to look up `$ref`s
|
|
368
|
+
* @returns - The index of the first matched option or 0 if none is available
|
|
369
|
+
*/
|
|
370
|
+
function getFirstMatchingOption(validator, formData, options, rootSchema) {
|
|
371
|
+
return getMatchingOption(validator, formData, options, rootSchema);
|
|
372
|
+
}
|
|
373
|
+
|
|
325
374
|
/** Given a specific `value` attempts to guess the type of a schema element. In the case where we have to implicitly
|
|
326
375
|
* create a schema, it is useful to know what type to use based on the data we are defining.
|
|
327
376
|
*
|
|
@@ -332,28 +381,22 @@ function guessType(value) {
|
|
|
332
381
|
if (Array.isArray(value)) {
|
|
333
382
|
return "array";
|
|
334
383
|
}
|
|
335
|
-
|
|
336
384
|
if (typeof value === "string") {
|
|
337
385
|
return "string";
|
|
338
386
|
}
|
|
339
|
-
|
|
340
387
|
if (value == null) {
|
|
341
388
|
return "null";
|
|
342
389
|
}
|
|
343
|
-
|
|
344
390
|
if (typeof value === "boolean") {
|
|
345
391
|
return "boolean";
|
|
346
392
|
}
|
|
347
|
-
|
|
348
393
|
if (!isNaN(value)) {
|
|
349
394
|
return "number";
|
|
350
395
|
}
|
|
351
|
-
|
|
352
396
|
if (typeof value === "object") {
|
|
353
397
|
return "object";
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
|
|
398
|
+
}
|
|
399
|
+
// Default to string if we can't figure it out
|
|
357
400
|
return "string";
|
|
358
401
|
}
|
|
359
402
|
|
|
@@ -368,121 +411,23 @@ function guessType(value) {
|
|
|
368
411
|
* @param schema - The schema for which to get the type
|
|
369
412
|
* @returns - The type of the schema
|
|
370
413
|
*/
|
|
371
|
-
|
|
372
414
|
function getSchemaType(schema) {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
if (!type && schema.const) {
|
|
378
|
-
return guessType(schema.const);
|
|
415
|
+
var type = schema.type;
|
|
416
|
+
if (!type && schema["const"]) {
|
|
417
|
+
return guessType(schema["const"]);
|
|
379
418
|
}
|
|
380
|
-
|
|
381
|
-
if (!type && schema.enum) {
|
|
419
|
+
if (!type && schema["enum"]) {
|
|
382
420
|
return "string";
|
|
383
421
|
}
|
|
384
|
-
|
|
385
422
|
if (!type && (schema.properties || schema.additionalProperties)) {
|
|
386
423
|
return "object";
|
|
387
424
|
}
|
|
388
|
-
|
|
389
425
|
if (Array.isArray(type) && type.length === 2 && type.includes("null")) {
|
|
390
|
-
type = type.find(
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
return type;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
/** Detects whether the given `schema` contains fixed items. This is the case when `schema.items` is a non-empty array
|
|
397
|
-
* that only contains objects.
|
|
398
|
-
*
|
|
399
|
-
* @param schema - The schema in which to check for fixed items
|
|
400
|
-
* @returns - True if there are fixed items in the schema, false otherwise
|
|
401
|
-
*/
|
|
402
|
-
|
|
403
|
-
function isFixedItems(schema) {
|
|
404
|
-
return Array.isArray(schema.items) && schema.items.length > 0 && schema.items.every(item => isObject(item));
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
/** Merges the `defaults` object of type `T` into the `formData` of type `T`
|
|
408
|
-
*
|
|
409
|
-
* When merging defaults and form data, we want to merge in this specific way:
|
|
410
|
-
* - objects are deeply merged
|
|
411
|
-
* - arrays are merged in such a way that:
|
|
412
|
-
* - when the array is set in form data, only array entries set in form data
|
|
413
|
-
* are deeply merged; additional entries from the defaults are ignored
|
|
414
|
-
* - when the array is not set in form data, the default is copied over
|
|
415
|
-
* - scalars are overwritten/set by form data
|
|
416
|
-
*
|
|
417
|
-
* @param defaults - The defaults to merge
|
|
418
|
-
* @param formData - The form data into which the defaults will be merged
|
|
419
|
-
* @returns - The resulting merged form data with defaults
|
|
420
|
-
*/
|
|
421
|
-
|
|
422
|
-
function mergeDefaultsWithFormData(defaults, formData) {
|
|
423
|
-
if (Array.isArray(formData)) {
|
|
424
|
-
const defaultsArray = Array.isArray(defaults) ? defaults : [];
|
|
425
|
-
const mapped = formData.map((value, idx) => {
|
|
426
|
-
if (defaultsArray[idx]) {
|
|
427
|
-
return mergeDefaultsWithFormData(defaultsArray[idx], value);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
return value;
|
|
426
|
+
type = type.find(function (type) {
|
|
427
|
+
return type !== "null";
|
|
431
428
|
});
|
|
432
|
-
return mapped;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
if (isObject(formData)) {
|
|
436
|
-
// eslint-disable-next-line no-unused-vars
|
|
437
|
-
const acc = Object.assign({}, defaults); // Prevent mutation of source object.
|
|
438
|
-
|
|
439
|
-
return Object.keys(formData).reduce((acc, key) => {
|
|
440
|
-
acc[key] = mergeDefaultsWithFormData(defaults ? get(defaults, key) : {}, get(formData, key));
|
|
441
|
-
return acc;
|
|
442
|
-
}, acc);
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
return formData;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
/** Recursively merge deeply nested objects.
|
|
449
|
-
*
|
|
450
|
-
* @param obj1 - The first object to merge
|
|
451
|
-
* @param obj2 - The second object to merge
|
|
452
|
-
* @param [concatArrays=false] - Optional flag that, when true, will cause arrays to be concatenated
|
|
453
|
-
* @returns - A new object that is the merge of the two given objects
|
|
454
|
-
*/
|
|
455
|
-
|
|
456
|
-
function mergeObjects(obj1, obj2, concatArrays) {
|
|
457
|
-
if (concatArrays === void 0) {
|
|
458
|
-
concatArrays = false;
|
|
459
429
|
}
|
|
460
|
-
|
|
461
|
-
return Object.keys(obj2).reduce((acc, key) => {
|
|
462
|
-
const left = obj1 ? obj1[key] : {},
|
|
463
|
-
right = obj2[key];
|
|
464
|
-
|
|
465
|
-
if (obj1 && key in obj1 && isObject(right)) {
|
|
466
|
-
acc[key] = mergeObjects(left, right, concatArrays);
|
|
467
|
-
} else if (concatArrays && Array.isArray(left) && Array.isArray(right)) {
|
|
468
|
-
acc[key] = left.concat(right);
|
|
469
|
-
} else {
|
|
470
|
-
acc[key] = right;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
return acc;
|
|
474
|
-
}, Object.assign({}, obj1)); // Prevent mutation of source object.
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
/** This function checks if the given `schema` matches a single constant value. This happens when either the schema has
|
|
478
|
-
* an `enum` array with a single value or there is a `const` defined.
|
|
479
|
-
*
|
|
480
|
-
* @param schema - The schema for a field
|
|
481
|
-
* @returns - True if the `schema` has a single constant value, false otherwise
|
|
482
|
-
*/
|
|
483
|
-
|
|
484
|
-
function isConstant(schema) {
|
|
485
|
-
return Array.isArray(schema.enum) && schema.enum.length === 1 || CONST_KEY in schema;
|
|
430
|
+
return type;
|
|
486
431
|
}
|
|
487
432
|
|
|
488
433
|
/** Recursively merge deeply nested schemas. The difference between `mergeSchemas` and `mergeObjects` is that
|
|
@@ -493,14 +438,11 @@ function isConstant(schema) {
|
|
|
493
438
|
* @param obj2 - The second schema object to merge
|
|
494
439
|
* @returns - The merged schema object
|
|
495
440
|
*/
|
|
496
|
-
|
|
497
441
|
function mergeSchemas(obj1, obj2) {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
right = obj2[key];
|
|
503
|
-
|
|
442
|
+
var acc = Object.assign({}, obj1); // Prevent mutation of source object.
|
|
443
|
+
return Object.keys(obj2).reduce(function (acc, key) {
|
|
444
|
+
var left = obj1 ? obj1[key] : {},
|
|
445
|
+
right = obj2[key];
|
|
504
446
|
if (obj1 && key in obj1 && isObject(right)) {
|
|
505
447
|
acc[key] = mergeSchemas(left, right);
|
|
506
448
|
} else if (obj1 && obj2 && (getSchemaType(obj1) === "object" || getSchemaType(obj2) === "object") && key === REQUIRED_KEY && Array.isArray(left) && Array.isArray(right)) {
|
|
@@ -509,124 +451,113 @@ function mergeSchemas(obj1, obj2) {
|
|
|
509
451
|
} else {
|
|
510
452
|
acc[key] = right;
|
|
511
453
|
}
|
|
512
|
-
|
|
513
454
|
return acc;
|
|
514
455
|
}, acc);
|
|
515
456
|
}
|
|
516
457
|
|
|
458
|
+
var _excluded$1 = ["if", "then", "else"],
|
|
459
|
+
_excluded2 = ["$ref"],
|
|
460
|
+
_excluded3 = ["allOf"],
|
|
461
|
+
_excluded4 = ["dependencies"],
|
|
462
|
+
_excluded5 = ["oneOf"];
|
|
517
463
|
/** Resolves a conditional block (if/else/then) by removing the condition and merging the appropriate conditional branch
|
|
518
464
|
* with the rest of the schema
|
|
519
465
|
*
|
|
520
|
-
* @param validator - An implementation of the `ValidatorType
|
|
466
|
+
* @param validator - An implementation of the `ValidatorType<T, S>` interface that is used to detect valid schema conditions
|
|
521
467
|
* @param schema - The schema for which resolving a condition is desired
|
|
522
468
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
523
|
-
* @param formData - The current formData to assist retrieving a schema
|
|
469
|
+
* @param [formData] - The current formData to assist retrieving a schema
|
|
524
470
|
* @returns - A schema with the appropriate condition resolved
|
|
525
471
|
*/
|
|
526
|
-
|
|
527
472
|
function resolveCondition(validator, schema, rootSchema, formData) {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
} = schema;
|
|
534
|
-
const conditionalSchema = validator.isValid(expression, formData, rootSchema) ? then : otherwise;
|
|
535
|
-
|
|
473
|
+
var expression = schema["if"],
|
|
474
|
+
then = schema.then,
|
|
475
|
+
otherwise = schema["else"],
|
|
476
|
+
resolvedSchemaLessConditional = _objectWithoutPropertiesLoose(schema, _excluded$1);
|
|
477
|
+
var conditionalSchema = validator.isValid(expression, formData, rootSchema) ? then : otherwise;
|
|
536
478
|
if (conditionalSchema && typeof conditionalSchema !== "boolean") {
|
|
537
479
|
return retrieveSchema(validator, mergeSchemas(resolvedSchemaLessConditional, retrieveSchema(validator, conditionalSchema, rootSchema, formData)), rootSchema, formData);
|
|
538
480
|
}
|
|
539
|
-
|
|
540
481
|
return retrieveSchema(validator, resolvedSchemaLessConditional, rootSchema, formData);
|
|
541
482
|
}
|
|
542
483
|
/** Resolves references and dependencies within a schema and its 'allOf' children.
|
|
543
484
|
* Called internally by retrieveSchema.
|
|
544
485
|
*
|
|
545
|
-
* @param validator - An implementation of the `ValidatorType
|
|
486
|
+
* @param validator - An implementation of the `ValidatorType<T, S>` interface that will be forwarded to all the APIs
|
|
546
487
|
* @param schema - The schema for which resolving a schema is desired
|
|
547
488
|
* @param [rootSchema={}] - The root schema that will be forwarded to all the APIs
|
|
548
489
|
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
549
490
|
* @returns - The schema having its references and dependencies resolved
|
|
550
491
|
*/
|
|
551
|
-
|
|
552
492
|
function resolveSchema(validator, schema, rootSchema, formData) {
|
|
553
493
|
if (rootSchema === void 0) {
|
|
554
494
|
rootSchema = {};
|
|
555
495
|
}
|
|
556
|
-
|
|
557
496
|
if (REF_KEY in schema) {
|
|
558
497
|
return resolveReference(validator, schema, rootSchema, formData);
|
|
559
498
|
}
|
|
560
|
-
|
|
561
499
|
if (DEPENDENCIES_KEY in schema) {
|
|
562
|
-
|
|
500
|
+
var resolvedSchema = resolveDependencies(validator, schema, rootSchema, formData);
|
|
563
501
|
return retrieveSchema(validator, resolvedSchema, rootSchema, formData);
|
|
564
502
|
}
|
|
565
|
-
|
|
566
503
|
if (ALL_OF_KEY in schema) {
|
|
567
|
-
return {
|
|
568
|
-
allOf: schema.allOf.map(
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
504
|
+
return _extends({}, schema, {
|
|
505
|
+
allOf: schema.allOf.map(function (allOfSubschema) {
|
|
506
|
+
return retrieveSchema(validator, allOfSubschema, rootSchema, formData);
|
|
507
|
+
})
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
// No $ref or dependencies attribute found, returning the original schema.
|
|
573
511
|
return schema;
|
|
574
512
|
}
|
|
575
513
|
/** Resolves references within a schema and its 'allOf' children.
|
|
576
514
|
*
|
|
577
|
-
* @param validator - An implementation of the `ValidatorType
|
|
515
|
+
* @param validator - An implementation of the `ValidatorType<T, S>` interface that will be forwarded to all the APIs
|
|
578
516
|
* @param schema - The schema for which resolving a reference is desired
|
|
579
517
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
580
518
|
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
581
519
|
* @returns - The schema having its references resolved
|
|
582
520
|
*/
|
|
583
|
-
|
|
584
521
|
function resolveReference(validator, schema, rootSchema, formData) {
|
|
585
522
|
// Retrieve the referenced schema definition.
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
} = schema; // Update referenced schema definition with local schema properties.
|
|
592
|
-
|
|
593
|
-
return retrieveSchema(validator, { ...$refSchema,
|
|
594
|
-
...localSchema
|
|
595
|
-
}, rootSchema, formData);
|
|
523
|
+
var $refSchema = findSchemaDefinition(schema.$ref, rootSchema);
|
|
524
|
+
// Drop the $ref property of the source schema.
|
|
525
|
+
var localSchema = _objectWithoutPropertiesLoose(schema, _excluded2);
|
|
526
|
+
// Update referenced schema definition with local schema properties.
|
|
527
|
+
return retrieveSchema(validator, _extends({}, $refSchema, localSchema), rootSchema, formData);
|
|
596
528
|
}
|
|
597
529
|
/** Creates new 'properties' items for each key in the `formData`
|
|
598
530
|
*
|
|
599
|
-
* @param validator - An implementation of the `ValidatorType
|
|
531
|
+
* @param validator - An implementation of the `ValidatorType<T, S>` interface that will be used when necessary
|
|
600
532
|
* @param theSchema - The schema for which the existing additional properties is desired
|
|
601
533
|
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s * @param validator
|
|
602
534
|
* @param [aFormData] - The current formData, if any, to assist retrieving a schema
|
|
603
535
|
* @returns - The updated schema with additional properties stubbed
|
|
604
536
|
*/
|
|
605
|
-
|
|
606
537
|
function stubExistingAdditionalProperties(validator, theSchema, rootSchema, aFormData) {
|
|
607
538
|
// Clone the schema so we don't ruin the consumer's original
|
|
608
|
-
|
|
609
|
-
properties: {
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
Object.keys(formData).forEach(key => {
|
|
539
|
+
var schema = _extends({}, theSchema, {
|
|
540
|
+
properties: _extends({}, theSchema.properties)
|
|
541
|
+
});
|
|
542
|
+
// make sure formData is an object
|
|
543
|
+
var formData = aFormData && isObject(aFormData) ? aFormData : {};
|
|
544
|
+
Object.keys(formData).forEach(function (key) {
|
|
615
545
|
if (key in schema.properties) {
|
|
616
546
|
// No need to stub, our schema already has the property
|
|
617
547
|
return;
|
|
618
548
|
}
|
|
619
|
-
|
|
620
|
-
let additionalProperties = {};
|
|
621
|
-
|
|
549
|
+
var additionalProperties = {};
|
|
622
550
|
if (typeof schema.additionalProperties !== "boolean") {
|
|
623
551
|
if (REF_KEY in schema.additionalProperties) {
|
|
624
552
|
additionalProperties = retrieveSchema(validator, {
|
|
625
553
|
$ref: get(schema.additionalProperties, [REF_KEY])
|
|
626
554
|
}, rootSchema, formData);
|
|
627
555
|
} else if ("type" in schema.additionalProperties) {
|
|
628
|
-
additionalProperties = {
|
|
629
|
-
|
|
556
|
+
additionalProperties = _extends({}, schema.additionalProperties);
|
|
557
|
+
} else if (ANY_OF_KEY in schema.additionalProperties || ONE_OF_KEY in schema.additionalProperties) {
|
|
558
|
+
additionalProperties = _extends({
|
|
559
|
+
type: "object"
|
|
560
|
+
}, schema.additionalProperties);
|
|
630
561
|
} else {
|
|
631
562
|
additionalProperties = {
|
|
632
563
|
type: guessType(get(formData, [key]))
|
|
@@ -636,11 +567,10 @@ function stubExistingAdditionalProperties(validator, theSchema, rootSchema, aFor
|
|
|
636
567
|
additionalProperties = {
|
|
637
568
|
type: guessType(get(formData, [key]))
|
|
638
569
|
};
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
570
|
+
}
|
|
571
|
+
// The type of our new key should match the additionalProperties value;
|
|
572
|
+
schema.properties[key] = additionalProperties;
|
|
573
|
+
// Set our additional property flag so we know it was dynamically added
|
|
644
574
|
set(schema.properties, [key, ADDITIONAL_PROPERTY_FLAG], true);
|
|
645
575
|
});
|
|
646
576
|
return schema;
|
|
@@ -649,132 +579,93 @@ function stubExistingAdditionalProperties(validator, theSchema, rootSchema, aFor
|
|
|
649
579
|
* resolved and merged into the `schema` given a `validator`, `rootSchema` and `rawFormData` that is used to do the
|
|
650
580
|
* potentially recursive resolution.
|
|
651
581
|
*
|
|
652
|
-
* @param validator - An implementation of the `ValidatorType
|
|
582
|
+
* @param validator - An implementation of the `ValidatorType<T, S>` interface that will be forwarded to all the APIs
|
|
653
583
|
* @param schema - The schema for which retrieving a schema is desired
|
|
654
584
|
* @param [rootSchema={}] - The root schema that will be forwarded to all the APIs
|
|
655
585
|
* @param [rawFormData] - The current formData, if any, to assist retrieving a schema
|
|
656
586
|
* @returns - The schema having its conditions, additional properties, references and dependencies resolved
|
|
657
587
|
*/
|
|
658
|
-
|
|
659
588
|
function retrieveSchema(validator, schema, rootSchema, rawFormData) {
|
|
660
589
|
if (rootSchema === void 0) {
|
|
661
590
|
rootSchema = {};
|
|
662
591
|
}
|
|
663
|
-
|
|
664
592
|
if (!isObject(schema)) {
|
|
665
593
|
return {};
|
|
666
594
|
}
|
|
667
|
-
|
|
668
|
-
let resolvedSchema = resolveSchema(validator, schema, rootSchema, rawFormData);
|
|
669
|
-
|
|
595
|
+
var resolvedSchema = resolveSchema(validator, schema, rootSchema, rawFormData);
|
|
670
596
|
if ("if" in schema) {
|
|
671
597
|
return resolveCondition(validator, schema, rootSchema, rawFormData);
|
|
672
598
|
}
|
|
673
|
-
|
|
674
|
-
const formData = rawFormData || {}; // For each level of the dependency, we need to recursively determine the appropriate resolved schema given the current state of formData.
|
|
675
|
-
// Otherwise, nested allOf subschemas will not be correctly displayed.
|
|
676
|
-
|
|
677
|
-
if (resolvedSchema.properties) {
|
|
678
|
-
const properties = {};
|
|
679
|
-
Object.entries(resolvedSchema.properties).forEach(entries => {
|
|
680
|
-
const propName = entries[0];
|
|
681
|
-
const propSchema = entries[1];
|
|
682
|
-
const rawPropData = formData[propName];
|
|
683
|
-
const propData = isObject(rawPropData) ? rawPropData : {};
|
|
684
|
-
const resolvedPropSchema = retrieveSchema(validator, propSchema, rootSchema, propData);
|
|
685
|
-
properties[propName] = resolvedPropSchema;
|
|
686
|
-
|
|
687
|
-
if (propSchema !== resolvedPropSchema && resolvedSchema.properties !== properties) {
|
|
688
|
-
resolvedSchema = { ...resolvedSchema,
|
|
689
|
-
properties
|
|
690
|
-
};
|
|
691
|
-
}
|
|
692
|
-
});
|
|
693
|
-
}
|
|
694
|
-
|
|
599
|
+
var formData = rawFormData || {};
|
|
695
600
|
if (ALL_OF_KEY in schema) {
|
|
696
601
|
try {
|
|
697
|
-
resolvedSchema = mergeAllOf(
|
|
698
|
-
|
|
602
|
+
resolvedSchema = mergeAllOf(resolvedSchema, {
|
|
603
|
+
deep: false
|
|
699
604
|
});
|
|
700
605
|
} catch (e) {
|
|
701
606
|
console.warn("could not merge subschemas in allOf:\n" + e);
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
...resolvedSchemaWithoutAllOf
|
|
705
|
-
} = resolvedSchema;
|
|
607
|
+
var _resolvedSchema = resolvedSchema,
|
|
608
|
+
resolvedSchemaWithoutAllOf = _objectWithoutPropertiesLoose(_resolvedSchema, _excluded3);
|
|
706
609
|
return resolvedSchemaWithoutAllOf;
|
|
707
610
|
}
|
|
708
611
|
}
|
|
709
|
-
|
|
710
|
-
const hasAdditionalProperties = ADDITIONAL_PROPERTIES_KEY in resolvedSchema && resolvedSchema.additionalProperties !== false;
|
|
711
|
-
|
|
612
|
+
var hasAdditionalProperties = ADDITIONAL_PROPERTIES_KEY in resolvedSchema && resolvedSchema.additionalProperties !== false;
|
|
712
613
|
if (hasAdditionalProperties) {
|
|
713
614
|
return stubExistingAdditionalProperties(validator, resolvedSchema, rootSchema, formData);
|
|
714
615
|
}
|
|
715
|
-
|
|
716
616
|
return resolvedSchema;
|
|
717
617
|
}
|
|
718
618
|
/** Resolves dependencies within a schema and its 'allOf' children.
|
|
719
619
|
*
|
|
720
|
-
* @param validator - An implementation of the `ValidatorType
|
|
620
|
+
* @param validator - An implementation of the `ValidatorType<T, S>` interface that will be forwarded to all the APIs
|
|
721
621
|
* @param schema - The schema for which resolving a dependency is desired
|
|
722
622
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
723
623
|
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
724
624
|
* @returns - The schema with its dependencies resolved
|
|
725
625
|
*/
|
|
726
|
-
|
|
727
626
|
function resolveDependencies(validator, schema, rootSchema, formData) {
|
|
728
627
|
// Drop the dependencies from the source schema.
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
} = schema;
|
|
733
|
-
let resolvedSchema = remainingSchema;
|
|
734
|
-
|
|
628
|
+
var dependencies = schema.dependencies,
|
|
629
|
+
remainingSchema = _objectWithoutPropertiesLoose(schema, _excluded4);
|
|
630
|
+
var resolvedSchema = remainingSchema;
|
|
735
631
|
if (Array.isArray(resolvedSchema.oneOf)) {
|
|
736
|
-
resolvedSchema = resolvedSchema.oneOf[
|
|
632
|
+
resolvedSchema = resolvedSchema.oneOf[getFirstMatchingOption(validator, formData, resolvedSchema.oneOf, rootSchema)];
|
|
737
633
|
} else if (Array.isArray(resolvedSchema.anyOf)) {
|
|
738
|
-
resolvedSchema = resolvedSchema.anyOf[
|
|
634
|
+
resolvedSchema = resolvedSchema.anyOf[getFirstMatchingOption(validator, formData, resolvedSchema.anyOf, rootSchema)];
|
|
739
635
|
}
|
|
740
|
-
|
|
741
636
|
return processDependencies(validator, dependencies, resolvedSchema, rootSchema, formData);
|
|
742
637
|
}
|
|
743
638
|
/** Processes all the `dependencies` recursively into the `resolvedSchema` as needed
|
|
744
639
|
*
|
|
745
|
-
* @param validator - An implementation of the `ValidatorType
|
|
640
|
+
* @param validator - An implementation of the `ValidatorType<T, S>` interface that will be forwarded to all the APIs
|
|
746
641
|
* @param dependencies - The set of dependencies that needs to be processed
|
|
747
642
|
* @param resolvedSchema - The schema for which processing dependencies is desired
|
|
748
643
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
749
644
|
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
750
645
|
* @returns - The schema with the `dependencies` resolved into it
|
|
751
646
|
*/
|
|
752
|
-
|
|
753
647
|
function processDependencies(validator, dependencies, resolvedSchema, rootSchema, formData) {
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
for (
|
|
648
|
+
var schema = resolvedSchema;
|
|
649
|
+
// Process dependencies updating the local schema properties as appropriate.
|
|
650
|
+
for (var dependencyKey in dependencies) {
|
|
757
651
|
// Skip this dependency if its trigger property is not present.
|
|
758
652
|
if (get(formData, [dependencyKey]) === undefined) {
|
|
759
653
|
continue;
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
|
|
654
|
+
}
|
|
655
|
+
// Skip this dependency if it is not included in the schema (such as when dependencyKey is itself a hidden dependency.)
|
|
763
656
|
if (schema.properties && !(dependencyKey in schema.properties)) {
|
|
764
657
|
continue;
|
|
765
658
|
}
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
659
|
+
var _splitKeyElementFromO = splitKeyElementFromObject(dependencyKey, dependencies),
|
|
660
|
+
remainingDependencies = _splitKeyElementFromO[0],
|
|
661
|
+
dependencyValue = _splitKeyElementFromO[1];
|
|
769
662
|
if (Array.isArray(dependencyValue)) {
|
|
770
663
|
schema = withDependentProperties(schema, dependencyValue);
|
|
771
664
|
} else if (isObject(dependencyValue)) {
|
|
772
665
|
schema = withDependentSchema(validator, schema, rootSchema, dependencyKey, dependencyValue, formData);
|
|
773
666
|
}
|
|
774
|
-
|
|
775
667
|
return processDependencies(validator, remainingDependencies, schema, rootSchema, formData);
|
|
776
668
|
}
|
|
777
|
-
|
|
778
669
|
return schema;
|
|
779
670
|
}
|
|
780
671
|
/** Updates a schema with additionally required properties added
|
|
@@ -783,20 +674,18 @@ function processDependencies(validator, dependencies, resolvedSchema, rootSchema
|
|
|
783
674
|
* @param [additionallyRequired] - An optional array of additionally required names
|
|
784
675
|
* @returns - The schema with the additional required values merged in
|
|
785
676
|
*/
|
|
786
|
-
|
|
787
677
|
function withDependentProperties(schema, additionallyRequired) {
|
|
788
678
|
if (!additionallyRequired) {
|
|
789
679
|
return schema;
|
|
790
680
|
}
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
return { ...schema,
|
|
681
|
+
var required = Array.isArray(schema.required) ? Array.from(new Set([].concat(schema.required, additionallyRequired))) : additionallyRequired;
|
|
682
|
+
return _extends({}, schema, {
|
|
794
683
|
required: required
|
|
795
|
-
};
|
|
684
|
+
});
|
|
796
685
|
}
|
|
797
686
|
/** Merges a dependent schema into the `schema` dealing with oneOfs and references
|
|
798
687
|
*
|
|
799
|
-
* @param validator - An implementation of the `ValidatorType
|
|
688
|
+
* @param validator - An implementation of the `ValidatorType<T, S>` interface that will be forwarded to all the APIs
|
|
800
689
|
* @param schema - The schema for which resolving a dependent schema is desired
|
|
801
690
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
802
691
|
* @param dependencyKey - The key name of the dependency
|
|
@@ -804,78 +693,301 @@ function withDependentProperties(schema, additionallyRequired) {
|
|
|
804
693
|
* @param formData- The current formData to assist retrieving a schema
|
|
805
694
|
* @returns - The schema with the dependent schema resolved into it
|
|
806
695
|
*/
|
|
807
|
-
|
|
808
696
|
function withDependentSchema(validator, schema, rootSchema, dependencyKey, dependencyValue, formData) {
|
|
809
|
-
|
|
810
|
-
oneOf,
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
697
|
+
var _retrieveSchema = retrieveSchema(validator, dependencyValue, rootSchema, formData),
|
|
698
|
+
oneOf = _retrieveSchema.oneOf,
|
|
699
|
+
dependentSchema = _objectWithoutPropertiesLoose(_retrieveSchema, _excluded5);
|
|
700
|
+
schema = mergeSchemas(schema, dependentSchema);
|
|
701
|
+
// Since it does not contain oneOf, we return the original schema.
|
|
815
702
|
if (oneOf === undefined) {
|
|
816
703
|
return schema;
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
const resolvedOneOf = oneOf.map(subschema => {
|
|
704
|
+
}
|
|
705
|
+
// Resolve $refs inside oneOf.
|
|
706
|
+
var resolvedOneOf = oneOf.map(function (subschema) {
|
|
821
707
|
if (typeof subschema === "boolean" || !(REF_KEY in subschema)) {
|
|
822
708
|
return subschema;
|
|
823
709
|
}
|
|
824
|
-
|
|
825
710
|
return resolveReference(validator, subschema, rootSchema, formData);
|
|
826
711
|
});
|
|
827
712
|
return withExactlyOneSubschema(validator, schema, rootSchema, dependencyKey, resolvedOneOf, formData);
|
|
828
713
|
}
|
|
829
714
|
/** Returns a `schema` with the best choice from the `oneOf` options merged into it
|
|
830
715
|
*
|
|
831
|
-
* @param validator - An implementation of the `ValidatorType
|
|
716
|
+
* @param validator - An implementation of the `ValidatorType<T, S>` interface that will be used to validate oneOf options
|
|
832
717
|
* @param schema - The schema for which resolving a oneOf subschema is desired
|
|
833
718
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
834
719
|
* @param dependencyKey - The key name of the oneOf dependency
|
|
835
720
|
* @param oneOf - The list of schemas representing the oneOf options
|
|
836
721
|
* @param [formData] - The current formData to assist retrieving a schema
|
|
837
|
-
* @returns The schema with best choice of oneOf schemas merged into
|
|
722
|
+
* @returns The schema with the best choice of oneOf schemas merged into
|
|
838
723
|
*/
|
|
839
|
-
|
|
840
724
|
function withExactlyOneSubschema(validator, schema, rootSchema, dependencyKey, oneOf, formData) {
|
|
841
|
-
|
|
842
|
-
if (typeof subschema === "boolean" || !subschema.properties) {
|
|
725
|
+
var validSubschemas = oneOf.filter(function (subschema) {
|
|
726
|
+
if (typeof subschema === "boolean" || !subschema || !subschema.properties) {
|
|
843
727
|
return false;
|
|
844
728
|
}
|
|
845
|
-
|
|
846
|
-
const {
|
|
847
|
-
[dependencyKey]: conditionPropertySchema
|
|
848
|
-
} = subschema.properties;
|
|
849
|
-
|
|
729
|
+
var conditionPropertySchema = subschema.properties[dependencyKey];
|
|
850
730
|
if (conditionPropertySchema) {
|
|
851
|
-
|
|
731
|
+
var _properties;
|
|
732
|
+
var conditionSchema = {
|
|
852
733
|
type: "object",
|
|
853
|
-
properties: {
|
|
854
|
-
[dependencyKey]: conditionPropertySchema
|
|
855
|
-
}
|
|
734
|
+
properties: (_properties = {}, _properties[dependencyKey] = conditionPropertySchema, _properties)
|
|
856
735
|
};
|
|
857
|
-
|
|
858
|
-
errors
|
|
859
|
-
} = validator.validateFormData(formData, conditionSchema);
|
|
736
|
+
var _validator$validateFo = validator.validateFormData(formData, conditionSchema),
|
|
737
|
+
errors = _validator$validateFo.errors;
|
|
860
738
|
return errors.length === 0;
|
|
861
739
|
}
|
|
862
|
-
|
|
863
740
|
return false;
|
|
864
741
|
});
|
|
865
|
-
|
|
866
742
|
if (validSubschemas.length !== 1) {
|
|
867
743
|
console.warn("ignoring oneOf in dependencies because there isn't exactly one subschema that is valid");
|
|
868
744
|
return schema;
|
|
869
745
|
}
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
746
|
+
var subschema = validSubschemas[0];
|
|
747
|
+
var _splitKeyElementFromO2 = splitKeyElementFromObject(dependencyKey, subschema.properties),
|
|
748
|
+
dependentSubschema = _splitKeyElementFromO2[0];
|
|
749
|
+
var dependentSchema = _extends({}, subschema, {
|
|
874
750
|
properties: dependentSubschema
|
|
875
|
-
};
|
|
751
|
+
});
|
|
876
752
|
return mergeSchemas(schema, retrieveSchema(validator, dependentSchema, rootSchema, formData));
|
|
877
753
|
}
|
|
878
754
|
|
|
755
|
+
/** A junk option used to determine when the getFirstMatchingOption call really matches an option rather than returning
|
|
756
|
+
* the first item
|
|
757
|
+
*/
|
|
758
|
+
var JUNK_OPTION = {
|
|
759
|
+
type: "object",
|
|
760
|
+
properties: {
|
|
761
|
+
__not_really_there__: {
|
|
762
|
+
type: "number"
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
};
|
|
766
|
+
/** Recursive function that calculates the score of a `formData` against the given `schema`. The computation is fairly
|
|
767
|
+
* simple. Initially the total score is 0. When `schema.properties` object exists, then all the `key/value` pairs within
|
|
768
|
+
* the object are processed as follows after obtaining the formValue from `formData` using the `key`:
|
|
769
|
+
* - If the `value` contains a `$ref`, `calculateIndexScore()` is called recursively with the formValue and the new
|
|
770
|
+
* schema that is the result of the ref in the schema being resolved and that sub-schema's resulting score is added to
|
|
771
|
+
* the total.
|
|
772
|
+
* - If the `value` contains a `oneOf` and there is a formValue, then score based on the index returned from calling
|
|
773
|
+
* `getClosestMatchingOption()` of that oneOf.
|
|
774
|
+
* - If the type of the `value` is 'object', `calculateIndexScore()` is called recursively with the formValue and the
|
|
775
|
+
* `value` itself as the sub-schema, and the score is added to the total.
|
|
776
|
+
* - If the type of the `value` matches the guessed-type of the `formValue`, the score is incremented by 1, UNLESS the
|
|
777
|
+
* value has a `default` or `const`. In those case, if the `default` or `const` and the `formValue` match, the score
|
|
778
|
+
* is incremented by another 1 otherwise it is decremented by 1.
|
|
779
|
+
*
|
|
780
|
+
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
781
|
+
* @param rootSchema - The root JSON schema of the entire form
|
|
782
|
+
* @param schema - The schema for which the score is being calculated
|
|
783
|
+
* @param formData - The form data associated with the schema, used to calculate the score
|
|
784
|
+
* @returns - The score a schema against the formData
|
|
785
|
+
*/
|
|
786
|
+
function calculateIndexScore(validator, rootSchema, schema, formData) {
|
|
787
|
+
if (formData === void 0) {
|
|
788
|
+
formData = {};
|
|
789
|
+
}
|
|
790
|
+
var totalScore = 0;
|
|
791
|
+
if (schema) {
|
|
792
|
+
if (isObject$1(schema.properties)) {
|
|
793
|
+
totalScore += reduce(schema.properties, function (score, value, key) {
|
|
794
|
+
var formValue = get(formData, key);
|
|
795
|
+
if (typeof value === "boolean") {
|
|
796
|
+
return score;
|
|
797
|
+
}
|
|
798
|
+
if (has(value, REF_KEY)) {
|
|
799
|
+
var newSchema = retrieveSchema(validator, value, rootSchema, formValue);
|
|
800
|
+
return score + calculateIndexScore(validator, rootSchema, newSchema, formValue || {});
|
|
801
|
+
}
|
|
802
|
+
if (has(value, ONE_OF_KEY) && formValue) {
|
|
803
|
+
return score + getClosestMatchingOption(validator, rootSchema, formValue, get(value, ONE_OF_KEY));
|
|
804
|
+
}
|
|
805
|
+
if (value.type === "object") {
|
|
806
|
+
return score + calculateIndexScore(validator, rootSchema, value, formValue || {});
|
|
807
|
+
}
|
|
808
|
+
if (value.type === guessType(formValue)) {
|
|
809
|
+
// If the types match, then we bump the score by one
|
|
810
|
+
var newScore = score + 1;
|
|
811
|
+
if (value["default"]) {
|
|
812
|
+
// If the schema contains a readonly default value score the value that matches the default higher and
|
|
813
|
+
// any non-matching value lower
|
|
814
|
+
newScore += formValue === value["default"] ? 1 : -1;
|
|
815
|
+
} else if (value["const"]) {
|
|
816
|
+
// If the schema contains a const value score the value that matches the default higher and
|
|
817
|
+
// any non-matching value lower
|
|
818
|
+
newScore += formValue === value["const"] ? 1 : -1;
|
|
819
|
+
}
|
|
820
|
+
// TODO eventually, deal with enums/arrays
|
|
821
|
+
return newScore;
|
|
822
|
+
}
|
|
823
|
+
return score;
|
|
824
|
+
}, 0);
|
|
825
|
+
} else if (isString(schema.type) && schema.type === guessType(formData)) {
|
|
826
|
+
totalScore += 1;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
return totalScore;
|
|
830
|
+
}
|
|
831
|
+
/** Determines which of the given `options` provided most closely matches the `formData`. Using
|
|
832
|
+
* `getFirstMatchingOption()` to match two schemas that differ only by the readOnly, default or const value of a field
|
|
833
|
+
* based on the `formData` and returns 0 when there is no match. Rather than passing in all the `options` at once to
|
|
834
|
+
* this utility, instead an array of valid option indexes is created by iterating over the list of options, call
|
|
835
|
+
* `getFirstMatchingOptions` with a list of one junk option and one good option, seeing if the good option is considered
|
|
836
|
+
* matched.
|
|
837
|
+
*
|
|
838
|
+
* Once the list of valid indexes is created, if there is only one valid index, just return it. Otherwise, if there are
|
|
839
|
+
* no valid indexes, then fill the valid indexes array with the indexes of all the options. Next, the index of the
|
|
840
|
+
* option with the highest score is determined by iterating over the list of valid options, calling
|
|
841
|
+
* `calculateIndexScore()` on each, comparing it against the current best score, and returning the index of the one that
|
|
842
|
+
* eventually has the best score.
|
|
843
|
+
*
|
|
844
|
+
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
845
|
+
* @param rootSchema - The root JSON schema of the entire form
|
|
846
|
+
* @param formData - The form data associated with the schema
|
|
847
|
+
* @param options - The list of options that can be selected from
|
|
848
|
+
* @param [selectedOption=-1] - The index of the currently selected option, defaulted to -1 if not specified
|
|
849
|
+
* @returns - The index of the option that is the closest match to the `formData` or the `selectedOption` if no match
|
|
850
|
+
*/
|
|
851
|
+
function getClosestMatchingOption(validator, rootSchema, formData, options, selectedOption) {
|
|
852
|
+
if (selectedOption === void 0) {
|
|
853
|
+
selectedOption = -1;
|
|
854
|
+
}
|
|
855
|
+
// Reduce the array of options down to a list of the indexes that are considered matching options
|
|
856
|
+
var allValidIndexes = options.reduce(function (validList, option, index) {
|
|
857
|
+
var testOptions = [JUNK_OPTION, option];
|
|
858
|
+
var match = getFirstMatchingOption(validator, formData, testOptions, rootSchema);
|
|
859
|
+
// The match is the real option, so add its index to list of valid indexes
|
|
860
|
+
if (match === 1) {
|
|
861
|
+
validList.push(index);
|
|
862
|
+
}
|
|
863
|
+
return validList;
|
|
864
|
+
}, []);
|
|
865
|
+
// There is only one valid index, so return it!
|
|
866
|
+
if (allValidIndexes.length === 1) {
|
|
867
|
+
return allValidIndexes[0];
|
|
868
|
+
}
|
|
869
|
+
if (!allValidIndexes.length) {
|
|
870
|
+
// No indexes were valid, so we'll score all the options, add all the indexes
|
|
871
|
+
times(options.length, function (i) {
|
|
872
|
+
return allValidIndexes.push(i);
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
// Score all the options in the list of valid indexes and return the index with the best score
|
|
876
|
+
var _allValidIndexes$redu = allValidIndexes.reduce(function (scoreData, index) {
|
|
877
|
+
var bestScore = scoreData.bestScore;
|
|
878
|
+
var option = options[index];
|
|
879
|
+
if (has(option, REF_KEY)) {
|
|
880
|
+
option = retrieveSchema(validator, option, rootSchema, formData);
|
|
881
|
+
}
|
|
882
|
+
var score = calculateIndexScore(validator, rootSchema, option, formData);
|
|
883
|
+
if (score > bestScore) {
|
|
884
|
+
return {
|
|
885
|
+
bestIndex: index,
|
|
886
|
+
bestScore: score
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
return scoreData;
|
|
890
|
+
}, {
|
|
891
|
+
bestIndex: selectedOption,
|
|
892
|
+
bestScore: 0
|
|
893
|
+
}),
|
|
894
|
+
bestIndex = _allValidIndexes$redu.bestIndex;
|
|
895
|
+
return bestIndex;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
/** Detects whether the given `schema` contains fixed items. This is the case when `schema.items` is a non-empty array
|
|
899
|
+
* that only contains objects.
|
|
900
|
+
*
|
|
901
|
+
* @param schema - The schema in which to check for fixed items
|
|
902
|
+
* @returns - True if there are fixed items in the schema, false otherwise
|
|
903
|
+
*/
|
|
904
|
+
function isFixedItems(schema) {
|
|
905
|
+
return Array.isArray(schema.items) && schema.items.length > 0 && schema.items.every(function (item) {
|
|
906
|
+
return isObject(item);
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
/** Merges the `defaults` object of type `T` into the `formData` of type `T`
|
|
911
|
+
*
|
|
912
|
+
* When merging defaults and form data, we want to merge in this specific way:
|
|
913
|
+
* - objects are deeply merged
|
|
914
|
+
* - arrays are merged in such a way that:
|
|
915
|
+
* - when the array is set in form data, only array entries set in form data
|
|
916
|
+
* are deeply merged; additional entries from the defaults are ignored
|
|
917
|
+
* - when the array is not set in form data, the default is copied over
|
|
918
|
+
* - scalars are overwritten/set by form data
|
|
919
|
+
*
|
|
920
|
+
* @param [defaults] - The defaults to merge
|
|
921
|
+
* @param [formData] - The form data into which the defaults will be merged
|
|
922
|
+
* @returns - The resulting merged form data with defaults
|
|
923
|
+
*/
|
|
924
|
+
function mergeDefaultsWithFormData(defaults, formData) {
|
|
925
|
+
if (Array.isArray(formData)) {
|
|
926
|
+
var defaultsArray = Array.isArray(defaults) ? defaults : [];
|
|
927
|
+
var mapped = formData.map(function (value, idx) {
|
|
928
|
+
if (defaultsArray[idx]) {
|
|
929
|
+
return mergeDefaultsWithFormData(defaultsArray[idx], value);
|
|
930
|
+
}
|
|
931
|
+
return value;
|
|
932
|
+
});
|
|
933
|
+
return mapped;
|
|
934
|
+
}
|
|
935
|
+
if (isObject(formData)) {
|
|
936
|
+
var acc = Object.assign({}, defaults); // Prevent mutation of source object.
|
|
937
|
+
return Object.keys(formData).reduce(function (acc, key) {
|
|
938
|
+
acc[key] = mergeDefaultsWithFormData(defaults ? get(defaults, key) : {}, get(formData, key));
|
|
939
|
+
return acc;
|
|
940
|
+
}, acc);
|
|
941
|
+
}
|
|
942
|
+
return formData;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
/** Recursively merge deeply nested objects.
|
|
946
|
+
*
|
|
947
|
+
* @param obj1 - The first object to merge
|
|
948
|
+
* @param obj2 - The second object to merge
|
|
949
|
+
* @param [concatArrays=false] - Optional flag that, when true, will cause arrays to be concatenated. Use
|
|
950
|
+
* "preventDuplicates" to merge arrays in a manner that prevents any duplicate entries from being merged.
|
|
951
|
+
* NOTE: Uses shallow comparison for the duplicate checking.
|
|
952
|
+
* @returns - A new object that is the merge of the two given objects
|
|
953
|
+
*/
|
|
954
|
+
function mergeObjects(obj1, obj2, concatArrays) {
|
|
955
|
+
if (concatArrays === void 0) {
|
|
956
|
+
concatArrays = false;
|
|
957
|
+
}
|
|
958
|
+
return Object.keys(obj2).reduce(function (acc, key) {
|
|
959
|
+
var left = obj1 ? obj1[key] : {},
|
|
960
|
+
right = obj2[key];
|
|
961
|
+
if (obj1 && key in obj1 && isObject(right)) {
|
|
962
|
+
acc[key] = mergeObjects(left, right, concatArrays);
|
|
963
|
+
} else if (concatArrays && Array.isArray(left) && Array.isArray(right)) {
|
|
964
|
+
var toMerge = right;
|
|
965
|
+
if (concatArrays === "preventDuplicates") {
|
|
966
|
+
toMerge = right.reduce(function (result, value) {
|
|
967
|
+
if (!left.includes(value)) {
|
|
968
|
+
result.push(value);
|
|
969
|
+
}
|
|
970
|
+
return result;
|
|
971
|
+
}, []);
|
|
972
|
+
}
|
|
973
|
+
acc[key] = left.concat(toMerge);
|
|
974
|
+
} else {
|
|
975
|
+
acc[key] = right;
|
|
976
|
+
}
|
|
977
|
+
return acc;
|
|
978
|
+
}, Object.assign({}, obj1)); // Prevent mutation of source object.
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
/** This function checks if the given `schema` matches a single constant value. This happens when either the schema has
|
|
982
|
+
* an `enum` array with a single value or there is a `const` defined.
|
|
983
|
+
*
|
|
984
|
+
* @param schema - The schema for a field
|
|
985
|
+
* @returns - True if the `schema` has a single constant value, false otherwise
|
|
986
|
+
*/
|
|
987
|
+
function isConstant(schema) {
|
|
988
|
+
return Array.isArray(schema["enum"]) && schema["enum"].length === 1 || CONST_KEY in schema;
|
|
989
|
+
}
|
|
990
|
+
|
|
879
991
|
/** Checks to see if the `schema` combination represents a select
|
|
880
992
|
*
|
|
881
993
|
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
@@ -883,23 +995,20 @@ function withExactlyOneSubschema(validator, schema, rootSchema, dependencyKey, o
|
|
|
883
995
|
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
884
996
|
* @returns - True if schema contains a select, otherwise false
|
|
885
997
|
*/
|
|
886
|
-
|
|
887
998
|
function isSelect(validator, theSchema, rootSchema) {
|
|
888
999
|
if (rootSchema === void 0) {
|
|
889
1000
|
rootSchema = {};
|
|
890
1001
|
}
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
if (Array.isArray(schema.enum)) {
|
|
1002
|
+
var schema = retrieveSchema(validator, theSchema, rootSchema, undefined);
|
|
1003
|
+
var altSchemas = schema.oneOf || schema.anyOf;
|
|
1004
|
+
if (Array.isArray(schema["enum"])) {
|
|
896
1005
|
return true;
|
|
897
1006
|
}
|
|
898
|
-
|
|
899
1007
|
if (Array.isArray(altSchemas)) {
|
|
900
|
-
return altSchemas.every(
|
|
1008
|
+
return altSchemas.every(function (altSchemas) {
|
|
1009
|
+
return typeof altSchemas !== "boolean" && isConstant(altSchemas);
|
|
1010
|
+
});
|
|
901
1011
|
}
|
|
902
|
-
|
|
903
1012
|
return false;
|
|
904
1013
|
}
|
|
905
1014
|
|
|
@@ -910,20 +1019,16 @@ function isSelect(validator, theSchema, rootSchema) {
|
|
|
910
1019
|
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
911
1020
|
* @returns - True if schema contains a multi-select, otherwise false
|
|
912
1021
|
*/
|
|
913
|
-
|
|
914
1022
|
function isMultiSelect(validator, schema, rootSchema) {
|
|
915
1023
|
if (!schema.uniqueItems || !schema.items || typeof schema.items === "boolean") {
|
|
916
1024
|
return false;
|
|
917
1025
|
}
|
|
918
|
-
|
|
919
1026
|
return isSelect(validator, schema.items, rootSchema);
|
|
920
1027
|
}
|
|
921
1028
|
|
|
922
1029
|
/** Enum that indicates how `schema.additionalItems` should be handled by the `getInnerSchemaForArrayItem()` function.
|
|
923
1030
|
*/
|
|
924
|
-
|
|
925
1031
|
var AdditionalItemsHandling;
|
|
926
|
-
|
|
927
1032
|
(function (AdditionalItemsHandling) {
|
|
928
1033
|
AdditionalItemsHandling[AdditionalItemsHandling["Ignore"] = 0] = "Ignore";
|
|
929
1034
|
AdditionalItemsHandling[AdditionalItemsHandling["Invert"] = 1] = "Invert";
|
|
@@ -944,21 +1049,16 @@ var AdditionalItemsHandling;
|
|
|
944
1049
|
* @param [idx=-1] - Index, if non-negative, will be used to return the idx-th element in a `schema.items` array
|
|
945
1050
|
* @returns - The best fit schema object from the `schema` given the `additionalItems` and `idx` modifiers
|
|
946
1051
|
*/
|
|
947
|
-
|
|
948
|
-
|
|
949
1052
|
function getInnerSchemaForArrayItem(schema, additionalItems, idx) {
|
|
950
1053
|
if (additionalItems === void 0) {
|
|
951
1054
|
additionalItems = AdditionalItemsHandling.Ignore;
|
|
952
1055
|
}
|
|
953
|
-
|
|
954
1056
|
if (idx === void 0) {
|
|
955
1057
|
idx = -1;
|
|
956
1058
|
}
|
|
957
|
-
|
|
958
1059
|
if (idx >= 0) {
|
|
959
1060
|
if (Array.isArray(schema.items) && idx < schema.items.length) {
|
|
960
|
-
|
|
961
|
-
|
|
1061
|
+
var item = schema.items[idx];
|
|
962
1062
|
if (typeof item !== "boolean") {
|
|
963
1063
|
return item;
|
|
964
1064
|
}
|
|
@@ -966,11 +1066,9 @@ function getInnerSchemaForArrayItem(schema, additionalItems, idx) {
|
|
|
966
1066
|
} else if (schema.items && !Array.isArray(schema.items) && typeof schema.items !== "boolean") {
|
|
967
1067
|
return schema.items;
|
|
968
1068
|
}
|
|
969
|
-
|
|
970
1069
|
if (additionalItems !== AdditionalItemsHandling.Ignore && isObject(schema.additionalItems)) {
|
|
971
1070
|
return schema.additionalItems;
|
|
972
1071
|
}
|
|
973
|
-
|
|
974
1072
|
return {};
|
|
975
1073
|
}
|
|
976
1074
|
/** Computes the defaults for the current `schema` given the `rawFormData` and `parentDefaults` if any. This drills into
|
|
@@ -981,101 +1079,99 @@ function getInnerSchemaForArrayItem(schema, additionalItems, idx) {
|
|
|
981
1079
|
* @param [parentDefaults] - Any defaults provided by the parent field in the schema
|
|
982
1080
|
* @param [rootSchema] - The options root schema, used to primarily to look up `$ref`s
|
|
983
1081
|
* @param [rawFormData] - The current formData, if any, onto which to provide any missing defaults
|
|
984
|
-
* @param [includeUndefinedValues=false] - Optional flag, if true, cause undefined values to be added as defaults
|
|
1082
|
+
* @param [includeUndefinedValues=false] - Optional flag, if true, cause undefined values to be added as defaults.
|
|
1083
|
+
* If "excludeObjectChildren", pass `includeUndefinedValues` as false when computing defaults for any nested
|
|
1084
|
+
* object properties.
|
|
985
1085
|
* @returns - The resulting `formData` with all the defaults provided
|
|
986
1086
|
*/
|
|
987
|
-
|
|
988
|
-
function computeDefaults(validator, schema, parentDefaults, rootSchema, rawFormData, includeUndefinedValues) {
|
|
1087
|
+
function computeDefaults(validator, rawSchema, parentDefaults, rootSchema, rawFormData, includeUndefinedValues) {
|
|
989
1088
|
if (rootSchema === void 0) {
|
|
990
1089
|
rootSchema = {};
|
|
991
1090
|
}
|
|
992
|
-
|
|
993
1091
|
if (includeUndefinedValues === void 0) {
|
|
994
1092
|
includeUndefinedValues = false;
|
|
995
1093
|
}
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
if (isObject(defaults) && isObject(schema.default)) {
|
|
1094
|
+
var formData = isObject(rawFormData) ? rawFormData : {};
|
|
1095
|
+
var schema = isObject(rawSchema) ? rawSchema : {};
|
|
1096
|
+
// Compute the defaults recursively: give highest priority to deepest nodes.
|
|
1097
|
+
var defaults = parentDefaults;
|
|
1098
|
+
if (isObject(defaults) && isObject(schema["default"])) {
|
|
1002
1099
|
// For object defaults, only override parent defaults that are defined in
|
|
1003
1100
|
// schema.default.
|
|
1004
|
-
defaults = mergeObjects(defaults, schema
|
|
1101
|
+
defaults = mergeObjects(defaults, schema["default"]);
|
|
1005
1102
|
} else if (DEFAULT_KEY in schema) {
|
|
1006
|
-
defaults = schema
|
|
1103
|
+
defaults = schema["default"];
|
|
1007
1104
|
} else if (REF_KEY in schema) {
|
|
1008
1105
|
// Use referenced schema defaults for this node.
|
|
1009
|
-
|
|
1106
|
+
var refSchema = findSchemaDefinition(schema[REF_KEY], rootSchema);
|
|
1010
1107
|
return computeDefaults(validator, refSchema, defaults, rootSchema, formData, includeUndefinedValues);
|
|
1011
1108
|
} else if (DEPENDENCIES_KEY in schema) {
|
|
1012
|
-
|
|
1109
|
+
var resolvedSchema = resolveDependencies(validator, schema, rootSchema, formData);
|
|
1013
1110
|
return computeDefaults(validator, resolvedSchema, defaults, rootSchema, formData, includeUndefinedValues);
|
|
1014
1111
|
} else if (isFixedItems(schema)) {
|
|
1015
|
-
defaults = schema.items.map((itemSchema, idx)
|
|
1112
|
+
defaults = schema.items.map(function (itemSchema, idx) {
|
|
1113
|
+
return computeDefaults(validator, itemSchema, Array.isArray(parentDefaults) ? parentDefaults[idx] : undefined, rootSchema, formData, includeUndefinedValues);
|
|
1114
|
+
});
|
|
1016
1115
|
} else if (ONE_OF_KEY in schema) {
|
|
1017
|
-
schema = schema.oneOf[
|
|
1116
|
+
schema = schema.oneOf[getClosestMatchingOption(validator, rootSchema, isEmpty(formData) ? undefined : formData, schema.oneOf, 0)];
|
|
1018
1117
|
} else if (ANY_OF_KEY in schema) {
|
|
1019
|
-
schema = schema.anyOf[
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
|
-
|
|
1118
|
+
schema = schema.anyOf[getClosestMatchingOption(validator, rootSchema, isEmpty(formData) ? undefined : formData, schema.anyOf, 0)];
|
|
1119
|
+
}
|
|
1120
|
+
// Not defaults defined for this node, fallback to generic typed ones.
|
|
1023
1121
|
if (typeof defaults === "undefined") {
|
|
1024
|
-
defaults = schema
|
|
1122
|
+
defaults = schema["default"];
|
|
1025
1123
|
}
|
|
1026
|
-
|
|
1027
1124
|
switch (getSchemaType(schema)) {
|
|
1028
1125
|
// We need to recur for object schema inner default values.
|
|
1029
1126
|
case "object":
|
|
1030
|
-
return Object.keys(schema.properties || {}).reduce((acc, key)
|
|
1127
|
+
return Object.keys(schema.properties || {}).reduce(function (acc, key) {
|
|
1031
1128
|
// Compute the defaults for this node, with the parent defaults we might
|
|
1032
1129
|
// have from a previous run: defaults[key].
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1130
|
+
var computedDefault = computeDefaults(validator, get(schema, [PROPERTIES_KEY, key]), get(defaults, [key]), rootSchema, get(formData, [key]), includeUndefinedValues === "excludeObjectChildren" ? false : includeUndefinedValues);
|
|
1131
|
+
if (includeUndefinedValues) {
|
|
1132
|
+
acc[key] = computedDefault;
|
|
1133
|
+
} else if (isObject(computedDefault)) {
|
|
1134
|
+
// Store computedDefault if it's a non-empty object (e.g. not {})
|
|
1135
|
+
if (!isEmpty(computedDefault)) {
|
|
1136
|
+
acc[key] = computedDefault;
|
|
1137
|
+
}
|
|
1138
|
+
} else if (computedDefault !== undefined) {
|
|
1139
|
+
// Store computedDefault if it's a defined primitive (e.g. true)
|
|
1036
1140
|
acc[key] = computedDefault;
|
|
1037
1141
|
}
|
|
1038
|
-
|
|
1039
1142
|
return acc;
|
|
1040
1143
|
}, {});
|
|
1041
|
-
|
|
1042
1144
|
case "array":
|
|
1043
1145
|
// Inject defaults into existing array defaults
|
|
1044
1146
|
if (Array.isArray(defaults)) {
|
|
1045
|
-
defaults = defaults.map((item, idx)
|
|
1046
|
-
|
|
1147
|
+
defaults = defaults.map(function (item, idx) {
|
|
1148
|
+
var schemaItem = getInnerSchemaForArrayItem(schema, AdditionalItemsHandling.Fallback, idx);
|
|
1047
1149
|
return computeDefaults(validator, schemaItem, item, rootSchema);
|
|
1048
1150
|
});
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
|
|
1151
|
+
}
|
|
1152
|
+
// Deeply inject defaults into already existing form data
|
|
1052
1153
|
if (Array.isArray(rawFormData)) {
|
|
1053
|
-
|
|
1054
|
-
defaults = rawFormData.map((item, idx)
|
|
1154
|
+
var schemaItem = getInnerSchemaForArrayItem(schema);
|
|
1155
|
+
defaults = rawFormData.map(function (item, idx) {
|
|
1055
1156
|
return computeDefaults(validator, schemaItem, get(defaults, [idx]), rootSchema, item);
|
|
1056
1157
|
});
|
|
1057
1158
|
}
|
|
1058
|
-
|
|
1059
1159
|
if (schema.minItems) {
|
|
1060
1160
|
if (!isMultiSelect(validator, schema, rootSchema)) {
|
|
1061
|
-
|
|
1062
|
-
|
|
1161
|
+
var defaultsLength = Array.isArray(defaults) ? defaults.length : 0;
|
|
1063
1162
|
if (schema.minItems > defaultsLength) {
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1163
|
+
var defaultEntries = defaults || [];
|
|
1164
|
+
// populate the array with the defaults
|
|
1165
|
+
var fillerSchema = getInnerSchemaForArrayItem(schema, AdditionalItemsHandling.Invert);
|
|
1166
|
+
var fillerDefault = fillerSchema["default"];
|
|
1167
|
+
var fillerEntries = new Array(schema.minItems - defaultsLength).fill(computeDefaults(validator, fillerSchema, fillerDefault, rootSchema));
|
|
1168
|
+
// then fill up the rest with either the item default or empty, up to minItems
|
|
1070
1169
|
return defaultEntries.concat(fillerEntries);
|
|
1071
1170
|
}
|
|
1072
1171
|
}
|
|
1073
|
-
|
|
1074
1172
|
return defaults ? defaults : [];
|
|
1075
1173
|
}
|
|
1076
|
-
|
|
1077
1174
|
}
|
|
1078
|
-
|
|
1079
1175
|
return defaults;
|
|
1080
1176
|
}
|
|
1081
1177
|
/** Returns the superset of `formData` that includes the given set updated to include any missing fields that have
|
|
@@ -1085,35 +1181,30 @@ function computeDefaults(validator, schema, parentDefaults, rootSchema, rawFormD
|
|
|
1085
1181
|
* @param theSchema - The schema for which the default state is desired
|
|
1086
1182
|
* @param [formData] - The current formData, if any, onto which to provide any missing defaults
|
|
1087
1183
|
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1088
|
-
* @param [includeUndefinedValues=false] - Optional flag, if true, cause undefined values to be added as defaults
|
|
1184
|
+
* @param [includeUndefinedValues=false] - Optional flag, if true, cause undefined values to be added as defaults.
|
|
1185
|
+
* If "excludeObjectChildren", pass `includeUndefinedValues` as false when computing defaults for any nested
|
|
1186
|
+
* object properties.
|
|
1089
1187
|
* @returns - The resulting `formData` with all the defaults provided
|
|
1090
1188
|
*/
|
|
1091
|
-
|
|
1092
1189
|
function getDefaultFormState(validator, theSchema, formData, rootSchema, includeUndefinedValues) {
|
|
1093
1190
|
if (includeUndefinedValues === void 0) {
|
|
1094
1191
|
includeUndefinedValues = false;
|
|
1095
1192
|
}
|
|
1096
|
-
|
|
1097
1193
|
if (!isObject(theSchema)) {
|
|
1098
1194
|
throw new Error("Invalid schema: " + theSchema);
|
|
1099
1195
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
const defaults = computeDefaults(validator, schema, undefined, rootSchema, formData, includeUndefinedValues);
|
|
1103
|
-
|
|
1196
|
+
var schema = retrieveSchema(validator, theSchema, rootSchema, formData);
|
|
1197
|
+
var defaults = computeDefaults(validator, schema, undefined, rootSchema, formData, includeUndefinedValues);
|
|
1104
1198
|
if (typeof formData === "undefined" || formData === null || typeof formData === "number" && isNaN(formData)) {
|
|
1105
1199
|
// No form data? Use schema defaults.
|
|
1106
1200
|
return defaults;
|
|
1107
1201
|
}
|
|
1108
|
-
|
|
1109
1202
|
if (isObject(formData)) {
|
|
1110
1203
|
return mergeDefaultsWithFormData(defaults, formData);
|
|
1111
1204
|
}
|
|
1112
|
-
|
|
1113
1205
|
if (Array.isArray(formData)) {
|
|
1114
1206
|
return mergeDefaultsWithFormData(defaults, formData);
|
|
1115
1207
|
}
|
|
1116
|
-
|
|
1117
1208
|
return formData;
|
|
1118
1209
|
}
|
|
1119
1210
|
|
|
@@ -1122,13 +1213,12 @@ function getDefaultFormState(validator, theSchema, formData, rootSchema, include
|
|
|
1122
1213
|
* @param uiSchema - The UI Schema from which to detect if it is customized
|
|
1123
1214
|
* @returns - True if the `uiSchema` describes a custom widget, false otherwise
|
|
1124
1215
|
*/
|
|
1125
|
-
|
|
1126
1216
|
function isCustomWidget(uiSchema) {
|
|
1127
1217
|
if (uiSchema === void 0) {
|
|
1128
1218
|
uiSchema = {};
|
|
1129
1219
|
}
|
|
1130
|
-
|
|
1131
|
-
|
|
1220
|
+
return (
|
|
1221
|
+
// TODO: Remove the `&& uiSchema['ui:widget'] !== 'hidden'` once we support hidden widgets for arrays.
|
|
1132
1222
|
// https://react-jsonschema-form.readthedocs.io/en/latest/usage/widgets/#hidden-widgets
|
|
1133
1223
|
"widget" in getUiOptions(uiSchema) && getUiOptions(uiSchema)["widget"] !== "hidden"
|
|
1134
1224
|
);
|
|
@@ -1142,21 +1232,17 @@ function isCustomWidget(uiSchema) {
|
|
|
1142
1232
|
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1143
1233
|
* @returns - True if schema/uiSchema contains an array of files, otherwise false
|
|
1144
1234
|
*/
|
|
1145
|
-
|
|
1146
1235
|
function isFilesArray(validator, schema, uiSchema, rootSchema) {
|
|
1147
1236
|
if (uiSchema === void 0) {
|
|
1148
1237
|
uiSchema = {};
|
|
1149
1238
|
}
|
|
1150
|
-
|
|
1151
1239
|
if (uiSchema[UI_WIDGET_KEY] === "files") {
|
|
1152
1240
|
return true;
|
|
1153
1241
|
}
|
|
1154
|
-
|
|
1155
1242
|
if (schema.items) {
|
|
1156
|
-
|
|
1243
|
+
var itemsSchema = retrieveSchema(validator, schema.items, rootSchema);
|
|
1157
1244
|
return itemsSchema.type === "string" && itemsSchema.format === "data-url";
|
|
1158
1245
|
}
|
|
1159
|
-
|
|
1160
1246
|
return false;
|
|
1161
1247
|
}
|
|
1162
1248
|
|
|
@@ -1169,35 +1255,27 @@ function isFilesArray(validator, schema, uiSchema, rootSchema) {
|
|
|
1169
1255
|
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1170
1256
|
* @returns - True if the label should be displayed or false if it should not
|
|
1171
1257
|
*/
|
|
1172
|
-
|
|
1173
1258
|
function getDisplayLabel(validator, schema, uiSchema, rootSchema) {
|
|
1174
1259
|
if (uiSchema === void 0) {
|
|
1175
1260
|
uiSchema = {};
|
|
1176
1261
|
}
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
let displayLabel = !!label;
|
|
1183
|
-
const schemaType = getSchemaType(schema);
|
|
1184
|
-
|
|
1262
|
+
var uiOptions = getUiOptions(uiSchema);
|
|
1263
|
+
var _uiOptions$label = uiOptions.label,
|
|
1264
|
+
label = _uiOptions$label === void 0 ? true : _uiOptions$label;
|
|
1265
|
+
var displayLabel = !!label;
|
|
1266
|
+
var schemaType = getSchemaType(schema);
|
|
1185
1267
|
if (schemaType === "array") {
|
|
1186
1268
|
displayLabel = isMultiSelect(validator, schema, rootSchema) || isFilesArray(validator, schema, uiSchema, rootSchema) || isCustomWidget(uiSchema);
|
|
1187
1269
|
}
|
|
1188
|
-
|
|
1189
1270
|
if (schemaType === "object") {
|
|
1190
1271
|
displayLabel = false;
|
|
1191
1272
|
}
|
|
1192
|
-
|
|
1193
1273
|
if (schemaType === "boolean" && !uiSchema[UI_WIDGET_KEY]) {
|
|
1194
1274
|
displayLabel = false;
|
|
1195
1275
|
}
|
|
1196
|
-
|
|
1197
1276
|
if (uiSchema[UI_FIELD_KEY]) {
|
|
1198
1277
|
displayLabel = false;
|
|
1199
1278
|
}
|
|
1200
|
-
|
|
1201
1279
|
return displayLabel;
|
|
1202
1280
|
}
|
|
1203
1281
|
|
|
@@ -1211,30 +1289,187 @@ function getDisplayLabel(validator, schema, uiSchema, rootSchema) {
|
|
|
1211
1289
|
* @param [additionalErrorSchema] - The additional set of errors in an `ErrorSchema`
|
|
1212
1290
|
* @returns - The `validationData` with the additional errors from `additionalErrorSchema` merged into it, if provided.
|
|
1213
1291
|
*/
|
|
1214
|
-
|
|
1215
1292
|
function mergeValidationData(validator, validationData, additionalErrorSchema) {
|
|
1216
1293
|
if (!additionalErrorSchema) {
|
|
1217
1294
|
return validationData;
|
|
1218
1295
|
}
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
} = validationData;
|
|
1224
|
-
let errors = validator.toErrorList(additionalErrorSchema);
|
|
1225
|
-
let errorSchema = additionalErrorSchema;
|
|
1226
|
-
|
|
1296
|
+
var oldErrors = validationData.errors,
|
|
1297
|
+
oldErrorSchema = validationData.errorSchema;
|
|
1298
|
+
var errors = validator.toErrorList(additionalErrorSchema);
|
|
1299
|
+
var errorSchema = additionalErrorSchema;
|
|
1227
1300
|
if (!isEmpty(oldErrorSchema)) {
|
|
1228
1301
|
errorSchema = mergeObjects(oldErrorSchema, additionalErrorSchema, true);
|
|
1229
|
-
errors = [
|
|
1302
|
+
errors = [].concat(oldErrors).concat(errors);
|
|
1230
1303
|
}
|
|
1231
|
-
|
|
1232
1304
|
return {
|
|
1233
|
-
errorSchema,
|
|
1234
|
-
errors
|
|
1305
|
+
errorSchema: errorSchema,
|
|
1306
|
+
errors: errors
|
|
1235
1307
|
};
|
|
1236
1308
|
}
|
|
1237
1309
|
|
|
1310
|
+
var NO_VALUE = /*#__PURE__*/Symbol("no Value");
|
|
1311
|
+
/** Sanitize the `data` associated with the `oldSchema` so it is considered appropriate for the `newSchema`. If the new
|
|
1312
|
+
* schema does not contain any properties, then `undefined` is returned to clear all the form data. Due to the nature
|
|
1313
|
+
* of schemas, this sanitization happens recursively for nested objects of data. Also, any properties in the old schema
|
|
1314
|
+
* that are non-existent in the new schema are set to `undefined`. The data sanitization process has the following flow:
|
|
1315
|
+
*
|
|
1316
|
+
* - If the new schema is an object that contains a `properties` object then:
|
|
1317
|
+
* - Create a `removeOldSchemaData` object, setting each key in the `oldSchema.properties` having `data` to undefined
|
|
1318
|
+
* - Create an empty `nestedData` object for use in the key filtering below:
|
|
1319
|
+
* - Iterate over each key in the `newSchema.properties` as follows:
|
|
1320
|
+
* - Get the `formValue` of the key from the `data`
|
|
1321
|
+
* - Get the `oldKeySchema` and `newKeyedSchema` for the key, defaulting to `{}` when it doesn't exist
|
|
1322
|
+
* - Retrieve the schema for any refs within each `oldKeySchema` and/or `newKeySchema`
|
|
1323
|
+
* - Get the types of the old and new keyed schemas and if the old doesn't exist or the old & new are the same then:
|
|
1324
|
+
* - If `removeOldSchemaData` has an entry for the key, delete it since the new schema has the same property
|
|
1325
|
+
* - If type of the key in the new schema is `object`:
|
|
1326
|
+
* - Store the value from the recursive `sanitizeDataForNewSchema` call in `nestedData[key]`
|
|
1327
|
+
* - Otherwise, check for default or const values:
|
|
1328
|
+
* - Get the old and new `default` values from the schema and check:
|
|
1329
|
+
* - If the new `default` value does not match the form value:
|
|
1330
|
+
* - If the old `default` value DOES match the form value, then:
|
|
1331
|
+
* - Replace `removeOldSchemaData[key]` with the new `default`
|
|
1332
|
+
* - Otherwise, if the new schema is `readOnly` then replace `removeOldSchemaData[key]` with undefined
|
|
1333
|
+
* - Get the old and new `const` values from the schema and check:
|
|
1334
|
+
* - If the new `const` value does not match the form value:
|
|
1335
|
+
* - If the old `const` value DOES match the form value, then:
|
|
1336
|
+
* - Replace `removeOldSchemaData[key]` with the new `const`
|
|
1337
|
+
* - Otherwise, replace `removeOldSchemaData[key]` with undefined
|
|
1338
|
+
* - Once all keys have been processed, return an object built as follows:
|
|
1339
|
+
* - `{ ...removeOldSchemaData, ...nestedData, ...pick(data, keysToKeep) }`
|
|
1340
|
+
* - If the new and old schema types are array and the `data` is an array then:
|
|
1341
|
+
* - If the type of the old and new schema `items` are a non-array objects:
|
|
1342
|
+
* - Retrieve the schema for any refs within each `oldKeySchema.items` and/or `newKeySchema.items`
|
|
1343
|
+
* - If the `type`s of both items are the same (or the old does not have a type):
|
|
1344
|
+
* - If the type is "object", then:
|
|
1345
|
+
* - For each element in the `data` recursively sanitize the data, stopping at `maxItems` if specified
|
|
1346
|
+
* - Otherwise, just return the `data` removing any values after `maxItems` if it is set
|
|
1347
|
+
* - If the type of the old and new schema `items` are booleans of the same value, return `data` as is
|
|
1348
|
+
* - Otherwise return `undefined`
|
|
1349
|
+
*
|
|
1350
|
+
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
1351
|
+
* @param rootSchema - The root JSON schema of the entire form
|
|
1352
|
+
* @param [newSchema] - The new schema for which the data is being sanitized
|
|
1353
|
+
* @param [oldSchema] - The old schema from which the data originated
|
|
1354
|
+
* @param [data={}] - The form data associated with the schema, defaulting to an empty object when undefined
|
|
1355
|
+
* @returns - The new form data, with all the fields uniquely associated with the old schema set
|
|
1356
|
+
* to `undefined`. Will return `undefined` if the new schema is not an object containing properties.
|
|
1357
|
+
*/
|
|
1358
|
+
function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, data) {
|
|
1359
|
+
if (data === void 0) {
|
|
1360
|
+
data = {};
|
|
1361
|
+
}
|
|
1362
|
+
// By default, we will clear the form data
|
|
1363
|
+
var newFormData;
|
|
1364
|
+
// If the new schema is of type object and that object contains a list of properties
|
|
1365
|
+
if (has(newSchema, PROPERTIES_KEY)) {
|
|
1366
|
+
// Create an object containing root-level keys in the old schema, setting each key to undefined to remove the data
|
|
1367
|
+
var removeOldSchemaData = {};
|
|
1368
|
+
if (has(oldSchema, PROPERTIES_KEY)) {
|
|
1369
|
+
var properties = get(oldSchema, PROPERTIES_KEY, {});
|
|
1370
|
+
Object.keys(properties).forEach(function (key) {
|
|
1371
|
+
if (has(data, key)) {
|
|
1372
|
+
removeOldSchemaData[key] = undefined;
|
|
1373
|
+
}
|
|
1374
|
+
});
|
|
1375
|
+
}
|
|
1376
|
+
var keys = Object.keys(get(newSchema, PROPERTIES_KEY, {}));
|
|
1377
|
+
// Create a place to store nested data that will be a side-effect of the filter
|
|
1378
|
+
var nestedData = {};
|
|
1379
|
+
keys.forEach(function (key) {
|
|
1380
|
+
var formValue = get(data, key);
|
|
1381
|
+
var oldKeyedSchema = get(oldSchema, [PROPERTIES_KEY, key], {});
|
|
1382
|
+
var newKeyedSchema = get(newSchema, [PROPERTIES_KEY, key], {});
|
|
1383
|
+
// Resolve the refs if they exist
|
|
1384
|
+
if (has(oldKeyedSchema, REF_KEY)) {
|
|
1385
|
+
oldKeyedSchema = retrieveSchema(validator, oldKeyedSchema, rootSchema, formValue);
|
|
1386
|
+
}
|
|
1387
|
+
if (has(newKeyedSchema, REF_KEY)) {
|
|
1388
|
+
newKeyedSchema = retrieveSchema(validator, newKeyedSchema, rootSchema, formValue);
|
|
1389
|
+
}
|
|
1390
|
+
// Now get types and see if they are the same
|
|
1391
|
+
var oldSchemaTypeForKey = get(oldKeyedSchema, "type");
|
|
1392
|
+
var newSchemaTypeForKey = get(newKeyedSchema, "type");
|
|
1393
|
+
// Check if the old option has the same key with the same type
|
|
1394
|
+
if (!oldSchemaTypeForKey || oldSchemaTypeForKey === newSchemaTypeForKey) {
|
|
1395
|
+
if (has(removeOldSchemaData, key)) {
|
|
1396
|
+
// SIDE-EFFECT: remove the undefined value for a key that has the same type between the old and new schemas
|
|
1397
|
+
delete removeOldSchemaData[key];
|
|
1398
|
+
}
|
|
1399
|
+
// If it is an object, we'll recurse and store the resulting sanitized data for the key
|
|
1400
|
+
if (newSchemaTypeForKey === "object" || newSchemaTypeForKey === "array" && Array.isArray(formValue)) {
|
|
1401
|
+
// SIDE-EFFECT: process the new schema type of object recursively to save iterations
|
|
1402
|
+
var itemData = sanitizeDataForNewSchema(validator, rootSchema, newKeyedSchema, oldKeyedSchema, formValue);
|
|
1403
|
+
if (itemData !== undefined || newSchemaTypeForKey === "array") {
|
|
1404
|
+
// only put undefined values for the array type and not the object type
|
|
1405
|
+
nestedData[key] = itemData;
|
|
1406
|
+
}
|
|
1407
|
+
} else {
|
|
1408
|
+
// Ok, the non-object types match, let's make sure that a default or a const of a different value is replaced
|
|
1409
|
+
// with the new default or const. This allows the case where two schemas differ that only by the default/const
|
|
1410
|
+
// value to be properly selected
|
|
1411
|
+
var newOptionDefault = get(newKeyedSchema, "default", NO_VALUE);
|
|
1412
|
+
var oldOptionDefault = get(oldKeyedSchema, "default", NO_VALUE);
|
|
1413
|
+
if (newOptionDefault !== NO_VALUE && newOptionDefault !== formValue) {
|
|
1414
|
+
if (oldOptionDefault === formValue) {
|
|
1415
|
+
// If the old default matches the formValue, we'll update the new value to match the new default
|
|
1416
|
+
removeOldSchemaData[key] = newOptionDefault;
|
|
1417
|
+
} else if (get(newKeyedSchema, "readOnly") === true) {
|
|
1418
|
+
// If the new schema has the default set to read-only, treat it like a const and remove the value
|
|
1419
|
+
removeOldSchemaData[key] = undefined;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
var newOptionConst = get(newKeyedSchema, "const", NO_VALUE);
|
|
1423
|
+
var oldOptionConst = get(oldKeyedSchema, "const", NO_VALUE);
|
|
1424
|
+
if (newOptionConst !== NO_VALUE && newOptionConst !== formValue) {
|
|
1425
|
+
// Since this is a const, if the old value matches, replace the value with the new const otherwise clear it
|
|
1426
|
+
removeOldSchemaData[key] = oldOptionConst === formValue ? newOptionConst : undefined;
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
});
|
|
1431
|
+
newFormData = _extends({}, data, removeOldSchemaData, nestedData);
|
|
1432
|
+
// First apply removing the old schema data, then apply the nested data, then apply the old data keys to keep
|
|
1433
|
+
} else if (get(oldSchema, "type") === "array" && get(newSchema, "type") === "array" && Array.isArray(data)) {
|
|
1434
|
+
var oldSchemaItems = get(oldSchema, "items");
|
|
1435
|
+
var newSchemaItems = get(newSchema, "items");
|
|
1436
|
+
// If any of the array types `items` are arrays (remember arrays are objects) then we'll just drop the data
|
|
1437
|
+
// Eventually, we may want to deal with when either of the `items` are arrays since those tuple validations
|
|
1438
|
+
if (typeof oldSchemaItems === "object" && typeof newSchemaItems === "object" && !Array.isArray(oldSchemaItems) && !Array.isArray(newSchemaItems)) {
|
|
1439
|
+
if (has(oldSchemaItems, REF_KEY)) {
|
|
1440
|
+
oldSchemaItems = retrieveSchema(validator, oldSchemaItems, rootSchema, data);
|
|
1441
|
+
}
|
|
1442
|
+
if (has(newSchemaItems, REF_KEY)) {
|
|
1443
|
+
newSchemaItems = retrieveSchema(validator, newSchemaItems, rootSchema, data);
|
|
1444
|
+
}
|
|
1445
|
+
// Now get types and see if they are the same
|
|
1446
|
+
var oldSchemaType = get(oldSchemaItems, "type");
|
|
1447
|
+
var newSchemaType = get(newSchemaItems, "type");
|
|
1448
|
+
// Check if the old option has the same key with the same type
|
|
1449
|
+
if (!oldSchemaType || oldSchemaType === newSchemaType) {
|
|
1450
|
+
var maxItems = get(newSchema, "maxItems", -1);
|
|
1451
|
+
if (newSchemaType === "object") {
|
|
1452
|
+
newFormData = data.reduce(function (newValue, aValue) {
|
|
1453
|
+
var itemValue = sanitizeDataForNewSchema(validator, rootSchema, newSchemaItems, oldSchemaItems, aValue);
|
|
1454
|
+
if (itemValue !== undefined && (maxItems < 0 || newValue.length < maxItems)) {
|
|
1455
|
+
newValue.push(itemValue);
|
|
1456
|
+
}
|
|
1457
|
+
return newValue;
|
|
1458
|
+
}, []);
|
|
1459
|
+
} else {
|
|
1460
|
+
newFormData = maxItems > 0 && data.length > maxItems ? data.slice(0, maxItems) : data;
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
} else if (typeof oldSchemaItems === "boolean" && typeof newSchemaItems === "boolean" && oldSchemaItems === newSchemaItems) {
|
|
1464
|
+
// If they are both booleans and have the same value just return the data as is otherwise fall-thru to undefined
|
|
1465
|
+
newFormData = data;
|
|
1466
|
+
}
|
|
1467
|
+
// Also probably want to deal with `prefixItems` as tuples with the latest 2020 draft
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
return newFormData;
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1238
1473
|
/** Generates an `IdSchema` object for the `schema`, recursively
|
|
1239
1474
|
*
|
|
1240
1475
|
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
@@ -1246,41 +1481,34 @@ function mergeValidationData(validator, validationData, additionalErrorSchema) {
|
|
|
1246
1481
|
* @param [idSeparator='_'] - The separator to use for the path segments in the id
|
|
1247
1482
|
* @returns - The `IdSchema` object for the `schema`
|
|
1248
1483
|
*/
|
|
1249
|
-
|
|
1250
1484
|
function toIdSchema(validator, schema, id, rootSchema, formData, idPrefix, idSeparator) {
|
|
1251
1485
|
if (idPrefix === void 0) {
|
|
1252
1486
|
idPrefix = "root";
|
|
1253
1487
|
}
|
|
1254
|
-
|
|
1255
1488
|
if (idSeparator === void 0) {
|
|
1256
1489
|
idSeparator = "_";
|
|
1257
1490
|
}
|
|
1258
|
-
|
|
1259
1491
|
if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
|
|
1260
|
-
|
|
1261
|
-
|
|
1492
|
+
var _schema = retrieveSchema(validator, schema, rootSchema, formData);
|
|
1262
1493
|
return toIdSchema(validator, _schema, id, rootSchema, formData, idPrefix, idSeparator);
|
|
1263
1494
|
}
|
|
1264
|
-
|
|
1265
1495
|
if (ITEMS_KEY in schema && !get(schema, [ITEMS_KEY, REF_KEY])) {
|
|
1266
1496
|
return toIdSchema(validator, get(schema, ITEMS_KEY), id, rootSchema, formData, idPrefix, idSeparator);
|
|
1267
1497
|
}
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
$id
|
|
1498
|
+
var $id = id || idPrefix;
|
|
1499
|
+
var idSchema = {
|
|
1500
|
+
$id: $id
|
|
1272
1501
|
};
|
|
1273
|
-
|
|
1274
1502
|
if (schema.type === "object" && PROPERTIES_KEY in schema) {
|
|
1275
|
-
for (
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
idSchema[name] = toIdSchema(validator, isObject(field) ? field : {}, fieldId, rootSchema,
|
|
1503
|
+
for (var name in schema.properties) {
|
|
1504
|
+
var field = get(schema, [PROPERTIES_KEY, name]);
|
|
1505
|
+
var fieldId = idSchema[ID_KEY] + idSeparator + name;
|
|
1506
|
+
idSchema[name] = toIdSchema(validator, isObject(field) ? field : {}, fieldId, rootSchema,
|
|
1507
|
+
// It's possible that formData is not an object -- this can happen if an
|
|
1279
1508
|
// array item has just been added, but not populated with data yet
|
|
1280
1509
|
get(formData, [name]), idPrefix, idSeparator);
|
|
1281
1510
|
}
|
|
1282
1511
|
}
|
|
1283
|
-
|
|
1284
1512
|
return idSchema;
|
|
1285
1513
|
}
|
|
1286
1514
|
|
|
@@ -1293,39 +1521,42 @@ function toIdSchema(validator, schema, id, rootSchema, formData, idPrefix, idSep
|
|
|
1293
1521
|
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
1294
1522
|
* @returns - The `PathSchema` object for the `schema`
|
|
1295
1523
|
*/
|
|
1296
|
-
|
|
1297
1524
|
function toPathSchema(validator, schema, name, rootSchema, formData) {
|
|
1525
|
+
var _pathSchema;
|
|
1298
1526
|
if (name === void 0) {
|
|
1299
1527
|
name = "";
|
|
1300
1528
|
}
|
|
1301
|
-
|
|
1302
1529
|
if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
|
|
1303
|
-
|
|
1304
|
-
|
|
1530
|
+
var _schema = retrieveSchema(validator, schema, rootSchema, formData);
|
|
1305
1531
|
return toPathSchema(validator, _schema, name, rootSchema, formData);
|
|
1306
1532
|
}
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1533
|
+
var pathSchema = (_pathSchema = {}, _pathSchema[NAME_KEY] = name.replace(/^\./, ""), _pathSchema);
|
|
1534
|
+
if (ONE_OF_KEY in schema) {
|
|
1535
|
+
var index = getClosestMatchingOption(validator, rootSchema, formData, schema.oneOf, 0);
|
|
1536
|
+
var _schema2 = schema.oneOf[index];
|
|
1537
|
+
return toPathSchema(validator, _schema2, name, rootSchema, formData);
|
|
1538
|
+
}
|
|
1539
|
+
if (ANY_OF_KEY in schema) {
|
|
1540
|
+
var _index = getClosestMatchingOption(validator, rootSchema, formData, schema.anyOf, 0);
|
|
1541
|
+
var _schema3 = schema.anyOf[_index];
|
|
1542
|
+
return toPathSchema(validator, _schema3, name, rootSchema, formData);
|
|
1543
|
+
}
|
|
1544
|
+
if (ADDITIONAL_PROPERTIES_KEY in schema && schema[ADDITIONAL_PROPERTIES_KEY] !== false) {
|
|
1313
1545
|
set(pathSchema, RJSF_ADDITONAL_PROPERTIES_FLAG, true);
|
|
1314
1546
|
}
|
|
1315
|
-
|
|
1316
1547
|
if (ITEMS_KEY in schema && Array.isArray(formData)) {
|
|
1317
|
-
formData.forEach((element, i)
|
|
1548
|
+
formData.forEach(function (element, i) {
|
|
1318
1549
|
pathSchema[i] = toPathSchema(validator, schema.items, name + "." + i, rootSchema, element);
|
|
1319
1550
|
});
|
|
1320
1551
|
} else if (PROPERTIES_KEY in schema) {
|
|
1321
|
-
for (
|
|
1322
|
-
|
|
1323
|
-
pathSchema[property] = toPathSchema(validator, field, name + "." + property, rootSchema,
|
|
1552
|
+
for (var property in schema.properties) {
|
|
1553
|
+
var field = get(schema, [PROPERTIES_KEY, property]);
|
|
1554
|
+
pathSchema[property] = toPathSchema(validator, field, name + "." + property, rootSchema,
|
|
1555
|
+
// It's possible that formData is not an object -- this can happen if an
|
|
1324
1556
|
// array item has just been added, but not populated with data yet
|
|
1325
1557
|
get(formData, [property]));
|
|
1326
1558
|
}
|
|
1327
1559
|
}
|
|
1328
|
-
|
|
1329
1560
|
return pathSchema;
|
|
1330
1561
|
}
|
|
1331
1562
|
|
|
@@ -1334,14 +1565,13 @@ function toPathSchema(validator, schema, name, rootSchema, formData) {
|
|
|
1334
1565
|
* and `rootSchema` generally does not change across a `Form`, this allows for providing a simplified set of APIs to the
|
|
1335
1566
|
* `@rjsf/core` components and the various themes as well. This class implements the `SchemaUtilsType` interface.
|
|
1336
1567
|
*/
|
|
1337
|
-
|
|
1338
|
-
class SchemaUtils {
|
|
1568
|
+
var SchemaUtils = /*#__PURE__*/function () {
|
|
1339
1569
|
/** Constructs the `SchemaUtils` instance with the given `validator` and `rootSchema` stored as instance variables
|
|
1340
1570
|
*
|
|
1341
1571
|
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
1342
1572
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
1343
1573
|
*/
|
|
1344
|
-
|
|
1574
|
+
function SchemaUtils(validator, rootSchema) {
|
|
1345
1575
|
this.rootSchema = void 0;
|
|
1346
1576
|
this.validator = void 0;
|
|
1347
1577
|
this.rootSchema = rootSchema;
|
|
@@ -1351,9 +1581,8 @@ class SchemaUtils {
|
|
|
1351
1581
|
*
|
|
1352
1582
|
* @returns - The `ValidatorType`
|
|
1353
1583
|
*/
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
getValidator() {
|
|
1584
|
+
var _proto = SchemaUtils.prototype;
|
|
1585
|
+
_proto.getValidator = function getValidator() {
|
|
1357
1586
|
return this.validator;
|
|
1358
1587
|
}
|
|
1359
1588
|
/** Determines whether either the `validator` and `rootSchema` differ from the ones associated with this instance of
|
|
@@ -1363,14 +1592,11 @@ class SchemaUtils {
|
|
|
1363
1592
|
* @param validator - An implementation of the `ValidatorType` interface that will be compared against the current one
|
|
1364
1593
|
* @param rootSchema - The root schema that will be compared against the current one
|
|
1365
1594
|
* @returns - True if the `SchemaUtilsType` differs from the given `validator` or `rootSchema`
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
doesSchemaUtilsDiffer(validator, rootSchema) {
|
|
1595
|
+
*/;
|
|
1596
|
+
_proto.doesSchemaUtilsDiffer = function doesSchemaUtilsDiffer(validator, rootSchema) {
|
|
1370
1597
|
if (!validator || !rootSchema) {
|
|
1371
1598
|
return false;
|
|
1372
1599
|
}
|
|
1373
|
-
|
|
1374
1600
|
return this.validator !== validator || !deepEquals(this.rootSchema, rootSchema);
|
|
1375
1601
|
}
|
|
1376
1602
|
/** Returns the superset of `formData` that includes the given set updated to include any missing fields that have
|
|
@@ -1378,16 +1604,15 @@ class SchemaUtils {
|
|
|
1378
1604
|
*
|
|
1379
1605
|
* @param schema - The schema for which the default state is desired
|
|
1380
1606
|
* @param [formData] - The current formData, if any, onto which to provide any missing defaults
|
|
1381
|
-
* @param [includeUndefinedValues=false] - Optional flag, if true, cause undefined values to be added as defaults
|
|
1607
|
+
* @param [includeUndefinedValues=false] - Optional flag, if true, cause undefined values to be added as defaults.
|
|
1608
|
+
* If "excludeObjectChildren", pass `includeUndefinedValues` as false when computing defaults for any nested
|
|
1609
|
+
* object properties.
|
|
1382
1610
|
* @returns - The resulting `formData` with all the defaults provided
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
getDefaultFormState(schema, formData, includeUndefinedValues) {
|
|
1611
|
+
*/;
|
|
1612
|
+
_proto.getDefaultFormState = function getDefaultFormState$1(schema, formData, includeUndefinedValues) {
|
|
1387
1613
|
if (includeUndefinedValues === void 0) {
|
|
1388
1614
|
includeUndefinedValues = false;
|
|
1389
1615
|
}
|
|
1390
|
-
|
|
1391
1616
|
return getDefaultFormState(this.validator, schema, formData, this.rootSchema, includeUndefinedValues);
|
|
1392
1617
|
}
|
|
1393
1618
|
/** Determines whether the combination of `schema` and `uiSchema` properties indicates that the label for the `schema`
|
|
@@ -1396,21 +1621,43 @@ class SchemaUtils {
|
|
|
1396
1621
|
* @param schema - The schema for which the display label flag is desired
|
|
1397
1622
|
* @param [uiSchema] - The UI schema from which to derive potentially displayable information
|
|
1398
1623
|
* @returns - True if the label should be displayed or false if it should not
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
getDisplayLabel(schema, uiSchema) {
|
|
1624
|
+
*/;
|
|
1625
|
+
_proto.getDisplayLabel = function getDisplayLabel$1(schema, uiSchema) {
|
|
1403
1626
|
return getDisplayLabel(this.validator, schema, uiSchema, this.rootSchema);
|
|
1404
1627
|
}
|
|
1628
|
+
/** Determines which of the given `options` provided most closely matches the `formData`.
|
|
1629
|
+
* Returns the index of the option that is valid and is the closest match, or 0 if there is no match.
|
|
1630
|
+
*
|
|
1631
|
+
* The closest match is determined using the number of matching properties, and more heavily favors options with
|
|
1632
|
+
* matching readOnly, default, or const values.
|
|
1633
|
+
*
|
|
1634
|
+
* @param formData - The form data associated with the schema
|
|
1635
|
+
* @param options - The list of options that can be selected from
|
|
1636
|
+
* @param [selectedOption] - The index of the currently selected option, defaulted to -1 if not specified
|
|
1637
|
+
* @returns - The index of the option that is the closest match to the `formData` or the `selectedOption` if no match
|
|
1638
|
+
*/;
|
|
1639
|
+
_proto.getClosestMatchingOption = function getClosestMatchingOption$1(formData, options, selectedOption) {
|
|
1640
|
+
return getClosestMatchingOption(this.validator, this.rootSchema, formData, options, selectedOption);
|
|
1641
|
+
}
|
|
1642
|
+
/** Given the `formData` and list of `options`, attempts to find the index of the first option that matches the data.
|
|
1643
|
+
* Always returns the first option if there is nothing that matches.
|
|
1644
|
+
*
|
|
1645
|
+
* @param formData - The current formData, if any, used to figure out a match
|
|
1646
|
+
* @param options - The list of options to find a matching options from
|
|
1647
|
+
* @returns - The firstindex of the matched option or 0 if none is available
|
|
1648
|
+
*/;
|
|
1649
|
+
_proto.getFirstMatchingOption = function getFirstMatchingOption$1(formData, options) {
|
|
1650
|
+
return getFirstMatchingOption(this.validator, formData, options, this.rootSchema);
|
|
1651
|
+
}
|
|
1405
1652
|
/** Given the `formData` and list of `options`, attempts to find the index of the option that best matches the data.
|
|
1653
|
+
* Deprecated, use `getFirstMatchingOption()` instead.
|
|
1406
1654
|
*
|
|
1407
1655
|
* @param formData - The current formData, if any, onto which to provide any missing defaults
|
|
1408
1656
|
* @param options - The list of options to find a matching options from
|
|
1409
1657
|
* @returns - The index of the matched option or 0 if none is available
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
getMatchingOption(formData, options) {
|
|
1658
|
+
* @deprecated
|
|
1659
|
+
*/;
|
|
1660
|
+
_proto.getMatchingOption = function getMatchingOption$1(formData, options) {
|
|
1414
1661
|
return getMatchingOption(this.validator, formData, options, this.rootSchema);
|
|
1415
1662
|
}
|
|
1416
1663
|
/** Checks to see if the `schema` and `uiSchema` combination represents an array of files
|
|
@@ -1418,30 +1665,24 @@ class SchemaUtils {
|
|
|
1418
1665
|
* @param schema - The schema for which check for array of files flag is desired
|
|
1419
1666
|
* @param [uiSchema] - The UI schema from which to check the widget
|
|
1420
1667
|
* @returns - True if schema/uiSchema contains an array of files, otherwise false
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
isFilesArray(schema, uiSchema) {
|
|
1668
|
+
*/;
|
|
1669
|
+
_proto.isFilesArray = function isFilesArray$1(schema, uiSchema) {
|
|
1425
1670
|
return isFilesArray(this.validator, schema, uiSchema, this.rootSchema);
|
|
1426
1671
|
}
|
|
1427
1672
|
/** Checks to see if the `schema` combination represents a multi-select
|
|
1428
1673
|
*
|
|
1429
1674
|
* @param schema - The schema for which check for a multi-select flag is desired
|
|
1430
1675
|
* @returns - True if schema contains a multi-select, otherwise false
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
isMultiSelect(schema) {
|
|
1676
|
+
*/;
|
|
1677
|
+
_proto.isMultiSelect = function isMultiSelect$1(schema) {
|
|
1435
1678
|
return isMultiSelect(this.validator, schema, this.rootSchema);
|
|
1436
1679
|
}
|
|
1437
1680
|
/** Checks to see if the `schema` combination represents a select
|
|
1438
1681
|
*
|
|
1439
1682
|
* @param schema - The schema for which check for a select flag is desired
|
|
1440
1683
|
* @returns - True if schema contains a select, otherwise false
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
isSelect(schema) {
|
|
1684
|
+
*/;
|
|
1685
|
+
_proto.isSelect = function isSelect$1(schema) {
|
|
1445
1686
|
return isSelect(this.validator, schema, this.rootSchema);
|
|
1446
1687
|
}
|
|
1447
1688
|
/** Merges the errors in `additionalErrorSchema` into the existing `validationData` by combining the hierarchies in
|
|
@@ -1452,10 +1693,8 @@ class SchemaUtils {
|
|
|
1452
1693
|
* @param validationData - The current `ValidationData` into which to merge the additional errors
|
|
1453
1694
|
* @param [additionalErrorSchema] - The additional set of errors
|
|
1454
1695
|
* @returns - The `validationData` with the additional errors from `additionalErrorSchema` merged into it, if provided.
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
mergeValidationData(validationData, additionalErrorSchema) {
|
|
1696
|
+
*/;
|
|
1697
|
+
_proto.mergeValidationData = function mergeValidationData$1(validationData, additionalErrorSchema) {
|
|
1459
1698
|
return mergeValidationData(this.validator, validationData, additionalErrorSchema);
|
|
1460
1699
|
}
|
|
1461
1700
|
/** Retrieves an expanded schema that has had all of its conditions, additional properties, references and
|
|
@@ -1465,12 +1704,24 @@ class SchemaUtils {
|
|
|
1465
1704
|
* @param schema - The schema for which retrieving a schema is desired
|
|
1466
1705
|
* @param [rawFormData] - The current formData, if any, to assist retrieving a schema
|
|
1467
1706
|
* @returns - The schema having its conditions, additional properties, references and dependencies resolved
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
retrieveSchema(schema, rawFormData) {
|
|
1707
|
+
*/;
|
|
1708
|
+
_proto.retrieveSchema = function retrieveSchema$1(schema, rawFormData) {
|
|
1472
1709
|
return retrieveSchema(this.validator, schema, this.rootSchema, rawFormData);
|
|
1473
1710
|
}
|
|
1711
|
+
/** Sanitize the `data` associated with the `oldSchema` so it is considered appropriate for the `newSchema`. If the
|
|
1712
|
+
* new schema does not contain any properties, then `undefined` is returned to clear all the form data. Due to the
|
|
1713
|
+
* nature of schemas, this sanitization happens recursively for nested objects of data. Also, any properties in the
|
|
1714
|
+
* old schemas that are non-existent in the new schema are set to `undefined`.
|
|
1715
|
+
*
|
|
1716
|
+
* @param [newSchema] - The new schema for which the data is being sanitized
|
|
1717
|
+
* @param [oldSchema] - The old schema from which the data originated
|
|
1718
|
+
* @param [data={}] - The form data associated with the schema, defaulting to an empty object when undefined
|
|
1719
|
+
* @returns - The new form data, with all the fields uniquely associated with the old schema set
|
|
1720
|
+
* to `undefined`. Will return `undefined` if the new schema is not an object containing properties.
|
|
1721
|
+
*/;
|
|
1722
|
+
_proto.sanitizeDataForNewSchema = function sanitizeDataForNewSchema$1(newSchema, oldSchema, data) {
|
|
1723
|
+
return sanitizeDataForNewSchema(this.validator, this.rootSchema, newSchema, oldSchema, data);
|
|
1724
|
+
}
|
|
1474
1725
|
/** Generates an `IdSchema` object for the `schema`, recursively
|
|
1475
1726
|
*
|
|
1476
1727
|
* @param schema - The schema for which the display label flag is desired
|
|
@@ -1479,18 +1730,14 @@ class SchemaUtils {
|
|
|
1479
1730
|
* @param [idPrefix='root'] - The prefix to use for the id
|
|
1480
1731
|
* @param [idSeparator='_'] - The separator to use for the path segments in the id
|
|
1481
1732
|
* @returns - The `IdSchema` object for the `schema`
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
toIdSchema(schema, id, formData, idPrefix, idSeparator) {
|
|
1733
|
+
*/;
|
|
1734
|
+
_proto.toIdSchema = function toIdSchema$1(schema, id, formData, idPrefix, idSeparator) {
|
|
1486
1735
|
if (idPrefix === void 0) {
|
|
1487
1736
|
idPrefix = "root";
|
|
1488
1737
|
}
|
|
1489
|
-
|
|
1490
1738
|
if (idSeparator === void 0) {
|
|
1491
1739
|
idSeparator = "_";
|
|
1492
1740
|
}
|
|
1493
|
-
|
|
1494
1741
|
return toIdSchema(this.validator, schema, id, this.rootSchema, formData, idPrefix, idSeparator);
|
|
1495
1742
|
}
|
|
1496
1743
|
/** Generates an `PathSchema` object for the `schema`, recursively
|
|
@@ -1499,14 +1746,12 @@ class SchemaUtils {
|
|
|
1499
1746
|
* @param [name] - The base name for the schema
|
|
1500
1747
|
* @param [formData] - The current formData, if any, onto which to provide any missing defaults
|
|
1501
1748
|
* @returns - The `PathSchema` object for the `schema`
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
toPathSchema(schema, name, formData) {
|
|
1749
|
+
*/;
|
|
1750
|
+
_proto.toPathSchema = function toPathSchema$1(schema, name, formData) {
|
|
1506
1751
|
return toPathSchema(this.validator, schema, name, this.rootSchema, formData);
|
|
1507
|
-
}
|
|
1508
|
-
|
|
1509
|
-
}
|
|
1752
|
+
};
|
|
1753
|
+
return SchemaUtils;
|
|
1754
|
+
}();
|
|
1510
1755
|
/** Creates a `SchemaUtilsType` interface that is based around the given `validator` and `rootSchema` parameters. The
|
|
1511
1756
|
* resulting interface implementation will forward the `validator` and `rootSchema` to all the wrapped APIs.
|
|
1512
1757
|
*
|
|
@@ -1514,8 +1759,6 @@ class SchemaUtils {
|
|
|
1514
1759
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
1515
1760
|
* @returns - An implementation of a `SchemaUtilsType` interface
|
|
1516
1761
|
*/
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
1762
|
function createSchemaUtils(validator, rootSchema) {
|
|
1520
1763
|
return new SchemaUtils(validator, rootSchema);
|
|
1521
1764
|
}
|
|
@@ -1528,44 +1771,273 @@ function createSchemaUtils(validator, rootSchema) {
|
|
|
1528
1771
|
*/
|
|
1529
1772
|
function dataURItoBlob(dataURI) {
|
|
1530
1773
|
// Split metadata from data
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1774
|
+
var splitted = dataURI.split(",");
|
|
1775
|
+
// Split params
|
|
1776
|
+
var params = splitted[0].split(";");
|
|
1777
|
+
// Get mime-type from params
|
|
1778
|
+
var type = params[0].replace("data:", "");
|
|
1779
|
+
// Filter the name property from params
|
|
1780
|
+
var properties = params.filter(function (param) {
|
|
1538
1781
|
return param.split("=")[0] === "name";
|
|
1539
|
-
});
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1782
|
+
});
|
|
1783
|
+
// Look for the name and use unknown if no name property.
|
|
1784
|
+
var name;
|
|
1543
1785
|
if (properties.length !== 1) {
|
|
1544
1786
|
name = "unknown";
|
|
1545
1787
|
} else {
|
|
1546
1788
|
// Because we filtered out the other property,
|
|
1547
1789
|
// we only have the name case here.
|
|
1548
1790
|
name = properties[0].split("=")[1];
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1791
|
+
}
|
|
1792
|
+
// Built the Uint8Array Blob parameter from the base64 string.
|
|
1793
|
+
var binary = atob(splitted[1]);
|
|
1794
|
+
var array = [];
|
|
1795
|
+
for (var i = 0; i < binary.length; i++) {
|
|
1796
|
+
array.push(binary.charCodeAt(i));
|
|
1797
|
+
}
|
|
1798
|
+
// Create the blob object
|
|
1799
|
+
var blob = new window.Blob([new Uint8Array(array)], {
|
|
1800
|
+
type: type
|
|
1801
|
+
});
|
|
1802
|
+
return {
|
|
1803
|
+
blob: blob,
|
|
1804
|
+
name: name
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1551
1807
|
|
|
1552
|
-
|
|
1553
|
-
|
|
1808
|
+
/** Returns the value(s) from `allEnumOptions` at the index(es) provided by `valueIndex`. If `valueIndex` is not an
|
|
1809
|
+
* array AND the index is not valid for `allEnumOptions`, `emptyValue` is returned. If `valueIndex` is an array, AND it
|
|
1810
|
+
* contains an invalid index, the returned array will have the resulting undefined values filtered out, leaving only
|
|
1811
|
+
* valid values or in the worst case, an empty array.
|
|
1812
|
+
*
|
|
1813
|
+
* @param valueIndex - The index(es) of the value(s) that should be returned
|
|
1814
|
+
* @param [allEnumOptions=[]] - The list of all the known enumOptions
|
|
1815
|
+
* @param [emptyValue] - The value to return when the non-array `valueIndex` does not refer to a real option
|
|
1816
|
+
* @returns - The single or list of values specified by the single or list of indexes if they are valid. Otherwise,
|
|
1817
|
+
* `emptyValue` or an empty list.
|
|
1818
|
+
*/
|
|
1819
|
+
function enumOptionsValueForIndex(valueIndex, allEnumOptions, emptyValue) {
|
|
1820
|
+
if (allEnumOptions === void 0) {
|
|
1821
|
+
allEnumOptions = [];
|
|
1822
|
+
}
|
|
1823
|
+
if (Array.isArray(valueIndex)) {
|
|
1824
|
+
return valueIndex.map(function (index) {
|
|
1825
|
+
return enumOptionsValueForIndex(index, allEnumOptions);
|
|
1826
|
+
}).filter(function (val) {
|
|
1827
|
+
return val;
|
|
1828
|
+
});
|
|
1829
|
+
}
|
|
1830
|
+
// So Number(null) and Number('') both return 0, so use emptyValue for those two values
|
|
1831
|
+
var index = valueIndex === "" || valueIndex === null ? -1 : Number(valueIndex);
|
|
1832
|
+
var option = allEnumOptions[index];
|
|
1833
|
+
return option ? option.value : emptyValue;
|
|
1834
|
+
}
|
|
1554
1835
|
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1836
|
+
/** Removes the enum option value at the `valueIndex` from the currently `selected` (list of) value(s). If `selected` is
|
|
1837
|
+
* a list, then that list is updated to remove the enum option value with the `valueIndex` in `allEnumOptions`. If it is
|
|
1838
|
+
* a single value, then if the enum option value with the `valueIndex` in `allEnumOptions` matches `selected`, undefined
|
|
1839
|
+
* is returned, otherwise the `selected` value is returned.
|
|
1840
|
+
*
|
|
1841
|
+
* @param valueIndex - The index of the value to be removed from the selected list or single value
|
|
1842
|
+
* @param selected - The current (list of) selected value(s)
|
|
1843
|
+
* @param [allEnumOptions=[]] - The list of all the known enumOptions
|
|
1844
|
+
* @returns - The updated `selected` with the enum option value at `valueIndex` in `allEnumOptions` removed from it,
|
|
1845
|
+
* unless `selected` is a single value. In that case, if the `valueIndex` value matches `selected`, returns
|
|
1846
|
+
* undefined, otherwise `selected`.
|
|
1847
|
+
*/
|
|
1848
|
+
function enumOptionsDeselectValue(valueIndex, selected, allEnumOptions) {
|
|
1849
|
+
if (allEnumOptions === void 0) {
|
|
1850
|
+
allEnumOptions = [];
|
|
1851
|
+
}
|
|
1852
|
+
var value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
|
|
1853
|
+
if (Array.isArray(selected)) {
|
|
1854
|
+
return selected.filter(function (v) {
|
|
1855
|
+
return !isEqual(v, value);
|
|
1856
|
+
});
|
|
1857
|
+
}
|
|
1858
|
+
return isEqual(value, selected) ? undefined : selected;
|
|
1859
|
+
}
|
|
1558
1860
|
|
|
1861
|
+
/** Determines whether the given `value` is (one of) the `selected` value(s).
|
|
1862
|
+
*
|
|
1863
|
+
* @param value - The value being checked to see if it is selected
|
|
1864
|
+
* @param selected - The current selected value or list of values
|
|
1865
|
+
* @returns - true if the `value` is one of the `selected` ones, false otherwise
|
|
1866
|
+
*/
|
|
1867
|
+
function enumOptionsIsSelected(value, selected) {
|
|
1868
|
+
if (Array.isArray(selected)) {
|
|
1869
|
+
return selected.some(function (sel) {
|
|
1870
|
+
return isEqual(sel, value);
|
|
1871
|
+
});
|
|
1872
|
+
}
|
|
1873
|
+
return isEqual(selected, value);
|
|
1874
|
+
}
|
|
1559
1875
|
|
|
1560
|
-
|
|
1561
|
-
|
|
1876
|
+
/** Returns the index(es) of the options in `allEnumOptions` whose value(s) match the ones in `value`. All the
|
|
1877
|
+
* `enumOptions` are filtered based on whether they are a "selected" `value` and the index of each selected one is then
|
|
1878
|
+
* stored in an array. If `multiple` is true, that array is returned, otherwise the first element in the array is
|
|
1879
|
+
* returned.
|
|
1880
|
+
*
|
|
1881
|
+
* @param value - The single value or list of values for which indexes are desired
|
|
1882
|
+
* @param [allEnumOptions=[]] - The list of all the known enumOptions
|
|
1883
|
+
* @param [multiple=false] - Optional flag, if true will return a list of index, otherwise a single one
|
|
1884
|
+
* @returns - A single string index for the first `value` in `allEnumOptions`, if not `multiple`. Otherwise, the list
|
|
1885
|
+
* of indexes for (each of) the value(s) in `value`.
|
|
1886
|
+
*/
|
|
1887
|
+
function enumOptionsIndexForValue(value, allEnumOptions, multiple) {
|
|
1888
|
+
if (allEnumOptions === void 0) {
|
|
1889
|
+
allEnumOptions = [];
|
|
1890
|
+
}
|
|
1891
|
+
if (multiple === void 0) {
|
|
1892
|
+
multiple = false;
|
|
1893
|
+
}
|
|
1894
|
+
var selectedIndexes = allEnumOptions.map(function (opt, index) {
|
|
1895
|
+
return enumOptionsIsSelected(opt.value, value) ? String(index) : undefined;
|
|
1896
|
+
}).filter(function (opt) {
|
|
1897
|
+
return typeof opt !== "undefined";
|
|
1562
1898
|
});
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1899
|
+
if (!multiple) {
|
|
1900
|
+
return selectedIndexes[0];
|
|
1901
|
+
}
|
|
1902
|
+
return selectedIndexes;
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1905
|
+
/** Add the enum option value at the `valueIndex` to the list of `selected` values in the proper order as defined by
|
|
1906
|
+
* `allEnumOptions`
|
|
1907
|
+
*
|
|
1908
|
+
* @param valueIndex - The index of the value that should be selected
|
|
1909
|
+
* @param selected - The current list of selected values
|
|
1910
|
+
* @param [allEnumOptions=[]] - The list of all the known enumOptions
|
|
1911
|
+
* @returns - The updated list of selected enum values with enum value at the `valueIndex` added to it
|
|
1912
|
+
*/
|
|
1913
|
+
function enumOptionsSelectValue(valueIndex, selected, allEnumOptions) {
|
|
1914
|
+
if (allEnumOptions === void 0) {
|
|
1915
|
+
allEnumOptions = [];
|
|
1916
|
+
}
|
|
1917
|
+
var value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
|
|
1918
|
+
if (value) {
|
|
1919
|
+
var index = allEnumOptions.findIndex(function (opt) {
|
|
1920
|
+
return value === opt.value;
|
|
1921
|
+
});
|
|
1922
|
+
var all = allEnumOptions.map(function (_ref) {
|
|
1923
|
+
var val = _ref.value;
|
|
1924
|
+
return val;
|
|
1925
|
+
});
|
|
1926
|
+
var updated = selected.slice(0, index).concat(value, selected.slice(index));
|
|
1927
|
+
// As inserting values at predefined index positions doesn't work with empty
|
|
1928
|
+
// arrays, we need to reorder the updated selection to match the initial order
|
|
1929
|
+
return updated.sort(function (a, b) {
|
|
1930
|
+
return Number(all.indexOf(a) > all.indexOf(b));
|
|
1931
|
+
});
|
|
1932
|
+
}
|
|
1933
|
+
return selected;
|
|
1567
1934
|
}
|
|
1568
1935
|
|
|
1936
|
+
/** The `ErrorSchemaBuilder<T>` is used to build an `ErrorSchema<T>` since the definition of the `ErrorSchema` type is
|
|
1937
|
+
* designed for reading information rather than writing it. Use this class to add, replace or clear errors in an error
|
|
1938
|
+
* schema by using either dotted path or an array of path names. Once you are done building the `ErrorSchema`, you can
|
|
1939
|
+
* get the result and/or reset all the errors back to an initial set and start again.
|
|
1940
|
+
*/
|
|
1941
|
+
var ErrorSchemaBuilder = /*#__PURE__*/function () {
|
|
1942
|
+
/** The error schema being built
|
|
1943
|
+
*
|
|
1944
|
+
* @private
|
|
1945
|
+
*/
|
|
1946
|
+
|
|
1947
|
+
/** Construct an `ErrorSchemaBuilder` with an optional initial set of errors in an `ErrorSchema`.
|
|
1948
|
+
*
|
|
1949
|
+
* @param [initialSchema] - The optional set of initial errors, that will be cloned into the class
|
|
1950
|
+
*/
|
|
1951
|
+
function ErrorSchemaBuilder(initialSchema) {
|
|
1952
|
+
this.errorSchema = {};
|
|
1953
|
+
this.resetAllErrors(initialSchema);
|
|
1954
|
+
}
|
|
1955
|
+
/** Returns the `ErrorSchema` that has been updated by the methods of the `ErrorSchemaBuilder`
|
|
1956
|
+
*/
|
|
1957
|
+
var _proto = ErrorSchemaBuilder.prototype;
|
|
1958
|
+
/** Will get an existing `ErrorSchema` at the specified `pathOfError` or create and return one.
|
|
1959
|
+
*
|
|
1960
|
+
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to add the error(s)
|
|
1961
|
+
* @returns - The error block for the given `pathOfError` or the root if not provided
|
|
1962
|
+
* @private
|
|
1963
|
+
*/
|
|
1964
|
+
_proto.getOrCreateErrorBlock = function getOrCreateErrorBlock(pathOfError) {
|
|
1965
|
+
var hasPath = Array.isArray(pathOfError) && pathOfError.length > 0 || typeof pathOfError === "string";
|
|
1966
|
+
var errorBlock = hasPath ? get(this.errorSchema, pathOfError) : this.errorSchema;
|
|
1967
|
+
if (!errorBlock && pathOfError) {
|
|
1968
|
+
errorBlock = {};
|
|
1969
|
+
set(this.errorSchema, pathOfError, errorBlock);
|
|
1970
|
+
}
|
|
1971
|
+
return errorBlock;
|
|
1972
|
+
}
|
|
1973
|
+
/** Resets all errors in the `ErrorSchemaBuilder` back to the `initialSchema` if provided, otherwise an empty set.
|
|
1974
|
+
*
|
|
1975
|
+
* @param [initialSchema] - The optional set of initial errors, that will be cloned into the class
|
|
1976
|
+
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
1977
|
+
*/;
|
|
1978
|
+
_proto.resetAllErrors = function resetAllErrors(initialSchema) {
|
|
1979
|
+
this.errorSchema = initialSchema ? cloneDeep(initialSchema) : {};
|
|
1980
|
+
return this;
|
|
1981
|
+
}
|
|
1982
|
+
/** Adds the `errorOrList` to the list of errors in the `ErrorSchema` at either the root level or the location within
|
|
1983
|
+
* the schema described by the `pathOfError`. For more information about how to specify the path see the
|
|
1984
|
+
* [eslint lodash plugin docs](https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/path-style.md).
|
|
1985
|
+
*
|
|
1986
|
+
* @param errorOrList - The error or list of errors to add into the `ErrorSchema`
|
|
1987
|
+
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to add the error(s)
|
|
1988
|
+
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
1989
|
+
*/;
|
|
1990
|
+
_proto.addErrors = function addErrors(errorOrList, pathOfError) {
|
|
1991
|
+
var errorBlock = this.getOrCreateErrorBlock(pathOfError);
|
|
1992
|
+
var errorsList = get(errorBlock, ERRORS_KEY);
|
|
1993
|
+
if (!Array.isArray(errorsList)) {
|
|
1994
|
+
errorsList = [];
|
|
1995
|
+
errorBlock[ERRORS_KEY] = errorsList;
|
|
1996
|
+
}
|
|
1997
|
+
if (Array.isArray(errorOrList)) {
|
|
1998
|
+
var _errorsList;
|
|
1999
|
+
(_errorsList = errorsList).push.apply(_errorsList, errorOrList);
|
|
2000
|
+
} else {
|
|
2001
|
+
errorsList.push(errorOrList);
|
|
2002
|
+
}
|
|
2003
|
+
return this;
|
|
2004
|
+
}
|
|
2005
|
+
/** Sets/replaces the `errorOrList` as the error(s) in the `ErrorSchema` at either the root level or the location
|
|
2006
|
+
* within the schema described by the `pathOfError`. For more information about how to specify the path see the
|
|
2007
|
+
* [eslint lodash plugin docs](https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/path-style.md).
|
|
2008
|
+
*
|
|
2009
|
+
* @param errorOrList - The error or list of errors to set into the `ErrorSchema`
|
|
2010
|
+
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to set the error(s)
|
|
2011
|
+
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
2012
|
+
*/;
|
|
2013
|
+
_proto.setErrors = function setErrors(errorOrList, pathOfError) {
|
|
2014
|
+
var errorBlock = this.getOrCreateErrorBlock(pathOfError);
|
|
2015
|
+
// Effectively clone the array being given to prevent accidental outside manipulation of the given list
|
|
2016
|
+
var listToAdd = Array.isArray(errorOrList) ? [].concat(errorOrList) : [errorOrList];
|
|
2017
|
+
set(errorBlock, ERRORS_KEY, listToAdd);
|
|
2018
|
+
return this;
|
|
2019
|
+
}
|
|
2020
|
+
/** Clears the error(s) in the `ErrorSchema` at either the root level or the location within the schema described by
|
|
2021
|
+
* the `pathOfError`. For more information about how to specify the path see the
|
|
2022
|
+
* [eslint lodash plugin docs](https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/path-style.md).
|
|
2023
|
+
*
|
|
2024
|
+
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to clear the error(s)
|
|
2025
|
+
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
2026
|
+
*/;
|
|
2027
|
+
_proto.clearErrors = function clearErrors(pathOfError) {
|
|
2028
|
+
var errorBlock = this.getOrCreateErrorBlock(pathOfError);
|
|
2029
|
+
set(errorBlock, ERRORS_KEY, []);
|
|
2030
|
+
return this;
|
|
2031
|
+
};
|
|
2032
|
+
_createClass(ErrorSchemaBuilder, [{
|
|
2033
|
+
key: "ErrorSchema",
|
|
2034
|
+
get: function get() {
|
|
2035
|
+
return this.errorSchema;
|
|
2036
|
+
}
|
|
2037
|
+
}]);
|
|
2038
|
+
return ErrorSchemaBuilder;
|
|
2039
|
+
}();
|
|
2040
|
+
|
|
1569
2041
|
/** Extracts the range spec information `{ step?: number, min?: number, max?: number }` that can be spread onto an HTML
|
|
1570
2042
|
* input from the range analog in the schema `{ multipleOf?: number, minimum?: number, maximum?: number }`.
|
|
1571
2043
|
*
|
|
@@ -1573,20 +2045,16 @@ function dataURItoBlob(dataURI) {
|
|
|
1573
2045
|
* @returns - A range specification from the schema
|
|
1574
2046
|
*/
|
|
1575
2047
|
function rangeSpec(schema) {
|
|
1576
|
-
|
|
1577
|
-
|
|
2048
|
+
var spec = {};
|
|
1578
2049
|
if (schema.multipleOf) {
|
|
1579
2050
|
spec.step = schema.multipleOf;
|
|
1580
2051
|
}
|
|
1581
|
-
|
|
1582
2052
|
if (schema.minimum || schema.minimum === 0) {
|
|
1583
2053
|
spec.min = schema.minimum;
|
|
1584
2054
|
}
|
|
1585
|
-
|
|
1586
2055
|
if (schema.maximum || schema.maximum === 0) {
|
|
1587
2056
|
spec.max = schema.maximum;
|
|
1588
2057
|
}
|
|
1589
|
-
|
|
1590
2058
|
return spec;
|
|
1591
2059
|
}
|
|
1592
2060
|
|
|
@@ -1598,54 +2066,47 @@ function rangeSpec(schema) {
|
|
|
1598
2066
|
* @param [autoDefaultStepAny=true] - Determines whether to auto-default step=any when the type is number and no step
|
|
1599
2067
|
* @returns - The extracted `InputPropsType` object
|
|
1600
2068
|
*/
|
|
1601
|
-
|
|
1602
2069
|
function getInputProps(schema, defaultType, options, autoDefaultStepAny) {
|
|
1603
2070
|
if (options === void 0) {
|
|
1604
2071
|
options = {};
|
|
1605
2072
|
}
|
|
1606
|
-
|
|
1607
2073
|
if (autoDefaultStepAny === void 0) {
|
|
1608
2074
|
autoDefaultStepAny = true;
|
|
1609
2075
|
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
}; // If options.inputType is set use that as the input type
|
|
1615
|
-
|
|
2076
|
+
var inputProps = _extends({
|
|
2077
|
+
type: defaultType || "text"
|
|
2078
|
+
}, rangeSpec(schema));
|
|
2079
|
+
// If options.inputType is set use that as the input type
|
|
1616
2080
|
if (options.inputType) {
|
|
1617
2081
|
inputProps.type = options.inputType;
|
|
1618
2082
|
} else if (!defaultType) {
|
|
1619
2083
|
// If the schema is of type number or integer, set the input type to number
|
|
1620
2084
|
if (schema.type === "number") {
|
|
1621
|
-
inputProps.type = "number";
|
|
1622
|
-
|
|
2085
|
+
inputProps.type = "number";
|
|
2086
|
+
// Only add step if one isn't already defined and we are auto-defaulting the "any" step
|
|
1623
2087
|
if (autoDefaultStepAny && inputProps.step === undefined) {
|
|
1624
2088
|
// Setting step to 'any' fixes a bug in Safari where decimals are not
|
|
1625
2089
|
// allowed in number inputs
|
|
1626
2090
|
inputProps.step = "any";
|
|
1627
2091
|
}
|
|
1628
2092
|
} else if (schema.type === "integer") {
|
|
1629
|
-
inputProps.type = "number";
|
|
1630
|
-
|
|
2093
|
+
inputProps.type = "number";
|
|
2094
|
+
// Only add step if one isn't already defined
|
|
1631
2095
|
if (inputProps.step === undefined) {
|
|
1632
2096
|
// Since this is integer, you always want to step up or down in multiples of 1
|
|
1633
2097
|
inputProps.step = 1;
|
|
1634
2098
|
}
|
|
1635
2099
|
}
|
|
1636
2100
|
}
|
|
1637
|
-
|
|
1638
2101
|
if (options.autocomplete) {
|
|
1639
2102
|
inputProps.autoComplete = options.autocomplete;
|
|
1640
2103
|
}
|
|
1641
|
-
|
|
1642
2104
|
return inputProps;
|
|
1643
2105
|
}
|
|
1644
2106
|
|
|
1645
2107
|
/** The default submit button options, exported for testing purposes
|
|
1646
2108
|
*/
|
|
1647
|
-
|
|
1648
|
-
const DEFAULT_OPTIONS = {
|
|
2109
|
+
var DEFAULT_OPTIONS = {
|
|
1649
2110
|
props: {
|
|
1650
2111
|
disabled: false
|
|
1651
2112
|
},
|
|
@@ -1657,21 +2118,15 @@ const DEFAULT_OPTIONS = {
|
|
|
1657
2118
|
* @param [uiSchema={}] - the UI Schema from which to extract submit button props
|
|
1658
2119
|
* @returns - The merging of the `DEFAULT_OPTIONS` with any custom ones
|
|
1659
2120
|
*/
|
|
1660
|
-
|
|
1661
2121
|
function getSubmitButtonOptions(uiSchema) {
|
|
1662
2122
|
if (uiSchema === void 0) {
|
|
1663
2123
|
uiSchema = {};
|
|
1664
2124
|
}
|
|
1665
|
-
|
|
1666
|
-
const uiOptions = getUiOptions(uiSchema);
|
|
1667
|
-
|
|
2125
|
+
var uiOptions = getUiOptions(uiSchema);
|
|
1668
2126
|
if (uiOptions && uiOptions[SUBMIT_BTN_OPTIONS_KEY]) {
|
|
1669
|
-
|
|
1670
|
-
return {
|
|
1671
|
-
...options
|
|
1672
|
-
};
|
|
2127
|
+
var options = uiOptions[SUBMIT_BTN_OPTIONS_KEY];
|
|
2128
|
+
return _extends({}, DEFAULT_OPTIONS, options);
|
|
1673
2129
|
}
|
|
1674
|
-
|
|
1675
2130
|
return DEFAULT_OPTIONS;
|
|
1676
2131
|
}
|
|
1677
2132
|
|
|
@@ -1687,23 +2142,22 @@ function getTemplate(name, registry, uiOptions) {
|
|
|
1687
2142
|
if (uiOptions === void 0) {
|
|
1688
2143
|
uiOptions = {};
|
|
1689
2144
|
}
|
|
1690
|
-
|
|
1691
|
-
const {
|
|
1692
|
-
templates
|
|
1693
|
-
} = registry;
|
|
1694
|
-
|
|
2145
|
+
var templates = registry.templates;
|
|
1695
2146
|
if (name === "ButtonTemplates") {
|
|
1696
2147
|
return templates[name];
|
|
1697
2148
|
}
|
|
1698
|
-
|
|
1699
|
-
|
|
2149
|
+
return (
|
|
2150
|
+
// Evaluating uiOptions[name] results in TS2590: Expression produces a union type that is too complex to represent
|
|
2151
|
+
// To avoid that, we cast uiOptions to `any` before accessing the name field
|
|
2152
|
+
uiOptions[name] || templates[name]
|
|
2153
|
+
);
|
|
1700
2154
|
}
|
|
1701
2155
|
|
|
2156
|
+
var _excluded = ["options"];
|
|
1702
2157
|
/** The map of schema types to widget type to widget name
|
|
1703
2158
|
*/
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
boolean: {
|
|
2159
|
+
var widgetMap = {
|
|
2160
|
+
"boolean": {
|
|
1707
2161
|
checkbox: "CheckboxWidget",
|
|
1708
2162
|
radio: "RadioWidget",
|
|
1709
2163
|
select: "SelectWidget",
|
|
@@ -1760,29 +2214,20 @@ const widgetMap = {
|
|
|
1760
2214
|
* @param AWidget - A widget that will be wrapped or one that is already wrapped
|
|
1761
2215
|
* @returns - The wrapper widget
|
|
1762
2216
|
*/
|
|
1763
|
-
|
|
1764
2217
|
function mergeWidgetOptions(AWidget) {
|
|
1765
|
-
|
|
1766
|
-
|
|
2218
|
+
var MergedWidget = get(AWidget, "MergedWidget");
|
|
2219
|
+
// cache return value as property of widget for proper react reconciliation
|
|
1767
2220
|
if (!MergedWidget) {
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
}
|
|
1775
|
-
return /*#__PURE__*/React.createElement(AWidget, {
|
|
1776
|
-
options: { ...defaultOptions,
|
|
1777
|
-
...options
|
|
1778
|
-
},
|
|
1779
|
-
...props
|
|
1780
|
-
});
|
|
2221
|
+
var defaultOptions = AWidget.defaultProps && AWidget.defaultProps.options || {};
|
|
2222
|
+
MergedWidget = function MergedWidget(_ref) {
|
|
2223
|
+
var options = _ref.options,
|
|
2224
|
+
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
2225
|
+
return /*#__PURE__*/React.createElement(AWidget, _extends({
|
|
2226
|
+
options: _extends({}, defaultOptions, options)
|
|
2227
|
+
}, props));
|
|
1781
2228
|
};
|
|
1782
|
-
|
|
1783
2229
|
set(AWidget, "MergedWidget", MergedWidget);
|
|
1784
2230
|
}
|
|
1785
|
-
|
|
1786
2231
|
return MergedWidget;
|
|
1787
2232
|
}
|
|
1788
2233
|
/** Given a schema representing a field to render and either the name or actual `Widget` implementation, returns the
|
|
@@ -1796,39 +2241,30 @@ function mergeWidgetOptions(AWidget) {
|
|
|
1796
2241
|
* @returns - The `Widget` component to use
|
|
1797
2242
|
* @throws - An error if there is no `Widget` component that can be returned
|
|
1798
2243
|
*/
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
2244
|
function getWidget(schema, widget, registeredWidgets) {
|
|
1802
2245
|
if (registeredWidgets === void 0) {
|
|
1803
2246
|
registeredWidgets = {};
|
|
1804
2247
|
}
|
|
1805
|
-
|
|
1806
|
-
const type = getSchemaType(schema);
|
|
1807
|
-
|
|
2248
|
+
var type = getSchemaType(schema);
|
|
1808
2249
|
if (typeof widget === "function" || widget && ReactIs.isForwardRef( /*#__PURE__*/React.createElement(widget)) || ReactIs.isMemo(widget)) {
|
|
1809
2250
|
return mergeWidgetOptions(widget);
|
|
1810
2251
|
}
|
|
1811
|
-
|
|
1812
2252
|
if (typeof widget !== "string") {
|
|
1813
2253
|
throw new Error("Unsupported widget definition: " + typeof widget);
|
|
1814
2254
|
}
|
|
1815
|
-
|
|
1816
2255
|
if (widget in registeredWidgets) {
|
|
1817
|
-
|
|
2256
|
+
var registeredWidget = registeredWidgets[widget];
|
|
1818
2257
|
return getWidget(schema, registeredWidget, registeredWidgets);
|
|
1819
2258
|
}
|
|
1820
|
-
|
|
1821
2259
|
if (typeof type === "string") {
|
|
1822
2260
|
if (!(type in widgetMap)) {
|
|
1823
2261
|
throw new Error("No widget for type '" + type + "'");
|
|
1824
2262
|
}
|
|
1825
|
-
|
|
1826
2263
|
if (widget in widgetMap[type]) {
|
|
1827
|
-
|
|
1828
|
-
return getWidget(schema,
|
|
2264
|
+
var _registeredWidget = registeredWidgets[widgetMap[type][widget]];
|
|
2265
|
+
return getWidget(schema, _registeredWidget, registeredWidgets);
|
|
1829
2266
|
}
|
|
1830
2267
|
}
|
|
1831
|
-
|
|
1832
2268
|
throw new Error("No widget '" + widget + "' for type '" + type + "'");
|
|
1833
2269
|
}
|
|
1834
2270
|
|
|
@@ -1840,26 +2276,96 @@ function getWidget(schema, widget, registeredWidgets) {
|
|
|
1840
2276
|
* @param [registeredWidgets={}] - A registry of widget name to `Widget` implementation
|
|
1841
2277
|
* @returns - True if the widget exists, false otherwise
|
|
1842
2278
|
*/
|
|
1843
|
-
|
|
1844
2279
|
function hasWidget(schema, widget, registeredWidgets) {
|
|
1845
2280
|
if (registeredWidgets === void 0) {
|
|
1846
2281
|
registeredWidgets = {};
|
|
1847
2282
|
}
|
|
1848
|
-
|
|
1849
2283
|
try {
|
|
1850
2284
|
getWidget(schema, widget, registeredWidgets);
|
|
1851
2285
|
return true;
|
|
1852
2286
|
} catch (e) {
|
|
1853
|
-
|
|
1854
|
-
|
|
2287
|
+
var err = e;
|
|
1855
2288
|
if (err.message && (err.message.startsWith("No widget") || err.message.startsWith("Unsupported widget"))) {
|
|
1856
2289
|
return false;
|
|
1857
2290
|
}
|
|
1858
|
-
|
|
1859
2291
|
throw e;
|
|
1860
2292
|
}
|
|
1861
2293
|
}
|
|
1862
2294
|
|
|
2295
|
+
/** Generates a consistent `id` pattern for a given `id` and a `suffix`
|
|
2296
|
+
*
|
|
2297
|
+
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2298
|
+
* @param suffix - The suffix to append to the id
|
|
2299
|
+
*/
|
|
2300
|
+
function idGenerator(id, suffix) {
|
|
2301
|
+
var theId = isString(id) ? id : id[ID_KEY];
|
|
2302
|
+
return theId + "__" + suffix;
|
|
2303
|
+
}
|
|
2304
|
+
/** Return a consistent `id` for the field description element
|
|
2305
|
+
*
|
|
2306
|
+
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2307
|
+
* @returns - The consistent id for the field description element from the given `id`
|
|
2308
|
+
*/
|
|
2309
|
+
function descriptionId(id) {
|
|
2310
|
+
return idGenerator(id, "description");
|
|
2311
|
+
}
|
|
2312
|
+
/** Return a consistent `id` for the field error element
|
|
2313
|
+
*
|
|
2314
|
+
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2315
|
+
* @returns - The consistent id for the field error element from the given `id`
|
|
2316
|
+
*/
|
|
2317
|
+
function errorId(id) {
|
|
2318
|
+
return idGenerator(id, "error");
|
|
2319
|
+
}
|
|
2320
|
+
/** Return a consistent `id` for the field examples element
|
|
2321
|
+
*
|
|
2322
|
+
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2323
|
+
* @returns - The consistent id for the field examples element from the given `id`
|
|
2324
|
+
*/
|
|
2325
|
+
function examplesId(id) {
|
|
2326
|
+
return idGenerator(id, "examples");
|
|
2327
|
+
}
|
|
2328
|
+
/** Return a consistent `id` for the field help element
|
|
2329
|
+
*
|
|
2330
|
+
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2331
|
+
* @returns - The consistent id for the field help element from the given `id`
|
|
2332
|
+
*/
|
|
2333
|
+
function helpId(id) {
|
|
2334
|
+
return idGenerator(id, "help");
|
|
2335
|
+
}
|
|
2336
|
+
/** Return a consistent `id` for the field title element
|
|
2337
|
+
*
|
|
2338
|
+
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2339
|
+
* @returns - The consistent id for the field title element from the given `id`
|
|
2340
|
+
*/
|
|
2341
|
+
function titleId(id) {
|
|
2342
|
+
return idGenerator(id, "title");
|
|
2343
|
+
}
|
|
2344
|
+
/** Return a list of element ids that contain additional information about the field that can be used to as the aria
|
|
2345
|
+
* description of the field. This is correctly omitting `titleId` which would be "labeling" rather than "describing" the
|
|
2346
|
+
* element.
|
|
2347
|
+
*
|
|
2348
|
+
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2349
|
+
* @param [includeExamples=false] - Optional flag, if true, will add the `examplesId` into the list
|
|
2350
|
+
* @returns - The string containing the list of ids for use in an `aria-describedBy` attribute
|
|
2351
|
+
*/
|
|
2352
|
+
function ariaDescribedByIds(id, includeExamples) {
|
|
2353
|
+
if (includeExamples === void 0) {
|
|
2354
|
+
includeExamples = false;
|
|
2355
|
+
}
|
|
2356
|
+
var examples = includeExamples ? " " + examplesId(id) : "";
|
|
2357
|
+
return errorId(id) + " " + descriptionId(id) + " " + helpId(id) + examples;
|
|
2358
|
+
}
|
|
2359
|
+
/** Return a consistent `id` for the `optionIndex`s of a `Radio` or `Checkboxes` widget
|
|
2360
|
+
*
|
|
2361
|
+
* @param id - The id of the parent component for the option
|
|
2362
|
+
* @param optionIndex - The index of the option for which the id is desired
|
|
2363
|
+
* @returns - An id for the option index based on the parent `id`
|
|
2364
|
+
*/
|
|
2365
|
+
function optionId(id, optionIndex) {
|
|
2366
|
+
return id + "-" + optionIndex;
|
|
2367
|
+
}
|
|
2368
|
+
|
|
1863
2369
|
/** Converts a local Date string into a UTC date string
|
|
1864
2370
|
*
|
|
1865
2371
|
* @param dateString - The string representation of a date as accepted by the `Date()` constructor
|
|
@@ -1876,16 +2382,13 @@ function localToUTC(dateString) {
|
|
|
1876
2382
|
* @returns - The constant value for the schema
|
|
1877
2383
|
* @throws - Error when the schema does not have a constant value
|
|
1878
2384
|
*/
|
|
1879
|
-
|
|
1880
2385
|
function toConstant(schema) {
|
|
1881
|
-
if (ENUM_KEY in schema && Array.isArray(schema
|
|
1882
|
-
return schema
|
|
2386
|
+
if (ENUM_KEY in schema && Array.isArray(schema["enum"]) && schema["enum"].length === 1) {
|
|
2387
|
+
return schema["enum"][0];
|
|
1883
2388
|
}
|
|
1884
|
-
|
|
1885
2389
|
if (CONST_KEY in schema) {
|
|
1886
|
-
return schema
|
|
2390
|
+
return schema["const"];
|
|
1887
2391
|
}
|
|
1888
|
-
|
|
1889
2392
|
throw new Error("schema cannot be inferred as a constant");
|
|
1890
2393
|
}
|
|
1891
2394
|
|
|
@@ -1897,35 +2400,31 @@ function toConstant(schema) {
|
|
|
1897
2400
|
* @param schema - The schema from which to extract the options list
|
|
1898
2401
|
* @returns - The list of options from the schema
|
|
1899
2402
|
*/
|
|
1900
|
-
|
|
1901
2403
|
function optionsList(schema) {
|
|
1902
2404
|
// enumNames was deprecated in v5 and is intentionally omitted from the RJSFSchema type.
|
|
1903
2405
|
// Cast the type to include enumNames so the feature still works.
|
|
1904
|
-
|
|
1905
|
-
|
|
2406
|
+
var schemaWithEnumNames = schema;
|
|
1906
2407
|
if (schemaWithEnumNames.enumNames && process.env.NODE_ENV !== "production") {
|
|
1907
2408
|
console.warn("The enumNames property is deprecated and may be removed in a future major release.");
|
|
1908
2409
|
}
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
const label = schemaWithEnumNames.enumNames && schemaWithEnumNames.enumNames[i] || String(value);
|
|
2410
|
+
if (schema["enum"]) {
|
|
2411
|
+
return schema["enum"].map(function (value, i) {
|
|
2412
|
+
var label = schemaWithEnumNames.enumNames && schemaWithEnumNames.enumNames[i] || String(value);
|
|
1913
2413
|
return {
|
|
1914
|
-
label,
|
|
1915
|
-
value
|
|
2414
|
+
label: label,
|
|
2415
|
+
value: value
|
|
1916
2416
|
};
|
|
1917
2417
|
});
|
|
1918
2418
|
}
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
const label = aSchema.title || String(value);
|
|
2419
|
+
var altSchemas = schema.oneOf || schema.anyOf;
|
|
2420
|
+
return altSchemas && altSchemas.map(function (aSchemaDef) {
|
|
2421
|
+
var aSchema = aSchemaDef;
|
|
2422
|
+
var value = toConstant(aSchema);
|
|
2423
|
+
var label = aSchema.title || String(value);
|
|
1925
2424
|
return {
|
|
1926
2425
|
schema: aSchema,
|
|
1927
|
-
label,
|
|
1928
|
-
value
|
|
2426
|
+
label: label,
|
|
2427
|
+
value: value
|
|
1929
2428
|
};
|
|
1930
2429
|
});
|
|
1931
2430
|
}
|
|
@@ -1944,34 +2443,35 @@ function orderProperties(properties, order) {
|
|
|
1944
2443
|
if (!Array.isArray(order)) {
|
|
1945
2444
|
return properties;
|
|
1946
2445
|
}
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
2446
|
+
var arrayToHash = function arrayToHash(arr) {
|
|
2447
|
+
return arr.reduce(function (prev, curr) {
|
|
2448
|
+
prev[curr] = true;
|
|
2449
|
+
return prev;
|
|
2450
|
+
}, {});
|
|
2451
|
+
};
|
|
2452
|
+
var errorPropList = function errorPropList(arr) {
|
|
2453
|
+
return arr.length > 1 ? "properties '" + arr.join("', '") + "'" : "property '" + arr[0] + "'";
|
|
2454
|
+
};
|
|
2455
|
+
var propertyHash = arrayToHash(properties);
|
|
2456
|
+
var orderFiltered = order.filter(function (prop) {
|
|
2457
|
+
return prop === "*" || propertyHash[prop];
|
|
2458
|
+
});
|
|
2459
|
+
var orderHash = arrayToHash(orderFiltered);
|
|
2460
|
+
var rest = properties.filter(function (prop) {
|
|
2461
|
+
return !orderHash[prop];
|
|
2462
|
+
});
|
|
2463
|
+
var restIndex = orderFiltered.indexOf("*");
|
|
1961
2464
|
if (restIndex === -1) {
|
|
1962
2465
|
if (rest.length) {
|
|
1963
2466
|
throw new Error("uiSchema order list does not contain " + errorPropList(rest));
|
|
1964
2467
|
}
|
|
1965
|
-
|
|
1966
2468
|
return orderFiltered;
|
|
1967
2469
|
}
|
|
1968
|
-
|
|
1969
2470
|
if (restIndex !== orderFiltered.lastIndexOf("*")) {
|
|
1970
2471
|
throw new Error("uiSchema order list contains more than one wildcard item");
|
|
1971
2472
|
}
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
complete.splice(restIndex, 1, ...rest);
|
|
2473
|
+
var complete = [].concat(orderFiltered);
|
|
2474
|
+
complete.splice.apply(complete, [restIndex, 1].concat(rest));
|
|
1975
2475
|
return complete;
|
|
1976
2476
|
}
|
|
1977
2477
|
|
|
@@ -1982,12 +2482,10 @@ function orderProperties(properties, order) {
|
|
|
1982
2482
|
* @returns - The number converted to a string with leading zero padding if the number of digits is less than `width`
|
|
1983
2483
|
*/
|
|
1984
2484
|
function pad(num, width) {
|
|
1985
|
-
|
|
1986
|
-
|
|
2485
|
+
var s = String(num);
|
|
1987
2486
|
while (s.length < width) {
|
|
1988
2487
|
s = "0" + s;
|
|
1989
2488
|
}
|
|
1990
|
-
|
|
1991
2489
|
return s;
|
|
1992
2490
|
}
|
|
1993
2491
|
|
|
@@ -2002,7 +2500,6 @@ function parseDateString(dateString, includeTime) {
|
|
|
2002
2500
|
if (includeTime === void 0) {
|
|
2003
2501
|
includeTime = true;
|
|
2004
2502
|
}
|
|
2005
|
-
|
|
2006
2503
|
if (!dateString) {
|
|
2007
2504
|
return {
|
|
2008
2505
|
year: -1,
|
|
@@ -2013,13 +2510,10 @@ function parseDateString(dateString, includeTime) {
|
|
|
2013
2510
|
second: includeTime ? -1 : 0
|
|
2014
2511
|
};
|
|
2015
2512
|
}
|
|
2016
|
-
|
|
2017
|
-
const date = new Date(dateString);
|
|
2018
|
-
|
|
2513
|
+
var date = new Date(dateString);
|
|
2019
2514
|
if (Number.isNaN(date.getTime())) {
|
|
2020
2515
|
throw new Error("Unable to parse date " + dateString);
|
|
2021
2516
|
}
|
|
2022
|
-
|
|
2023
2517
|
return {
|
|
2024
2518
|
year: date.getUTCFullYear(),
|
|
2025
2519
|
month: date.getUTCMonth() + 1,
|
|
@@ -2030,55 +2524,6 @@ function parseDateString(dateString, includeTime) {
|
|
|
2030
2524
|
};
|
|
2031
2525
|
}
|
|
2032
2526
|
|
|
2033
|
-
const nums = /*#__PURE__*/new Set(["number", "integer"]);
|
|
2034
|
-
/** Returns the real value for a select widget due to a silly limitation in the DOM which causes option change event
|
|
2035
|
-
* values to always be retrieved as strings. Uses the `schema` to help determine the value's true type. If the value is
|
|
2036
|
-
* an empty string, then the `emptyValue` from the `options` is returned, falling back to undefined.
|
|
2037
|
-
*
|
|
2038
|
-
* @param schema - The schema to used to determine the value's true type
|
|
2039
|
-
* @param [value] - The value to convert
|
|
2040
|
-
* @param [options] - The UIOptionsType from which to potentially extract the emptyValue
|
|
2041
|
-
* @returns - The `value` converted to the proper type
|
|
2042
|
-
*/
|
|
2043
|
-
|
|
2044
|
-
function processSelectValue(schema, value, options) {
|
|
2045
|
-
const {
|
|
2046
|
-
enum: schemaEnum,
|
|
2047
|
-
type,
|
|
2048
|
-
items
|
|
2049
|
-
} = schema;
|
|
2050
|
-
|
|
2051
|
-
if (value === "") {
|
|
2052
|
-
return options && options.emptyValue !== undefined ? options.emptyValue : undefined;
|
|
2053
|
-
}
|
|
2054
|
-
|
|
2055
|
-
if (type === "array" && items && nums.has(get(items, "type"))) {
|
|
2056
|
-
return value.map(asNumber);
|
|
2057
|
-
}
|
|
2058
|
-
|
|
2059
|
-
if (type === "boolean") {
|
|
2060
|
-
return value === "true";
|
|
2061
|
-
}
|
|
2062
|
-
|
|
2063
|
-
if (nums.has(type)) {
|
|
2064
|
-
return asNumber(value);
|
|
2065
|
-
} // If type is undefined, but an enum is present, try and infer the type from
|
|
2066
|
-
// the enum values
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
if (Array.isArray(schemaEnum)) {
|
|
2070
|
-
if (schemaEnum.every(x => nums.has(guessType(x)))) {
|
|
2071
|
-
return asNumber(value);
|
|
2072
|
-
}
|
|
2073
|
-
|
|
2074
|
-
if (schemaEnum.every(x => guessType(x) === "boolean")) {
|
|
2075
|
-
return value === "true";
|
|
2076
|
-
}
|
|
2077
|
-
}
|
|
2078
|
-
|
|
2079
|
-
return value;
|
|
2080
|
-
}
|
|
2081
|
-
|
|
2082
2527
|
/** Check to see if a `schema` specifies that a value must be true. This happens when:
|
|
2083
2528
|
* - `schema.const` is truthy
|
|
2084
2529
|
* - `schema.enum` == `[true]`
|
|
@@ -2090,32 +2535,28 @@ function processSelectValue(schema, value, options) {
|
|
|
2090
2535
|
*/
|
|
2091
2536
|
function schemaRequiresTrueValue(schema) {
|
|
2092
2537
|
// Check if const is a truthy value
|
|
2093
|
-
if (schema
|
|
2538
|
+
if (schema["const"]) {
|
|
2094
2539
|
return true;
|
|
2095
|
-
}
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
if (schema.enum && schema.enum.length === 1 && schema.enum[0] === true) {
|
|
2540
|
+
}
|
|
2541
|
+
// Check if an enum has a single value of true
|
|
2542
|
+
if (schema["enum"] && schema["enum"].length === 1 && schema["enum"][0] === true) {
|
|
2099
2543
|
return true;
|
|
2100
|
-
}
|
|
2101
|
-
|
|
2102
|
-
|
|
2544
|
+
}
|
|
2545
|
+
// If anyOf has a single value, evaluate the subschema
|
|
2103
2546
|
if (schema.anyOf && schema.anyOf.length === 1) {
|
|
2104
2547
|
return schemaRequiresTrueValue(schema.anyOf[0]);
|
|
2105
|
-
}
|
|
2106
|
-
|
|
2107
|
-
|
|
2548
|
+
}
|
|
2549
|
+
// If oneOf has a single value, evaluate the subschema
|
|
2108
2550
|
if (schema.oneOf && schema.oneOf.length === 1) {
|
|
2109
2551
|
return schemaRequiresTrueValue(schema.oneOf[0]);
|
|
2110
|
-
}
|
|
2111
|
-
|
|
2112
|
-
|
|
2552
|
+
}
|
|
2553
|
+
// Evaluate each subschema in allOf, to see if one of them requires a true value
|
|
2113
2554
|
if (schema.allOf) {
|
|
2114
|
-
|
|
2115
|
-
|
|
2555
|
+
var schemaSome = function schemaSome(subSchema) {
|
|
2556
|
+
return schemaRequiresTrueValue(subSchema);
|
|
2557
|
+
};
|
|
2116
2558
|
return schema.allOf.some(schemaSome);
|
|
2117
2559
|
}
|
|
2118
|
-
|
|
2119
2560
|
return false;
|
|
2120
2561
|
}
|
|
2121
2562
|
|
|
@@ -2127,12 +2568,9 @@ function schemaRequiresTrueValue(schema) {
|
|
|
2127
2568
|
* @param nextState - The next set of state against which to check
|
|
2128
2569
|
* @returns - True if the component should be re-rendered, false otherwise
|
|
2129
2570
|
*/
|
|
2130
|
-
|
|
2131
2571
|
function shouldRender(component, nextProps, nextState) {
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
state
|
|
2135
|
-
} = component;
|
|
2572
|
+
var props = component.props,
|
|
2573
|
+
state = component.state;
|
|
2136
2574
|
return !deepEquals(props, nextProps) || !deepEquals(state, nextState);
|
|
2137
2575
|
}
|
|
2138
2576
|
|
|
@@ -2147,17 +2585,17 @@ function toDateString(dateObject, time) {
|
|
|
2147
2585
|
if (time === void 0) {
|
|
2148
2586
|
time = true;
|
|
2149
2587
|
}
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
minute = 0,
|
|
2157
|
-
second =
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2588
|
+
var year = dateObject.year,
|
|
2589
|
+
month = dateObject.month,
|
|
2590
|
+
day = dateObject.day,
|
|
2591
|
+
_dateObject$hour = dateObject.hour,
|
|
2592
|
+
hour = _dateObject$hour === void 0 ? 0 : _dateObject$hour,
|
|
2593
|
+
_dateObject$minute = dateObject.minute,
|
|
2594
|
+
minute = _dateObject$minute === void 0 ? 0 : _dateObject$minute,
|
|
2595
|
+
_dateObject$second = dateObject.second,
|
|
2596
|
+
second = _dateObject$second === void 0 ? 0 : _dateObject$second;
|
|
2597
|
+
var utcTime = Date.UTC(year, month - 1, day, hour, minute, second);
|
|
2598
|
+
var datetime = new Date(utcTime).toJSON();
|
|
2161
2599
|
return time ? datetime : datetime.slice(0, 10);
|
|
2162
2600
|
}
|
|
2163
2601
|
|
|
@@ -2166,27 +2604,25 @@ function toDateString(dateObject, time) {
|
|
|
2166
2604
|
* @param jsonDate - A UTC date string
|
|
2167
2605
|
* @returns - An empty string when `jsonDate` is falsey, otherwise a date string in local format
|
|
2168
2606
|
*/
|
|
2169
|
-
|
|
2170
2607
|
function utcToLocal(jsonDate) {
|
|
2171
2608
|
if (!jsonDate) {
|
|
2172
2609
|
return "";
|
|
2173
|
-
}
|
|
2610
|
+
}
|
|
2611
|
+
// required format of `'yyyy-MM-ddThh:mm' followed by optional ':ss' or ':ss.SSS'
|
|
2174
2612
|
// https://html.spec.whatwg.org/multipage/input.html#local-date-and-time-state-(type%3Ddatetime-local)
|
|
2175
2613
|
// > should be a _valid local date and time string_ (not GMT)
|
|
2176
2614
|
// Note - date constructor passed local ISO-8601 does not correctly
|
|
2177
2615
|
// change time to UTC in node pre-8
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
const ss = pad(date.getSeconds(), 2);
|
|
2187
|
-
const SSS = pad(date.getMilliseconds(), 3);
|
|
2616
|
+
var date = new Date(jsonDate);
|
|
2617
|
+
var yyyy = pad(date.getFullYear(), 4);
|
|
2618
|
+
var MM = pad(date.getMonth() + 1, 2);
|
|
2619
|
+
var dd = pad(date.getDate(), 2);
|
|
2620
|
+
var hh = pad(date.getHours(), 2);
|
|
2621
|
+
var mm = pad(date.getMinutes(), 2);
|
|
2622
|
+
var ss = pad(date.getSeconds(), 2);
|
|
2623
|
+
var SSS = pad(date.getMilliseconds(), 3);
|
|
2188
2624
|
return yyyy + "-" + MM + "-" + dd + "T" + hh + ":" + mm + ":" + ss + "." + SSS;
|
|
2189
2625
|
}
|
|
2190
2626
|
|
|
2191
|
-
export { ADDITIONAL_PROPERTIES_KEY, ADDITIONAL_PROPERTY_FLAG, ALL_OF_KEY, ANY_OF_KEY, CONST_KEY, DEFAULT_KEY, DEFINITIONS_KEY, DEPENDENCIES_KEY, ENUM_KEY, ERRORS_KEY, ID_KEY, ITEMS_KEY, NAME_KEY, ONE_OF_KEY, PROPERTIES_KEY, REF_KEY, REQUIRED_KEY, RJSF_ADDITONAL_PROPERTIES_FLAG, SUBMIT_BTN_OPTIONS_KEY, UI_FIELD_KEY, UI_OPTIONS_KEY, UI_WIDGET_KEY, allowAdditionalItems, asNumber, canExpand, createSchemaUtils, dataURItoBlob, deepEquals, findSchemaDefinition, getDefaultFormState, getDisplayLabel, getInputProps, getMatchingOption, getSchemaType, getSubmitButtonOptions, getTemplate, getUiOptions, getWidget, guessType, hasWidget, isConstant, isCustomWidget, isFilesArray, isFixedItems, isMultiSelect, isObject, isSelect, localToUTC, mergeDefaultsWithFormData, mergeObjects, mergeSchemas, mergeValidationData, optionsList, orderProperties, pad, parseDateString,
|
|
2627
|
+
export { ADDITIONAL_PROPERTIES_KEY, ADDITIONAL_PROPERTY_FLAG, ALL_OF_KEY, ANY_OF_KEY, CONST_KEY, DEFAULT_KEY, DEFINITIONS_KEY, DEPENDENCIES_KEY, ENUM_KEY, ERRORS_KEY, ErrorSchemaBuilder, ID_KEY, ITEMS_KEY, NAME_KEY, ONE_OF_KEY, PROPERTIES_KEY, REF_KEY, REQUIRED_KEY, RJSF_ADDITONAL_PROPERTIES_FLAG, SUBMIT_BTN_OPTIONS_KEY, UI_FIELD_KEY, UI_OPTIONS_KEY, UI_WIDGET_KEY, allowAdditionalItems, ariaDescribedByIds, asNumber, canExpand, createSchemaUtils, dataURItoBlob, deepEquals, descriptionId, enumOptionsDeselectValue, enumOptionsIndexForValue, enumOptionsIsSelected, enumOptionsSelectValue, enumOptionsValueForIndex, errorId, examplesId, findSchemaDefinition, getClosestMatchingOption, getDefaultFormState, getDisplayLabel, getFirstMatchingOption, getInputProps, getMatchingOption, getSchemaType, getSubmitButtonOptions, getTemplate, getUiOptions, getWidget, guessType, hasWidget, helpId, isConstant, isCustomWidget, isFilesArray, isFixedItems, isMultiSelect, isObject, isSelect, localToUTC, mergeDefaultsWithFormData, mergeObjects, mergeSchemas, mergeValidationData, optionId, optionsList, orderProperties, pad, parseDateString, rangeSpec, retrieveSchema, sanitizeDataForNewSchema, schemaRequiresTrueValue, shouldRender, titleId, toConstant, toDateString, toIdSchema, toPathSchema, utcToLocal };
|
|
2192
2628
|
//# sourceMappingURL=utils.esm.js.map
|