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