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