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