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