@rjsf/utils 5.11.1 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2544 -5
- package/dist/index.js.map +7 -0
- package/dist/utils.esm.js +1228 -2105
- package/dist/utils.esm.js.map +7 -1
- package/dist/utils.umd.js +2414 -0
- package/lib/ErrorSchemaBuilder.d.ts +60 -0
- package/lib/ErrorSchemaBuilder.js +103 -0
- package/lib/ErrorSchemaBuilder.js.map +1 -0
- package/lib/allowAdditionalItems.d.ts +8 -0
- package/lib/allowAdditionalItems.js +14 -0
- package/lib/allowAdditionalItems.js.map +1 -0
- package/lib/asNumber.d.ts +10 -0
- package/lib/asNumber.js +36 -0
- package/lib/asNumber.js.map +1 -0
- package/lib/canExpand.d.ts +11 -0
- package/lib/canExpand.js +26 -0
- package/lib/canExpand.js.map +1 -0
- package/lib/constants.d.ts +31 -0
- package/lib/constants.js +32 -0
- package/lib/constants.js.map +1 -0
- package/lib/createErrorHandler.d.ts +7 -0
- package/lib/createErrorHandler.js +31 -0
- package/lib/createErrorHandler.js.map +1 -0
- package/lib/createSchemaUtils.d.ts +10 -0
- package/lib/createSchemaUtils.js +207 -0
- package/lib/createSchemaUtils.js.map +1 -0
- package/lib/dataURItoBlob.d.ts +16 -0
- package/lib/dataURItoBlob.js +43 -0
- package/lib/dataURItoBlob.js.map +1 -0
- package/lib/deepEquals.d.ts +8 -0
- package/lib/deepEquals.js +19 -0
- package/lib/deepEquals.js.map +1 -0
- package/lib/englishStringTranslator.d.ts +10 -0
- package/lib/englishStringTranslator.js +13 -0
- package/lib/englishStringTranslator.js.map +1 -0
- package/lib/enumOptionsDeselectValue.d.ts +14 -0
- package/lib/enumOptionsDeselectValue.js +22 -0
- package/lib/enumOptionsDeselectValue.js.map +1 -0
- package/lib/enumOptionsIndexForValue.d.ts +13 -0
- package/lib/enumOptionsIndexForValue.js +22 -0
- package/lib/enumOptionsIndexForValue.js.map +1 -0
- package/lib/enumOptionsIsSelected.d.ts +8 -0
- package/lib/enumOptionsIsSelected.js +14 -0
- package/lib/enumOptionsIsSelected.js.map +1 -0
- package/lib/enumOptionsSelectValue.d.ts +10 -0
- package/lib/enumOptionsSelectValue.js +23 -0
- package/lib/enumOptionsSelectValue.js.map +1 -0
- package/lib/enumOptionsValueForIndex.d.ts +13 -0
- package/lib/enumOptionsValueForIndex.js +21 -0
- package/lib/enumOptionsValueForIndex.js.map +1 -0
- package/lib/enums.d.ts +72 -0
- package/lib/enums.js +76 -0
- package/lib/enums.js.map +1 -0
- package/lib/findSchemaDefinition.d.ts +20 -0
- package/lib/findSchemaDefinition.js +49 -0
- package/lib/findSchemaDefinition.js.map +1 -0
- package/lib/getDiscriminatorFieldFromSchema.d.ts +8 -0
- package/lib/getDiscriminatorFieldFromSchema.js +20 -0
- package/lib/getDiscriminatorFieldFromSchema.js.map +1 -0
- package/lib/getInputProps.d.ts +10 -0
- package/lib/getInputProps.js +41 -0
- package/lib/getInputProps.js.map +1 -0
- package/lib/getSchemaType.d.ts +13 -0
- package/lib/getSchemaType.js +29 -0
- package/lib/getSchemaType.js.map +1 -0
- package/lib/getSubmitButtonOptions.d.ts +10 -0
- package/lib/getSubmitButtonOptions.js +25 -0
- package/lib/getSubmitButtonOptions.js.map +1 -0
- package/lib/getTemplate.d.ts +10 -0
- package/lib/getTemplate.js +19 -0
- package/lib/getTemplate.js.map +1 -0
- package/lib/getUiOptions.d.ts +9 -0
- package/lib/getUiOptions.js +25 -0
- package/lib/getUiOptions.js.map +1 -0
- package/lib/getWidget.d.ts +13 -0
- package/lib/getWidget.js +118 -0
- package/lib/getWidget.js.map +1 -0
- package/lib/guessType.d.ts +7 -0
- package/lib/guessType.js +29 -0
- package/lib/guessType.js.map +1 -0
- package/lib/hasWidget.d.ts +10 -0
- package/lib/hasWidget.js +23 -0
- package/lib/hasWidget.js.map +1 -0
- package/lib/hashForSchema.d.ts +8 -0
- package/lib/hashForSchema.js +29 -0
- package/lib/hashForSchema.js.map +1 -0
- package/lib/idGenerators.d.ts +47 -0
- package/lib/idGenerators.js +73 -0
- package/lib/idGenerators.js.map +1 -0
- package/lib/index.d.ts +57 -0
- package/lib/index.js +58 -0
- package/lib/index.js.map +1 -0
- package/lib/isConstant.d.ts +8 -0
- package/lib/isConstant.js +11 -0
- package/lib/isConstant.js.map +1 -0
- package/lib/isCustomWidget.d.ts +7 -0
- package/lib/isCustomWidget.js +13 -0
- package/lib/isCustomWidget.js.map +1 -0
- package/lib/isFixedItems.d.ts +8 -0
- package/lib/isFixedItems.js +11 -0
- package/lib/isFixedItems.js.map +1 -0
- package/lib/isObject.d.ts +7 -0
- package/lib/isObject.js +16 -0
- package/lib/isObject.js.map +1 -0
- package/lib/labelValue.d.ts +13 -0
- package/lib/labelValue.js +4 -0
- package/lib/labelValue.js.map +1 -0
- package/lib/localToUTC.d.ts +6 -0
- package/lib/localToUTC.js +9 -0
- package/lib/localToUTC.js.map +1 -0
- package/lib/mergeDefaultsWithFormData.d.ts +17 -0
- package/lib/mergeDefaultsWithFormData.js +43 -0
- package/lib/mergeDefaultsWithFormData.js.map +1 -0
- package/lib/mergeObjects.d.ts +11 -0
- package/lib/mergeObjects.js +35 -0
- package/lib/mergeObjects.js.map +1 -0
- package/lib/mergeSchemas.d.ts +10 -0
- package/lib/mergeSchemas.js +35 -0
- package/lib/mergeSchemas.js.map +1 -0
- package/lib/optionsList.d.ts +10 -0
- package/lib/optionsList.js +36 -0
- package/lib/optionsList.js.map +1 -0
- package/lib/orderProperties.d.ts +11 -0
- package/lib/orderProperties.js +38 -0
- package/lib/orderProperties.js.map +1 -0
- package/lib/pad.d.ts +7 -0
- package/lib/pad.js +14 -0
- package/lib/pad.js.map +1 -0
- package/lib/parseDateString.d.ts +9 -0
- package/lib/parseDateString.js +32 -0
- package/lib/parseDateString.js.map +1 -0
- package/lib/parser/ParserValidator.d.ts +70 -0
- package/lib/parser/ParserValidator.js +93 -0
- package/lib/parser/ParserValidator.js.map +1 -0
- package/lib/parser/index.d.ts +4 -0
- package/lib/parser/index.js +3 -0
- package/lib/parser/index.js.map +1 -0
- package/lib/parser/schemaParser.d.ts +9 -0
- package/lib/parser/schemaParser.js +48 -0
- package/lib/parser/schemaParser.js.map +1 -0
- package/lib/rangeSpec.d.ts +9 -0
- package/lib/rangeSpec.js +20 -0
- package/lib/rangeSpec.js.map +1 -0
- package/lib/replaceStringParameters.d.ts +9 -0
- package/lib/replaceStringParameters.js +23 -0
- package/lib/replaceStringParameters.js.map +1 -0
- package/lib/schema/getClosestMatchingOption.d.ts +49 -0
- package/lib/schema/getClosestMatchingOption.js +154 -0
- package/lib/schema/getClosestMatchingOption.js.map +1 -0
- package/lib/schema/getDefaultFormState.d.ts +66 -0
- package/lib/schema/getDefaultFormState.js +351 -0
- package/lib/schema/getDefaultFormState.js.map +1 -0
- package/lib/schema/getDisplayLabel.d.ts +12 -0
- package/lib/schema/getDisplayLabel.js +39 -0
- package/lib/schema/getDisplayLabel.js.map +1 -0
- package/lib/schema/getFirstMatchingOption.d.ts +13 -0
- package/lib/schema/getFirstMatchingOption.js +16 -0
- package/lib/schema/getFirstMatchingOption.js.map +1 -0
- package/lib/schema/getMatchingOption.d.ts +14 -0
- package/lib/schema/getMatchingOption.js +80 -0
- package/lib/schema/getMatchingOption.js.map +1 -0
- package/lib/schema/index.d.ts +14 -0
- package/lib/schema/index.js +15 -0
- package/lib/schema/index.js.map +1 -0
- package/lib/schema/isFilesArray.d.ts +10 -0
- package/lib/schema/isFilesArray.js +21 -0
- package/lib/schema/isFilesArray.js.map +1 -0
- package/lib/schema/isMultiSelect.d.ts +9 -0
- package/lib/schema/isMultiSelect.js +15 -0
- package/lib/schema/isMultiSelect.js.map +1 -0
- package/lib/schema/isSelect.d.ts +9 -0
- package/lib/schema/isSelect.js +21 -0
- package/lib/schema/isSelect.js.map +1 -0
- package/lib/schema/mergeValidationData.d.ts +14 -0
- package/lib/schema/mergeValidationData.js +28 -0
- package/lib/schema/mergeValidationData.js.map +1 -0
- package/lib/schema/retrieveSchema.d.ts +170 -0
- package/lib/schema/retrieveSchema.js +437 -0
- package/lib/schema/retrieveSchema.js.map +1 -0
- package/lib/schema/sanitizeDataForNewSchema.d.ts +49 -0
- package/lib/schema/sanitizeDataForNewSchema.js +173 -0
- package/lib/schema/sanitizeDataForNewSchema.js.map +1 -0
- package/lib/schema/toIdSchema.d.ts +13 -0
- package/lib/schema/toIdSchema.js +59 -0
- package/lib/schema/toIdSchema.js.map +1 -0
- package/lib/schema/toPathSchema.d.ts +11 -0
- package/lib/schema/toPathSchema.js +68 -0
- package/lib/schema/toPathSchema.js.map +1 -0
- package/lib/schemaRequiresTrueValue.d.ts +11 -0
- package/lib/schemaRequiresTrueValue.js +34 -0
- package/lib/schemaRequiresTrueValue.js.map +1 -0
- package/lib/shouldRender.d.ts +10 -0
- package/lib/shouldRender.js +14 -0
- package/lib/shouldRender.js.map +1 -0
- package/lib/toConstant.d.ts +9 -0
- package/lib/toConstant.js +18 -0
- package/lib/toConstant.js.map +1 -0
- package/lib/toDateString.d.ts +9 -0
- package/lib/toDateString.js +14 -0
- package/lib/toDateString.js.map +1 -0
- package/lib/toErrorList.d.ts +8 -0
- package/lib/toErrorList.js +34 -0
- package/lib/toErrorList.js.map +1 -0
- package/lib/toErrorSchema.d.ts +21 -0
- package/lib/toErrorSchema.js +41 -0
- package/lib/toErrorSchema.js.map +1 -0
- package/lib/types.d.ts +982 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -0
- package/lib/unwrapErrorHandler.d.ts +7 -0
- package/lib/unwrapErrorHandler.js +21 -0
- package/lib/unwrapErrorHandler.js.map +1 -0
- package/lib/utcToLocal.d.ts +6 -0
- package/lib/utcToLocal.js +26 -0
- package/lib/utcToLocal.js.map +1 -0
- package/lib/validationDataMerge.d.ts +11 -0
- package/lib/validationDataMerge.js +26 -0
- package/lib/validationDataMerge.js.map +1 -0
- package/lib/withIdRefPrefix.d.ts +8 -0
- package/lib/withIdRefPrefix.js +47 -0
- package/lib/withIdRefPrefix.js.map +1 -0
- package/package.json +21 -13
- package/src/ErrorSchemaBuilder.ts +112 -0
- package/src/allowAdditionalItems.ts +15 -0
- package/src/asNumber.ts +38 -0
- package/src/canExpand.ts +31 -0
- package/src/constants.ts +31 -0
- package/src/createErrorHandler.ts +33 -0
- package/src/createSchemaUtils.ts +298 -0
- package/src/dataURItoBlob.ts +42 -0
- package/src/deepEquals.ts +19 -0
- package/src/englishStringTranslator.ts +14 -0
- package/src/enumOptionsDeselectValue.ts +28 -0
- package/src/enumOptionsIndexForValue.ts +27 -0
- package/src/enumOptionsIsSelected.ts +19 -0
- package/src/enumOptionsSelectValue.ts +28 -0
- package/src/enumOptionsValueForIndex.ts +26 -0
- package/src/enums.ts +74 -0
- package/src/findSchemaDefinition.ts +54 -0
- package/src/getDiscriminatorFieldFromSchema.ts +21 -0
- package/src/getInputProps.ts +55 -0
- package/src/getSchemaType.ts +37 -0
- package/src/getSubmitButtonOptions.ts +32 -0
- package/src/getTemplate.ts +26 -0
- package/src/getUiOptions.ts +32 -0
- package/src/getWidget.tsx +133 -0
- package/src/guessType.ts +28 -0
- package/src/hasWidget.ts +27 -0
- package/src/hashForSchema.ts +31 -0
- package/src/idGenerators.ts +81 -0
- package/src/index.ts +118 -0
- package/src/isConstant.ts +12 -0
- package/src/isCustomWidget.ts +19 -0
- package/src/isFixedItems.ts +12 -0
- package/src/isObject.ts +15 -0
- package/src/labelValue.ts +16 -0
- package/src/localToUTC.ts +8 -0
- package/src/mergeDefaultsWithFormData.ts +53 -0
- package/src/mergeObjects.ts +39 -0
- package/src/mergeSchemas.ts +38 -0
- package/src/optionsList.ts +41 -0
- package/src/orderProperties.ts +44 -0
- package/src/pad.ts +13 -0
- package/src/parseDateString.ts +33 -0
- package/src/parser/ParserValidator.ts +132 -0
- package/src/parser/index.ts +6 -0
- package/src/parser/schemaParser.ts +60 -0
- package/src/rangeSpec.ts +22 -0
- package/src/replaceStringParameters.ts +22 -0
- package/src/schema/getClosestMatchingOption.ts +191 -0
- package/src/schema/getDefaultFormState.ts +447 -0
- package/src/schema/getDisplayLabel.ts +59 -0
- package/src/schema/getFirstMatchingOption.ts +27 -0
- package/src/schema/getMatchingOption.ts +95 -0
- package/src/schema/index.ts +29 -0
- package/src/schema/isFilesArray.ts +27 -0
- package/src/schema/isMultiSelect.ts +21 -0
- package/src/schema/isSelect.ts +26 -0
- package/src/schema/mergeValidationData.ts +38 -0
- package/src/schema/retrieveSchema.ts +614 -0
- package/src/schema/sanitizeDataForNewSchema.ts +197 -0
- package/src/schema/toIdSchema.ts +105 -0
- package/src/schema/toPathSchema.ts +121 -0
- package/src/schemaRequiresTrueValue.ts +40 -0
- package/src/shouldRender.ts +16 -0
- package/src/toConstant.ts +19 -0
- package/src/toDateString.ts +15 -0
- package/src/toErrorList.ts +41 -0
- package/src/toErrorSchema.ts +43 -0
- package/src/types.ts +1139 -0
- package/src/unwrapErrorHandler.ts +25 -0
- package/src/utcToLocal.ts +30 -0
- package/src/validationDataMerge.ts +31 -0
- package/src/withIdRefPrefix.ts +49 -0
- package/dist/index.d.ts +0 -1912
- package/dist/utils.cjs.development.js +0 -3513
- package/dist/utils.cjs.development.js.map +0 -1
- package/dist/utils.cjs.production.min.js +0 -2
- package/dist/utils.cjs.production.min.js.map +0 -1
- package/dist/utils.umd.development.js +0 -3496
- package/dist/utils.umd.development.js.map +0 -1
- package/dist/utils.umd.production.min.js +0 -2
- package/dist/utils.umd.production.min.js.map +0 -1
package/dist/utils.esm.js
CHANGED
|
@@ -1,184 +1,107 @@
|
|
|
1
|
-
|
|
2
|
-
import isEqualWith from 'lodash-es/isEqualWith';
|
|
3
|
-
import get from 'lodash-es/get';
|
|
4
|
-
import isEmpty from 'lodash-es/isEmpty';
|
|
5
|
-
import jsonpointer from 'jsonpointer';
|
|
6
|
-
import omit from 'lodash-es/omit';
|
|
7
|
-
import has from 'lodash-es/has';
|
|
8
|
-
import isObject$1 from 'lodash-es/isObject';
|
|
9
|
-
import isString from 'lodash-es/isString';
|
|
10
|
-
import reduce from 'lodash-es/reduce';
|
|
11
|
-
import times from 'lodash-es/times';
|
|
12
|
-
import set from 'lodash-es/set';
|
|
13
|
-
import forEach from 'lodash-es/forEach';
|
|
14
|
-
import mergeAllOf from 'json-schema-merge-allof';
|
|
15
|
-
import union from 'lodash-es/union';
|
|
16
|
-
import isEqual from 'lodash-es/isEqual';
|
|
17
|
-
import { isNil } from 'lodash-es';
|
|
18
|
-
import cloneDeep from 'lodash-es/cloneDeep';
|
|
19
|
-
import { jsx } from 'react/jsx-runtime';
|
|
20
|
-
import { createElement } from 'react';
|
|
21
|
-
import ReactIs from 'react-is';
|
|
22
|
-
import toPath from 'lodash-es/toPath';
|
|
23
|
-
|
|
24
|
-
/** Determines whether a `thing` is an object for the purposes of RSJF. In this case, `thing` is an object if it has
|
|
25
|
-
* the type `object` but is NOT null, an array or a File.
|
|
26
|
-
*
|
|
27
|
-
* @param thing - The thing to check to see whether it is an object
|
|
28
|
-
* @returns - True if it is a non-null, non-array, non-File object
|
|
29
|
-
*/
|
|
1
|
+
// src/isObject.ts
|
|
30
2
|
function isObject(thing) {
|
|
31
|
-
if (typeof File !==
|
|
3
|
+
if (typeof File !== "undefined" && thing instanceof File) {
|
|
32
4
|
return false;
|
|
33
5
|
}
|
|
34
|
-
if (typeof Date !==
|
|
6
|
+
if (typeof Date !== "undefined" && thing instanceof Date) {
|
|
35
7
|
return false;
|
|
36
8
|
}
|
|
37
|
-
return typeof thing ===
|
|
9
|
+
return typeof thing === "object" && thing !== null && !Array.isArray(thing);
|
|
38
10
|
}
|
|
39
11
|
|
|
40
|
-
|
|
41
|
-
* object. The user is warned in the console if `schema.additionalItems` has the value `true`.
|
|
42
|
-
*
|
|
43
|
-
* @param schema - The schema object to check
|
|
44
|
-
* @returns - True if additional items is allowed, otherwise false
|
|
45
|
-
*/
|
|
12
|
+
// src/allowAdditionalItems.ts
|
|
46
13
|
function allowAdditionalItems(schema) {
|
|
47
14
|
if (schema.additionalItems === true) {
|
|
48
|
-
console.warn(
|
|
15
|
+
console.warn("additionalItems=true is currently not supported");
|
|
49
16
|
}
|
|
50
17
|
return isObject(schema.additionalItems);
|
|
51
18
|
}
|
|
52
19
|
|
|
53
|
-
|
|
54
|
-
* `null` is provided, it is returned. If the string ends in a `.` then the string is returned because the user may be
|
|
55
|
-
* in the middle of typing a float number. If a number ends in a pattern like `.0`, `.20`, `.030`, string is returned
|
|
56
|
-
* because the user may be typing number that will end in a non-zero digit. Otherwise, the string is wrapped by
|
|
57
|
-
* `Number()` and if that result is not `NaN`, that number will be returned, otherwise the string `value` will be.
|
|
58
|
-
*
|
|
59
|
-
* @param value - The string or null value to convert to a number
|
|
60
|
-
* @returns - The `value` converted to a number when appropriate, otherwise the `value`
|
|
61
|
-
*/
|
|
20
|
+
// src/asNumber.ts
|
|
62
21
|
function asNumber(value) {
|
|
63
|
-
if (value ===
|
|
64
|
-
return
|
|
22
|
+
if (value === "") {
|
|
23
|
+
return void 0;
|
|
65
24
|
}
|
|
66
25
|
if (value === null) {
|
|
67
26
|
return null;
|
|
68
27
|
}
|
|
69
28
|
if (/\.$/.test(value)) {
|
|
70
|
-
// '3.' can't really be considered a number even if it parses in js. The
|
|
71
|
-
// user is most likely entering a float.
|
|
72
29
|
return value;
|
|
73
30
|
}
|
|
74
31
|
if (/\.0$/.test(value)) {
|
|
75
|
-
// we need to return this as a string here, to allow for input like 3.07
|
|
76
32
|
return value;
|
|
77
33
|
}
|
|
78
34
|
if (/\.\d*0$/.test(value)) {
|
|
79
|
-
// It's a number, that's cool - but we need it as a string so it doesn't screw
|
|
80
|
-
// with the user when entering dollar amounts or other values (such as those with
|
|
81
|
-
// specific precision or number of significant digits)
|
|
82
35
|
return value;
|
|
83
36
|
}
|
|
84
37
|
const n = Number(value);
|
|
85
|
-
const valid = typeof n ===
|
|
38
|
+
const valid = typeof n === "number" && !Number.isNaN(n);
|
|
86
39
|
return valid ? n : value;
|
|
87
40
|
}
|
|
88
41
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const UI_OPTIONS_KEY = 'ui:options';
|
|
119
|
-
const UI_GLOBAL_OPTIONS_KEY = 'ui:globalOptions';
|
|
120
|
-
|
|
121
|
-
/** Get all passed options from ui:options, and ui:<optionName>, returning them in an object with the `ui:`
|
|
122
|
-
* stripped off. Any `globalOptions` will always be returned, unless they are overridden by options in the `uiSchema`.
|
|
123
|
-
*
|
|
124
|
-
* @param [uiSchema={}] - The UI Schema from which to get any `ui:xxx` options
|
|
125
|
-
* @param [globalOptions={}] - The optional Global UI Schema from which to get any fallback `xxx` options
|
|
126
|
-
* @returns - An object containing all the `ui:xxx` options with the `ui:` stripped off along with all `globalOptions`
|
|
127
|
-
*/
|
|
42
|
+
// src/constants.ts
|
|
43
|
+
var ADDITIONAL_PROPERTY_FLAG = "__additional_property";
|
|
44
|
+
var ADDITIONAL_PROPERTIES_KEY = "additionalProperties";
|
|
45
|
+
var ALL_OF_KEY = "allOf";
|
|
46
|
+
var ANY_OF_KEY = "anyOf";
|
|
47
|
+
var CONST_KEY = "const";
|
|
48
|
+
var DEFAULT_KEY = "default";
|
|
49
|
+
var DEFINITIONS_KEY = "definitions";
|
|
50
|
+
var DEPENDENCIES_KEY = "dependencies";
|
|
51
|
+
var ENUM_KEY = "enum";
|
|
52
|
+
var ERRORS_KEY = "__errors";
|
|
53
|
+
var ID_KEY = "$id";
|
|
54
|
+
var IF_KEY = "if";
|
|
55
|
+
var ITEMS_KEY = "items";
|
|
56
|
+
var JUNK_OPTION_ID = "_$junk_option_schema_id$_";
|
|
57
|
+
var NAME_KEY = "$name";
|
|
58
|
+
var ONE_OF_KEY = "oneOf";
|
|
59
|
+
var PROPERTIES_KEY = "properties";
|
|
60
|
+
var REQUIRED_KEY = "required";
|
|
61
|
+
var SUBMIT_BTN_OPTIONS_KEY = "submitButtonOptions";
|
|
62
|
+
var REF_KEY = "$ref";
|
|
63
|
+
var RJSF_ADDITONAL_PROPERTIES_FLAG = "__rjsf_additionalProperties";
|
|
64
|
+
var ROOT_SCHEMA_PREFIX = "__rjsf_rootSchema";
|
|
65
|
+
var UI_FIELD_KEY = "ui:field";
|
|
66
|
+
var UI_WIDGET_KEY = "ui:widget";
|
|
67
|
+
var UI_OPTIONS_KEY = "ui:options";
|
|
68
|
+
var UI_GLOBAL_OPTIONS_KEY = "ui:globalOptions";
|
|
69
|
+
|
|
70
|
+
// src/getUiOptions.ts
|
|
128
71
|
function getUiOptions(uiSchema = {}, globalOptions = {}) {
|
|
129
|
-
return Object.keys(uiSchema).filter(key => key.indexOf(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
...options,
|
|
138
|
-
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
[key.substring(3)]: value
|
|
144
|
-
};
|
|
145
|
-
}, {
|
|
146
|
-
...globalOptions
|
|
147
|
-
});
|
|
72
|
+
return Object.keys(uiSchema).filter((key) => key.indexOf("ui:") === 0).reduce(
|
|
73
|
+
(options, key) => {
|
|
74
|
+
const value = uiSchema[key];
|
|
75
|
+
if (key === UI_WIDGET_KEY && isObject(value)) {
|
|
76
|
+
console.error("Setting options via ui:widget object is no longer supported, use ui:options instead");
|
|
77
|
+
return options;
|
|
78
|
+
}
|
|
79
|
+
if (key === UI_OPTIONS_KEY && isObject(value)) {
|
|
80
|
+
return { ...options, ...value };
|
|
81
|
+
}
|
|
82
|
+
return { ...options, [key.substring(3)]: value };
|
|
83
|
+
},
|
|
84
|
+
{ ...globalOptions }
|
|
85
|
+
);
|
|
148
86
|
}
|
|
149
87
|
|
|
150
|
-
|
|
151
|
-
* the field can expand if it has additional properties, is not forced as non-expandable by the `uiSchema` and the
|
|
152
|
-
* `formData` object doesn't already have `schema.maxProperties` elements.
|
|
153
|
-
*
|
|
154
|
-
* @param schema - The schema for the field that is being checked
|
|
155
|
-
* @param [uiSchema={}] - The uiSchema for the field
|
|
156
|
-
* @param [formData] - The formData for the field
|
|
157
|
-
* @returns - True if the schema element has additionalProperties, is expandable, and not at the maxProperties limit
|
|
158
|
-
*/
|
|
88
|
+
// src/canExpand.ts
|
|
159
89
|
function canExpand(schema, uiSchema = {}, formData) {
|
|
160
90
|
if (!schema.additionalProperties) {
|
|
161
91
|
return false;
|
|
162
92
|
}
|
|
163
|
-
const {
|
|
164
|
-
expandable = true
|
|
165
|
-
} = getUiOptions(uiSchema);
|
|
93
|
+
const { expandable = true } = getUiOptions(uiSchema);
|
|
166
94
|
if (expandable === false) {
|
|
167
95
|
return expandable;
|
|
168
96
|
}
|
|
169
|
-
|
|
170
|
-
// another property if we have not exceeded maxProperties yet
|
|
171
|
-
if (schema.maxProperties !== undefined && formData) {
|
|
97
|
+
if (schema.maxProperties !== void 0 && formData) {
|
|
172
98
|
return Object.keys(formData).length < schema.maxProperties;
|
|
173
99
|
}
|
|
174
100
|
return true;
|
|
175
101
|
}
|
|
176
102
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
* @param formData - The form data around which the error handler is created
|
|
180
|
-
* @returns - A `FormValidation` object based on the `formData` structure
|
|
181
|
-
*/
|
|
103
|
+
// src/createErrorHandler.ts
|
|
104
|
+
import isPlainObject from "lodash/isPlainObject";
|
|
182
105
|
function createErrorHandler(formData) {
|
|
183
106
|
const handler = {
|
|
184
107
|
// We store the list of errors for this node in a property named __errors
|
|
@@ -191,111 +114,80 @@ function createErrorHandler(formData) {
|
|
|
191
114
|
};
|
|
192
115
|
if (Array.isArray(formData)) {
|
|
193
116
|
return formData.reduce((acc, value, key) => {
|
|
194
|
-
return {
|
|
195
|
-
...acc,
|
|
196
|
-
[key]: createErrorHandler(value)
|
|
197
|
-
};
|
|
117
|
+
return { ...acc, [key]: createErrorHandler(value) };
|
|
198
118
|
}, handler);
|
|
199
119
|
}
|
|
200
120
|
if (isPlainObject(formData)) {
|
|
201
121
|
const formObject = formData;
|
|
202
122
|
return Object.keys(formObject).reduce((acc, key) => {
|
|
203
|
-
return {
|
|
204
|
-
...acc,
|
|
205
|
-
[key]: createErrorHandler(formObject[key])
|
|
206
|
-
};
|
|
123
|
+
return { ...acc, [key]: createErrorHandler(formObject[key]) };
|
|
207
124
|
}, handler);
|
|
208
125
|
}
|
|
209
126
|
return handler;
|
|
210
127
|
}
|
|
211
128
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
*
|
|
215
|
-
* @param a - The first element to compare
|
|
216
|
-
* @param b - The second element to compare
|
|
217
|
-
* @returns - True if the `a` and `b` are deeply equal, false otherwise
|
|
218
|
-
*/
|
|
129
|
+
// src/deepEquals.ts
|
|
130
|
+
import isEqualWith from "lodash/isEqualWith";
|
|
219
131
|
function deepEquals(a, b) {
|
|
220
132
|
return isEqualWith(a, b, (obj, other) => {
|
|
221
|
-
if (typeof obj ===
|
|
222
|
-
// Assume all functions are equivalent
|
|
223
|
-
// see https://github.com/rjsf-team/react-jsonschema-form/issues/255
|
|
133
|
+
if (typeof obj === "function" && typeof other === "function") {
|
|
224
134
|
return true;
|
|
225
135
|
}
|
|
226
|
-
return
|
|
136
|
+
return void 0;
|
|
227
137
|
});
|
|
228
138
|
}
|
|
229
139
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
*/
|
|
140
|
+
// src/schema/getDefaultFormState.ts
|
|
141
|
+
import get6 from "lodash/get";
|
|
142
|
+
import isEmpty from "lodash/isEmpty";
|
|
143
|
+
|
|
144
|
+
// src/findSchemaDefinition.ts
|
|
145
|
+
import jsonpointer from "jsonpointer";
|
|
146
|
+
import omit from "lodash/omit";
|
|
238
147
|
function splitKeyElementFromObject(key, object) {
|
|
239
148
|
const value = object[key];
|
|
240
149
|
const remaining = omit(object, [key]);
|
|
241
150
|
return [remaining, value];
|
|
242
151
|
}
|
|
243
|
-
/** Given the name of a `$ref` from within a schema, using the `rootSchema`, look up and return the sub-schema using the
|
|
244
|
-
* path provided by that reference. If `#` is not the first character of the reference, or the path does not exist in
|
|
245
|
-
* the schema, then throw an Error. Otherwise return the sub-schema. Also deals with nested `$ref`s in the sub-schema.
|
|
246
|
-
*
|
|
247
|
-
* @param $ref - The ref string for which the schema definition is desired
|
|
248
|
-
* @param [rootSchema={}] - The root schema in which to search for the definition
|
|
249
|
-
* @returns - The sub-schema within the `rootSchema` which matches the `$ref` if it exists
|
|
250
|
-
* @throws - Error indicating that no schema for that reference exists
|
|
251
|
-
*/
|
|
252
152
|
function findSchemaDefinition($ref, rootSchema = {}) {
|
|
253
|
-
let ref = $ref ||
|
|
254
|
-
if (ref.startsWith(
|
|
255
|
-
// Decode URI fragment representation.
|
|
153
|
+
let ref = $ref || "";
|
|
154
|
+
if (ref.startsWith("#")) {
|
|
256
155
|
ref = decodeURIComponent(ref.substring(1));
|
|
257
156
|
} else {
|
|
258
157
|
throw new Error(`Could not find a definition for ${$ref}.`);
|
|
259
158
|
}
|
|
260
159
|
const current = jsonpointer.get(rootSchema, ref);
|
|
261
|
-
if (current ===
|
|
160
|
+
if (current === void 0) {
|
|
262
161
|
throw new Error(`Could not find a definition for ${$ref}.`);
|
|
263
162
|
}
|
|
264
163
|
if (current[REF_KEY]) {
|
|
265
164
|
const [remaining, theRef] = splitKeyElementFromObject(REF_KEY, current);
|
|
266
165
|
const subSchema = findSchemaDefinition(theRef, rootSchema);
|
|
267
166
|
if (Object.keys(remaining).length > 0) {
|
|
268
|
-
return {
|
|
269
|
-
...remaining,
|
|
270
|
-
...subSchema
|
|
271
|
-
};
|
|
167
|
+
return { ...remaining, ...subSchema };
|
|
272
168
|
}
|
|
273
169
|
return subSchema;
|
|
274
170
|
}
|
|
275
171
|
return current;
|
|
276
172
|
}
|
|
277
173
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
*/
|
|
174
|
+
// src/schema/getClosestMatchingOption.ts
|
|
175
|
+
import get4 from "lodash/get";
|
|
176
|
+
import has2 from "lodash/has";
|
|
177
|
+
import isObject2 from "lodash/isObject";
|
|
178
|
+
import isString2 from "lodash/isString";
|
|
179
|
+
import reduce from "lodash/reduce";
|
|
180
|
+
import times2 from "lodash/times";
|
|
181
|
+
|
|
182
|
+
// src/schema/getMatchingOption.ts
|
|
183
|
+
import get from "lodash/get";
|
|
184
|
+
import has from "lodash/has";
|
|
290
185
|
function getMatchingOption(validator, formData, options, rootSchema, discriminatorField) {
|
|
291
|
-
|
|
292
|
-
// want to get the first option in that case.
|
|
293
|
-
if (formData === undefined) {
|
|
186
|
+
if (formData === void 0) {
|
|
294
187
|
return 0;
|
|
295
188
|
}
|
|
296
189
|
for (let i = 0; i < options.length; i++) {
|
|
297
190
|
const option = options[i];
|
|
298
|
-
// If we have a discriminator field, then we will use this to make the determination
|
|
299
191
|
if (discriminatorField && has(option, [PROPERTIES_KEY, discriminatorField])) {
|
|
300
192
|
const value = get(formData, discriminatorField);
|
|
301
193
|
const discriminator = get(option, [PROPERTIES_KEY, discriminatorField], {});
|
|
@@ -303,32 +195,17 @@ function getMatchingOption(validator, formData, options, rootSchema, discriminat
|
|
|
303
195
|
return i;
|
|
304
196
|
}
|
|
305
197
|
} else if (option[PROPERTIES_KEY]) {
|
|
306
|
-
// If the schema describes an object then we need to add slightly more
|
|
307
|
-
// strict matching to the schema, because unless the schema uses the
|
|
308
|
-
// "requires" keyword, an object will match the schema as long as it
|
|
309
|
-
// doesn't have matching keys with a conflicting type. To do this we use an
|
|
310
|
-
// "anyOf" with an array of requires. This augmentation expresses that the
|
|
311
|
-
// schema should match if any of the keys in the schema are present on the
|
|
312
|
-
// object and pass validation.
|
|
313
|
-
//
|
|
314
|
-
// Create an "anyOf" schema that requires at least one of the keys in the
|
|
315
|
-
// "properties" object
|
|
316
198
|
const requiresAnyOf = {
|
|
317
|
-
anyOf: Object.keys(option[PROPERTIES_KEY]).map(key => ({
|
|
199
|
+
anyOf: Object.keys(option[PROPERTIES_KEY]).map((key) => ({
|
|
318
200
|
required: [key]
|
|
319
201
|
}))
|
|
320
202
|
};
|
|
321
203
|
let augmentedSchema;
|
|
322
|
-
// If the "anyOf" keyword already exists, wrap the augmentation in an "allOf"
|
|
323
204
|
if (option.anyOf) {
|
|
324
|
-
|
|
325
|
-
const {
|
|
326
|
-
...shallowClone
|
|
327
|
-
} = option;
|
|
205
|
+
const { ...shallowClone } = option;
|
|
328
206
|
if (!shallowClone.allOf) {
|
|
329
207
|
shallowClone.allOf = [];
|
|
330
208
|
} else {
|
|
331
|
-
// If "allOf" already exists, shallow clone the array
|
|
332
209
|
shallowClone.allOf = shallowClone.allOf.slice();
|
|
333
210
|
}
|
|
334
211
|
shallowClone.allOf.push(requiresAnyOf);
|
|
@@ -336,8 +213,6 @@ function getMatchingOption(validator, formData, options, rootSchema, discriminat
|
|
|
336
213
|
} else {
|
|
337
214
|
augmentedSchema = Object.assign({}, option, requiresAnyOf);
|
|
338
215
|
}
|
|
339
|
-
// Remove the "required" field as it's likely that not all fields have
|
|
340
|
-
// been filled in yet, which will mean that the schema is not valid
|
|
341
216
|
delete augmentedSchema.required;
|
|
342
217
|
if (validator.isValid(augmentedSchema, formData, rootSchema)) {
|
|
343
218
|
return i;
|
|
@@ -349,373 +224,241 @@ function getMatchingOption(validator, formData, options, rootSchema, discriminat
|
|
|
349
224
|
return 0;
|
|
350
225
|
}
|
|
351
226
|
|
|
352
|
-
|
|
353
|
-
* Always returns the first option if there is nothing that matches.
|
|
354
|
-
*
|
|
355
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
356
|
-
* @param formData - The current formData, if any, used to figure out a match
|
|
357
|
-
* @param options - The list of options to find a matching options from
|
|
358
|
-
* @param rootSchema - The root schema, used to primarily to look up `$ref`s
|
|
359
|
-
* @param [discriminatorField] - The optional name of the field within the options object whose value is used to
|
|
360
|
-
* determine which option is selected
|
|
361
|
-
* @returns - The index of the first matched option or 0 if none is available
|
|
362
|
-
*/
|
|
227
|
+
// src/schema/getFirstMatchingOption.ts
|
|
363
228
|
function getFirstMatchingOption(validator, formData, options, rootSchema, discriminatorField) {
|
|
364
229
|
return getMatchingOption(validator, formData, options, rootSchema, discriminatorField);
|
|
365
230
|
}
|
|
366
231
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
232
|
+
// src/schema/retrieveSchema.ts
|
|
233
|
+
import get3 from "lodash/get";
|
|
234
|
+
import set from "lodash/set";
|
|
235
|
+
import times from "lodash/times";
|
|
236
|
+
import transform from "lodash/transform";
|
|
237
|
+
import mergeAllOf from "json-schema-merge-allof";
|
|
238
|
+
|
|
239
|
+
// src/getDiscriminatorFieldFromSchema.ts
|
|
240
|
+
import get2 from "lodash/get";
|
|
241
|
+
import isString from "lodash/isString";
|
|
373
242
|
function getDiscriminatorFieldFromSchema(schema) {
|
|
374
243
|
let discriminator;
|
|
375
|
-
const maybeString =
|
|
244
|
+
const maybeString = get2(schema, "discriminator.propertyName", void 0);
|
|
376
245
|
if (isString(maybeString)) {
|
|
377
246
|
discriminator = maybeString;
|
|
378
|
-
} else if (maybeString !==
|
|
247
|
+
} else if (maybeString !== void 0) {
|
|
379
248
|
console.warn(`Expecting discriminator to be a string, got "${typeof maybeString}" instead`);
|
|
380
249
|
}
|
|
381
250
|
return discriminator;
|
|
382
251
|
}
|
|
383
252
|
|
|
384
|
-
|
|
385
|
-
* create a schema, it is useful to know what type to use based on the data we are defining.
|
|
386
|
-
*
|
|
387
|
-
* @param value - The value from which to guess the type
|
|
388
|
-
* @returns - The best guess for the object type
|
|
389
|
-
*/
|
|
253
|
+
// src/guessType.ts
|
|
390
254
|
function guessType(value) {
|
|
391
255
|
if (Array.isArray(value)) {
|
|
392
|
-
return
|
|
256
|
+
return "array";
|
|
393
257
|
}
|
|
394
|
-
if (typeof value ===
|
|
395
|
-
return
|
|
258
|
+
if (typeof value === "string") {
|
|
259
|
+
return "string";
|
|
396
260
|
}
|
|
397
261
|
if (value == null) {
|
|
398
|
-
return
|
|
262
|
+
return "null";
|
|
399
263
|
}
|
|
400
|
-
if (typeof value ===
|
|
401
|
-
return
|
|
264
|
+
if (typeof value === "boolean") {
|
|
265
|
+
return "boolean";
|
|
402
266
|
}
|
|
403
267
|
if (!isNaN(value)) {
|
|
404
|
-
return
|
|
405
|
-
}
|
|
406
|
-
if (typeof value ===
|
|
407
|
-
return
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
* - schema.enum: Returns `string`
|
|
417
|
-
* - schema.properties: Returns `object`
|
|
418
|
-
* - schema.additionalProperties: Returns `object`
|
|
419
|
-
* - type is an array with a length of 2 and one type is 'null': Returns the other type
|
|
420
|
-
*
|
|
421
|
-
* @param schema - The schema for which to get the type
|
|
422
|
-
* @returns - The type of the schema
|
|
423
|
-
*/
|
|
268
|
+
return "number";
|
|
269
|
+
}
|
|
270
|
+
if (typeof value === "object") {
|
|
271
|
+
return "object";
|
|
272
|
+
}
|
|
273
|
+
return "string";
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// src/mergeSchemas.ts
|
|
277
|
+
import union from "lodash/union";
|
|
278
|
+
|
|
279
|
+
// src/getSchemaType.ts
|
|
424
280
|
function getSchemaType(schema) {
|
|
425
|
-
let {
|
|
426
|
-
type
|
|
427
|
-
} = schema;
|
|
281
|
+
let { type } = schema;
|
|
428
282
|
if (!type && schema.const) {
|
|
429
283
|
return guessType(schema.const);
|
|
430
284
|
}
|
|
431
285
|
if (!type && schema.enum) {
|
|
432
|
-
return
|
|
286
|
+
return "string";
|
|
433
287
|
}
|
|
434
288
|
if (!type && (schema.properties || schema.additionalProperties)) {
|
|
435
|
-
return
|
|
289
|
+
return "object";
|
|
436
290
|
}
|
|
437
|
-
if (Array.isArray(type) && type.length === 2 && type.includes(
|
|
438
|
-
type = type.find(
|
|
291
|
+
if (Array.isArray(type) && type.length === 2 && type.includes("null")) {
|
|
292
|
+
type = type.find((type2) => type2 !== "null");
|
|
439
293
|
}
|
|
440
294
|
return type;
|
|
441
295
|
}
|
|
442
296
|
|
|
443
|
-
|
|
444
|
-
* `mergeSchemas` only concats arrays for values under the 'required' keyword, and when it does, it doesn't include
|
|
445
|
-
* duplicate values.
|
|
446
|
-
*
|
|
447
|
-
* @param obj1 - The first schema object to merge
|
|
448
|
-
* @param obj2 - The second schema object to merge
|
|
449
|
-
* @returns - The merged schema object
|
|
450
|
-
*/
|
|
297
|
+
// src/mergeSchemas.ts
|
|
451
298
|
function mergeSchemas(obj1, obj2) {
|
|
452
|
-
const acc = Object.assign({}, obj1);
|
|
453
|
-
return Object.keys(obj2).reduce((
|
|
454
|
-
const left = obj1 ? obj1[key] : {},
|
|
455
|
-
right = obj2[key];
|
|
299
|
+
const acc = Object.assign({}, obj1);
|
|
300
|
+
return Object.keys(obj2).reduce((acc2, key) => {
|
|
301
|
+
const left = obj1 ? obj1[key] : {}, right = obj2[key];
|
|
456
302
|
if (obj1 && key in obj1 && isObject(right)) {
|
|
457
|
-
|
|
458
|
-
} else if (obj1 && obj2 && (getSchemaType(obj1) ===
|
|
459
|
-
|
|
460
|
-
acc[key] = union(left, right);
|
|
303
|
+
acc2[key] = mergeSchemas(left, right);
|
|
304
|
+
} else if (obj1 && obj2 && (getSchemaType(obj1) === "object" || getSchemaType(obj2) === "object") && key === REQUIRED_KEY && Array.isArray(left) && Array.isArray(right)) {
|
|
305
|
+
acc2[key] = union(left, right);
|
|
461
306
|
} else {
|
|
462
|
-
|
|
307
|
+
acc2[key] = right;
|
|
463
308
|
}
|
|
464
|
-
return
|
|
309
|
+
return acc2;
|
|
465
310
|
}, acc);
|
|
466
311
|
}
|
|
467
312
|
|
|
468
|
-
|
|
469
|
-
* resolved and merged into the `schema` given a `validator`, `rootSchema` and `rawFormData` that is used to do the
|
|
470
|
-
* potentially recursive resolution.
|
|
471
|
-
*
|
|
472
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
473
|
-
* @param schema - The schema for which retrieving a schema is desired
|
|
474
|
-
* @param [rootSchema={}] - The root schema that will be forwarded to all the APIs
|
|
475
|
-
* @param [rawFormData] - The current formData, if any, to assist retrieving a schema
|
|
476
|
-
* @returns - The schema having its conditions, additional properties, references and dependencies resolved
|
|
477
|
-
*/
|
|
313
|
+
// src/schema/retrieveSchema.ts
|
|
478
314
|
function retrieveSchema(validator, schema, rootSchema = {}, rawFormData) {
|
|
479
315
|
return retrieveSchemaInternal(validator, schema, rootSchema, rawFormData)[0];
|
|
480
316
|
}
|
|
481
|
-
/** Resolves a conditional block (if/else/then) by removing the condition and merging the appropriate conditional branch
|
|
482
|
-
* with the rest of the schema. If `expandAllBranches` is true, then the `retrieveSchemaInteral()` results for both
|
|
483
|
-
* conditions will be returned.
|
|
484
|
-
*
|
|
485
|
-
* @param validator - An implementation of the `ValidatorType` interface that is used to detect valid schema conditions
|
|
486
|
-
* @param schema - The schema for which resolving a condition is desired
|
|
487
|
-
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
488
|
-
* @param expandAllBranches - Flag, if true, will return all possible branches of conditions, any/oneOf and
|
|
489
|
-
* dependencies as a list of schemas
|
|
490
|
-
* @param [formData] - The current formData to assist retrieving a schema
|
|
491
|
-
* @returns - A list of schemas with the appropriate conditions resolved, possibly with all branches expanded
|
|
492
|
-
*/
|
|
493
317
|
function resolveCondition(validator, schema, rootSchema, expandAllBranches, formData) {
|
|
494
|
-
const {
|
|
495
|
-
if: expression,
|
|
496
|
-
then,
|
|
497
|
-
else: otherwise,
|
|
498
|
-
...resolvedSchemaLessConditional
|
|
499
|
-
} = schema;
|
|
318
|
+
const { if: expression, then, else: otherwise, ...resolvedSchemaLessConditional } = schema;
|
|
500
319
|
const conditionValue = validator.isValid(expression, formData || {}, rootSchema);
|
|
501
320
|
let resolvedSchemas = [resolvedSchemaLessConditional];
|
|
502
321
|
let schemas = [];
|
|
503
322
|
if (expandAllBranches) {
|
|
504
|
-
if (then && typeof then !==
|
|
505
|
-
schemas = schemas.concat(
|
|
323
|
+
if (then && typeof then !== "boolean") {
|
|
324
|
+
schemas = schemas.concat(
|
|
325
|
+
retrieveSchemaInternal(validator, then, rootSchema, formData, expandAllBranches)
|
|
326
|
+
);
|
|
506
327
|
}
|
|
507
|
-
if (otherwise && typeof otherwise !==
|
|
508
|
-
schemas = schemas.concat(
|
|
328
|
+
if (otherwise && typeof otherwise !== "boolean") {
|
|
329
|
+
schemas = schemas.concat(
|
|
330
|
+
retrieveSchemaInternal(validator, otherwise, rootSchema, formData, expandAllBranches)
|
|
331
|
+
);
|
|
509
332
|
}
|
|
510
333
|
} else {
|
|
511
334
|
const conditionalSchema = conditionValue ? then : otherwise;
|
|
512
|
-
if (conditionalSchema && typeof conditionalSchema !==
|
|
513
|
-
schemas = schemas.concat(
|
|
335
|
+
if (conditionalSchema && typeof conditionalSchema !== "boolean") {
|
|
336
|
+
schemas = schemas.concat(
|
|
337
|
+
retrieveSchemaInternal(validator, conditionalSchema, rootSchema, formData, expandAllBranches)
|
|
338
|
+
);
|
|
514
339
|
}
|
|
515
340
|
}
|
|
516
341
|
if (schemas.length) {
|
|
517
|
-
resolvedSchemas = schemas.map(s => mergeSchemas(resolvedSchemaLessConditional, s));
|
|
518
|
-
}
|
|
519
|
-
return resolvedSchemas.flatMap(
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
* From those lists, build a matrix for each `xxxOf` where there is more than one schema for a row in the list of lists.
|
|
524
|
-
*
|
|
525
|
-
* For example:
|
|
526
|
-
* - If there are three xxxOf rows (A, B, C) and they have been resolved such that there is only one A, two B and three
|
|
527
|
-
* C schemas then:
|
|
528
|
-
* - The permutation for the first row is `[[A]]`
|
|
529
|
-
* - The permutations for the second row are `[[A,B1], [A,B2]]`
|
|
530
|
-
* - The permutations for the third row are `[[A,B1,C1], [A,B1,C2], [A,B1,C3], [A,B2,C1], [A,B2,C2], [A,B2,C3]]`
|
|
531
|
-
*
|
|
532
|
-
* @param listOfLists - The list of lists of elements that represent the allOf, anyOf or oneOf resolved values in order
|
|
533
|
-
* @returns - The list of all permutations of schemas for a set of `xxxOf`s
|
|
534
|
-
*/
|
|
342
|
+
resolvedSchemas = schemas.map((s) => mergeSchemas(resolvedSchemaLessConditional, s));
|
|
343
|
+
}
|
|
344
|
+
return resolvedSchemas.flatMap(
|
|
345
|
+
(s) => retrieveSchemaInternal(validator, s, rootSchema, formData, expandAllBranches)
|
|
346
|
+
);
|
|
347
|
+
}
|
|
535
348
|
function getAllPermutationsOfXxxOf(listOfLists) {
|
|
536
|
-
const allPermutations = listOfLists.reduce(
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
349
|
+
const allPermutations = listOfLists.reduce(
|
|
350
|
+
(permutations, list) => {
|
|
351
|
+
if (list.length > 1) {
|
|
352
|
+
return list.flatMap((element) => times(permutations.length, (i) => [...permutations[i]].concat(element)));
|
|
353
|
+
}
|
|
354
|
+
permutations.forEach((permutation) => permutation.push(list[0]));
|
|
355
|
+
return permutations;
|
|
356
|
+
},
|
|
357
|
+
[[]]
|
|
358
|
+
// Start with an empty list
|
|
545
359
|
);
|
|
546
|
-
|
|
547
360
|
return allPermutations;
|
|
548
361
|
}
|
|
549
|
-
/** Resolves references and dependencies within a schema and its 'allOf' children. Passes the `expandAllBranches` flag
|
|
550
|
-
* down to the `retrieveSchemaInternal()`, `resolveReference()` and `resolveDependencies()` helper calls. If
|
|
551
|
-
* `expandAllBranches` is true, then all possible dependencies and/or allOf branches are returned.
|
|
552
|
-
*
|
|
553
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
554
|
-
* @param schema - The schema for which resolving a schema is desired
|
|
555
|
-
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
556
|
-
* @param expandAllBranches - Flag, if true, will return all possible branches of conditions, any/oneOf and dependencies
|
|
557
|
-
* as a list of schemas
|
|
558
|
-
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
559
|
-
* @returns - The list of schemas having its references, dependencies and allOf schemas resolved
|
|
560
|
-
*/
|
|
561
362
|
function resolveSchema(validator, schema, rootSchema, expandAllBranches, formData) {
|
|
562
363
|
if (REF_KEY in schema) {
|
|
563
364
|
return resolveReference(validator, schema, rootSchema, expandAllBranches, formData);
|
|
564
365
|
}
|
|
565
366
|
if (DEPENDENCIES_KEY in schema) {
|
|
566
367
|
const resolvedSchemas = resolveDependencies(validator, schema, rootSchema, expandAllBranches, formData);
|
|
567
|
-
return resolvedSchemas.flatMap(s => {
|
|
368
|
+
return resolvedSchemas.flatMap((s) => {
|
|
568
369
|
return retrieveSchemaInternal(validator, s, rootSchema, formData, expandAllBranches);
|
|
569
370
|
});
|
|
570
371
|
}
|
|
571
372
|
if (ALL_OF_KEY in schema && Array.isArray(schema.allOf)) {
|
|
572
|
-
const allOfSchemaElements = schema.allOf.map(
|
|
373
|
+
const allOfSchemaElements = schema.allOf.map(
|
|
374
|
+
(allOfSubschema) => retrieveSchemaInternal(validator, allOfSubschema, rootSchema, formData, expandAllBranches)
|
|
375
|
+
);
|
|
573
376
|
const allPermutations = getAllPermutationsOfXxxOf(allOfSchemaElements);
|
|
574
|
-
return allPermutations.map(permutation => ({
|
|
575
|
-
...schema,
|
|
576
|
-
allOf: permutation
|
|
577
|
-
}));
|
|
377
|
+
return allPermutations.map((permutation) => ({ ...schema, allOf: permutation }));
|
|
578
378
|
}
|
|
579
|
-
// No $ref or dependencies or allOf attribute was found, returning the original schema.
|
|
580
379
|
return [schema];
|
|
581
380
|
}
|
|
582
|
-
/** Resolves references within a schema and then returns the `retrieveSchemaInternal()` of the resolved schema. Passes
|
|
583
|
-
* the `expandAllBranches` flag down to the `retrieveSchemaInternal()` helper call.
|
|
584
|
-
*
|
|
585
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
586
|
-
* @param schema - The schema for which resolving a reference is desired
|
|
587
|
-
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
588
|
-
* @param expandAllBranches - Flag, if true, will return all possible branches of conditions, any/oneOf and dependencies
|
|
589
|
-
* as a list of schemas
|
|
590
|
-
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
591
|
-
* @returns - The list schemas retrieved after having all references resolved
|
|
592
|
-
*/
|
|
593
381
|
function resolveReference(validator, schema, rootSchema, expandAllBranches, formData) {
|
|
594
|
-
|
|
595
|
-
const {
|
|
596
|
-
$ref,
|
|
597
|
-
...localSchema
|
|
598
|
-
} = schema;
|
|
599
|
-
// Retrieve the referenced schema definition.
|
|
382
|
+
const { $ref, ...localSchema } = schema;
|
|
600
383
|
const refSchema = findSchemaDefinition($ref, rootSchema);
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
...refSchema,
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
* @param schema - The schema for which resolving all references is desired
|
|
610
|
-
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
611
|
-
* @returns - given schema will all references resolved
|
|
612
|
-
*/
|
|
384
|
+
return retrieveSchemaInternal(
|
|
385
|
+
validator,
|
|
386
|
+
{ ...refSchema, ...localSchema },
|
|
387
|
+
rootSchema,
|
|
388
|
+
formData,
|
|
389
|
+
expandAllBranches
|
|
390
|
+
);
|
|
391
|
+
}
|
|
613
392
|
function resolveAllReferences(schema, rootSchema) {
|
|
614
393
|
let resolvedSchema = schema;
|
|
615
|
-
// resolve top level ref
|
|
616
394
|
if (REF_KEY in resolvedSchema) {
|
|
617
|
-
const {
|
|
618
|
-
$ref,
|
|
619
|
-
...localSchema
|
|
620
|
-
} = resolvedSchema;
|
|
621
|
-
// Retrieve the referenced schema definition.
|
|
395
|
+
const { $ref, ...localSchema } = resolvedSchema;
|
|
622
396
|
const refSchema = findSchemaDefinition($ref, rootSchema);
|
|
623
|
-
resolvedSchema = {
|
|
624
|
-
...refSchema,
|
|
625
|
-
...localSchema
|
|
626
|
-
};
|
|
397
|
+
resolvedSchema = { ...refSchema, ...localSchema };
|
|
627
398
|
}
|
|
628
399
|
if (PROPERTIES_KEY in resolvedSchema) {
|
|
629
|
-
|
|
630
|
-
resolvedSchema[PROPERTIES_KEY]
|
|
631
|
-
|
|
400
|
+
const updatedProps = transform(
|
|
401
|
+
resolvedSchema[PROPERTIES_KEY],
|
|
402
|
+
(result, value, key) => {
|
|
403
|
+
result[key] = resolveAllReferences(value, rootSchema);
|
|
404
|
+
},
|
|
405
|
+
{}
|
|
406
|
+
);
|
|
407
|
+
resolvedSchema = { ...resolvedSchema, [PROPERTIES_KEY]: updatedProps };
|
|
632
408
|
}
|
|
633
|
-
if (ITEMS_KEY in resolvedSchema && !Array.isArray(resolvedSchema.items) && typeof resolvedSchema.items !==
|
|
634
|
-
resolvedSchema
|
|
409
|
+
if (ITEMS_KEY in resolvedSchema && !Array.isArray(resolvedSchema.items) && typeof resolvedSchema.items !== "boolean") {
|
|
410
|
+
resolvedSchema = { ...resolvedSchema, items: resolveAllReferences(resolvedSchema.items, rootSchema) };
|
|
635
411
|
}
|
|
636
412
|
return resolvedSchema;
|
|
637
413
|
}
|
|
638
|
-
/** Creates new 'properties' items for each key in the `formData`
|
|
639
|
-
*
|
|
640
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
641
|
-
* @param theSchema - The schema for which the existing additional properties is desired
|
|
642
|
-
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s * @param validator
|
|
643
|
-
* @param [aFormData] - The current formData, if any, to assist retrieving a schema
|
|
644
|
-
* @returns - The updated schema with additional properties stubbed
|
|
645
|
-
*/
|
|
646
414
|
function stubExistingAdditionalProperties(validator, theSchema, rootSchema, aFormData) {
|
|
647
|
-
// Clone the schema so that we don't ruin the consumer's original
|
|
648
415
|
const schema = {
|
|
649
416
|
...theSchema,
|
|
650
|
-
properties: {
|
|
651
|
-
...theSchema.properties
|
|
652
|
-
}
|
|
417
|
+
properties: { ...theSchema.properties }
|
|
653
418
|
};
|
|
654
|
-
// make sure formData is an object
|
|
655
419
|
const formData = aFormData && isObject(aFormData) ? aFormData : {};
|
|
656
|
-
Object.keys(formData).forEach(key => {
|
|
420
|
+
Object.keys(formData).forEach((key) => {
|
|
657
421
|
if (key in schema.properties) {
|
|
658
|
-
// No need to stub, our schema already has the property
|
|
659
422
|
return;
|
|
660
423
|
}
|
|
661
424
|
let additionalProperties = {};
|
|
662
|
-
if (typeof schema.additionalProperties !==
|
|
425
|
+
if (typeof schema.additionalProperties !== "boolean") {
|
|
663
426
|
if (REF_KEY in schema.additionalProperties) {
|
|
664
|
-
additionalProperties = retrieveSchema(
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
427
|
+
additionalProperties = retrieveSchema(
|
|
428
|
+
validator,
|
|
429
|
+
{ $ref: get3(schema.additionalProperties, [REF_KEY]) },
|
|
430
|
+
rootSchema,
|
|
431
|
+
formData
|
|
432
|
+
);
|
|
433
|
+
} else if ("type" in schema.additionalProperties) {
|
|
434
|
+
additionalProperties = { ...schema.additionalProperties };
|
|
671
435
|
} else if (ANY_OF_KEY in schema.additionalProperties || ONE_OF_KEY in schema.additionalProperties) {
|
|
672
436
|
additionalProperties = {
|
|
673
|
-
type:
|
|
437
|
+
type: "object",
|
|
674
438
|
...schema.additionalProperties
|
|
675
439
|
};
|
|
676
440
|
} else {
|
|
677
|
-
additionalProperties = {
|
|
678
|
-
type: guessType(get(formData, [key]))
|
|
679
|
-
};
|
|
441
|
+
additionalProperties = { type: guessType(get3(formData, [key])) };
|
|
680
442
|
}
|
|
681
443
|
} else {
|
|
682
|
-
additionalProperties = {
|
|
683
|
-
type: guessType(get(formData, [key]))
|
|
684
|
-
};
|
|
444
|
+
additionalProperties = { type: guessType(get3(formData, [key])) };
|
|
685
445
|
}
|
|
686
|
-
// The type of our new key should match the additionalProperties value;
|
|
687
446
|
schema.properties[key] = additionalProperties;
|
|
688
|
-
// Set our additional property flag so we know it was dynamically added
|
|
689
447
|
set(schema.properties, [key, ADDITIONAL_PROPERTY_FLAG], true);
|
|
690
448
|
});
|
|
691
449
|
return schema;
|
|
692
450
|
}
|
|
693
|
-
/** Internal handler that retrieves an expanded schema that has had all of its conditions, additional properties,
|
|
694
|
-
* references and dependencies resolved and merged into the `schema` given a `validator`, `rootSchema` and `rawFormData`
|
|
695
|
-
* that is used to do the potentially recursive resolution. If `expandAllBranches` is true, then all possible branches
|
|
696
|
-
* of the schema and its references, conditions and dependencies are returned.
|
|
697
|
-
*
|
|
698
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
699
|
-
* @param schema - The schema for which retrieving a schema is desired
|
|
700
|
-
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
701
|
-
* @param [rawFormData] - The current formData, if any, to assist retrieving a schema
|
|
702
|
-
* @param [expandAllBranches=false] - Flag, if true, will return all possible branches of conditions, any/oneOf and
|
|
703
|
-
* dependencies as a list of schemas
|
|
704
|
-
* @returns - The schema(s) resulting from having its conditions, additional properties, references and dependencies
|
|
705
|
-
* resolved. Multiple schemas may be returned if `expandAllBranches` is true.
|
|
706
|
-
*/
|
|
707
451
|
function retrieveSchemaInternal(validator, schema, rootSchema, rawFormData, expandAllBranches = false) {
|
|
708
452
|
if (!isObject(schema)) {
|
|
709
453
|
return [{}];
|
|
710
454
|
}
|
|
711
455
|
const resolvedSchemas = resolveSchema(validator, schema, rootSchema, expandAllBranches, rawFormData);
|
|
712
|
-
return resolvedSchemas.flatMap(s => {
|
|
456
|
+
return resolvedSchemas.flatMap((s) => {
|
|
713
457
|
let resolvedSchema = s;
|
|
714
458
|
if (IF_KEY in resolvedSchema) {
|
|
715
459
|
return resolveCondition(validator, resolvedSchema, rootSchema, expandAllBranches, rawFormData);
|
|
716
460
|
}
|
|
717
461
|
if (ALL_OF_KEY in resolvedSchema) {
|
|
718
|
-
// resolve allOf schemas
|
|
719
462
|
if (expandAllBranches) {
|
|
720
463
|
return [...resolvedSchema.allOf];
|
|
721
464
|
}
|
|
@@ -724,11 +467,8 @@ function retrieveSchemaInternal(validator, schema, rootSchema, rawFormData, expa
|
|
|
724
467
|
deep: false
|
|
725
468
|
});
|
|
726
469
|
} catch (e) {
|
|
727
|
-
console.warn(
|
|
728
|
-
const {
|
|
729
|
-
allOf,
|
|
730
|
-
...resolvedSchemaWithoutAllOf
|
|
731
|
-
} = resolvedSchema;
|
|
470
|
+
console.warn("could not merge subschemas in allOf:\n", e);
|
|
471
|
+
const { allOf, ...resolvedSchemaWithoutAllOf } = resolvedSchema;
|
|
732
472
|
return resolvedSchemaWithoutAllOf;
|
|
733
473
|
}
|
|
734
474
|
}
|
|
@@ -739,177 +479,123 @@ function retrieveSchemaInternal(validator, schema, rootSchema, rawFormData, expa
|
|
|
739
479
|
return resolvedSchema;
|
|
740
480
|
});
|
|
741
481
|
}
|
|
742
|
-
/** Resolves an `anyOf` or `oneOf` within a schema (if present) to the list of schemas returned from
|
|
743
|
-
* `retrieveSchemaInternal()` for the best matching option. If `expandAllBranches` is true, then a list of schemas for ALL
|
|
744
|
-
* options are retrieved and returned.
|
|
745
|
-
*
|
|
746
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
747
|
-
* @param schema - The schema for which retrieving a schema is desired
|
|
748
|
-
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
749
|
-
* @param expandAllBranches - Flag, if true, will return all possible branches of conditions, any/oneOf and dependencies
|
|
750
|
-
* as a list of schemas
|
|
751
|
-
* @param [rawFormData] - The current formData, if any, to assist retrieving a schema, defaults to an empty object
|
|
752
|
-
* @returns - Either an array containing the best matching option or all options if `expandAllBranches` is true
|
|
753
|
-
*/
|
|
754
482
|
function resolveAnyOrOneOfSchemas(validator, schema, rootSchema, expandAllBranches, rawFormData) {
|
|
755
483
|
let anyOrOneOf;
|
|
756
|
-
const {
|
|
757
|
-
oneOf,
|
|
758
|
-
anyOf,
|
|
759
|
-
...remaining
|
|
760
|
-
} = schema;
|
|
484
|
+
const { oneOf, anyOf, ...remaining } = schema;
|
|
761
485
|
if (Array.isArray(oneOf)) {
|
|
762
486
|
anyOrOneOf = oneOf;
|
|
763
487
|
} else if (Array.isArray(anyOf)) {
|
|
764
488
|
anyOrOneOf = anyOf;
|
|
765
489
|
}
|
|
766
490
|
if (anyOrOneOf) {
|
|
767
|
-
|
|
768
|
-
const formData = rawFormData === undefined && expandAllBranches ? {} : rawFormData;
|
|
491
|
+
const formData = rawFormData === void 0 && expandAllBranches ? {} : rawFormData;
|
|
769
492
|
const discriminator = getDiscriminatorFieldFromSchema(schema);
|
|
770
|
-
anyOrOneOf = anyOrOneOf.map(s => {
|
|
493
|
+
anyOrOneOf = anyOrOneOf.map((s) => {
|
|
771
494
|
return resolveAllReferences(s, rootSchema);
|
|
772
495
|
});
|
|
773
|
-
// Call this to trigger the set of isValid() calls that the schema parser will need
|
|
774
496
|
const option = getFirstMatchingOption(validator, formData, anyOrOneOf, rootSchema, discriminator);
|
|
775
497
|
if (expandAllBranches) {
|
|
776
|
-
return anyOrOneOf.map(item => mergeSchemas(remaining, item));
|
|
498
|
+
return anyOrOneOf.map((item) => mergeSchemas(remaining, item));
|
|
777
499
|
}
|
|
778
500
|
schema = mergeSchemas(remaining, anyOrOneOf[option]);
|
|
779
501
|
}
|
|
780
502
|
return [schema];
|
|
781
503
|
}
|
|
782
|
-
/** Resolves dependencies within a schema and its 'anyOf/oneOf' children. Passes the `expandAllBranches` flag down to
|
|
783
|
-
* the `resolveAnyOrOneOfSchema()` and `processDependencies()` helper calls.
|
|
784
|
-
*
|
|
785
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
786
|
-
* @param schema - The schema for which resolving a dependency is desired
|
|
787
|
-
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
788
|
-
* @param expandAllBranches - Flag, if true, will return all possible branches of conditions, any/oneOf and dependencies
|
|
789
|
-
* as a list of schemas
|
|
790
|
-
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
791
|
-
* @returns - The list of schemas with their dependencies resolved
|
|
792
|
-
*/
|
|
793
504
|
function resolveDependencies(validator, schema, rootSchema, expandAllBranches, formData) {
|
|
794
|
-
|
|
795
|
-
const
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
* @param dependencies - The set of dependencies that needs to be processed
|
|
807
|
-
* @param resolvedSchema - The schema for which processing dependencies is desired
|
|
808
|
-
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
809
|
-
* @param expandAllBranches - Flag, if true, will return all possible branches of conditions, any/oneOf and dependencies
|
|
810
|
-
* as a list of schemas
|
|
811
|
-
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
812
|
-
* @returns - The schema with the `dependencies` resolved into it
|
|
813
|
-
*/
|
|
505
|
+
const { dependencies, ...remainingSchema } = schema;
|
|
506
|
+
const resolvedSchemas = resolveAnyOrOneOfSchemas(
|
|
507
|
+
validator,
|
|
508
|
+
remainingSchema,
|
|
509
|
+
rootSchema,
|
|
510
|
+
expandAllBranches,
|
|
511
|
+
formData
|
|
512
|
+
);
|
|
513
|
+
return resolvedSchemas.flatMap(
|
|
514
|
+
(resolvedSchema) => processDependencies(validator, dependencies, resolvedSchema, rootSchema, expandAllBranches, formData)
|
|
515
|
+
);
|
|
516
|
+
}
|
|
814
517
|
function processDependencies(validator, dependencies, resolvedSchema, rootSchema, expandAllBranches, formData) {
|
|
815
518
|
let schemas = [resolvedSchema];
|
|
816
|
-
// Process dependencies updating the local schema properties as appropriate.
|
|
817
519
|
for (const dependencyKey in dependencies) {
|
|
818
|
-
|
|
819
|
-
if (!expandAllBranches && get(formData, [dependencyKey]) === undefined) {
|
|
520
|
+
if (!expandAllBranches && get3(formData, [dependencyKey]) === void 0) {
|
|
820
521
|
continue;
|
|
821
522
|
}
|
|
822
|
-
// Skip this dependency if it is not included in the schema (such as when dependencyKey is itself a hidden dependency.)
|
|
823
523
|
if (resolvedSchema.properties && !(dependencyKey in resolvedSchema.properties)) {
|
|
824
524
|
continue;
|
|
825
525
|
}
|
|
826
|
-
const [remainingDependencies, dependencyValue] = splitKeyElementFromObject(
|
|
526
|
+
const [remainingDependencies, dependencyValue] = splitKeyElementFromObject(
|
|
527
|
+
dependencyKey,
|
|
528
|
+
dependencies
|
|
529
|
+
);
|
|
827
530
|
if (Array.isArray(dependencyValue)) {
|
|
828
531
|
schemas[0] = withDependentProperties(resolvedSchema, dependencyValue);
|
|
829
532
|
} else if (isObject(dependencyValue)) {
|
|
830
|
-
schemas = withDependentSchema(
|
|
533
|
+
schemas = withDependentSchema(
|
|
534
|
+
validator,
|
|
535
|
+
resolvedSchema,
|
|
536
|
+
rootSchema,
|
|
537
|
+
dependencyKey,
|
|
538
|
+
dependencyValue,
|
|
539
|
+
expandAllBranches,
|
|
540
|
+
formData
|
|
541
|
+
);
|
|
831
542
|
}
|
|
832
|
-
return schemas.flatMap(
|
|
543
|
+
return schemas.flatMap(
|
|
544
|
+
(schema) => processDependencies(validator, remainingDependencies, schema, rootSchema, expandAllBranches, formData)
|
|
545
|
+
);
|
|
833
546
|
}
|
|
834
547
|
return schemas;
|
|
835
548
|
}
|
|
836
|
-
/** Updates a schema with additionally required properties added
|
|
837
|
-
*
|
|
838
|
-
* @param schema - The schema for which resolving a dependent properties is desired
|
|
839
|
-
* @param [additionallyRequired] - An optional array of additionally required names
|
|
840
|
-
* @returns - The schema with the additional required values merged in
|
|
841
|
-
*/
|
|
842
549
|
function withDependentProperties(schema, additionallyRequired) {
|
|
843
550
|
if (!additionallyRequired) {
|
|
844
551
|
return schema;
|
|
845
552
|
}
|
|
846
|
-
const required = Array.isArray(schema.required) ? Array.from(new Set([...schema.required, ...additionallyRequired])) : additionallyRequired;
|
|
847
|
-
return {
|
|
848
|
-
...schema,
|
|
849
|
-
required: required
|
|
850
|
-
};
|
|
553
|
+
const required = Array.isArray(schema.required) ? Array.from(/* @__PURE__ */ new Set([...schema.required, ...additionallyRequired])) : additionallyRequired;
|
|
554
|
+
return { ...schema, required };
|
|
851
555
|
}
|
|
852
|
-
/** Merges a dependent schema into the `schema` dealing with oneOfs and references. Passes the `expandAllBranches` flag
|
|
853
|
-
* down to the `retrieveSchemaInternal()`, `resolveReference()` and `withExactlyOneSubschema()` helper calls.
|
|
854
|
-
*
|
|
855
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
856
|
-
* @param schema - The schema for which resolving a dependent schema is desired
|
|
857
|
-
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
858
|
-
* @param dependencyKey - The key name of the dependency
|
|
859
|
-
* @param dependencyValue - The potentially dependent schema
|
|
860
|
-
* @param expandAllBranches - Flag, if true, will return all possible branches of conditions, any/oneOf and dependencies
|
|
861
|
-
* as a list of schemas
|
|
862
|
-
* @param [formData]- The current formData to assist retrieving a schema
|
|
863
|
-
* @returns - The list of schemas with the dependent schema resolved into them
|
|
864
|
-
*/
|
|
865
556
|
function withDependentSchema(validator, schema, rootSchema, dependencyKey, dependencyValue, expandAllBranches, formData) {
|
|
866
|
-
const dependentSchemas = retrieveSchemaInternal(
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
557
|
+
const dependentSchemas = retrieveSchemaInternal(
|
|
558
|
+
validator,
|
|
559
|
+
dependencyValue,
|
|
560
|
+
rootSchema,
|
|
561
|
+
formData,
|
|
562
|
+
expandAllBranches
|
|
563
|
+
);
|
|
564
|
+
return dependentSchemas.flatMap((dependent) => {
|
|
565
|
+
const { oneOf, ...dependentSchema } = dependent;
|
|
872
566
|
schema = mergeSchemas(schema, dependentSchema);
|
|
873
|
-
|
|
874
|
-
if (oneOf === undefined) {
|
|
567
|
+
if (oneOf === void 0) {
|
|
875
568
|
return schema;
|
|
876
569
|
}
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
if (typeof subschema === 'boolean' || !(REF_KEY in subschema)) {
|
|
570
|
+
const resolvedOneOfs = oneOf.map((subschema) => {
|
|
571
|
+
if (typeof subschema === "boolean" || !(REF_KEY in subschema)) {
|
|
880
572
|
return [subschema];
|
|
881
573
|
}
|
|
882
574
|
return resolveReference(validator, subschema, rootSchema, expandAllBranches, formData);
|
|
883
575
|
});
|
|
884
576
|
const allPermutations = getAllPermutationsOfXxxOf(resolvedOneOfs);
|
|
885
|
-
return allPermutations.flatMap(
|
|
577
|
+
return allPermutations.flatMap(
|
|
578
|
+
(resolvedOneOf) => withExactlyOneSubschema(
|
|
579
|
+
validator,
|
|
580
|
+
schema,
|
|
581
|
+
rootSchema,
|
|
582
|
+
dependencyKey,
|
|
583
|
+
resolvedOneOf,
|
|
584
|
+
expandAllBranches,
|
|
585
|
+
formData
|
|
586
|
+
)
|
|
587
|
+
);
|
|
886
588
|
});
|
|
887
589
|
}
|
|
888
|
-
/** Returns a list of `schema`s with the best choice from the `oneOf` options merged into it. If `expandAllBranches` is
|
|
889
|
-
* true, then a list of schemas for ALL options are retrieved and returned. Passes the `expandAllBranches` flag down to
|
|
890
|
-
* the `retrieveSchemaInternal()` helper call.
|
|
891
|
-
*
|
|
892
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used to validate oneOf options
|
|
893
|
-
* @param schema - The schema for which resolving a oneOf subschema is desired
|
|
894
|
-
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
895
|
-
* @param dependencyKey - The key name of the oneOf dependency
|
|
896
|
-
* @param oneOf - The list of schemas representing the oneOf options
|
|
897
|
-
* @param expandAllBranches - Flag, if true, will return all possible branches of conditions, any/oneOf and dependencies
|
|
898
|
-
* as a list of schemas
|
|
899
|
-
* @param [formData] - The current formData to assist retrieving a schema
|
|
900
|
-
* @returns - Either an array containing the best matching option or all options if `expandAllBranches` is true
|
|
901
|
-
*/
|
|
902
590
|
function withExactlyOneSubschema(validator, schema, rootSchema, dependencyKey, oneOf, expandAllBranches, formData) {
|
|
903
|
-
const validSubschemas = oneOf.filter(subschema => {
|
|
904
|
-
if (typeof subschema ===
|
|
591
|
+
const validSubschemas = oneOf.filter((subschema) => {
|
|
592
|
+
if (typeof subschema === "boolean" || !subschema || !subschema.properties) {
|
|
905
593
|
return false;
|
|
906
594
|
}
|
|
907
|
-
const {
|
|
908
|
-
[dependencyKey]: conditionPropertySchema
|
|
909
|
-
} = subschema.properties;
|
|
595
|
+
const { [dependencyKey]: conditionPropertySchema } = subschema.properties;
|
|
910
596
|
if (conditionPropertySchema) {
|
|
911
597
|
const conditionSchema = {
|
|
912
|
-
type:
|
|
598
|
+
type: "object",
|
|
913
599
|
properties: {
|
|
914
600
|
[dependencyKey]: conditionPropertySchema
|
|
915
601
|
}
|
|
@@ -922,194 +608,125 @@ function withExactlyOneSubschema(validator, schema, rootSchema, dependencyKey, o
|
|
|
922
608
|
console.warn("ignoring oneOf in dependencies because there isn't exactly one subschema that is valid");
|
|
923
609
|
return [schema];
|
|
924
610
|
}
|
|
925
|
-
return validSubschemas.flatMap(s => {
|
|
611
|
+
return validSubschemas.flatMap((s) => {
|
|
926
612
|
const subschema = s;
|
|
927
613
|
const [dependentSubschema] = splitKeyElementFromObject(dependencyKey, subschema.properties);
|
|
928
|
-
const dependentSchema = {
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
614
|
+
const dependentSchema = { ...subschema, properties: dependentSubschema };
|
|
615
|
+
const schemas = retrieveSchemaInternal(
|
|
616
|
+
validator,
|
|
617
|
+
dependentSchema,
|
|
618
|
+
rootSchema,
|
|
619
|
+
formData,
|
|
620
|
+
expandAllBranches
|
|
621
|
+
);
|
|
622
|
+
return schemas.map((s2) => mergeSchemas(schema, s2));
|
|
934
623
|
});
|
|
935
624
|
}
|
|
936
625
|
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
const JUNK_OPTION = {
|
|
941
|
-
type: 'object',
|
|
626
|
+
// src/schema/getClosestMatchingOption.ts
|
|
627
|
+
var JUNK_OPTION = {
|
|
628
|
+
type: "object",
|
|
942
629
|
$id: JUNK_OPTION_ID,
|
|
943
630
|
properties: {
|
|
944
631
|
__not_really_there__: {
|
|
945
|
-
type:
|
|
632
|
+
type: "number"
|
|
946
633
|
}
|
|
947
634
|
}
|
|
948
635
|
};
|
|
949
|
-
/** Recursive function that calculates the score of a `formData` against the given `schema`. The computation is fairly
|
|
950
|
-
* simple. Initially the total score is 0. When `schema.properties` object exists, then all the `key/value` pairs within
|
|
951
|
-
* the object are processed as follows after obtaining the formValue from `formData` using the `key`:
|
|
952
|
-
* - If the `value` contains a `$ref`, `calculateIndexScore()` is called recursively with the formValue and the new
|
|
953
|
-
* schema that is the result of the ref in the schema being resolved and that sub-schema's resulting score is added to
|
|
954
|
-
* the total.
|
|
955
|
-
* - If the `value` contains a `oneOf` and there is a formValue, then score based on the index returned from calling
|
|
956
|
-
* `getClosestMatchingOption()` of that oneOf.
|
|
957
|
-
* - If the type of the `value` is 'object', `calculateIndexScore()` is called recursively with the formValue and the
|
|
958
|
-
* `value` itself as the sub-schema, and the score is added to the total.
|
|
959
|
-
* - If the type of the `value` matches the guessed-type of the `formValue`, the score is incremented by 1, UNLESS the
|
|
960
|
-
* value has a `default` or `const`. In those case, if the `default` or `const` and the `formValue` match, the score
|
|
961
|
-
* is incremented by another 1 otherwise it is decremented by 1.
|
|
962
|
-
*
|
|
963
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
964
|
-
* @param rootSchema - The root JSON schema of the entire form
|
|
965
|
-
* @param schema - The schema for which the score is being calculated
|
|
966
|
-
* @param formData - The form data associated with the schema, used to calculate the score
|
|
967
|
-
* @returns - The score a schema against the formData
|
|
968
|
-
*/
|
|
969
636
|
function calculateIndexScore(validator, rootSchema, schema, formData = {}) {
|
|
970
637
|
let totalScore = 0;
|
|
971
638
|
if (schema) {
|
|
972
|
-
if (
|
|
973
|
-
totalScore += reduce(
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
const newSchema = retrieveSchema(validator, value, rootSchema, formValue);
|
|
980
|
-
return score + calculateIndexScore(validator, rootSchema, newSchema, formValue || {});
|
|
981
|
-
}
|
|
982
|
-
if ((has(value, ONE_OF_KEY) || has(value, ANY_OF_KEY)) && formValue) {
|
|
983
|
-
const key = has(value, ONE_OF_KEY) ? ONE_OF_KEY : ANY_OF_KEY;
|
|
984
|
-
const discriminator = getDiscriminatorFieldFromSchema(value);
|
|
985
|
-
return score + getClosestMatchingOption(validator, rootSchema, formValue, get(value, key), -1, discriminator);
|
|
986
|
-
}
|
|
987
|
-
if (value.type === 'object') {
|
|
988
|
-
return score + calculateIndexScore(validator, rootSchema, value, formValue || {});
|
|
989
|
-
}
|
|
990
|
-
if (value.type === guessType(formValue)) {
|
|
991
|
-
// If the types match, then we bump the score by one
|
|
992
|
-
let newScore = score + 1;
|
|
993
|
-
if (value.default) {
|
|
994
|
-
// If the schema contains a readonly default value score the value that matches the default higher and
|
|
995
|
-
// any non-matching value lower
|
|
996
|
-
newScore += formValue === value.default ? 1 : -1;
|
|
997
|
-
} else if (value.const) {
|
|
998
|
-
// If the schema contains a const value score the value that matches the default higher and
|
|
999
|
-
// any non-matching value lower
|
|
1000
|
-
newScore += formValue === value.const ? 1 : -1;
|
|
639
|
+
if (isObject2(schema.properties)) {
|
|
640
|
+
totalScore += reduce(
|
|
641
|
+
schema.properties,
|
|
642
|
+
(score, value, key) => {
|
|
643
|
+
const formValue = get4(formData, key);
|
|
644
|
+
if (typeof value === "boolean") {
|
|
645
|
+
return score;
|
|
1001
646
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
647
|
+
if (has2(value, REF_KEY)) {
|
|
648
|
+
const newSchema = retrieveSchema(validator, value, rootSchema, formValue);
|
|
649
|
+
return score + calculateIndexScore(validator, rootSchema, newSchema, formValue || {});
|
|
650
|
+
}
|
|
651
|
+
if ((has2(value, ONE_OF_KEY) || has2(value, ANY_OF_KEY)) && formValue) {
|
|
652
|
+
const key2 = has2(value, ONE_OF_KEY) ? ONE_OF_KEY : ANY_OF_KEY;
|
|
653
|
+
const discriminator = getDiscriminatorFieldFromSchema(value);
|
|
654
|
+
return score + getClosestMatchingOption(
|
|
655
|
+
validator,
|
|
656
|
+
rootSchema,
|
|
657
|
+
formValue,
|
|
658
|
+
get4(value, key2),
|
|
659
|
+
-1,
|
|
660
|
+
discriminator
|
|
661
|
+
);
|
|
662
|
+
}
|
|
663
|
+
if (value.type === "object") {
|
|
664
|
+
return score + calculateIndexScore(validator, rootSchema, value, formValue || {});
|
|
665
|
+
}
|
|
666
|
+
if (value.type === guessType(formValue)) {
|
|
667
|
+
let newScore = score + 1;
|
|
668
|
+
if (value.default) {
|
|
669
|
+
newScore += formValue === value.default ? 1 : -1;
|
|
670
|
+
} else if (value.const) {
|
|
671
|
+
newScore += formValue === value.const ? 1 : -1;
|
|
672
|
+
}
|
|
673
|
+
return newScore;
|
|
674
|
+
}
|
|
675
|
+
return score;
|
|
676
|
+
},
|
|
677
|
+
0
|
|
678
|
+
);
|
|
679
|
+
} else if (isString2(schema.type) && schema.type === guessType(formData)) {
|
|
1008
680
|
totalScore += 1;
|
|
1009
681
|
}
|
|
1010
682
|
}
|
|
1011
683
|
return totalScore;
|
|
1012
684
|
}
|
|
1013
|
-
/** Determines which of the given `options` provided most closely matches the `formData`. Using
|
|
1014
|
-
* `getFirstMatchingOption()` to match two schemas that differ only by the readOnly, default or const value of a field
|
|
1015
|
-
* based on the `formData` and returns 0 when there is no match. Rather than passing in all the `options` at once to
|
|
1016
|
-
* this utility, instead an array of valid option indexes is created by iterating over the list of options, call
|
|
1017
|
-
* `getFirstMatchingOptions` with a list of one junk option and one good option, seeing if the good option is considered
|
|
1018
|
-
* matched.
|
|
1019
|
-
*
|
|
1020
|
-
* Once the list of valid indexes is created, if there is only one valid index, just return it. Otherwise, if there are
|
|
1021
|
-
* no valid indexes, then fill the valid indexes array with the indexes of all the options. Next, the index of the
|
|
1022
|
-
* option with the highest score is determined by iterating over the list of valid options, calling
|
|
1023
|
-
* `calculateIndexScore()` on each, comparing it against the current best score, and returning the index of the one that
|
|
1024
|
-
* eventually has the best score.
|
|
1025
|
-
*
|
|
1026
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
1027
|
-
* @param rootSchema - The root JSON schema of the entire form
|
|
1028
|
-
* @param formData - The form data associated with the schema
|
|
1029
|
-
* @param options - The list of options that can be selected from
|
|
1030
|
-
* @param [selectedOption=-1] - The index of the currently selected option, defaulted to -1 if not specified
|
|
1031
|
-
* @param [discriminatorField] - The optional name of the field within the options object whose value is used to
|
|
1032
|
-
* determine which option is selected
|
|
1033
|
-
* @returns - The index of the option that is the closest match to the `formData` or the `selectedOption` if no match
|
|
1034
|
-
*/
|
|
1035
685
|
function getClosestMatchingOption(validator, rootSchema, formData, options, selectedOption = -1, discriminatorField) {
|
|
1036
|
-
|
|
1037
|
-
const resolvedOptions = options.map(option => {
|
|
686
|
+
const resolvedOptions = options.map((option) => {
|
|
1038
687
|
return resolveAllReferences(option, rootSchema);
|
|
1039
688
|
});
|
|
1040
|
-
// Reduce the array of options down to a list of the indexes that are considered matching options
|
|
1041
689
|
const allValidIndexes = resolvedOptions.reduce((validList, option, index) => {
|
|
1042
690
|
const testOptions = [JUNK_OPTION, option];
|
|
1043
691
|
const match = getFirstMatchingOption(validator, formData, testOptions, rootSchema, discriminatorField);
|
|
1044
|
-
// The match is the real option, so add its index to list of valid indexes
|
|
1045
692
|
if (match === 1) {
|
|
1046
693
|
validList.push(index);
|
|
1047
694
|
}
|
|
1048
695
|
return validList;
|
|
1049
696
|
}, []);
|
|
1050
|
-
// There is only one valid index, so return it!
|
|
1051
697
|
if (allValidIndexes.length === 1) {
|
|
1052
698
|
return allValidIndexes[0];
|
|
1053
699
|
}
|
|
1054
700
|
if (!allValidIndexes.length) {
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
const
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
bestScore
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
bestIndex: index,
|
|
1072
|
-
bestScore: score
|
|
1073
|
-
};
|
|
1074
|
-
}
|
|
1075
|
-
return scoreData;
|
|
1076
|
-
}, {
|
|
1077
|
-
bestIndex: selectedOption,
|
|
1078
|
-
bestScore: 0
|
|
1079
|
-
});
|
|
1080
|
-
// if all scores are the same go with selectedOption
|
|
701
|
+
times2(resolvedOptions.length, (i) => allValidIndexes.push(i));
|
|
702
|
+
}
|
|
703
|
+
const scoreCount = /* @__PURE__ */ new Set();
|
|
704
|
+
const { bestIndex } = allValidIndexes.reduce(
|
|
705
|
+
(scoreData, index) => {
|
|
706
|
+
const { bestScore } = scoreData;
|
|
707
|
+
const option = resolvedOptions[index];
|
|
708
|
+
const score = calculateIndexScore(validator, rootSchema, option, formData);
|
|
709
|
+
scoreCount.add(score);
|
|
710
|
+
if (score > bestScore) {
|
|
711
|
+
return { bestIndex: index, bestScore: score };
|
|
712
|
+
}
|
|
713
|
+
return scoreData;
|
|
714
|
+
},
|
|
715
|
+
{ bestIndex: selectedOption, bestScore: 0 }
|
|
716
|
+
);
|
|
1081
717
|
if (scoreCount.size === 1 && selectedOption >= 0) {
|
|
1082
718
|
return selectedOption;
|
|
1083
719
|
}
|
|
1084
720
|
return bestIndex;
|
|
1085
721
|
}
|
|
1086
722
|
|
|
1087
|
-
|
|
1088
|
-
* that only contains objects.
|
|
1089
|
-
*
|
|
1090
|
-
* @param schema - The schema in which to check for fixed items
|
|
1091
|
-
* @returns - True if there are fixed items in the schema, false otherwise
|
|
1092
|
-
*/
|
|
723
|
+
// src/isFixedItems.ts
|
|
1093
724
|
function isFixedItems(schema) {
|
|
1094
|
-
return Array.isArray(schema.items) && schema.items.length > 0 && schema.items.every(item => isObject(item));
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
* When merging defaults and form data, we want to merge in this specific way:
|
|
1100
|
-
* - objects are deeply merged
|
|
1101
|
-
* - arrays are merged in such a way that:
|
|
1102
|
-
* - when the array is set in form data, only array entries set in form data
|
|
1103
|
-
* are deeply merged; additional entries from the defaults are ignored unless `mergeExtraArrayDefaults` is true, in
|
|
1104
|
-
* which case the extras are appended onto the end of the form data
|
|
1105
|
-
* - when the array is not set in form data, the default is copied over
|
|
1106
|
-
* - scalars are overwritten/set by form data
|
|
1107
|
-
*
|
|
1108
|
-
* @param [defaults] - The defaults to merge
|
|
1109
|
-
* @param [formData] - The form data into which the defaults will be merged
|
|
1110
|
-
* @param [mergeExtraArrayDefaults=false] - If true, any additional default array entries are appended onto the formData
|
|
1111
|
-
* @returns - The resulting merged form data with defaults
|
|
1112
|
-
*/
|
|
725
|
+
return Array.isArray(schema.items) && schema.items.length > 0 && schema.items.every((item) => isObject(item));
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
// src/mergeDefaultsWithFormData.ts
|
|
729
|
+
import get5 from "lodash/get";
|
|
1113
730
|
function mergeDefaultsWithFormData(defaults, formData, mergeExtraArrayDefaults = false) {
|
|
1114
731
|
if (Array.isArray(formData)) {
|
|
1115
732
|
const defaultsArray = Array.isArray(defaults) ? defaults : [];
|
|
@@ -1119,40 +736,34 @@ function mergeDefaultsWithFormData(defaults, formData, mergeExtraArrayDefaults =
|
|
|
1119
736
|
}
|
|
1120
737
|
return value;
|
|
1121
738
|
});
|
|
1122
|
-
// Merge any extra defaults when mergeExtraArrayDefaults is true
|
|
1123
739
|
if (mergeExtraArrayDefaults && mapped.length < defaultsArray.length) {
|
|
1124
740
|
mapped.push(...defaultsArray.slice(mapped.length));
|
|
1125
741
|
}
|
|
1126
742
|
return mapped;
|
|
1127
743
|
}
|
|
1128
744
|
if (isObject(formData)) {
|
|
1129
|
-
const acc = Object.assign({}, defaults);
|
|
1130
|
-
return Object.keys(formData).reduce((
|
|
1131
|
-
|
|
1132
|
-
|
|
745
|
+
const acc = Object.assign({}, defaults);
|
|
746
|
+
return Object.keys(formData).reduce((acc2, key) => {
|
|
747
|
+
acc2[key] = mergeDefaultsWithFormData(
|
|
748
|
+
defaults ? get5(defaults, key) : {},
|
|
749
|
+
get5(formData, key),
|
|
750
|
+
mergeExtraArrayDefaults
|
|
751
|
+
);
|
|
752
|
+
return acc2;
|
|
1133
753
|
}, acc);
|
|
1134
754
|
}
|
|
1135
755
|
return formData;
|
|
1136
756
|
}
|
|
1137
757
|
|
|
1138
|
-
|
|
1139
|
-
*
|
|
1140
|
-
* @param obj1 - The first object to merge
|
|
1141
|
-
* @param obj2 - The second object to merge
|
|
1142
|
-
* @param [concatArrays=false] - Optional flag that, when true, will cause arrays to be concatenated. Use
|
|
1143
|
-
* "preventDuplicates" to merge arrays in a manner that prevents any duplicate entries from being merged.
|
|
1144
|
-
* NOTE: Uses shallow comparison for the duplicate checking.
|
|
1145
|
-
* @returns - A new object that is the merge of the two given objects
|
|
1146
|
-
*/
|
|
758
|
+
// src/mergeObjects.ts
|
|
1147
759
|
function mergeObjects(obj1, obj2, concatArrays = false) {
|
|
1148
760
|
return Object.keys(obj2).reduce((acc, key) => {
|
|
1149
|
-
const left = obj1 ? obj1[key] : {},
|
|
1150
|
-
right = obj2[key];
|
|
761
|
+
const left = obj1 ? obj1[key] : {}, right = obj2[key];
|
|
1151
762
|
if (obj1 && key in obj1 && isObject(right)) {
|
|
1152
763
|
acc[key] = mergeObjects(left, right, concatArrays);
|
|
1153
764
|
} else if (concatArrays && Array.isArray(left) && Array.isArray(right)) {
|
|
1154
765
|
let toMerge = right;
|
|
1155
|
-
if (concatArrays ===
|
|
766
|
+
if (concatArrays === "preventDuplicates") {
|
|
1156
767
|
toMerge = right.reduce((result, value) => {
|
|
1157
768
|
if (!left.includes(value)) {
|
|
1158
769
|
result.push(value);
|
|
@@ -1165,216 +776,140 @@ function mergeObjects(obj1, obj2, concatArrays = false) {
|
|
|
1165
776
|
acc[key] = right;
|
|
1166
777
|
}
|
|
1167
778
|
return acc;
|
|
1168
|
-
}, Object.assign({}, obj1));
|
|
779
|
+
}, Object.assign({}, obj1));
|
|
1169
780
|
}
|
|
1170
781
|
|
|
1171
|
-
|
|
1172
|
-
* an `enum` array with a single value or there is a `const` defined.
|
|
1173
|
-
*
|
|
1174
|
-
* @param schema - The schema for a field
|
|
1175
|
-
* @returns - True if the `schema` has a single constant value, false otherwise
|
|
1176
|
-
*/
|
|
782
|
+
// src/isConstant.ts
|
|
1177
783
|
function isConstant(schema) {
|
|
1178
784
|
return Array.isArray(schema.enum) && schema.enum.length === 1 || CONST_KEY in schema;
|
|
1179
785
|
}
|
|
1180
786
|
|
|
1181
|
-
|
|
1182
|
-
*
|
|
1183
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
1184
|
-
* @param theSchema - The schema for which check for a select flag is desired
|
|
1185
|
-
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1186
|
-
* @returns - True if schema contains a select, otherwise false
|
|
1187
|
-
*/
|
|
787
|
+
// src/schema/isSelect.ts
|
|
1188
788
|
function isSelect(validator, theSchema, rootSchema = {}) {
|
|
1189
|
-
const schema = retrieveSchema(validator, theSchema, rootSchema,
|
|
789
|
+
const schema = retrieveSchema(validator, theSchema, rootSchema, void 0);
|
|
1190
790
|
const altSchemas = schema.oneOf || schema.anyOf;
|
|
1191
791
|
if (Array.isArray(schema.enum)) {
|
|
1192
792
|
return true;
|
|
1193
793
|
}
|
|
1194
794
|
if (Array.isArray(altSchemas)) {
|
|
1195
|
-
return altSchemas.every(
|
|
795
|
+
return altSchemas.every((altSchemas2) => typeof altSchemas2 !== "boolean" && isConstant(altSchemas2));
|
|
1196
796
|
}
|
|
1197
797
|
return false;
|
|
1198
798
|
}
|
|
1199
799
|
|
|
1200
|
-
|
|
1201
|
-
*
|
|
1202
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
1203
|
-
* @param schema - The schema for which check for a multi-select flag is desired
|
|
1204
|
-
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1205
|
-
* @returns - True if schema contains a multi-select, otherwise false
|
|
1206
|
-
*/
|
|
800
|
+
// src/schema/isMultiSelect.ts
|
|
1207
801
|
function isMultiSelect(validator, schema, rootSchema) {
|
|
1208
|
-
if (!schema.uniqueItems || !schema.items || typeof schema.items ===
|
|
802
|
+
if (!schema.uniqueItems || !schema.items || typeof schema.items === "boolean") {
|
|
1209
803
|
return false;
|
|
1210
804
|
}
|
|
1211
805
|
return isSelect(validator, schema.items, rootSchema);
|
|
1212
806
|
}
|
|
1213
807
|
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
var AdditionalItemsHandling;
|
|
1217
|
-
(function (AdditionalItemsHandling) {
|
|
1218
|
-
AdditionalItemsHandling[AdditionalItemsHandling["Ignore"] = 0] = "Ignore";
|
|
1219
|
-
AdditionalItemsHandling[AdditionalItemsHandling["Invert"] = 1] = "Invert";
|
|
1220
|
-
AdditionalItemsHandling[AdditionalItemsHandling["Fallback"] = 2] = "Fallback";
|
|
1221
|
-
})(AdditionalItemsHandling || (AdditionalItemsHandling = {}));
|
|
1222
|
-
/** Given a `schema` will return an inner schema that for an array item. This is computed differently based on the
|
|
1223
|
-
* `additionalItems` enum and the value of `idx`. There are four possible returns:
|
|
1224
|
-
* 1. If `idx` is >= 0, then if `schema.items` is an array the `idx`th element of the array is returned if it is a valid
|
|
1225
|
-
* index and not a boolean, otherwise it falls through to 3.
|
|
1226
|
-
* 2. If `schema.items` is not an array AND truthy and not a boolean, then `schema.items` is returned since it actually
|
|
1227
|
-
* is a schema, otherwise it falls through to 3.
|
|
1228
|
-
* 3. If `additionalItems` is not `AdditionalItemsHandling.Ignore` and `schema.additionalItems` is an object, then
|
|
1229
|
-
* `schema.additionalItems` is returned since it actually is a schema, otherwise it falls through to 4.
|
|
1230
|
-
* 4. {} is returned representing an empty schema
|
|
1231
|
-
*
|
|
1232
|
-
* @param schema - The schema from which to get the particular item
|
|
1233
|
-
* @param [additionalItems=AdditionalItemsHandling.Ignore] - How do we want to handle additional items?
|
|
1234
|
-
* @param [idx=-1] - Index, if non-negative, will be used to return the idx-th element in a `schema.items` array
|
|
1235
|
-
* @returns - The best fit schema object from the `schema` given the `additionalItems` and `idx` modifiers
|
|
1236
|
-
*/
|
|
1237
|
-
function getInnerSchemaForArrayItem(schema, additionalItems = AdditionalItemsHandling.Ignore, idx = -1) {
|
|
808
|
+
// src/schema/getDefaultFormState.ts
|
|
809
|
+
function getInnerSchemaForArrayItem(schema, additionalItems = 0 /* Ignore */, idx = -1) {
|
|
1238
810
|
if (idx >= 0) {
|
|
1239
811
|
if (Array.isArray(schema.items) && idx < schema.items.length) {
|
|
1240
812
|
const item = schema.items[idx];
|
|
1241
|
-
if (typeof item !==
|
|
813
|
+
if (typeof item !== "boolean") {
|
|
1242
814
|
return item;
|
|
1243
815
|
}
|
|
1244
816
|
}
|
|
1245
|
-
} else if (schema.items && !Array.isArray(schema.items) && typeof schema.items !==
|
|
817
|
+
} else if (schema.items && !Array.isArray(schema.items) && typeof schema.items !== "boolean") {
|
|
1246
818
|
return schema.items;
|
|
1247
819
|
}
|
|
1248
|
-
if (additionalItems !==
|
|
820
|
+
if (additionalItems !== 0 /* Ignore */ && isObject(schema.additionalItems)) {
|
|
1249
821
|
return schema.additionalItems;
|
|
1250
822
|
}
|
|
1251
823
|
return {};
|
|
1252
824
|
}
|
|
1253
|
-
/** Either add `computedDefault` at `key` into `obj` or not add it based on its value, the value of
|
|
1254
|
-
* `includeUndefinedValues`, the value of `emptyObjectFields` and if its parent field is required. Generally undefined
|
|
1255
|
-
* `computedDefault` values are added only when `includeUndefinedValues` is either true/"excludeObjectChildren". If `
|
|
1256
|
-
* includeUndefinedValues` is false and `emptyObjectFields` is not "skipDefaults", then non-undefined and non-empty-object
|
|
1257
|
-
* values will be added based on certain conditions.
|
|
1258
|
-
*
|
|
1259
|
-
* @param obj - The object into which the computed default may be added
|
|
1260
|
-
* @param key - The key into the object at which the computed default may be added
|
|
1261
|
-
* @param computedDefault - The computed default value that maybe should be added to the obj
|
|
1262
|
-
* @param includeUndefinedValues - Optional flag, if true, cause undefined values to be added as defaults.
|
|
1263
|
-
* If "excludeObjectChildren", cause undefined values for this object and pass `includeUndefinedValues` as
|
|
1264
|
-
* false when computing defaults for any nested object properties. If "allowEmptyObject", prevents undefined
|
|
1265
|
-
* values in this object while allow the object itself to be empty and passing `includeUndefinedValues` as
|
|
1266
|
-
* false when computing defaults for any nested object properties.
|
|
1267
|
-
* @param isParentRequired - The optional boolean that indicates whether the parent field is required
|
|
1268
|
-
* @param requiredFields - The list of fields that are required
|
|
1269
|
-
* @param experimental_defaultFormStateBehavior - Optional configuration object, if provided, allows users to override
|
|
1270
|
-
* default form state behavior
|
|
1271
|
-
*/
|
|
1272
825
|
function maybeAddDefaultToObject(obj, key, computedDefault, includeUndefinedValues, isParentRequired, requiredFields = [], experimental_defaultFormStateBehavior = {}) {
|
|
1273
|
-
const {
|
|
1274
|
-
emptyObjectFields = 'populateAllDefaults'
|
|
1275
|
-
} = experimental_defaultFormStateBehavior;
|
|
826
|
+
const { emptyObjectFields = "populateAllDefaults" } = experimental_defaultFormStateBehavior;
|
|
1276
827
|
if (includeUndefinedValues) {
|
|
1277
828
|
obj[key] = computedDefault;
|
|
1278
|
-
} else if (emptyObjectFields !==
|
|
829
|
+
} else if (emptyObjectFields !== "skipDefaults") {
|
|
1279
830
|
if (isObject(computedDefault)) {
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
const isSelfOrParentRequired = isParentRequired === undefined ? requiredFields.includes(key) : isParentRequired;
|
|
1283
|
-
// Store computedDefault if it's a non-empty object(e.g. not {}) and satisfies certain conditions
|
|
1284
|
-
// Condition 1: If computedDefault is not empty or if the key is a required field
|
|
1285
|
-
// Condition 2: If the parent object is required or emptyObjectFields is not 'populateRequiredDefaults'
|
|
1286
|
-
if ((!isEmpty(computedDefault) || requiredFields.includes(key)) && (isSelfOrParentRequired || emptyObjectFields !== 'populateRequiredDefaults')) {
|
|
831
|
+
const isSelfOrParentRequired = isParentRequired === void 0 ? requiredFields.includes(key) : isParentRequired;
|
|
832
|
+
if ((!isEmpty(computedDefault) || requiredFields.includes(key)) && (isSelfOrParentRequired || emptyObjectFields !== "populateRequiredDefaults")) {
|
|
1287
833
|
obj[key] = computedDefault;
|
|
1288
834
|
}
|
|
1289
835
|
} else if (
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
836
|
+
// Store computedDefault if it's a defined primitive (e.g., true) and satisfies certain conditions
|
|
837
|
+
// Condition 1: computedDefault is not undefined
|
|
838
|
+
// Condition 2: If emptyObjectFields is 'populateAllDefaults' or if the key is a required field
|
|
839
|
+
computedDefault !== void 0 && (emptyObjectFields === "populateAllDefaults" || requiredFields.includes(key))
|
|
840
|
+
) {
|
|
1294
841
|
obj[key] = computedDefault;
|
|
1295
842
|
}
|
|
1296
843
|
}
|
|
1297
844
|
}
|
|
1298
|
-
/** Computes the defaults for the current `schema` given the `rawFormData` and `parentDefaults` if any. This drills into
|
|
1299
|
-
* each level of the schema, recursively, to fill out every level of defaults provided by the schema.
|
|
1300
|
-
*
|
|
1301
|
-
* @param validator - an implementation of the `ValidatorType` interface that will be used when necessary
|
|
1302
|
-
* @param rawSchema - The schema for which the default state is desired
|
|
1303
|
-
* @param [props] - Optional props for this function
|
|
1304
|
-
* @param [props.parentDefaults] - Any defaults provided by the parent field in the schema
|
|
1305
|
-
* @param [props.rootSchema] - The options root schema, used to primarily to look up `$ref`s
|
|
1306
|
-
* @param [props.rawFormData] - The current formData, if any, onto which to provide any missing defaults
|
|
1307
|
-
* @param [props.includeUndefinedValues=false] - Optional flag, if true, cause undefined values to be added as defaults.
|
|
1308
|
-
* If "excludeObjectChildren", cause undefined values for this object and pass `includeUndefinedValues` as
|
|
1309
|
-
* false when computing defaults for any nested object properties.
|
|
1310
|
-
* @param [props._recurseList=[]] - The list of ref names currently being recursed, used to prevent infinite recursion
|
|
1311
|
-
* @param [props.experimental_defaultFormStateBehavior] Optional configuration object, if provided, allows users to override default form state behavior
|
|
1312
|
-
* @param [props.required] - Optional flag, if true, indicates this schema was required in the parent schema.
|
|
1313
|
-
* @returns - The resulting `formData` with all the defaults provided
|
|
1314
|
-
*/
|
|
1315
845
|
function computeDefaults(validator, rawSchema, {
|
|
1316
846
|
parentDefaults,
|
|
1317
847
|
rawFormData,
|
|
1318
848
|
rootSchema = {},
|
|
1319
849
|
includeUndefinedValues = false,
|
|
1320
850
|
_recurseList = [],
|
|
1321
|
-
experimental_defaultFormStateBehavior =
|
|
851
|
+
experimental_defaultFormStateBehavior = void 0,
|
|
1322
852
|
required
|
|
1323
853
|
} = {}) {
|
|
1324
854
|
const formData = isObject(rawFormData) ? rawFormData : {};
|
|
1325
855
|
const schema = isObject(rawSchema) ? rawSchema : {};
|
|
1326
|
-
// Compute the defaults recursively: give highest priority to deepest nodes.
|
|
1327
856
|
let defaults = parentDefaults;
|
|
1328
|
-
// If we get a new schema, then we need to recompute defaults again for the new schema found.
|
|
1329
857
|
let schemaToCompute = null;
|
|
1330
858
|
let updatedRecurseList = _recurseList;
|
|
1331
859
|
if (isObject(defaults) && isObject(schema.default)) {
|
|
1332
|
-
// For object defaults, only override parent defaults that are defined in
|
|
1333
|
-
// schema.default.
|
|
1334
860
|
defaults = mergeObjects(defaults, schema.default);
|
|
1335
861
|
} else if (DEFAULT_KEY in schema) {
|
|
1336
862
|
defaults = schema.default;
|
|
1337
863
|
} else if (REF_KEY in schema) {
|
|
1338
864
|
const refName = schema[REF_KEY];
|
|
1339
|
-
// Use referenced schema defaults for this node.
|
|
1340
865
|
if (!_recurseList.includes(refName)) {
|
|
1341
866
|
updatedRecurseList = _recurseList.concat(refName);
|
|
1342
867
|
schemaToCompute = findSchemaDefinition(refName, rootSchema);
|
|
1343
868
|
}
|
|
1344
869
|
} else if (DEPENDENCIES_KEY in schema) {
|
|
1345
870
|
const resolvedSchema = resolveDependencies(validator, schema, rootSchema, false, formData);
|
|
1346
|
-
schemaToCompute = resolvedSchema[0];
|
|
871
|
+
schemaToCompute = resolvedSchema[0];
|
|
1347
872
|
} else if (isFixedItems(schema)) {
|
|
1348
|
-
defaults = schema.items.map(
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
873
|
+
defaults = schema.items.map(
|
|
874
|
+
(itemSchema, idx) => computeDefaults(validator, itemSchema, {
|
|
875
|
+
rootSchema,
|
|
876
|
+
includeUndefinedValues,
|
|
877
|
+
_recurseList,
|
|
878
|
+
experimental_defaultFormStateBehavior,
|
|
879
|
+
parentDefaults: Array.isArray(parentDefaults) ? parentDefaults[idx] : void 0,
|
|
880
|
+
rawFormData: formData,
|
|
881
|
+
required
|
|
882
|
+
})
|
|
883
|
+
);
|
|
1357
884
|
} else if (ONE_OF_KEY in schema) {
|
|
1358
|
-
const {
|
|
1359
|
-
oneOf,
|
|
1360
|
-
...remaining
|
|
1361
|
-
} = schema;
|
|
885
|
+
const { oneOf, ...remaining } = schema;
|
|
1362
886
|
if (oneOf.length === 0) {
|
|
1363
|
-
return
|
|
887
|
+
return void 0;
|
|
1364
888
|
}
|
|
1365
889
|
const discriminator = getDiscriminatorFieldFromSchema(schema);
|
|
1366
|
-
schemaToCompute = oneOf[getClosestMatchingOption(
|
|
890
|
+
schemaToCompute = oneOf[getClosestMatchingOption(
|
|
891
|
+
validator,
|
|
892
|
+
rootSchema,
|
|
893
|
+
isEmpty(formData) ? void 0 : formData,
|
|
894
|
+
oneOf,
|
|
895
|
+
0,
|
|
896
|
+
discriminator
|
|
897
|
+
)];
|
|
1367
898
|
schemaToCompute = mergeSchemas(remaining, schemaToCompute);
|
|
1368
899
|
} else if (ANY_OF_KEY in schema) {
|
|
1369
|
-
const {
|
|
1370
|
-
anyOf,
|
|
1371
|
-
...remaining
|
|
1372
|
-
} = schema;
|
|
900
|
+
const { anyOf, ...remaining } = schema;
|
|
1373
901
|
if (anyOf.length === 0) {
|
|
1374
|
-
return
|
|
902
|
+
return void 0;
|
|
1375
903
|
}
|
|
1376
904
|
const discriminator = getDiscriminatorFieldFromSchema(schema);
|
|
1377
|
-
schemaToCompute = anyOf[getClosestMatchingOption(
|
|
905
|
+
schemaToCompute = anyOf[getClosestMatchingOption(
|
|
906
|
+
validator,
|
|
907
|
+
rootSchema,
|
|
908
|
+
isEmpty(formData) ? void 0 : formData,
|
|
909
|
+
anyOf,
|
|
910
|
+
0,
|
|
911
|
+
discriminator
|
|
912
|
+
)];
|
|
1378
913
|
schemaToCompute = mergeSchemas(remaining, schemaToCompute);
|
|
1379
914
|
}
|
|
1380
915
|
if (schemaToCompute) {
|
|
@@ -1388,135 +923,130 @@ function computeDefaults(validator, rawSchema, {
|
|
|
1388
923
|
required
|
|
1389
924
|
});
|
|
1390
925
|
}
|
|
1391
|
-
|
|
1392
|
-
if (defaults === undefined) {
|
|
926
|
+
if (defaults === void 0) {
|
|
1393
927
|
defaults = schema.default;
|
|
1394
928
|
}
|
|
1395
929
|
switch (getSchemaType(schema)) {
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
930
|
+
case "object": {
|
|
931
|
+
const objectDefaults = Object.keys(schema.properties || {}).reduce((acc, key) => {
|
|
932
|
+
const computedDefault = computeDefaults(validator, get6(schema, [PROPERTIES_KEY, key]), {
|
|
933
|
+
rootSchema,
|
|
934
|
+
_recurseList,
|
|
935
|
+
experimental_defaultFormStateBehavior,
|
|
936
|
+
includeUndefinedValues: includeUndefinedValues === true,
|
|
937
|
+
parentDefaults: get6(defaults, [key]),
|
|
938
|
+
rawFormData: get6(formData, [key]),
|
|
939
|
+
required: schema.required?.includes(key)
|
|
940
|
+
});
|
|
941
|
+
maybeAddDefaultToObject(
|
|
942
|
+
acc,
|
|
943
|
+
key,
|
|
944
|
+
computedDefault,
|
|
945
|
+
includeUndefinedValues,
|
|
946
|
+
required,
|
|
947
|
+
schema.required,
|
|
948
|
+
experimental_defaultFormStateBehavior
|
|
949
|
+
);
|
|
950
|
+
return acc;
|
|
951
|
+
}, {});
|
|
952
|
+
if (schema.additionalProperties) {
|
|
953
|
+
const additionalPropertiesSchema = isObject(schema.additionalProperties) ? schema.additionalProperties : {};
|
|
954
|
+
const keys = /* @__PURE__ */ new Set();
|
|
955
|
+
if (isObject(defaults)) {
|
|
956
|
+
Object.keys(defaults).filter((key) => !schema.properties || !schema.properties[key]).forEach((key) => keys.add(key));
|
|
957
|
+
}
|
|
958
|
+
let formDataRequired;
|
|
959
|
+
if (isObject(formData)) {
|
|
960
|
+
formDataRequired = [];
|
|
961
|
+
Object.keys(formData).filter((key) => !schema.properties || !schema.properties[key]).forEach((key) => {
|
|
962
|
+
keys.add(key);
|
|
963
|
+
formDataRequired.push(key);
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
keys.forEach((key) => {
|
|
967
|
+
const computedDefault = computeDefaults(validator, additionalPropertiesSchema, {
|
|
1404
968
|
rootSchema,
|
|
1405
969
|
_recurseList,
|
|
1406
970
|
experimental_defaultFormStateBehavior,
|
|
1407
971
|
includeUndefinedValues: includeUndefinedValues === true,
|
|
1408
|
-
parentDefaults:
|
|
1409
|
-
rawFormData:
|
|
1410
|
-
required:
|
|
1411
|
-
});
|
|
1412
|
-
maybeAddDefaultToObject(acc, key, computedDefault, includeUndefinedValues, required, schema.required, experimental_defaultFormStateBehavior);
|
|
1413
|
-
return acc;
|
|
1414
|
-
}, {});
|
|
1415
|
-
if (schema.additionalProperties) {
|
|
1416
|
-
// as per spec additionalProperties may be either schema or boolean
|
|
1417
|
-
const additionalPropertiesSchema = isObject(schema.additionalProperties) ? schema.additionalProperties : {};
|
|
1418
|
-
const keys = new Set();
|
|
1419
|
-
if (isObject(defaults)) {
|
|
1420
|
-
Object.keys(defaults).filter(key => !schema.properties || !schema.properties[key]).forEach(key => keys.add(key));
|
|
1421
|
-
}
|
|
1422
|
-
let formDataRequired;
|
|
1423
|
-
if (isObject(formData)) {
|
|
1424
|
-
formDataRequired = [];
|
|
1425
|
-
Object.keys(formData).filter(key => !schema.properties || !schema.properties[key]).forEach(key => {
|
|
1426
|
-
keys.add(key);
|
|
1427
|
-
formDataRequired.push(key);
|
|
1428
|
-
});
|
|
1429
|
-
}
|
|
1430
|
-
keys.forEach(key => {
|
|
1431
|
-
var _schema$required2;
|
|
1432
|
-
const computedDefault = computeDefaults(validator, additionalPropertiesSchema, {
|
|
1433
|
-
rootSchema,
|
|
1434
|
-
_recurseList,
|
|
1435
|
-
experimental_defaultFormStateBehavior,
|
|
1436
|
-
includeUndefinedValues: includeUndefinedValues === true,
|
|
1437
|
-
parentDefaults: get(defaults, [key]),
|
|
1438
|
-
rawFormData: get(formData, [key]),
|
|
1439
|
-
required: (_schema$required2 = schema.required) === null || _schema$required2 === void 0 ? void 0 : _schema$required2.includes(key)
|
|
1440
|
-
});
|
|
1441
|
-
// Since these are additional properties we don’t need to add the `experimental_defaultFormStateBehavior` prop
|
|
1442
|
-
maybeAddDefaultToObject(objectDefaults, key, computedDefault, includeUndefinedValues, required, formDataRequired);
|
|
972
|
+
parentDefaults: get6(defaults, [key]),
|
|
973
|
+
rawFormData: get6(formData, [key]),
|
|
974
|
+
required: schema.required?.includes(key)
|
|
1443
975
|
});
|
|
1444
|
-
|
|
1445
|
-
|
|
976
|
+
maybeAddDefaultToObject(
|
|
977
|
+
objectDefaults,
|
|
978
|
+
key,
|
|
979
|
+
computedDefault,
|
|
980
|
+
includeUndefinedValues,
|
|
981
|
+
required,
|
|
982
|
+
formDataRequired
|
|
983
|
+
);
|
|
984
|
+
});
|
|
1446
985
|
}
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
986
|
+
return objectDefaults;
|
|
987
|
+
}
|
|
988
|
+
case "array": {
|
|
989
|
+
const neverPopulate = experimental_defaultFormStateBehavior?.arrayMinItems?.populate === "never";
|
|
990
|
+
const ignoreMinItemsFlagSet = experimental_defaultFormStateBehavior?.arrayMinItems?.populate === "requiredOnly";
|
|
991
|
+
if (Array.isArray(defaults)) {
|
|
992
|
+
defaults = defaults.map((item, idx) => {
|
|
993
|
+
const schemaItem = getInnerSchemaForArrayItem(schema, 2 /* Fallback */, idx);
|
|
994
|
+
return computeDefaults(validator, schemaItem, {
|
|
995
|
+
rootSchema,
|
|
996
|
+
_recurseList,
|
|
997
|
+
experimental_defaultFormStateBehavior,
|
|
998
|
+
parentDefaults: item,
|
|
999
|
+
required
|
|
1461
1000
|
});
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
1003
|
+
if (Array.isArray(rawFormData)) {
|
|
1004
|
+
const schemaItem = getInnerSchemaForArrayItem(schema);
|
|
1005
|
+
if (neverPopulate) {
|
|
1006
|
+
defaults = rawFormData;
|
|
1007
|
+
} else {
|
|
1466
1008
|
defaults = rawFormData.map((item, idx) => {
|
|
1467
1009
|
return computeDefaults(validator, schemaItem, {
|
|
1468
1010
|
rootSchema,
|
|
1469
1011
|
_recurseList,
|
|
1470
1012
|
experimental_defaultFormStateBehavior,
|
|
1471
1013
|
rawFormData: item,
|
|
1472
|
-
parentDefaults:
|
|
1014
|
+
parentDefaults: get6(defaults, [idx]),
|
|
1473
1015
|
required
|
|
1474
1016
|
});
|
|
1475
1017
|
});
|
|
1476
1018
|
}
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1019
|
+
}
|
|
1020
|
+
if (neverPopulate) {
|
|
1021
|
+
return defaults ?? [];
|
|
1022
|
+
}
|
|
1023
|
+
if (ignoreMinItemsFlagSet && !required) {
|
|
1024
|
+
return defaults ? defaults : void 0;
|
|
1025
|
+
}
|
|
1026
|
+
const defaultsLength = Array.isArray(defaults) ? defaults.length : 0;
|
|
1027
|
+
if (!schema.minItems || isMultiSelect(validator, schema, rootSchema) || schema.minItems <= defaultsLength) {
|
|
1028
|
+
return defaults ? defaults : [];
|
|
1029
|
+
}
|
|
1030
|
+
const defaultEntries = defaults || [];
|
|
1031
|
+
const fillerSchema = getInnerSchemaForArrayItem(schema, 1 /* Invert */);
|
|
1032
|
+
const fillerDefault = fillerSchema.default;
|
|
1033
|
+
const fillerEntries = new Array(schema.minItems - defaultsLength).fill(
|
|
1034
|
+
computeDefaults(validator, fillerSchema, {
|
|
1492
1035
|
parentDefaults: fillerDefault,
|
|
1493
1036
|
rootSchema,
|
|
1494
1037
|
_recurseList,
|
|
1495
1038
|
experimental_defaultFormStateBehavior,
|
|
1496
1039
|
required
|
|
1497
|
-
})
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1040
|
+
})
|
|
1041
|
+
);
|
|
1042
|
+
return defaultEntries.concat(fillerEntries);
|
|
1043
|
+
}
|
|
1501
1044
|
}
|
|
1502
1045
|
return defaults;
|
|
1503
1046
|
}
|
|
1504
|
-
/** Returns the superset of `formData` that includes the given set updated to include any missing fields that have
|
|
1505
|
-
* computed to have defaults provided in the `schema`.
|
|
1506
|
-
*
|
|
1507
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
1508
|
-
* @param theSchema - The schema for which the default state is desired
|
|
1509
|
-
* @param [formData] - The current formData, if any, onto which to provide any missing defaults
|
|
1510
|
-
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1511
|
-
* @param [includeUndefinedValues=false] - Optional flag, if true, cause undefined values to be added as defaults.
|
|
1512
|
-
* If "excludeObjectChildren", cause undefined values for this object and pass `includeUndefinedValues` as
|
|
1513
|
-
* false when computing defaults for any nested object properties.
|
|
1514
|
-
* @param [experimental_defaultFormStateBehavior] Optional configuration object, if provided, allows users to override default form state behavior
|
|
1515
|
-
* @returns - The resulting `formData` with all the defaults provided
|
|
1516
|
-
*/
|
|
1517
1047
|
function getDefaultFormState(validator, theSchema, formData, rootSchema, includeUndefinedValues = false, experimental_defaultFormStateBehavior) {
|
|
1518
1048
|
if (!isObject(theSchema)) {
|
|
1519
|
-
throw new Error(
|
|
1049
|
+
throw new Error("Invalid schema: " + theSchema);
|
|
1520
1050
|
}
|
|
1521
1051
|
const schema = retrieveSchema(validator, theSchema, rootSchema, formData);
|
|
1522
1052
|
const defaults = computeDefaults(validator, schema, {
|
|
@@ -1525,13 +1055,10 @@ function getDefaultFormState(validator, theSchema, formData, rootSchema, include
|
|
|
1525
1055
|
experimental_defaultFormStateBehavior,
|
|
1526
1056
|
rawFormData: formData
|
|
1527
1057
|
});
|
|
1528
|
-
if (formData ===
|
|
1529
|
-
// No form data? Use schema defaults.
|
|
1058
|
+
if (formData === void 0 || formData === null || typeof formData === "number" && isNaN(formData)) {
|
|
1530
1059
|
return defaults;
|
|
1531
1060
|
}
|
|
1532
|
-
const {
|
|
1533
|
-
mergeExtraDefaults
|
|
1534
|
-
} = (experimental_defaultFormStateBehavior === null || experimental_defaultFormStateBehavior === void 0 ? void 0 : experimental_defaultFormStateBehavior.arrayMinItems) || {};
|
|
1061
|
+
const { mergeExtraDefaults } = experimental_defaultFormStateBehavior?.arrayMinItems || {};
|
|
1535
1062
|
if (isObject(formData)) {
|
|
1536
1063
|
return mergeDefaultsWithFormData(defaults, formData, mergeExtraDefaults);
|
|
1537
1064
|
}
|
|
@@ -1541,62 +1068,40 @@ function getDefaultFormState(validator, theSchema, formData, rootSchema, include
|
|
|
1541
1068
|
return formData;
|
|
1542
1069
|
}
|
|
1543
1070
|
|
|
1544
|
-
|
|
1545
|
-
*
|
|
1546
|
-
* @param uiSchema - The UI Schema from which to detect if it is customized
|
|
1547
|
-
* @returns - True if the `uiSchema` describes a custom widget, false otherwise
|
|
1548
|
-
*/
|
|
1071
|
+
// src/isCustomWidget.ts
|
|
1549
1072
|
function isCustomWidget(uiSchema = {}) {
|
|
1550
1073
|
return (
|
|
1551
1074
|
// TODO: Remove the `&& uiSchema['ui:widget'] !== 'hidden'` once we support hidden widgets for arrays.
|
|
1552
1075
|
// https://rjsf-team.github.io/react-jsonschema-form/docs/usage/widgets/#hidden-widgets
|
|
1553
|
-
|
|
1076
|
+
"widget" in getUiOptions(uiSchema) && getUiOptions(uiSchema)["widget"] !== "hidden"
|
|
1554
1077
|
);
|
|
1555
1078
|
}
|
|
1556
1079
|
|
|
1557
|
-
|
|
1558
|
-
*
|
|
1559
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
1560
|
-
* @param schema - The schema for which check for array of files flag is desired
|
|
1561
|
-
* @param [uiSchema={}] - The UI schema from which to check the widget
|
|
1562
|
-
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1563
|
-
* @returns - True if schema/uiSchema contains an array of files, otherwise false
|
|
1564
|
-
*/
|
|
1080
|
+
// src/schema/isFilesArray.ts
|
|
1565
1081
|
function isFilesArray(validator, schema, uiSchema = {}, rootSchema) {
|
|
1566
|
-
if (uiSchema[UI_WIDGET_KEY] ===
|
|
1082
|
+
if (uiSchema[UI_WIDGET_KEY] === "files") {
|
|
1567
1083
|
return true;
|
|
1568
1084
|
}
|
|
1569
1085
|
if (schema.items) {
|
|
1570
1086
|
const itemsSchema = retrieveSchema(validator, schema.items, rootSchema);
|
|
1571
|
-
return itemsSchema.type ===
|
|
1087
|
+
return itemsSchema.type === "string" && itemsSchema.format === "data-url";
|
|
1572
1088
|
}
|
|
1573
1089
|
return false;
|
|
1574
1090
|
}
|
|
1575
1091
|
|
|
1576
|
-
|
|
1577
|
-
* should be displayed in a UI.
|
|
1578
|
-
*
|
|
1579
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
1580
|
-
* @param schema - The schema for which the display label flag is desired
|
|
1581
|
-
* @param [uiSchema={}] - The UI schema from which to derive potentially displayable information
|
|
1582
|
-
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1583
|
-
* @param [globalOptions={}] - The optional Global UI Schema from which to get any fallback `xxx` options
|
|
1584
|
-
* @returns - True if the label should be displayed or false if it should not
|
|
1585
|
-
*/
|
|
1092
|
+
// src/schema/getDisplayLabel.ts
|
|
1586
1093
|
function getDisplayLabel(validator, schema, uiSchema = {}, rootSchema, globalOptions) {
|
|
1587
1094
|
const uiOptions = getUiOptions(uiSchema, globalOptions);
|
|
1588
|
-
const {
|
|
1589
|
-
label = true
|
|
1590
|
-
} = uiOptions;
|
|
1095
|
+
const { label = true } = uiOptions;
|
|
1591
1096
|
let displayLabel = !!label;
|
|
1592
1097
|
const schemaType = getSchemaType(schema);
|
|
1593
|
-
if (schemaType ===
|
|
1098
|
+
if (schemaType === "array") {
|
|
1594
1099
|
displayLabel = isMultiSelect(validator, schema, rootSchema) || isFilesArray(validator, schema, uiSchema, rootSchema) || isCustomWidget(uiSchema);
|
|
1595
1100
|
}
|
|
1596
|
-
if (schemaType ===
|
|
1101
|
+
if (schemaType === "object") {
|
|
1597
1102
|
displayLabel = false;
|
|
1598
1103
|
}
|
|
1599
|
-
if (schemaType ===
|
|
1104
|
+
if (schemaType === "boolean" && !uiSchema[UI_WIDGET_KEY]) {
|
|
1600
1105
|
displayLabel = false;
|
|
1601
1106
|
}
|
|
1602
1107
|
if (uiSchema[UI_FIELD_KEY]) {
|
|
@@ -1605,152 +1110,81 @@ function getDisplayLabel(validator, schema, uiSchema = {}, rootSchema, globalOpt
|
|
|
1605
1110
|
return displayLabel;
|
|
1606
1111
|
}
|
|
1607
1112
|
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
* `validator.toErrorList()` onto the `errors` in the `validationData`. If no `additionalErrorSchema` is passed, then
|
|
1611
|
-
* `validationData` is returned.
|
|
1612
|
-
*
|
|
1613
|
-
* @param validator - The validator used to convert an ErrorSchema to a list of errors
|
|
1614
|
-
* @param validationData - The current `ValidationData` into which to merge the additional errors
|
|
1615
|
-
* @param [additionalErrorSchema] - The additional set of errors in an `ErrorSchema`
|
|
1616
|
-
* @returns - The `validationData` with the additional errors from `additionalErrorSchema` merged into it, if provided.
|
|
1617
|
-
* @deprecated - Use the `validationDataMerge()` function exported from `@rjsf/utils` instead. This function will be
|
|
1618
|
-
* removed in the next major release.
|
|
1619
|
-
*/
|
|
1113
|
+
// src/schema/mergeValidationData.ts
|
|
1114
|
+
import isEmpty2 from "lodash/isEmpty";
|
|
1620
1115
|
function mergeValidationData(validator, validationData, additionalErrorSchema) {
|
|
1621
1116
|
if (!additionalErrorSchema) {
|
|
1622
1117
|
return validationData;
|
|
1623
1118
|
}
|
|
1624
|
-
const {
|
|
1625
|
-
errors: oldErrors,
|
|
1626
|
-
errorSchema: oldErrorSchema
|
|
1627
|
-
} = validationData;
|
|
1119
|
+
const { errors: oldErrors, errorSchema: oldErrorSchema } = validationData;
|
|
1628
1120
|
let errors = validator.toErrorList(additionalErrorSchema);
|
|
1629
1121
|
let errorSchema = additionalErrorSchema;
|
|
1630
|
-
if (!
|
|
1122
|
+
if (!isEmpty2(oldErrorSchema)) {
|
|
1631
1123
|
errorSchema = mergeObjects(oldErrorSchema, additionalErrorSchema, true);
|
|
1632
1124
|
errors = [...oldErrors].concat(errors);
|
|
1633
1125
|
}
|
|
1634
|
-
return {
|
|
1635
|
-
errorSchema,
|
|
1636
|
-
errors
|
|
1637
|
-
};
|
|
1126
|
+
return { errorSchema, errors };
|
|
1638
1127
|
}
|
|
1639
1128
|
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
* that are non-existent in the new schema are set to `undefined`. The data sanitization process has the following flow:
|
|
1645
|
-
*
|
|
1646
|
-
* - If the new schema is an object that contains a `properties` object then:
|
|
1647
|
-
* - Create a `removeOldSchemaData` object, setting each key in the `oldSchema.properties` having `data` to undefined
|
|
1648
|
-
* - Create an empty `nestedData` object for use in the key filtering below:
|
|
1649
|
-
* - Iterate over each key in the `newSchema.properties` as follows:
|
|
1650
|
-
* - Get the `formValue` of the key from the `data`
|
|
1651
|
-
* - Get the `oldKeySchema` and `newKeyedSchema` for the key, defaulting to `{}` when it doesn't exist
|
|
1652
|
-
* - Retrieve the schema for any refs within each `oldKeySchema` and/or `newKeySchema`
|
|
1653
|
-
* - Get the types of the old and new keyed schemas and if the old doesn't exist or the old & new are the same then:
|
|
1654
|
-
* - If `removeOldSchemaData` has an entry for the key, delete it since the new schema has the same property
|
|
1655
|
-
* - If type of the key in the new schema is `object`:
|
|
1656
|
-
* - Store the value from the recursive `sanitizeDataForNewSchema` call in `nestedData[key]`
|
|
1657
|
-
* - Otherwise, check for default or const values:
|
|
1658
|
-
* - Get the old and new `default` values from the schema and check:
|
|
1659
|
-
* - If the new `default` value does not match the form value:
|
|
1660
|
-
* - If the old `default` value DOES match the form value, then:
|
|
1661
|
-
* - Replace `removeOldSchemaData[key]` with the new `default`
|
|
1662
|
-
* - Otherwise, if the new schema is `readOnly` then replace `removeOldSchemaData[key]` with undefined
|
|
1663
|
-
* - Get the old and new `const` values from the schema and check:
|
|
1664
|
-
* - If the new `const` value does not match the form value:
|
|
1665
|
-
* - If the old `const` value DOES match the form value, then:
|
|
1666
|
-
* - Replace `removeOldSchemaData[key]` with the new `const`
|
|
1667
|
-
* - Otherwise, replace `removeOldSchemaData[key]` with undefined
|
|
1668
|
-
* - Once all keys have been processed, return an object built as follows:
|
|
1669
|
-
* - `{ ...removeOldSchemaData, ...nestedData, ...pick(data, keysToKeep) }`
|
|
1670
|
-
* - If the new and old schema types are array and the `data` is an array then:
|
|
1671
|
-
* - If the type of the old and new schema `items` are a non-array objects:
|
|
1672
|
-
* - Retrieve the schema for any refs within each `oldKeySchema.items` and/or `newKeySchema.items`
|
|
1673
|
-
* - If the `type`s of both items are the same (or the old does not have a type):
|
|
1674
|
-
* - If the type is "object", then:
|
|
1675
|
-
* - For each element in the `data` recursively sanitize the data, stopping at `maxItems` if specified
|
|
1676
|
-
* - Otherwise, just return the `data` removing any values after `maxItems` if it is set
|
|
1677
|
-
* - If the type of the old and new schema `items` are booleans of the same value, return `data` as is
|
|
1678
|
-
* - Otherwise return `undefined`
|
|
1679
|
-
*
|
|
1680
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
1681
|
-
* @param rootSchema - The root JSON schema of the entire form
|
|
1682
|
-
* @param [newSchema] - The new schema for which the data is being sanitized
|
|
1683
|
-
* @param [oldSchema] - The old schema from which the data originated
|
|
1684
|
-
* @param [data={}] - The form data associated with the schema, defaulting to an empty object when undefined
|
|
1685
|
-
* @returns - The new form data, with all the fields uniquely associated with the old schema set
|
|
1686
|
-
* to `undefined`. Will return `undefined` if the new schema is not an object containing properties.
|
|
1687
|
-
*/
|
|
1129
|
+
// src/schema/sanitizeDataForNewSchema.ts
|
|
1130
|
+
import get7 from "lodash/get";
|
|
1131
|
+
import has3 from "lodash/has";
|
|
1132
|
+
var NO_VALUE = Symbol("no Value");
|
|
1688
1133
|
function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, data = {}) {
|
|
1689
|
-
// By default, we will clear the form data
|
|
1690
1134
|
let newFormData;
|
|
1691
|
-
|
|
1692
|
-
if (has(newSchema, PROPERTIES_KEY)) {
|
|
1693
|
-
// Create an object containing root-level keys in the old schema, setting each key to undefined to remove the data
|
|
1135
|
+
if (has3(newSchema, PROPERTIES_KEY)) {
|
|
1694
1136
|
const removeOldSchemaData = {};
|
|
1695
|
-
if (
|
|
1696
|
-
const properties =
|
|
1697
|
-
Object.keys(properties).forEach(key => {
|
|
1698
|
-
if (
|
|
1699
|
-
removeOldSchemaData[key] =
|
|
1137
|
+
if (has3(oldSchema, PROPERTIES_KEY)) {
|
|
1138
|
+
const properties = get7(oldSchema, PROPERTIES_KEY, {});
|
|
1139
|
+
Object.keys(properties).forEach((key) => {
|
|
1140
|
+
if (has3(data, key)) {
|
|
1141
|
+
removeOldSchemaData[key] = void 0;
|
|
1700
1142
|
}
|
|
1701
1143
|
});
|
|
1702
1144
|
}
|
|
1703
|
-
const keys = Object.keys(
|
|
1704
|
-
// Create a place to store nested data that will be a side-effect of the filter
|
|
1145
|
+
const keys = Object.keys(get7(newSchema, PROPERTIES_KEY, {}));
|
|
1705
1146
|
const nestedData = {};
|
|
1706
|
-
keys.forEach(key => {
|
|
1707
|
-
const formValue =
|
|
1708
|
-
let oldKeyedSchema =
|
|
1709
|
-
let newKeyedSchema =
|
|
1710
|
-
|
|
1711
|
-
if (has(oldKeyedSchema, REF_KEY)) {
|
|
1147
|
+
keys.forEach((key) => {
|
|
1148
|
+
const formValue = get7(data, key);
|
|
1149
|
+
let oldKeyedSchema = get7(oldSchema, [PROPERTIES_KEY, key], {});
|
|
1150
|
+
let newKeyedSchema = get7(newSchema, [PROPERTIES_KEY, key], {});
|
|
1151
|
+
if (has3(oldKeyedSchema, REF_KEY)) {
|
|
1712
1152
|
oldKeyedSchema = retrieveSchema(validator, oldKeyedSchema, rootSchema, formValue);
|
|
1713
1153
|
}
|
|
1714
|
-
if (
|
|
1154
|
+
if (has3(newKeyedSchema, REF_KEY)) {
|
|
1715
1155
|
newKeyedSchema = retrieveSchema(validator, newKeyedSchema, rootSchema, formValue);
|
|
1716
1156
|
}
|
|
1717
|
-
|
|
1718
|
-
const
|
|
1719
|
-
const newSchemaTypeForKey = get(newKeyedSchema, 'type');
|
|
1720
|
-
// Check if the old option has the same key with the same type
|
|
1157
|
+
const oldSchemaTypeForKey = get7(oldKeyedSchema, "type");
|
|
1158
|
+
const newSchemaTypeForKey = get7(newKeyedSchema, "type");
|
|
1721
1159
|
if (!oldSchemaTypeForKey || oldSchemaTypeForKey === newSchemaTypeForKey) {
|
|
1722
|
-
if (
|
|
1723
|
-
// SIDE-EFFECT: remove the undefined value for a key that has the same type between the old and new schemas
|
|
1160
|
+
if (has3(removeOldSchemaData, key)) {
|
|
1724
1161
|
delete removeOldSchemaData[key];
|
|
1725
1162
|
}
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1163
|
+
if (newSchemaTypeForKey === "object" || newSchemaTypeForKey === "array" && Array.isArray(formValue)) {
|
|
1164
|
+
const itemData = sanitizeDataForNewSchema(
|
|
1165
|
+
validator,
|
|
1166
|
+
rootSchema,
|
|
1167
|
+
newKeyedSchema,
|
|
1168
|
+
oldKeyedSchema,
|
|
1169
|
+
formValue
|
|
1170
|
+
);
|
|
1171
|
+
if (itemData !== void 0 || newSchemaTypeForKey === "array") {
|
|
1732
1172
|
nestedData[key] = itemData;
|
|
1733
1173
|
}
|
|
1734
1174
|
} else {
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
// value to be properly selected
|
|
1738
|
-
const newOptionDefault = get(newKeyedSchema, 'default', NO_VALUE);
|
|
1739
|
-
const oldOptionDefault = get(oldKeyedSchema, 'default', NO_VALUE);
|
|
1175
|
+
const newOptionDefault = get7(newKeyedSchema, "default", NO_VALUE);
|
|
1176
|
+
const oldOptionDefault = get7(oldKeyedSchema, "default", NO_VALUE);
|
|
1740
1177
|
if (newOptionDefault !== NO_VALUE && newOptionDefault !== formValue) {
|
|
1741
1178
|
if (oldOptionDefault === formValue) {
|
|
1742
|
-
// If the old default matches the formValue, we'll update the new value to match the new default
|
|
1743
1179
|
removeOldSchemaData[key] = newOptionDefault;
|
|
1744
|
-
} else if (
|
|
1745
|
-
|
|
1746
|
-
removeOldSchemaData[key] = undefined;
|
|
1180
|
+
} else if (get7(newKeyedSchema, "readOnly") === true) {
|
|
1181
|
+
removeOldSchemaData[key] = void 0;
|
|
1747
1182
|
}
|
|
1748
1183
|
}
|
|
1749
|
-
const newOptionConst =
|
|
1750
|
-
const oldOptionConst =
|
|
1184
|
+
const newOptionConst = get7(newKeyedSchema, "const", NO_VALUE);
|
|
1185
|
+
const oldOptionConst = get7(oldKeyedSchema, "const", NO_VALUE);
|
|
1751
1186
|
if (newOptionConst !== NO_VALUE && newOptionConst !== formValue) {
|
|
1752
|
-
|
|
1753
|
-
removeOldSchemaData[key] = oldOptionConst === formValue ? newOptionConst : undefined;
|
|
1187
|
+
removeOldSchemaData[key] = oldOptionConst === formValue ? newOptionConst : void 0;
|
|
1754
1188
|
}
|
|
1755
1189
|
}
|
|
1756
1190
|
}
|
|
@@ -1760,29 +1194,30 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
|
|
|
1760
1194
|
...removeOldSchemaData,
|
|
1761
1195
|
...nestedData
|
|
1762
1196
|
};
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
let
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
// Eventually, we may want to deal with when either of the `items` are arrays since those tuple validations
|
|
1769
|
-
if (typeof oldSchemaItems === 'object' && typeof newSchemaItems === 'object' && !Array.isArray(oldSchemaItems) && !Array.isArray(newSchemaItems)) {
|
|
1770
|
-
if (has(oldSchemaItems, REF_KEY)) {
|
|
1197
|
+
} else if (get7(oldSchema, "type") === "array" && get7(newSchema, "type") === "array" && Array.isArray(data)) {
|
|
1198
|
+
let oldSchemaItems = get7(oldSchema, "items");
|
|
1199
|
+
let newSchemaItems = get7(newSchema, "items");
|
|
1200
|
+
if (typeof oldSchemaItems === "object" && typeof newSchemaItems === "object" && !Array.isArray(oldSchemaItems) && !Array.isArray(newSchemaItems)) {
|
|
1201
|
+
if (has3(oldSchemaItems, REF_KEY)) {
|
|
1771
1202
|
oldSchemaItems = retrieveSchema(validator, oldSchemaItems, rootSchema, data);
|
|
1772
1203
|
}
|
|
1773
|
-
if (
|
|
1204
|
+
if (has3(newSchemaItems, REF_KEY)) {
|
|
1774
1205
|
newSchemaItems = retrieveSchema(validator, newSchemaItems, rootSchema, data);
|
|
1775
1206
|
}
|
|
1776
|
-
|
|
1777
|
-
const
|
|
1778
|
-
const newSchemaType = get(newSchemaItems, 'type');
|
|
1779
|
-
// Check if the old option has the same key with the same type
|
|
1207
|
+
const oldSchemaType = get7(oldSchemaItems, "type");
|
|
1208
|
+
const newSchemaType = get7(newSchemaItems, "type");
|
|
1780
1209
|
if (!oldSchemaType || oldSchemaType === newSchemaType) {
|
|
1781
|
-
const maxItems =
|
|
1782
|
-
if (newSchemaType ===
|
|
1210
|
+
const maxItems = get7(newSchema, "maxItems", -1);
|
|
1211
|
+
if (newSchemaType === "object") {
|
|
1783
1212
|
newFormData = data.reduce((newValue, aValue) => {
|
|
1784
|
-
const itemValue = sanitizeDataForNewSchema(
|
|
1785
|
-
|
|
1213
|
+
const itemValue = sanitizeDataForNewSchema(
|
|
1214
|
+
validator,
|
|
1215
|
+
rootSchema,
|
|
1216
|
+
newSchemaItems,
|
|
1217
|
+
oldSchemaItems,
|
|
1218
|
+
aValue
|
|
1219
|
+
);
|
|
1220
|
+
if (itemValue !== void 0 && (maxItems < 0 || newValue.length < maxItems)) {
|
|
1786
1221
|
newValue.push(itemValue);
|
|
1787
1222
|
}
|
|
1788
1223
|
return newValue;
|
|
@@ -1791,92 +1226,92 @@ function sanitizeDataForNewSchema(validator, rootSchema, newSchema, oldSchema, d
|
|
|
1791
1226
|
newFormData = maxItems > 0 && data.length > maxItems ? data.slice(0, maxItems) : data;
|
|
1792
1227
|
}
|
|
1793
1228
|
}
|
|
1794
|
-
} else if (typeof oldSchemaItems ===
|
|
1795
|
-
// If they are both booleans and have the same value just return the data as is otherwise fall-thru to undefined
|
|
1229
|
+
} else if (typeof oldSchemaItems === "boolean" && typeof newSchemaItems === "boolean" && oldSchemaItems === newSchemaItems) {
|
|
1796
1230
|
newFormData = data;
|
|
1797
1231
|
}
|
|
1798
|
-
// Also probably want to deal with `prefixItems` as tuples with the latest 2020 draft
|
|
1799
1232
|
}
|
|
1800
|
-
|
|
1801
1233
|
return newFormData;
|
|
1802
1234
|
}
|
|
1803
1235
|
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
1808
|
-
* @param schema - The schema for which the `IdSchema` is desired
|
|
1809
|
-
* @param idPrefix - The prefix to use for the id
|
|
1810
|
-
* @param idSeparator - The separator to use for the path segments in the id
|
|
1811
|
-
* @param [id] - The base id for the schema
|
|
1812
|
-
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1813
|
-
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
1814
|
-
* @param [_recurseList=[]] - The list of retrieved schemas currently being recursed, used to prevent infinite recursion
|
|
1815
|
-
* @returns - The `IdSchema` object for the `schema`
|
|
1816
|
-
*/
|
|
1236
|
+
// src/schema/toIdSchema.ts
|
|
1237
|
+
import get8 from "lodash/get";
|
|
1238
|
+
import isEqual from "lodash/isEqual";
|
|
1817
1239
|
function toIdSchemaInternal(validator, schema, idPrefix, idSeparator, id, rootSchema, formData, _recurseList = []) {
|
|
1818
1240
|
if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
|
|
1819
1241
|
const _schema = retrieveSchema(validator, schema, rootSchema, formData);
|
|
1820
|
-
const sameSchemaIndex = _recurseList.findIndex(item => isEqual(item, _schema));
|
|
1242
|
+
const sameSchemaIndex = _recurseList.findIndex((item) => isEqual(item, _schema));
|
|
1821
1243
|
if (sameSchemaIndex === -1) {
|
|
1822
|
-
return toIdSchemaInternal(
|
|
1244
|
+
return toIdSchemaInternal(
|
|
1245
|
+
validator,
|
|
1246
|
+
_schema,
|
|
1247
|
+
idPrefix,
|
|
1248
|
+
idSeparator,
|
|
1249
|
+
id,
|
|
1250
|
+
rootSchema,
|
|
1251
|
+
formData,
|
|
1252
|
+
_recurseList.concat(_schema)
|
|
1253
|
+
);
|
|
1823
1254
|
}
|
|
1824
1255
|
}
|
|
1825
|
-
if (ITEMS_KEY in schema && !
|
|
1826
|
-
return toIdSchemaInternal(
|
|
1256
|
+
if (ITEMS_KEY in schema && !get8(schema, [ITEMS_KEY, REF_KEY])) {
|
|
1257
|
+
return toIdSchemaInternal(
|
|
1258
|
+
validator,
|
|
1259
|
+
get8(schema, ITEMS_KEY),
|
|
1260
|
+
idPrefix,
|
|
1261
|
+
idSeparator,
|
|
1262
|
+
id,
|
|
1263
|
+
rootSchema,
|
|
1264
|
+
formData,
|
|
1265
|
+
_recurseList
|
|
1266
|
+
);
|
|
1827
1267
|
}
|
|
1828
1268
|
const $id = id || idPrefix;
|
|
1829
|
-
const idSchema = {
|
|
1830
|
-
|
|
1831
|
-
};
|
|
1832
|
-
if (getSchemaType(schema) === 'object' && PROPERTIES_KEY in schema) {
|
|
1269
|
+
const idSchema = { $id };
|
|
1270
|
+
if (getSchemaType(schema) === "object" && PROPERTIES_KEY in schema) {
|
|
1833
1271
|
for (const name in schema.properties) {
|
|
1834
|
-
const field =
|
|
1272
|
+
const field = get8(schema, [PROPERTIES_KEY, name]);
|
|
1835
1273
|
const fieldId = idSchema[ID_KEY] + idSeparator + name;
|
|
1836
|
-
idSchema[name] = toIdSchemaInternal(
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1274
|
+
idSchema[name] = toIdSchemaInternal(
|
|
1275
|
+
validator,
|
|
1276
|
+
isObject(field) ? field : {},
|
|
1277
|
+
idPrefix,
|
|
1278
|
+
idSeparator,
|
|
1279
|
+
fieldId,
|
|
1280
|
+
rootSchema,
|
|
1281
|
+
// It's possible that formData is not an object -- this can happen if an
|
|
1282
|
+
// array item has just been added, but not populated with data yet
|
|
1283
|
+
get8(formData, [name]),
|
|
1284
|
+
_recurseList
|
|
1285
|
+
);
|
|
1840
1286
|
}
|
|
1841
1287
|
}
|
|
1842
1288
|
return idSchema;
|
|
1843
1289
|
}
|
|
1844
|
-
|
|
1845
|
-
*
|
|
1846
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
1847
|
-
* @param schema - The schema for which the `IdSchema` is desired
|
|
1848
|
-
* @param [id] - The base id for the schema
|
|
1849
|
-
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1850
|
-
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
1851
|
-
* @param [idPrefix='root'] - The prefix to use for the id
|
|
1852
|
-
* @param [idSeparator='_'] - The separator to use for the path segments in the id
|
|
1853
|
-
* @returns - The `IdSchema` object for the `schema`
|
|
1854
|
-
*/
|
|
1855
|
-
function toIdSchema(validator, schema, id, rootSchema, formData, idPrefix = 'root', idSeparator = '_') {
|
|
1290
|
+
function toIdSchema(validator, schema, id, rootSchema, formData, idPrefix = "root", idSeparator = "_") {
|
|
1856
1291
|
return toIdSchemaInternal(validator, schema, idPrefix, idSeparator, id, rootSchema, formData);
|
|
1857
1292
|
}
|
|
1858
1293
|
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
* @param schema - The schema for which the `PathSchema` is desired
|
|
1864
|
-
* @param [name=''] - The base name for the schema
|
|
1865
|
-
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1866
|
-
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
1867
|
-
* @param [_recurseList=[]] - The list of retrieved schemas currently being recursed, used to prevent infinite recursion
|
|
1868
|
-
* @returns - The `PathSchema` object for the `schema`
|
|
1869
|
-
*/
|
|
1294
|
+
// src/schema/toPathSchema.ts
|
|
1295
|
+
import get9 from "lodash/get";
|
|
1296
|
+
import isEqual2 from "lodash/isEqual";
|
|
1297
|
+
import set2 from "lodash/set";
|
|
1870
1298
|
function toPathSchemaInternal(validator, schema, name, rootSchema, formData, _recurseList = []) {
|
|
1871
1299
|
if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
|
|
1872
1300
|
const _schema = retrieveSchema(validator, schema, rootSchema, formData);
|
|
1873
|
-
const sameSchemaIndex = _recurseList.findIndex(item =>
|
|
1301
|
+
const sameSchemaIndex = _recurseList.findIndex((item) => isEqual2(item, _schema));
|
|
1874
1302
|
if (sameSchemaIndex === -1) {
|
|
1875
|
-
return toPathSchemaInternal(
|
|
1303
|
+
return toPathSchemaInternal(
|
|
1304
|
+
validator,
|
|
1305
|
+
_schema,
|
|
1306
|
+
name,
|
|
1307
|
+
rootSchema,
|
|
1308
|
+
formData,
|
|
1309
|
+
_recurseList.concat(_schema)
|
|
1310
|
+
);
|
|
1876
1311
|
}
|
|
1877
1312
|
}
|
|
1878
1313
|
let pathSchema = {
|
|
1879
|
-
[NAME_KEY]: name.replace(/^\./,
|
|
1314
|
+
[NAME_KEY]: name.replace(/^\./, "")
|
|
1880
1315
|
};
|
|
1881
1316
|
if (ONE_OF_KEY in schema || ANY_OF_KEY in schema) {
|
|
1882
1317
|
const xxxOf = ONE_OF_KEY in schema ? schema.oneOf : schema.anyOf;
|
|
@@ -1889,71 +1324,68 @@ function toPathSchemaInternal(validator, schema, name, rootSchema, formData, _re
|
|
|
1889
1324
|
};
|
|
1890
1325
|
}
|
|
1891
1326
|
if (ADDITIONAL_PROPERTIES_KEY in schema && schema[ADDITIONAL_PROPERTIES_KEY] !== false) {
|
|
1892
|
-
|
|
1327
|
+
set2(pathSchema, RJSF_ADDITONAL_PROPERTIES_FLAG, true);
|
|
1893
1328
|
}
|
|
1894
1329
|
if (ITEMS_KEY in schema && Array.isArray(formData)) {
|
|
1895
1330
|
formData.forEach((element, i) => {
|
|
1896
|
-
pathSchema[i] = toPathSchemaInternal(
|
|
1331
|
+
pathSchema[i] = toPathSchemaInternal(
|
|
1332
|
+
validator,
|
|
1333
|
+
schema.items,
|
|
1334
|
+
`${name}.${i}`,
|
|
1335
|
+
rootSchema,
|
|
1336
|
+
element,
|
|
1337
|
+
_recurseList
|
|
1338
|
+
);
|
|
1897
1339
|
});
|
|
1898
1340
|
} else if (PROPERTIES_KEY in schema) {
|
|
1899
1341
|
for (const property in schema.properties) {
|
|
1900
|
-
const field =
|
|
1901
|
-
pathSchema[property] = toPathSchemaInternal(
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1342
|
+
const field = get9(schema, [PROPERTIES_KEY, property]);
|
|
1343
|
+
pathSchema[property] = toPathSchemaInternal(
|
|
1344
|
+
validator,
|
|
1345
|
+
field,
|
|
1346
|
+
`${name}.${property}`,
|
|
1347
|
+
rootSchema,
|
|
1348
|
+
// It's possible that formData is not an object -- this can happen if an
|
|
1349
|
+
// array item has just been added, but not populated with data yet
|
|
1350
|
+
get9(formData, [property]),
|
|
1351
|
+
_recurseList
|
|
1352
|
+
);
|
|
1905
1353
|
}
|
|
1906
1354
|
}
|
|
1907
1355
|
return pathSchema;
|
|
1908
1356
|
}
|
|
1909
|
-
|
|
1910
|
-
*
|
|
1911
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
1912
|
-
* @param schema - The schema for which the `PathSchema` is desired
|
|
1913
|
-
* @param [name=''] - The base name for the schema
|
|
1914
|
-
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
|
|
1915
|
-
* @param [formData] - The current formData, if any, to assist retrieving a schema
|
|
1916
|
-
* @returns - The `PathSchema` object for the `schema`
|
|
1917
|
-
*/
|
|
1918
|
-
function toPathSchema(validator, schema, name = '', rootSchema, formData) {
|
|
1357
|
+
function toPathSchema(validator, schema, name = "", rootSchema, formData) {
|
|
1919
1358
|
return toPathSchemaInternal(validator, schema, name, rootSchema, formData);
|
|
1920
1359
|
}
|
|
1921
1360
|
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
*
|
|
1930
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
1931
|
-
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
1932
|
-
* @param experimental_defaultFormStateBehavior - Configuration flags to allow users to override default form state behavior
|
|
1361
|
+
// src/createSchemaUtils.ts
|
|
1362
|
+
var SchemaUtils = class {
|
|
1363
|
+
/** Constructs the `SchemaUtils` instance with the given `validator` and `rootSchema` stored as instance variables
|
|
1364
|
+
*
|
|
1365
|
+
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
1366
|
+
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
1367
|
+
* @param experimental_defaultFormStateBehavior - Configuration flags to allow users to override default form state behavior
|
|
1933
1368
|
*/
|
|
1934
1369
|
constructor(validator, rootSchema, experimental_defaultFormStateBehavior) {
|
|
1935
|
-
this.rootSchema = void 0;
|
|
1936
|
-
this.validator = void 0;
|
|
1937
|
-
this.experimental_defaultFormStateBehavior = void 0;
|
|
1938
1370
|
this.rootSchema = rootSchema;
|
|
1939
1371
|
this.validator = validator;
|
|
1940
1372
|
this.experimental_defaultFormStateBehavior = experimental_defaultFormStateBehavior;
|
|
1941
1373
|
}
|
|
1942
|
-
/** Returns the `ValidatorType` in the `SchemaUtilsType`
|
|
1943
|
-
*
|
|
1944
|
-
* @returns - The `ValidatorType`
|
|
1374
|
+
/** Returns the `ValidatorType` in the `SchemaUtilsType`
|
|
1375
|
+
*
|
|
1376
|
+
* @returns - The `ValidatorType`
|
|
1945
1377
|
*/
|
|
1946
1378
|
getValidator() {
|
|
1947
1379
|
return this.validator;
|
|
1948
1380
|
}
|
|
1949
|
-
/** Determines whether either the `validator` and `rootSchema` differ from the ones associated with this instance of
|
|
1950
|
-
* the `SchemaUtilsType`. If either `validator` or `rootSchema` are falsy, then return false to prevent the creation
|
|
1951
|
-
* of a new `SchemaUtilsType` with incomplete properties.
|
|
1952
|
-
*
|
|
1953
|
-
* @param validator - An implementation of the `ValidatorType` interface that will be compared against the current one
|
|
1954
|
-
* @param rootSchema - The root schema that will be compared against the current one
|
|
1955
|
-
* @param [experimental_defaultFormStateBehavior] Optional configuration object, if provided, allows users to override default form state behavior
|
|
1956
|
-
* @returns - True if the `SchemaUtilsType` differs from the given `validator` or `rootSchema`
|
|
1381
|
+
/** Determines whether either the `validator` and `rootSchema` differ from the ones associated with this instance of
|
|
1382
|
+
* the `SchemaUtilsType`. If either `validator` or `rootSchema` are falsy, then return false to prevent the creation
|
|
1383
|
+
* of a new `SchemaUtilsType` with incomplete properties.
|
|
1384
|
+
*
|
|
1385
|
+
* @param validator - An implementation of the `ValidatorType` interface that will be compared against the current one
|
|
1386
|
+
* @param rootSchema - The root schema that will be compared against the current one
|
|
1387
|
+
* @param [experimental_defaultFormStateBehavior] Optional configuration object, if provided, allows users to override default form state behavior
|
|
1388
|
+
* @returns - True if the `SchemaUtilsType` differs from the given `validator` or `rootSchema`
|
|
1957
1389
|
*/
|
|
1958
1390
|
doesSchemaUtilsDiffer(validator, rootSchema, experimental_defaultFormStateBehavior = {}) {
|
|
1959
1391
|
if (!validator || !rootSchema) {
|
|
@@ -1961,411 +1393,334 @@ class SchemaUtils {
|
|
|
1961
1393
|
}
|
|
1962
1394
|
return this.validator !== validator || !deepEquals(this.rootSchema, rootSchema) || !deepEquals(this.experimental_defaultFormStateBehavior, experimental_defaultFormStateBehavior);
|
|
1963
1395
|
}
|
|
1964
|
-
/** Returns the superset of `formData` that includes the given set updated to include any missing fields that have
|
|
1965
|
-
* computed to have defaults provided in the `schema`.
|
|
1966
|
-
*
|
|
1967
|
-
* @param schema - The schema for which the default state is desired
|
|
1968
|
-
* @param [formData] - The current formData, if any, onto which to provide any missing defaults
|
|
1969
|
-
* @param [includeUndefinedValues=false] - Optional flag, if true, cause undefined values to be added as defaults.
|
|
1970
|
-
* If "excludeObjectChildren", pass `includeUndefinedValues` as false when computing defaults for any nested
|
|
1971
|
-
* object properties.
|
|
1972
|
-
* @returns - The resulting `formData` with all the defaults provided
|
|
1396
|
+
/** Returns the superset of `formData` that includes the given set updated to include any missing fields that have
|
|
1397
|
+
* computed to have defaults provided in the `schema`.
|
|
1398
|
+
*
|
|
1399
|
+
* @param schema - The schema for which the default state is desired
|
|
1400
|
+
* @param [formData] - The current formData, if any, onto which to provide any missing defaults
|
|
1401
|
+
* @param [includeUndefinedValues=false] - Optional flag, if true, cause undefined values to be added as defaults.
|
|
1402
|
+
* If "excludeObjectChildren", pass `includeUndefinedValues` as false when computing defaults for any nested
|
|
1403
|
+
* object properties.
|
|
1404
|
+
* @returns - The resulting `formData` with all the defaults provided
|
|
1973
1405
|
*/
|
|
1974
1406
|
getDefaultFormState(schema, formData, includeUndefinedValues = false) {
|
|
1975
|
-
return getDefaultFormState(
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1407
|
+
return getDefaultFormState(
|
|
1408
|
+
this.validator,
|
|
1409
|
+
schema,
|
|
1410
|
+
formData,
|
|
1411
|
+
this.rootSchema,
|
|
1412
|
+
includeUndefinedValues,
|
|
1413
|
+
this.experimental_defaultFormStateBehavior
|
|
1414
|
+
);
|
|
1415
|
+
}
|
|
1416
|
+
/** Determines whether the combination of `schema` and `uiSchema` properties indicates that the label for the `schema`
|
|
1417
|
+
* should be displayed in a UI.
|
|
1418
|
+
*
|
|
1419
|
+
* @param schema - The schema for which the display label flag is desired
|
|
1420
|
+
* @param [uiSchema] - The UI schema from which to derive potentially displayable information
|
|
1421
|
+
* @param [globalOptions={}] - The optional Global UI Schema from which to get any fallback `xxx` options
|
|
1422
|
+
* @returns - True if the label should be displayed or false if it should not
|
|
1984
1423
|
*/
|
|
1985
1424
|
getDisplayLabel(schema, uiSchema, globalOptions) {
|
|
1986
1425
|
return getDisplayLabel(this.validator, schema, uiSchema, this.rootSchema, globalOptions);
|
|
1987
1426
|
}
|
|
1988
|
-
/** Determines which of the given `options` provided most closely matches the `formData`.
|
|
1989
|
-
* Returns the index of the option that is valid and is the closest match, or 0 if there is no match.
|
|
1990
|
-
*
|
|
1991
|
-
* The closest match is determined using the number of matching properties, and more heavily favors options with
|
|
1992
|
-
* matching readOnly, default, or const values.
|
|
1993
|
-
*
|
|
1994
|
-
* @param formData - The form data associated with the schema
|
|
1995
|
-
* @param options - The list of options that can be selected from
|
|
1996
|
-
* @param [selectedOption] - The index of the currently selected option, defaulted to -1 if not specified
|
|
1997
|
-
* @param [discriminatorField] - The optional name of the field within the options object whose value is used to
|
|
1998
|
-
* determine which option is selected
|
|
1999
|
-
* @returns - The index of the option that is the closest match to the `formData` or the `selectedOption` if no match
|
|
1427
|
+
/** Determines which of the given `options` provided most closely matches the `formData`.
|
|
1428
|
+
* Returns the index of the option that is valid and is the closest match, or 0 if there is no match.
|
|
1429
|
+
*
|
|
1430
|
+
* The closest match is determined using the number of matching properties, and more heavily favors options with
|
|
1431
|
+
* matching readOnly, default, or const values.
|
|
1432
|
+
*
|
|
1433
|
+
* @param formData - The form data associated with the schema
|
|
1434
|
+
* @param options - The list of options that can be selected from
|
|
1435
|
+
* @param [selectedOption] - The index of the currently selected option, defaulted to -1 if not specified
|
|
1436
|
+
* @param [discriminatorField] - The optional name of the field within the options object whose value is used to
|
|
1437
|
+
* determine which option is selected
|
|
1438
|
+
* @returns - The index of the option that is the closest match to the `formData` or the `selectedOption` if no match
|
|
2000
1439
|
*/
|
|
2001
1440
|
getClosestMatchingOption(formData, options, selectedOption, discriminatorField) {
|
|
2002
|
-
return getClosestMatchingOption(
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
1441
|
+
return getClosestMatchingOption(
|
|
1442
|
+
this.validator,
|
|
1443
|
+
this.rootSchema,
|
|
1444
|
+
formData,
|
|
1445
|
+
options,
|
|
1446
|
+
selectedOption,
|
|
1447
|
+
discriminatorField
|
|
1448
|
+
);
|
|
1449
|
+
}
|
|
1450
|
+
/** Given the `formData` and list of `options`, attempts to find the index of the first option that matches the data.
|
|
1451
|
+
* Always returns the first option if there is nothing that matches.
|
|
1452
|
+
*
|
|
1453
|
+
* @param formData - The current formData, if any, used to figure out a match
|
|
1454
|
+
* @param options - The list of options to find a matching options from
|
|
1455
|
+
* @param [discriminatorField] - The optional name of the field within the options object whose value is used to
|
|
1456
|
+
* determine which option is selected
|
|
1457
|
+
* @returns - The firstindex of the matched option or 0 if none is available
|
|
2012
1458
|
*/
|
|
2013
1459
|
getFirstMatchingOption(formData, options, discriminatorField) {
|
|
2014
1460
|
return getFirstMatchingOption(this.validator, formData, options, this.rootSchema, discriminatorField);
|
|
2015
1461
|
}
|
|
2016
|
-
/** Given the `formData` and list of `options`, attempts to find the index of the option that best matches the data.
|
|
2017
|
-
* Deprecated, use `getFirstMatchingOption()` instead.
|
|
2018
|
-
*
|
|
2019
|
-
* @param formData - The current formData, if any, onto which to provide any missing defaults
|
|
2020
|
-
* @param options - The list of options to find a matching options from
|
|
2021
|
-
* @param [discriminatorField] - The optional name of the field within the options object whose value is used to
|
|
2022
|
-
* determine which option is selected
|
|
2023
|
-
* @returns - The index of the matched option or 0 if none is available
|
|
2024
|
-
* @deprecated
|
|
1462
|
+
/** Given the `formData` and list of `options`, attempts to find the index of the option that best matches the data.
|
|
1463
|
+
* Deprecated, use `getFirstMatchingOption()` instead.
|
|
1464
|
+
*
|
|
1465
|
+
* @param formData - The current formData, if any, onto which to provide any missing defaults
|
|
1466
|
+
* @param options - The list of options to find a matching options from
|
|
1467
|
+
* @param [discriminatorField] - The optional name of the field within the options object whose value is used to
|
|
1468
|
+
* determine which option is selected
|
|
1469
|
+
* @returns - The index of the matched option or 0 if none is available
|
|
1470
|
+
* @deprecated
|
|
2025
1471
|
*/
|
|
2026
1472
|
getMatchingOption(formData, options, discriminatorField) {
|
|
2027
1473
|
return getMatchingOption(this.validator, formData, options, this.rootSchema, discriminatorField);
|
|
2028
1474
|
}
|
|
2029
|
-
/** Checks to see if the `schema` and `uiSchema` combination represents an array of files
|
|
2030
|
-
*
|
|
2031
|
-
* @param schema - The schema for which check for array of files flag is desired
|
|
2032
|
-
* @param [uiSchema] - The UI schema from which to check the widget
|
|
2033
|
-
* @returns - True if schema/uiSchema contains an array of files, otherwise false
|
|
1475
|
+
/** Checks to see if the `schema` and `uiSchema` combination represents an array of files
|
|
1476
|
+
*
|
|
1477
|
+
* @param schema - The schema for which check for array of files flag is desired
|
|
1478
|
+
* @param [uiSchema] - The UI schema from which to check the widget
|
|
1479
|
+
* @returns - True if schema/uiSchema contains an array of files, otherwise false
|
|
2034
1480
|
*/
|
|
2035
1481
|
isFilesArray(schema, uiSchema) {
|
|
2036
1482
|
return isFilesArray(this.validator, schema, uiSchema, this.rootSchema);
|
|
2037
1483
|
}
|
|
2038
|
-
/** Checks to see if the `schema` combination represents a multi-select
|
|
2039
|
-
*
|
|
2040
|
-
* @param schema - The schema for which check for a multi-select flag is desired
|
|
2041
|
-
* @returns - True if schema contains a multi-select, otherwise false
|
|
1484
|
+
/** Checks to see if the `schema` combination represents a multi-select
|
|
1485
|
+
*
|
|
1486
|
+
* @param schema - The schema for which check for a multi-select flag is desired
|
|
1487
|
+
* @returns - True if schema contains a multi-select, otherwise false
|
|
2042
1488
|
*/
|
|
2043
1489
|
isMultiSelect(schema) {
|
|
2044
1490
|
return isMultiSelect(this.validator, schema, this.rootSchema);
|
|
2045
1491
|
}
|
|
2046
|
-
/** Checks to see if the `schema` combination represents a select
|
|
2047
|
-
*
|
|
2048
|
-
* @param schema - The schema for which check for a select flag is desired
|
|
2049
|
-
* @returns - True if schema contains a select, otherwise false
|
|
1492
|
+
/** Checks to see if the `schema` combination represents a select
|
|
1493
|
+
*
|
|
1494
|
+
* @param schema - The schema for which check for a select flag is desired
|
|
1495
|
+
* @returns - True if schema contains a select, otherwise false
|
|
2050
1496
|
*/
|
|
2051
1497
|
isSelect(schema) {
|
|
2052
1498
|
return isSelect(this.validator, schema, this.rootSchema);
|
|
2053
1499
|
}
|
|
2054
|
-
/** Merges the errors in `additionalErrorSchema` into the existing `validationData` by combining the hierarchies in
|
|
2055
|
-
* the two `ErrorSchema`s and then appending the error list from the `additionalErrorSchema` obtained by calling
|
|
2056
|
-
* `getValidator().toErrorList()` onto the `errors` in the `validationData`. If no `additionalErrorSchema` is passed,
|
|
2057
|
-
* then `validationData` is returned.
|
|
2058
|
-
*
|
|
2059
|
-
* @param validationData - The current `ValidationData` into which to merge the additional errors
|
|
2060
|
-
* @param [additionalErrorSchema] - The additional set of errors
|
|
2061
|
-
* @returns - The `validationData` with the additional errors from `additionalErrorSchema` merged into it, if provided.
|
|
2062
|
-
* @deprecated - Use the `validationDataMerge()` function exported from `@rjsf/utils` instead. This function will be
|
|
2063
|
-
* removed in the next major release.
|
|
1500
|
+
/** Merges the errors in `additionalErrorSchema` into the existing `validationData` by combining the hierarchies in
|
|
1501
|
+
* the two `ErrorSchema`s and then appending the error list from the `additionalErrorSchema` obtained by calling
|
|
1502
|
+
* `getValidator().toErrorList()` onto the `errors` in the `validationData`. If no `additionalErrorSchema` is passed,
|
|
1503
|
+
* then `validationData` is returned.
|
|
1504
|
+
*
|
|
1505
|
+
* @param validationData - The current `ValidationData` into which to merge the additional errors
|
|
1506
|
+
* @param [additionalErrorSchema] - The additional set of errors
|
|
1507
|
+
* @returns - The `validationData` with the additional errors from `additionalErrorSchema` merged into it, if provided.
|
|
1508
|
+
* @deprecated - Use the `validationDataMerge()` function exported from `@rjsf/utils` instead. This function will be
|
|
1509
|
+
* removed in the next major release.
|
|
2064
1510
|
*/
|
|
2065
1511
|
mergeValidationData(validationData, additionalErrorSchema) {
|
|
2066
1512
|
return mergeValidationData(this.validator, validationData, additionalErrorSchema);
|
|
2067
1513
|
}
|
|
2068
|
-
/** Retrieves an expanded schema that has had all of its conditions, additional properties, references and
|
|
2069
|
-
* dependencies resolved and merged into the `schema` given a `rawFormData` that is used to do the potentially
|
|
2070
|
-
* recursive resolution.
|
|
2071
|
-
*
|
|
2072
|
-
* @param schema - The schema for which retrieving a schema is desired
|
|
2073
|
-
* @param [rawFormData] - The current formData, if any, to assist retrieving a schema
|
|
2074
|
-
* @returns - The schema having its conditions, additional properties, references and dependencies resolved
|
|
1514
|
+
/** Retrieves an expanded schema that has had all of its conditions, additional properties, references and
|
|
1515
|
+
* dependencies resolved and merged into the `schema` given a `rawFormData` that is used to do the potentially
|
|
1516
|
+
* recursive resolution.
|
|
1517
|
+
*
|
|
1518
|
+
* @param schema - The schema for which retrieving a schema is desired
|
|
1519
|
+
* @param [rawFormData] - The current formData, if any, to assist retrieving a schema
|
|
1520
|
+
* @returns - The schema having its conditions, additional properties, references and dependencies resolved
|
|
2075
1521
|
*/
|
|
2076
1522
|
retrieveSchema(schema, rawFormData) {
|
|
2077
1523
|
return retrieveSchema(this.validator, schema, this.rootSchema, rawFormData);
|
|
2078
1524
|
}
|
|
2079
|
-
/** Sanitize the `data` associated with the `oldSchema` so it is considered appropriate for the `newSchema`. If the
|
|
2080
|
-
* new schema does not contain any properties, then `undefined` is returned to clear all the form data. Due to the
|
|
2081
|
-
* nature of schemas, this sanitization happens recursively for nested objects of data. Also, any properties in the
|
|
2082
|
-
* old schemas that are non-existent in the new schema are set to `undefined`.
|
|
2083
|
-
*
|
|
2084
|
-
* @param [newSchema] - The new schema for which the data is being sanitized
|
|
2085
|
-
* @param [oldSchema] - The old schema from which the data originated
|
|
2086
|
-
* @param [data={}] - The form data associated with the schema, defaulting to an empty object when undefined
|
|
2087
|
-
* @returns - The new form data, with all the fields uniquely associated with the old schema set
|
|
2088
|
-
* to `undefined`. Will return `undefined` if the new schema is not an object containing properties.
|
|
1525
|
+
/** Sanitize the `data` associated with the `oldSchema` so it is considered appropriate for the `newSchema`. If the
|
|
1526
|
+
* new schema does not contain any properties, then `undefined` is returned to clear all the form data. Due to the
|
|
1527
|
+
* nature of schemas, this sanitization happens recursively for nested objects of data. Also, any properties in the
|
|
1528
|
+
* old schemas that are non-existent in the new schema are set to `undefined`.
|
|
1529
|
+
*
|
|
1530
|
+
* @param [newSchema] - The new schema for which the data is being sanitized
|
|
1531
|
+
* @param [oldSchema] - The old schema from which the data originated
|
|
1532
|
+
* @param [data={}] - The form data associated with the schema, defaulting to an empty object when undefined
|
|
1533
|
+
* @returns - The new form data, with all the fields uniquely associated with the old schema set
|
|
1534
|
+
* to `undefined`. Will return `undefined` if the new schema is not an object containing properties.
|
|
2089
1535
|
*/
|
|
2090
1536
|
sanitizeDataForNewSchema(newSchema, oldSchema, data) {
|
|
2091
1537
|
return sanitizeDataForNewSchema(this.validator, this.rootSchema, newSchema, oldSchema, data);
|
|
2092
1538
|
}
|
|
2093
|
-
/** Generates an `IdSchema` object for the `schema`, recursively
|
|
2094
|
-
*
|
|
2095
|
-
* @param schema - The schema for which the display label flag is desired
|
|
2096
|
-
* @param [id] - The base id for the schema
|
|
2097
|
-
* @param [formData] - The current formData, if any, onto which to provide any missing defaults
|
|
2098
|
-
* @param [idPrefix='root'] - The prefix to use for the id
|
|
2099
|
-
* @param [idSeparator='_'] - The separator to use for the path segments in the id
|
|
2100
|
-
* @returns - The `IdSchema` object for the `schema`
|
|
1539
|
+
/** Generates an `IdSchema` object for the `schema`, recursively
|
|
1540
|
+
*
|
|
1541
|
+
* @param schema - The schema for which the display label flag is desired
|
|
1542
|
+
* @param [id] - The base id for the schema
|
|
1543
|
+
* @param [formData] - The current formData, if any, onto which to provide any missing defaults
|
|
1544
|
+
* @param [idPrefix='root'] - The prefix to use for the id
|
|
1545
|
+
* @param [idSeparator='_'] - The separator to use for the path segments in the id
|
|
1546
|
+
* @returns - The `IdSchema` object for the `schema`
|
|
2101
1547
|
*/
|
|
2102
|
-
toIdSchema(schema, id, formData, idPrefix =
|
|
1548
|
+
toIdSchema(schema, id, formData, idPrefix = "root", idSeparator = "_") {
|
|
2103
1549
|
return toIdSchema(this.validator, schema, id, this.rootSchema, formData, idPrefix, idSeparator);
|
|
2104
1550
|
}
|
|
2105
|
-
/** Generates an `PathSchema` object for the `schema`, recursively
|
|
2106
|
-
*
|
|
2107
|
-
* @param schema - The schema for which the display label flag is desired
|
|
2108
|
-
* @param [name] - The base name for the schema
|
|
2109
|
-
* @param [formData] - The current formData, if any, onto which to provide any missing defaults
|
|
2110
|
-
* @returns - The `PathSchema` object for the `schema`
|
|
1551
|
+
/** Generates an `PathSchema` object for the `schema`, recursively
|
|
1552
|
+
*
|
|
1553
|
+
* @param schema - The schema for which the display label flag is desired
|
|
1554
|
+
* @param [name] - The base name for the schema
|
|
1555
|
+
* @param [formData] - The current formData, if any, onto which to provide any missing defaults
|
|
1556
|
+
* @returns - The `PathSchema` object for the `schema`
|
|
2111
1557
|
*/
|
|
2112
1558
|
toPathSchema(schema, name, formData) {
|
|
2113
1559
|
return toPathSchema(this.validator, schema, name, this.rootSchema, formData);
|
|
2114
1560
|
}
|
|
2115
|
-
}
|
|
2116
|
-
/** Creates a `SchemaUtilsType` interface that is based around the given `validator` and `rootSchema` parameters. The
|
|
2117
|
-
* resulting interface implementation will forward the `validator` and `rootSchema` to all the wrapped APIs.
|
|
2118
|
-
*
|
|
2119
|
-
* @param validator - an implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
2120
|
-
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
2121
|
-
* @param [experimental_defaultFormStateBehavior] Optional configuration object, if provided, allows users to override default form state behavior
|
|
2122
|
-
* @returns - An implementation of a `SchemaUtilsType` interface
|
|
2123
|
-
*/
|
|
1561
|
+
};
|
|
2124
1562
|
function createSchemaUtils(validator, rootSchema, experimental_defaultFormStateBehavior = {}) {
|
|
2125
1563
|
return new SchemaUtils(validator, rootSchema, experimental_defaultFormStateBehavior);
|
|
2126
1564
|
}
|
|
2127
1565
|
|
|
2128
|
-
|
|
2129
|
-
* of that Blob if provided in the URL. If no name is provided, then the name falls back to `unknown`.
|
|
2130
|
-
*
|
|
2131
|
-
* @param dataURI - The `DataUrl` potentially containing name and raw data to be converted to a Blob
|
|
2132
|
-
* @returns - an object containing a Blob and its name, extracted from the URI
|
|
2133
|
-
*/
|
|
1566
|
+
// src/dataURItoBlob.ts
|
|
2134
1567
|
function dataURItoBlob(dataURI) {
|
|
2135
|
-
|
|
2136
|
-
const
|
|
2137
|
-
|
|
2138
|
-
const
|
|
2139
|
-
|
|
2140
|
-
const type = params[0].replace('data:', '');
|
|
2141
|
-
// Filter the name property from params
|
|
2142
|
-
const properties = params.filter(param => {
|
|
2143
|
-
return param.split('=')[0] === 'name';
|
|
1568
|
+
const splitted = dataURI.split(",");
|
|
1569
|
+
const params = splitted[0].split(";");
|
|
1570
|
+
const type = params[0].replace("data:", "");
|
|
1571
|
+
const properties = params.filter((param) => {
|
|
1572
|
+
return param.split("=")[0] === "name";
|
|
2144
1573
|
});
|
|
2145
|
-
// Look for the name and use unknown if no name property.
|
|
2146
1574
|
let name;
|
|
2147
1575
|
if (properties.length !== 1) {
|
|
2148
|
-
name =
|
|
1576
|
+
name = "unknown";
|
|
2149
1577
|
} else {
|
|
2150
|
-
|
|
2151
|
-
// we only have the name case here, which we decode to make it human-readable
|
|
2152
|
-
name = decodeURI(properties[0].split('=')[1]);
|
|
1578
|
+
name = decodeURI(properties[0].split("=")[1]);
|
|
2153
1579
|
}
|
|
2154
|
-
// Built the Uint8Array Blob parameter from the base64 string.
|
|
2155
1580
|
try {
|
|
2156
1581
|
const binary = atob(splitted[1]);
|
|
2157
1582
|
const array = [];
|
|
2158
1583
|
for (let i = 0; i < binary.length; i++) {
|
|
2159
1584
|
array.push(binary.charCodeAt(i));
|
|
2160
1585
|
}
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
type
|
|
2164
|
-
});
|
|
2165
|
-
return {
|
|
2166
|
-
blob,
|
|
2167
|
-
name
|
|
2168
|
-
};
|
|
1586
|
+
const blob = new window.Blob([new Uint8Array(array)], { type });
|
|
1587
|
+
return { blob, name };
|
|
2169
1588
|
} catch (error) {
|
|
2170
|
-
return {
|
|
2171
|
-
blob: {
|
|
2172
|
-
size: 0,
|
|
2173
|
-
type: error.message
|
|
2174
|
-
},
|
|
2175
|
-
name: dataURI
|
|
2176
|
-
};
|
|
1589
|
+
return { blob: { size: 0, type: error.message }, name: dataURI };
|
|
2177
1590
|
}
|
|
2178
1591
|
}
|
|
2179
1592
|
|
|
2180
|
-
|
|
2181
|
-
* a `params` array is provided, each value in the array is used to replace any of the replaceable parameters in the
|
|
2182
|
-
* `inputString` using the `%1`, `%2`, etc. replacement specifiers.
|
|
2183
|
-
*
|
|
2184
|
-
* @param inputString - The string which will be potentially updated with replacement parameters
|
|
2185
|
-
* @param params - The optional list of replaceable parameter values to substitute into the english string
|
|
2186
|
-
* @returns - The updated string with any replacement specifiers replaced
|
|
2187
|
-
*/
|
|
1593
|
+
// src/replaceStringParameters.ts
|
|
2188
1594
|
function replaceStringParameters(inputString, params) {
|
|
2189
1595
|
let output = inputString;
|
|
2190
1596
|
if (Array.isArray(params)) {
|
|
2191
1597
|
const parts = output.split(/(%\d)/);
|
|
2192
1598
|
params.forEach((param, index) => {
|
|
2193
|
-
const partIndex = parts.findIndex(part => part === `%${index + 1}`);
|
|
1599
|
+
const partIndex = parts.findIndex((part) => part === `%${index + 1}`);
|
|
2194
1600
|
if (partIndex >= 0) {
|
|
2195
1601
|
parts[partIndex] = param;
|
|
2196
1602
|
}
|
|
2197
1603
|
});
|
|
2198
|
-
output = parts.join(
|
|
1604
|
+
output = parts.join("");
|
|
2199
1605
|
}
|
|
2200
1606
|
return output;
|
|
2201
1607
|
}
|
|
2202
1608
|
|
|
2203
|
-
|
|
2204
|
-
* value in the array is used to replace any of the replaceable parameters in the `stringToTranslate` using the `%1`,
|
|
2205
|
-
* `%2`, etc. replacement specifiers.
|
|
2206
|
-
*
|
|
2207
|
-
* @param stringToTranslate - The `TranslatableString` value to convert to english
|
|
2208
|
-
* @param params - The optional list of replaceable parameter values to substitute into the english string
|
|
2209
|
-
* @returns - The `stringToTranslate` itself with any replaceable parameter values substituted
|
|
2210
|
-
*/
|
|
1609
|
+
// src/englishStringTranslator.ts
|
|
2211
1610
|
function englishStringTranslator(stringToTranslate, params) {
|
|
2212
1611
|
return replaceStringParameters(stringToTranslate, params);
|
|
2213
1612
|
}
|
|
2214
1613
|
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
*
|
|
2220
|
-
* @param valueIndex - The index(es) of the value(s) that should be returned
|
|
2221
|
-
* @param [allEnumOptions=[]] - The list of all the known enumOptions
|
|
2222
|
-
* @param [emptyValue] - The value to return when the non-array `valueIndex` does not refer to a real option
|
|
2223
|
-
* @returns - The single or list of values specified by the single or list of indexes if they are valid. Otherwise,
|
|
2224
|
-
* `emptyValue` or an empty list.
|
|
2225
|
-
*/
|
|
1614
|
+
// src/enumOptionsDeselectValue.ts
|
|
1615
|
+
import isEqual3 from "lodash/isEqual";
|
|
1616
|
+
|
|
1617
|
+
// src/enumOptionsValueForIndex.ts
|
|
2226
1618
|
function enumOptionsValueForIndex(valueIndex, allEnumOptions = [], emptyValue) {
|
|
2227
1619
|
if (Array.isArray(valueIndex)) {
|
|
2228
|
-
return valueIndex.map(
|
|
1620
|
+
return valueIndex.map((index2) => enumOptionsValueForIndex(index2, allEnumOptions)).filter((val) => val);
|
|
2229
1621
|
}
|
|
2230
|
-
|
|
2231
|
-
const index = valueIndex === '' || valueIndex === null ? -1 : Number(valueIndex);
|
|
1622
|
+
const index = valueIndex === "" || valueIndex === null ? -1 : Number(valueIndex);
|
|
2232
1623
|
const option = allEnumOptions[index];
|
|
2233
1624
|
return option ? option.value : emptyValue;
|
|
2234
1625
|
}
|
|
2235
1626
|
|
|
2236
|
-
|
|
2237
|
-
* a list, then that list is updated to remove the enum option value with the `valueIndex` in `allEnumOptions`. If it is
|
|
2238
|
-
* a single value, then if the enum option value with the `valueIndex` in `allEnumOptions` matches `selected`, undefined
|
|
2239
|
-
* is returned, otherwise the `selected` value is returned.
|
|
2240
|
-
*
|
|
2241
|
-
* @param valueIndex - The index of the value to be removed from the selected list or single value
|
|
2242
|
-
* @param selected - The current (list of) selected value(s)
|
|
2243
|
-
* @param [allEnumOptions=[]] - The list of all the known enumOptions
|
|
2244
|
-
* @returns - The updated `selected` with the enum option value at `valueIndex` in `allEnumOptions` removed from it,
|
|
2245
|
-
* unless `selected` is a single value. In that case, if the `valueIndex` value matches `selected`, returns
|
|
2246
|
-
* undefined, otherwise `selected`.
|
|
2247
|
-
*/
|
|
1627
|
+
// src/enumOptionsDeselectValue.ts
|
|
2248
1628
|
function enumOptionsDeselectValue(valueIndex, selected, allEnumOptions = []) {
|
|
2249
1629
|
const value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
|
|
2250
1630
|
if (Array.isArray(selected)) {
|
|
2251
|
-
return selected.filter(v => !
|
|
1631
|
+
return selected.filter((v) => !isEqual3(v, value));
|
|
2252
1632
|
}
|
|
2253
|
-
return
|
|
1633
|
+
return isEqual3(value, selected) ? void 0 : selected;
|
|
2254
1634
|
}
|
|
2255
1635
|
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
* @param value - The value being checked to see if it is selected
|
|
2259
|
-
* @param selected - The current selected value or list of values
|
|
2260
|
-
* @returns - true if the `value` is one of the `selected` ones, false otherwise
|
|
2261
|
-
*/
|
|
1636
|
+
// src/enumOptionsIsSelected.ts
|
|
1637
|
+
import isEqual4 from "lodash/isEqual";
|
|
2262
1638
|
function enumOptionsIsSelected(value, selected) {
|
|
2263
1639
|
if (Array.isArray(selected)) {
|
|
2264
|
-
return selected.some(sel =>
|
|
2265
|
-
}
|
|
2266
|
-
return
|
|
2267
|
-
}
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
* `enumOptions` are filtered based on whether they are a "selected" `value` and the index of each selected one is then
|
|
2271
|
-
* stored in an array. If `multiple` is true, that array is returned, otherwise the first element in the array is
|
|
2272
|
-
* returned.
|
|
2273
|
-
*
|
|
2274
|
-
* @param value - The single value or list of values for which indexes are desired
|
|
2275
|
-
* @param [allEnumOptions=[]] - The list of all the known enumOptions
|
|
2276
|
-
* @param [multiple=false] - Optional flag, if true will return a list of index, otherwise a single one
|
|
2277
|
-
* @returns - A single string index for the first `value` in `allEnumOptions`, if not `multiple`. Otherwise, the list
|
|
2278
|
-
* of indexes for (each of) the value(s) in `value`.
|
|
2279
|
-
*/
|
|
1640
|
+
return selected.some((sel) => isEqual4(sel, value));
|
|
1641
|
+
}
|
|
1642
|
+
return isEqual4(selected, value);
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
// src/enumOptionsIndexForValue.ts
|
|
2280
1646
|
function enumOptionsIndexForValue(value, allEnumOptions = [], multiple = false) {
|
|
2281
|
-
const selectedIndexes = allEnumOptions.map((opt, index) => enumOptionsIsSelected(opt.value, value) ? String(index) :
|
|
1647
|
+
const selectedIndexes = allEnumOptions.map((opt, index) => enumOptionsIsSelected(opt.value, value) ? String(index) : void 0).filter((opt) => typeof opt !== "undefined");
|
|
2282
1648
|
if (!multiple) {
|
|
2283
1649
|
return selectedIndexes[0];
|
|
2284
1650
|
}
|
|
2285
1651
|
return selectedIndexes;
|
|
2286
1652
|
}
|
|
2287
1653
|
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
*
|
|
2291
|
-
* @param valueIndex - The index of the value that should be selected
|
|
2292
|
-
* @param selected - The current list of selected values
|
|
2293
|
-
* @param [allEnumOptions=[]] - The list of all the known enumOptions
|
|
2294
|
-
* @returns - The updated list of selected enum values with enum value at the `valueIndex` added to it
|
|
2295
|
-
*/
|
|
1654
|
+
// src/enumOptionsSelectValue.ts
|
|
1655
|
+
import { isNil } from "lodash";
|
|
2296
1656
|
function enumOptionsSelectValue(valueIndex, selected, allEnumOptions = []) {
|
|
2297
1657
|
const value = enumOptionsValueForIndex(valueIndex, allEnumOptions);
|
|
2298
1658
|
if (!isNil(value)) {
|
|
2299
|
-
const index = allEnumOptions.findIndex(opt => value === opt.value);
|
|
2300
|
-
const all = allEnumOptions.map(({
|
|
2301
|
-
value: val
|
|
2302
|
-
}) => val);
|
|
1659
|
+
const index = allEnumOptions.findIndex((opt) => value === opt.value);
|
|
1660
|
+
const all = allEnumOptions.map(({ value: val }) => val);
|
|
2303
1661
|
const updated = selected.slice(0, index).concat(value, selected.slice(index));
|
|
2304
|
-
// As inserting values at predefined index positions doesn't work with empty
|
|
2305
|
-
// arrays, we need to reorder the updated selection to match the initial order
|
|
2306
1662
|
return updated.sort((a, b) => Number(all.indexOf(a) > all.indexOf(b)));
|
|
2307
1663
|
}
|
|
2308
1664
|
return selected;
|
|
2309
1665
|
}
|
|
2310
1666
|
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
*
|
|
2319
|
-
* @param [initialSchema] - The optional set of initial errors, that will be cloned into the class
|
|
1667
|
+
// src/ErrorSchemaBuilder.ts
|
|
1668
|
+
import cloneDeep from "lodash/cloneDeep";
|
|
1669
|
+
import get10 from "lodash/get";
|
|
1670
|
+
import set3 from "lodash/set";
|
|
1671
|
+
var ErrorSchemaBuilder = class {
|
|
1672
|
+
/** Construct an `ErrorSchemaBuilder` with an optional initial set of errors in an `ErrorSchema`.
|
|
1673
|
+
*
|
|
1674
|
+
* @param [initialSchema] - The optional set of initial errors, that will be cloned into the class
|
|
2320
1675
|
*/
|
|
2321
1676
|
constructor(initialSchema) {
|
|
2322
|
-
/** The error schema being built
|
|
2323
|
-
*
|
|
2324
|
-
* @private
|
|
1677
|
+
/** The error schema being built
|
|
1678
|
+
*
|
|
1679
|
+
* @private
|
|
2325
1680
|
*/
|
|
2326
1681
|
this.errorSchema = {};
|
|
2327
1682
|
this.resetAllErrors(initialSchema);
|
|
2328
1683
|
}
|
|
2329
|
-
/** Returns the `ErrorSchema` that has been updated by the methods of the `ErrorSchemaBuilder`
|
|
1684
|
+
/** Returns the `ErrorSchema` that has been updated by the methods of the `ErrorSchemaBuilder`
|
|
2330
1685
|
*/
|
|
2331
1686
|
get ErrorSchema() {
|
|
2332
1687
|
return this.errorSchema;
|
|
2333
1688
|
}
|
|
2334
|
-
/** Will get an existing `ErrorSchema` at the specified `pathOfError` or create and return one.
|
|
2335
|
-
*
|
|
2336
|
-
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to add the error(s)
|
|
2337
|
-
* @returns - The error block for the given `pathOfError` or the root if not provided
|
|
2338
|
-
* @private
|
|
1689
|
+
/** Will get an existing `ErrorSchema` at the specified `pathOfError` or create and return one.
|
|
1690
|
+
*
|
|
1691
|
+
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to add the error(s)
|
|
1692
|
+
* @returns - The error block for the given `pathOfError` or the root if not provided
|
|
1693
|
+
* @private
|
|
2339
1694
|
*/
|
|
2340
1695
|
getOrCreateErrorBlock(pathOfError) {
|
|
2341
|
-
const hasPath = Array.isArray(pathOfError) && pathOfError.length > 0 || typeof pathOfError ===
|
|
2342
|
-
let errorBlock = hasPath ?
|
|
1696
|
+
const hasPath = Array.isArray(pathOfError) && pathOfError.length > 0 || typeof pathOfError === "string";
|
|
1697
|
+
let errorBlock = hasPath ? get10(this.errorSchema, pathOfError) : this.errorSchema;
|
|
2343
1698
|
if (!errorBlock && pathOfError) {
|
|
2344
1699
|
errorBlock = {};
|
|
2345
|
-
|
|
1700
|
+
set3(this.errorSchema, pathOfError, errorBlock);
|
|
2346
1701
|
}
|
|
2347
1702
|
return errorBlock;
|
|
2348
1703
|
}
|
|
2349
|
-
/** Resets all errors in the `ErrorSchemaBuilder` back to the `initialSchema` if provided, otherwise an empty set.
|
|
2350
|
-
*
|
|
2351
|
-
* @param [initialSchema] - The optional set of initial errors, that will be cloned into the class
|
|
2352
|
-
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
1704
|
+
/** Resets all errors in the `ErrorSchemaBuilder` back to the `initialSchema` if provided, otherwise an empty set.
|
|
1705
|
+
*
|
|
1706
|
+
* @param [initialSchema] - The optional set of initial errors, that will be cloned into the class
|
|
1707
|
+
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
2353
1708
|
*/
|
|
2354
1709
|
resetAllErrors(initialSchema) {
|
|
2355
1710
|
this.errorSchema = initialSchema ? cloneDeep(initialSchema) : {};
|
|
2356
1711
|
return this;
|
|
2357
1712
|
}
|
|
2358
|
-
/** Adds the `errorOrList` to the list of errors in the `ErrorSchema` at either the root level or the location within
|
|
2359
|
-
* the schema described by the `pathOfError`. For more information about how to specify the path see the
|
|
2360
|
-
* [eslint lodash plugin docs](https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/path-style.md).
|
|
2361
|
-
*
|
|
2362
|
-
* @param errorOrList - The error or list of errors to add into the `ErrorSchema`
|
|
2363
|
-
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to add the error(s)
|
|
2364
|
-
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
1713
|
+
/** Adds the `errorOrList` to the list of errors in the `ErrorSchema` at either the root level or the location within
|
|
1714
|
+
* the schema described by the `pathOfError`. For more information about how to specify the path see the
|
|
1715
|
+
* [eslint lodash plugin docs](https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/path-style.md).
|
|
1716
|
+
*
|
|
1717
|
+
* @param errorOrList - The error or list of errors to add into the `ErrorSchema`
|
|
1718
|
+
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to add the error(s)
|
|
1719
|
+
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
2365
1720
|
*/
|
|
2366
1721
|
addErrors(errorOrList, pathOfError) {
|
|
2367
1722
|
const errorBlock = this.getOrCreateErrorBlock(pathOfError);
|
|
2368
|
-
let errorsList =
|
|
1723
|
+
let errorsList = get10(errorBlock, ERRORS_KEY);
|
|
2369
1724
|
if (!Array.isArray(errorsList)) {
|
|
2370
1725
|
errorsList = [];
|
|
2371
1726
|
errorBlock[ERRORS_KEY] = errorsList;
|
|
@@ -2377,41 +1732,35 @@ class ErrorSchemaBuilder {
|
|
|
2377
1732
|
}
|
|
2378
1733
|
return this;
|
|
2379
1734
|
}
|
|
2380
|
-
/** Sets/replaces the `errorOrList` as the error(s) in the `ErrorSchema` at either the root level or the location
|
|
2381
|
-
* within the schema described by the `pathOfError`. For more information about how to specify the path see the
|
|
2382
|
-
* [eslint lodash plugin docs](https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/path-style.md).
|
|
2383
|
-
*
|
|
2384
|
-
* @param errorOrList - The error or list of errors to set into the `ErrorSchema`
|
|
2385
|
-
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to set the error(s)
|
|
2386
|
-
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
1735
|
+
/** Sets/replaces the `errorOrList` as the error(s) in the `ErrorSchema` at either the root level or the location
|
|
1736
|
+
* within the schema described by the `pathOfError`. For more information about how to specify the path see the
|
|
1737
|
+
* [eslint lodash plugin docs](https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/path-style.md).
|
|
1738
|
+
*
|
|
1739
|
+
* @param errorOrList - The error or list of errors to set into the `ErrorSchema`
|
|
1740
|
+
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to set the error(s)
|
|
1741
|
+
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
2387
1742
|
*/
|
|
2388
1743
|
setErrors(errorOrList, pathOfError) {
|
|
2389
1744
|
const errorBlock = this.getOrCreateErrorBlock(pathOfError);
|
|
2390
|
-
// Effectively clone the array being given to prevent accidental outside manipulation of the given list
|
|
2391
1745
|
const listToAdd = Array.isArray(errorOrList) ? [...errorOrList] : [errorOrList];
|
|
2392
|
-
|
|
1746
|
+
set3(errorBlock, ERRORS_KEY, listToAdd);
|
|
2393
1747
|
return this;
|
|
2394
1748
|
}
|
|
2395
|
-
/** Clears the error(s) in the `ErrorSchema` at either the root level or the location within the schema described by
|
|
2396
|
-
* the `pathOfError`. For more information about how to specify the path see the
|
|
2397
|
-
* [eslint lodash plugin docs](https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/path-style.md).
|
|
2398
|
-
*
|
|
2399
|
-
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to clear the error(s)
|
|
2400
|
-
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
1749
|
+
/** Clears the error(s) in the `ErrorSchema` at either the root level or the location within the schema described by
|
|
1750
|
+
* the `pathOfError`. For more information about how to specify the path see the
|
|
1751
|
+
* [eslint lodash plugin docs](https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/path-style.md).
|
|
1752
|
+
*
|
|
1753
|
+
* @param [pathOfError] - The optional path into the `ErrorSchema` at which to clear the error(s)
|
|
1754
|
+
* @returns - The `ErrorSchemaBuilder` object for chaining purposes
|
|
2401
1755
|
*/
|
|
2402
1756
|
clearErrors(pathOfError) {
|
|
2403
1757
|
const errorBlock = this.getOrCreateErrorBlock(pathOfError);
|
|
2404
|
-
|
|
1758
|
+
set3(errorBlock, ERRORS_KEY, []);
|
|
2405
1759
|
return this;
|
|
2406
1760
|
}
|
|
2407
|
-
}
|
|
1761
|
+
};
|
|
2408
1762
|
|
|
2409
|
-
|
|
2410
|
-
* input from the range analog in the schema `{ multipleOf?: number, minimum?: number, maximum?: number }`.
|
|
2411
|
-
*
|
|
2412
|
-
* @param schema - The schema from which to extract the range spec
|
|
2413
|
-
* @returns - A range specification from the schema
|
|
2414
|
-
*/
|
|
1763
|
+
// src/rangeSpec.ts
|
|
2415
1764
|
function rangeSpec(schema) {
|
|
2416
1765
|
const spec = {};
|
|
2417
1766
|
if (schema.multipleOf) {
|
|
@@ -2426,37 +1775,23 @@ function rangeSpec(schema) {
|
|
|
2426
1775
|
return spec;
|
|
2427
1776
|
}
|
|
2428
1777
|
|
|
2429
|
-
|
|
2430
|
-
*
|
|
2431
|
-
* @param schema - The schema for the field provided by the widget
|
|
2432
|
-
* @param [defaultType] - The default type, if any, for the field provided by the widget
|
|
2433
|
-
* @param [options={}] - The UI Options for the field provided by the widget
|
|
2434
|
-
* @param [autoDefaultStepAny=true] - Determines whether to auto-default step=any when the type is number and no step
|
|
2435
|
-
* @returns - The extracted `InputPropsType` object
|
|
2436
|
-
*/
|
|
1778
|
+
// src/getInputProps.ts
|
|
2437
1779
|
function getInputProps(schema, defaultType, options = {}, autoDefaultStepAny = true) {
|
|
2438
1780
|
const inputProps = {
|
|
2439
|
-
type: defaultType ||
|
|
1781
|
+
type: defaultType || "text",
|
|
2440
1782
|
...rangeSpec(schema)
|
|
2441
1783
|
};
|
|
2442
|
-
// If options.inputType is set use that as the input type
|
|
2443
1784
|
if (options.inputType) {
|
|
2444
1785
|
inputProps.type = options.inputType;
|
|
2445
1786
|
} else if (!defaultType) {
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
inputProps.
|
|
2449
|
-
|
|
2450
|
-
if (autoDefaultStepAny && inputProps.step === undefined) {
|
|
2451
|
-
// Setting step to 'any' fixes a bug in Safari where decimals are not
|
|
2452
|
-
// allowed in number inputs
|
|
2453
|
-
inputProps.step = 'any';
|
|
1787
|
+
if (schema.type === "number") {
|
|
1788
|
+
inputProps.type = "number";
|
|
1789
|
+
if (autoDefaultStepAny && inputProps.step === void 0) {
|
|
1790
|
+
inputProps.step = "any";
|
|
2454
1791
|
}
|
|
2455
|
-
} else if (schema.type ===
|
|
2456
|
-
inputProps.type =
|
|
2457
|
-
|
|
2458
|
-
if (inputProps.step === undefined) {
|
|
2459
|
-
// Since this is integer, you always want to step up or down in multiples of 1
|
|
1792
|
+
} else if (schema.type === "integer") {
|
|
1793
|
+
inputProps.type = "number";
|
|
1794
|
+
if (inputProps.step === void 0) {
|
|
2460
1795
|
inputProps.step = 1;
|
|
2461
1796
|
}
|
|
2462
1797
|
}
|
|
@@ -2467,45 +1802,27 @@ function getInputProps(schema, defaultType, options = {}, autoDefaultStepAny = t
|
|
|
2467
1802
|
return inputProps;
|
|
2468
1803
|
}
|
|
2469
1804
|
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
const DEFAULT_OPTIONS = {
|
|
1805
|
+
// src/getSubmitButtonOptions.ts
|
|
1806
|
+
var DEFAULT_OPTIONS = {
|
|
2473
1807
|
props: {
|
|
2474
1808
|
disabled: false
|
|
2475
1809
|
},
|
|
2476
|
-
submitText:
|
|
1810
|
+
submitText: "Submit",
|
|
2477
1811
|
norender: false
|
|
2478
1812
|
};
|
|
2479
|
-
/** Extracts any `ui:submitButtonOptions` from the `uiSchema` and merges them onto the `DEFAULT_OPTIONS`
|
|
2480
|
-
*
|
|
2481
|
-
* @param [uiSchema={}] - the UI Schema from which to extract submit button props
|
|
2482
|
-
* @returns - The merging of the `DEFAULT_OPTIONS` with any custom ones
|
|
2483
|
-
*/
|
|
2484
1813
|
function getSubmitButtonOptions(uiSchema = {}) {
|
|
2485
1814
|
const uiOptions = getUiOptions(uiSchema);
|
|
2486
1815
|
if (uiOptions && uiOptions[SUBMIT_BTN_OPTIONS_KEY]) {
|
|
2487
1816
|
const options = uiOptions[SUBMIT_BTN_OPTIONS_KEY];
|
|
2488
|
-
return {
|
|
2489
|
-
...DEFAULT_OPTIONS,
|
|
2490
|
-
...options
|
|
2491
|
-
};
|
|
1817
|
+
return { ...DEFAULT_OPTIONS, ...options };
|
|
2492
1818
|
}
|
|
2493
1819
|
return DEFAULT_OPTIONS;
|
|
2494
1820
|
}
|
|
2495
1821
|
|
|
2496
|
-
|
|
2497
|
-
* otherwise. NOTE, since `ButtonTemplates` are not overridden in `uiSchema` only those in the `registry` are returned.
|
|
2498
|
-
*
|
|
2499
|
-
* @param name - The name of the template to fetch, restricted to the keys of `TemplatesType`
|
|
2500
|
-
* @param registry - The `Registry` from which to read the template
|
|
2501
|
-
* @param [uiOptions={}] - The `UIOptionsType` from which to read an alternate template
|
|
2502
|
-
* @returns - The template from either the `uiSchema` or `registry` for the `name`
|
|
2503
|
-
*/
|
|
1822
|
+
// src/getTemplate.ts
|
|
2504
1823
|
function getTemplate(name, registry, uiOptions = {}) {
|
|
2505
|
-
const {
|
|
2506
|
-
|
|
2507
|
-
} = registry;
|
|
2508
|
-
if (name === 'ButtonTemplates') {
|
|
1824
|
+
const { templates } = registry;
|
|
1825
|
+
if (name === "ButtonTemplates") {
|
|
2509
1826
|
return templates[name];
|
|
2510
1827
|
}
|
|
2511
1828
|
return (
|
|
@@ -2515,112 +1832,88 @@ function getTemplate(name, registry, uiOptions = {}) {
|
|
|
2515
1832
|
);
|
|
2516
1833
|
}
|
|
2517
1834
|
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
1835
|
+
// src/getWidget.tsx
|
|
1836
|
+
import { createElement } from "react";
|
|
1837
|
+
import ReactIs from "react-is";
|
|
1838
|
+
import get11 from "lodash/get";
|
|
1839
|
+
import set4 from "lodash/set";
|
|
1840
|
+
import { jsx } from "react/jsx-runtime";
|
|
1841
|
+
var widgetMap = {
|
|
2521
1842
|
boolean: {
|
|
2522
|
-
checkbox:
|
|
2523
|
-
radio:
|
|
2524
|
-
select:
|
|
2525
|
-
hidden:
|
|
1843
|
+
checkbox: "CheckboxWidget",
|
|
1844
|
+
radio: "RadioWidget",
|
|
1845
|
+
select: "SelectWidget",
|
|
1846
|
+
hidden: "HiddenWidget"
|
|
2526
1847
|
},
|
|
2527
1848
|
string: {
|
|
2528
|
-
text:
|
|
2529
|
-
password:
|
|
2530
|
-
email:
|
|
2531
|
-
hostname:
|
|
2532
|
-
ipv4:
|
|
2533
|
-
ipv6:
|
|
2534
|
-
uri:
|
|
2535
|
-
|
|
2536
|
-
radio:
|
|
2537
|
-
select:
|
|
2538
|
-
textarea:
|
|
2539
|
-
hidden:
|
|
2540
|
-
date:
|
|
2541
|
-
datetime:
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
time:
|
|
2546
|
-
color:
|
|
2547
|
-
file:
|
|
1849
|
+
text: "TextWidget",
|
|
1850
|
+
password: "PasswordWidget",
|
|
1851
|
+
email: "EmailWidget",
|
|
1852
|
+
hostname: "TextWidget",
|
|
1853
|
+
ipv4: "TextWidget",
|
|
1854
|
+
ipv6: "TextWidget",
|
|
1855
|
+
uri: "URLWidget",
|
|
1856
|
+
"data-url": "FileWidget",
|
|
1857
|
+
radio: "RadioWidget",
|
|
1858
|
+
select: "SelectWidget",
|
|
1859
|
+
textarea: "TextareaWidget",
|
|
1860
|
+
hidden: "HiddenWidget",
|
|
1861
|
+
date: "DateWidget",
|
|
1862
|
+
datetime: "DateTimeWidget",
|
|
1863
|
+
"date-time": "DateTimeWidget",
|
|
1864
|
+
"alt-date": "AltDateWidget",
|
|
1865
|
+
"alt-datetime": "AltDateTimeWidget",
|
|
1866
|
+
time: "TimeWidget",
|
|
1867
|
+
color: "ColorWidget",
|
|
1868
|
+
file: "FileWidget"
|
|
2548
1869
|
},
|
|
2549
1870
|
number: {
|
|
2550
|
-
text:
|
|
2551
|
-
select:
|
|
2552
|
-
updown:
|
|
2553
|
-
range:
|
|
2554
|
-
radio:
|
|
2555
|
-
hidden:
|
|
1871
|
+
text: "TextWidget",
|
|
1872
|
+
select: "SelectWidget",
|
|
1873
|
+
updown: "UpDownWidget",
|
|
1874
|
+
range: "RangeWidget",
|
|
1875
|
+
radio: "RadioWidget",
|
|
1876
|
+
hidden: "HiddenWidget"
|
|
2556
1877
|
},
|
|
2557
1878
|
integer: {
|
|
2558
|
-
text:
|
|
2559
|
-
select:
|
|
2560
|
-
updown:
|
|
2561
|
-
range:
|
|
2562
|
-
radio:
|
|
2563
|
-
hidden:
|
|
1879
|
+
text: "TextWidget",
|
|
1880
|
+
select: "SelectWidget",
|
|
1881
|
+
updown: "UpDownWidget",
|
|
1882
|
+
range: "RangeWidget",
|
|
1883
|
+
radio: "RadioWidget",
|
|
1884
|
+
hidden: "HiddenWidget"
|
|
2564
1885
|
},
|
|
2565
1886
|
array: {
|
|
2566
|
-
select:
|
|
2567
|
-
checkboxes:
|
|
2568
|
-
files:
|
|
2569
|
-
hidden:
|
|
1887
|
+
select: "SelectWidget",
|
|
1888
|
+
checkboxes: "CheckboxesWidget",
|
|
1889
|
+
files: "FileWidget",
|
|
1890
|
+
hidden: "HiddenWidget"
|
|
2570
1891
|
}
|
|
2571
1892
|
};
|
|
2572
|
-
/** Wraps the given widget with stateless functional component that will merge any `defaultProps.options` with the
|
|
2573
|
-
* `options` that are provided in the props. It will add the wrapper component as a `MergedWidget` property onto the
|
|
2574
|
-
* `Widget` so that future attempts to wrap `AWidget` will return the already existing wrapper.
|
|
2575
|
-
*
|
|
2576
|
-
* @param AWidget - A widget that will be wrapped or one that is already wrapped
|
|
2577
|
-
* @returns - The wrapper widget
|
|
2578
|
-
*/
|
|
2579
1893
|
function mergeWidgetOptions(AWidget) {
|
|
2580
|
-
let MergedWidget =
|
|
2581
|
-
// cache return value as property of widget for proper react reconciliation
|
|
1894
|
+
let MergedWidget = get11(AWidget, "MergedWidget");
|
|
2582
1895
|
if (!MergedWidget) {
|
|
2583
1896
|
const defaultOptions = AWidget.defaultProps && AWidget.defaultProps.options || {};
|
|
2584
|
-
MergedWidget = ({
|
|
2585
|
-
options,
|
|
2586
|
-
...props
|
|
2587
|
-
}) => {
|
|
2588
|
-
return jsx(AWidget, {
|
|
2589
|
-
options: {
|
|
2590
|
-
...defaultOptions,
|
|
2591
|
-
...options
|
|
2592
|
-
},
|
|
2593
|
-
...props
|
|
2594
|
-
});
|
|
1897
|
+
MergedWidget = ({ options, ...props }) => {
|
|
1898
|
+
return /* @__PURE__ */ jsx(AWidget, { options: { ...defaultOptions, ...options }, ...props });
|
|
2595
1899
|
};
|
|
2596
|
-
|
|
1900
|
+
set4(AWidget, "MergedWidget", MergedWidget);
|
|
2597
1901
|
}
|
|
2598
1902
|
return MergedWidget;
|
|
2599
1903
|
}
|
|
2600
|
-
/** Given a schema representing a field to render and either the name or actual `Widget` implementation, returns the
|
|
2601
|
-
* React component that is used to render the widget. If the `widget` is already a React component, then it is wrapped
|
|
2602
|
-
* with a `MergedWidget`. Otherwise an attempt is made to look up the widget inside of the `registeredWidgets` map based
|
|
2603
|
-
* on the schema type and `widget` name. If no widget component can be found an `Error` is thrown.
|
|
2604
|
-
*
|
|
2605
|
-
* @param schema - The schema for the field
|
|
2606
|
-
* @param [widget] - Either the name of the widget OR a `Widget` implementation to use
|
|
2607
|
-
* @param [registeredWidgets={}] - A registry of widget name to `Widget` implementation
|
|
2608
|
-
* @returns - The `Widget` component to use
|
|
2609
|
-
* @throws - An error if there is no `Widget` component that can be returned
|
|
2610
|
-
*/
|
|
2611
1904
|
function getWidget(schema, widget, registeredWidgets = {}) {
|
|
2612
1905
|
const type = getSchemaType(schema);
|
|
2613
|
-
if (typeof widget ===
|
|
1906
|
+
if (typeof widget === "function" || widget && ReactIs.isForwardRef(createElement(widget)) || ReactIs.isMemo(widget)) {
|
|
2614
1907
|
return mergeWidgetOptions(widget);
|
|
2615
1908
|
}
|
|
2616
|
-
if (typeof widget !==
|
|
1909
|
+
if (typeof widget !== "string") {
|
|
2617
1910
|
throw new Error(`Unsupported widget definition: ${typeof widget}`);
|
|
2618
1911
|
}
|
|
2619
1912
|
if (widget in registeredWidgets) {
|
|
2620
1913
|
const registeredWidget = registeredWidgets[widget];
|
|
2621
1914
|
return getWidget(schema, registeredWidget, registeredWidgets);
|
|
2622
1915
|
}
|
|
2623
|
-
if (typeof type ===
|
|
1916
|
+
if (typeof type === "string") {
|
|
2624
1917
|
if (!(type in widgetMap)) {
|
|
2625
1918
|
throw new Error(`No widget for type '${type}'`);
|
|
2626
1919
|
}
|
|
@@ -2632,148 +1925,76 @@ function getWidget(schema, widget, registeredWidgets = {}) {
|
|
|
2632
1925
|
throw new Error(`No widget '${widget}' for type '${type}'`);
|
|
2633
1926
|
}
|
|
2634
1927
|
|
|
2635
|
-
|
|
2636
|
-
* based on Java's hashing fn:
|
|
2637
|
-
* http://www.java2s.com/example/nodejs-utility-method/string-hash/hashcode-4dc2b.html
|
|
2638
|
-
*
|
|
2639
|
-
* @param string - The string for which to get the hash
|
|
2640
|
-
* @returns - The resulting hash of the string in hex format
|
|
2641
|
-
*/
|
|
1928
|
+
// src/hashForSchema.ts
|
|
2642
1929
|
function hashString(string) {
|
|
2643
1930
|
let hash = 0;
|
|
2644
1931
|
for (let i = 0; i < string.length; i += 1) {
|
|
2645
1932
|
const chr = string.charCodeAt(i);
|
|
2646
1933
|
hash = (hash << 5) - hash + chr;
|
|
2647
|
-
hash = hash & hash;
|
|
1934
|
+
hash = hash & hash;
|
|
2648
1935
|
}
|
|
2649
|
-
|
|
2650
1936
|
return hash.toString(16);
|
|
2651
1937
|
}
|
|
2652
|
-
/** Stringifies the schema and returns the hash of the resulting string. Sorts schema fields
|
|
2653
|
-
* in consistent order before stringify to prevent different hash ids for the same schema.
|
|
2654
|
-
*
|
|
2655
|
-
* @param schema - The schema for which the hash is desired
|
|
2656
|
-
* @returns - The string obtained from the hash of the stringified schema
|
|
2657
|
-
*/
|
|
2658
1938
|
function hashForSchema(schema) {
|
|
2659
|
-
const allKeys = new Set();
|
|
2660
|
-
// solution source: https://stackoverflow.com/questions/16167581/sort-object-properties-and-json-stringify/53593328#53593328
|
|
1939
|
+
const allKeys = /* @__PURE__ */ new Set();
|
|
2661
1940
|
JSON.stringify(schema, (key, value) => (allKeys.add(key), value));
|
|
2662
1941
|
return hashString(JSON.stringify(schema, Array.from(allKeys).sort()));
|
|
2663
1942
|
}
|
|
2664
1943
|
|
|
2665
|
-
|
|
2666
|
-
* does, or false if it doesn't.
|
|
2667
|
-
*
|
|
2668
|
-
* @param schema - The schema for the field
|
|
2669
|
-
* @param widget - Either the name of the widget OR a `Widget` implementation to use
|
|
2670
|
-
* @param [registeredWidgets={}] - A registry of widget name to `Widget` implementation
|
|
2671
|
-
* @returns - True if the widget exists, false otherwise
|
|
2672
|
-
*/
|
|
1944
|
+
// src/hasWidget.ts
|
|
2673
1945
|
function hasWidget(schema, widget, registeredWidgets = {}) {
|
|
2674
1946
|
try {
|
|
2675
1947
|
getWidget(schema, widget, registeredWidgets);
|
|
2676
1948
|
return true;
|
|
2677
1949
|
} catch (e) {
|
|
2678
1950
|
const err = e;
|
|
2679
|
-
if (err.message && (err.message.startsWith(
|
|
1951
|
+
if (err.message && (err.message.startsWith("No widget") || err.message.startsWith("Unsupported widget"))) {
|
|
2680
1952
|
return false;
|
|
2681
1953
|
}
|
|
2682
1954
|
throw e;
|
|
2683
1955
|
}
|
|
2684
1956
|
}
|
|
2685
1957
|
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2689
|
-
* @param suffix - The suffix to append to the id
|
|
2690
|
-
*/
|
|
1958
|
+
// src/idGenerators.ts
|
|
1959
|
+
import isString3 from "lodash/isString";
|
|
2691
1960
|
function idGenerator(id, suffix) {
|
|
2692
|
-
const theId =
|
|
1961
|
+
const theId = isString3(id) ? id : id[ID_KEY];
|
|
2693
1962
|
return `${theId}__${suffix}`;
|
|
2694
1963
|
}
|
|
2695
|
-
/** Return a consistent `id` for the field description element
|
|
2696
|
-
*
|
|
2697
|
-
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2698
|
-
* @returns - The consistent id for the field description element from the given `id`
|
|
2699
|
-
*/
|
|
2700
1964
|
function descriptionId(id) {
|
|
2701
|
-
return idGenerator(id,
|
|
1965
|
+
return idGenerator(id, "description");
|
|
2702
1966
|
}
|
|
2703
|
-
/** Return a consistent `id` for the field error element
|
|
2704
|
-
*
|
|
2705
|
-
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2706
|
-
* @returns - The consistent id for the field error element from the given `id`
|
|
2707
|
-
*/
|
|
2708
1967
|
function errorId(id) {
|
|
2709
|
-
return idGenerator(id,
|
|
1968
|
+
return idGenerator(id, "error");
|
|
2710
1969
|
}
|
|
2711
|
-
/** Return a consistent `id` for the field examples element
|
|
2712
|
-
*
|
|
2713
|
-
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2714
|
-
* @returns - The consistent id for the field examples element from the given `id`
|
|
2715
|
-
*/
|
|
2716
1970
|
function examplesId(id) {
|
|
2717
|
-
return idGenerator(id,
|
|
1971
|
+
return idGenerator(id, "examples");
|
|
2718
1972
|
}
|
|
2719
|
-
/** Return a consistent `id` for the field help element
|
|
2720
|
-
*
|
|
2721
|
-
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2722
|
-
* @returns - The consistent id for the field help element from the given `id`
|
|
2723
|
-
*/
|
|
2724
1973
|
function helpId(id) {
|
|
2725
|
-
return idGenerator(id,
|
|
1974
|
+
return idGenerator(id, "help");
|
|
2726
1975
|
}
|
|
2727
|
-
/** Return a consistent `id` for the field title element
|
|
2728
|
-
*
|
|
2729
|
-
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2730
|
-
* @returns - The consistent id for the field title element from the given `id`
|
|
2731
|
-
*/
|
|
2732
1976
|
function titleId(id) {
|
|
2733
|
-
return idGenerator(id,
|
|
2734
|
-
}
|
|
2735
|
-
/** Return a list of element ids that contain additional information about the field that can be used to as the aria
|
|
2736
|
-
* description of the field. This is correctly omitting `titleId` which would be "labeling" rather than "describing" the
|
|
2737
|
-
* element.
|
|
2738
|
-
*
|
|
2739
|
-
* @param id - Either simple string id or an IdSchema from which to extract it
|
|
2740
|
-
* @param [includeExamples=false] - Optional flag, if true, will add the `examplesId` into the list
|
|
2741
|
-
* @returns - The string containing the list of ids for use in an `aria-describedBy` attribute
|
|
2742
|
-
*/
|
|
1977
|
+
return idGenerator(id, "title");
|
|
1978
|
+
}
|
|
2743
1979
|
function ariaDescribedByIds(id, includeExamples = false) {
|
|
2744
|
-
const examples = includeExamples ? ` ${examplesId(id)}` :
|
|
1980
|
+
const examples = includeExamples ? ` ${examplesId(id)}` : "";
|
|
2745
1981
|
return `${errorId(id)} ${descriptionId(id)} ${helpId(id)}${examples}`;
|
|
2746
1982
|
}
|
|
2747
|
-
/** Return a consistent `id` for the `optionIndex`s of a `Radio` or `Checkboxes` widget
|
|
2748
|
-
*
|
|
2749
|
-
* @param id - The id of the parent component for the option
|
|
2750
|
-
* @param optionIndex - The index of the option for which the id is desired
|
|
2751
|
-
* @returns - An id for the option index based on the parent `id`
|
|
2752
|
-
*/
|
|
2753
1983
|
function optionId(id, optionIndex) {
|
|
2754
1984
|
return `${id}-${optionIndex}`;
|
|
2755
1985
|
}
|
|
2756
1986
|
|
|
1987
|
+
// src/labelValue.ts
|
|
2757
1988
|
function labelValue(label, hideLabel, fallback) {
|
|
2758
1989
|
return hideLabel ? fallback : label;
|
|
2759
1990
|
}
|
|
2760
1991
|
|
|
2761
|
-
|
|
2762
|
-
*
|
|
2763
|
-
* @param dateString - The string representation of a date as accepted by the `Date()` constructor
|
|
2764
|
-
* @returns - A UTC date string if `dateString` is truthy, otherwise undefined
|
|
2765
|
-
*/
|
|
1992
|
+
// src/localToUTC.ts
|
|
2766
1993
|
function localToUTC(dateString) {
|
|
2767
|
-
return dateString ? new Date(dateString).toJSON() :
|
|
1994
|
+
return dateString ? new Date(dateString).toJSON() : void 0;
|
|
2768
1995
|
}
|
|
2769
1996
|
|
|
2770
|
-
|
|
2771
|
-
* throws an error.
|
|
2772
|
-
*
|
|
2773
|
-
* @param schema - The schema from which to obtain the constant value
|
|
2774
|
-
* @returns - The constant value for the schema
|
|
2775
|
-
* @throws - Error when the schema does not have a constant value
|
|
2776
|
-
*/
|
|
1997
|
+
// src/toConstant.ts
|
|
2777
1998
|
function toConstant(schema) {
|
|
2778
1999
|
if (ENUM_KEY in schema && Array.isArray(schema.enum) && schema.enum.length === 1) {
|
|
2779
2000
|
return schema.enum[0];
|
|
@@ -2781,35 +2002,23 @@ function toConstant(schema) {
|
|
|
2781
2002
|
if (CONST_KEY in schema) {
|
|
2782
2003
|
return schema.const;
|
|
2783
2004
|
}
|
|
2784
|
-
throw new Error(
|
|
2005
|
+
throw new Error("schema cannot be inferred as a constant");
|
|
2785
2006
|
}
|
|
2786
2007
|
|
|
2787
|
-
|
|
2788
|
-
* labels for the options will be extracted from the non-standard, RJSF-deprecated `enumNames` if it exists, otherwise
|
|
2789
|
-
* the label will be the same as the `value`. If the schema has a `oneOf` or `anyOf`, then the value is the list of
|
|
2790
|
-
* `const` values from the schema and the label is either the `schema.title` or the value.
|
|
2791
|
-
*
|
|
2792
|
-
* @param schema - The schema from which to extract the options list
|
|
2793
|
-
* @returns - The list of options from the schema
|
|
2794
|
-
*/
|
|
2008
|
+
// src/optionsList.ts
|
|
2795
2009
|
function optionsList(schema) {
|
|
2796
|
-
// enumNames was deprecated in v5 and is intentionally omitted from the RJSFSchema type.
|
|
2797
|
-
// Cast the type to include enumNames so the feature still works.
|
|
2798
2010
|
const schemaWithEnumNames = schema;
|
|
2799
|
-
if (schemaWithEnumNames.enumNames &&
|
|
2800
|
-
console.warn(
|
|
2011
|
+
if (schemaWithEnumNames.enumNames && true) {
|
|
2012
|
+
console.warn("The enumNames property is deprecated and may be removed in a future major release.");
|
|
2801
2013
|
}
|
|
2802
2014
|
if (schema.enum) {
|
|
2803
2015
|
return schema.enum.map((value, i) => {
|
|
2804
2016
|
const label = schemaWithEnumNames.enumNames && schemaWithEnumNames.enumNames[i] || String(value);
|
|
2805
|
-
return {
|
|
2806
|
-
label,
|
|
2807
|
-
value
|
|
2808
|
-
};
|
|
2017
|
+
return { label, value };
|
|
2809
2018
|
});
|
|
2810
2019
|
}
|
|
2811
2020
|
const altSchemas = schema.oneOf || schema.anyOf;
|
|
2812
|
-
return altSchemas && altSchemas.map(aSchemaDef => {
|
|
2021
|
+
return altSchemas && altSchemas.map((aSchemaDef) => {
|
|
2813
2022
|
const aSchema = aSchemaDef;
|
|
2814
2023
|
const value = toConstant(aSchema);
|
|
2815
2024
|
const label = aSchema.title || String(value);
|
|
@@ -2821,65 +2030,45 @@ function optionsList(schema) {
|
|
|
2821
2030
|
});
|
|
2822
2031
|
}
|
|
2823
2032
|
|
|
2824
|
-
|
|
2825
|
-
* If `order` is not an array, then the untouched `properties` list is returned. Otherwise `properties` is ordered per
|
|
2826
|
-
* the `order` list. If `order` contains a '*' then any `properties` that are not mentioned explicity in `order` will be
|
|
2827
|
-
* places in the location of the `*`.
|
|
2828
|
-
*
|
|
2829
|
-
* @param properties - The list of property keys to be ordered
|
|
2830
|
-
* @param order - An array of property keys to be ordered first, with an optional '*' property
|
|
2831
|
-
* @returns - A list with the `properties` ordered
|
|
2832
|
-
* @throws - Error when the properties cannot be ordered correctly
|
|
2833
|
-
*/
|
|
2033
|
+
// src/orderProperties.ts
|
|
2834
2034
|
function orderProperties(properties, order) {
|
|
2835
2035
|
if (!Array.isArray(order)) {
|
|
2836
2036
|
return properties;
|
|
2837
2037
|
}
|
|
2838
|
-
const arrayToHash = arr => arr.reduce((prev, curr) => {
|
|
2038
|
+
const arrayToHash = (arr) => arr.reduce((prev, curr) => {
|
|
2839
2039
|
prev[curr] = true;
|
|
2840
2040
|
return prev;
|
|
2841
2041
|
}, {});
|
|
2842
|
-
const errorPropList = arr => arr.length > 1 ? `properties '${arr.join("', '")}'` : `property '${arr[0]}'`;
|
|
2042
|
+
const errorPropList = (arr) => arr.length > 1 ? `properties '${arr.join("', '")}'` : `property '${arr[0]}'`;
|
|
2843
2043
|
const propertyHash = arrayToHash(properties);
|
|
2844
|
-
const orderFiltered = order.filter(prop => prop ===
|
|
2044
|
+
const orderFiltered = order.filter((prop) => prop === "*" || propertyHash[prop]);
|
|
2845
2045
|
const orderHash = arrayToHash(orderFiltered);
|
|
2846
|
-
const rest = properties.filter(prop => !orderHash[prop]);
|
|
2847
|
-
const restIndex = orderFiltered.indexOf(
|
|
2046
|
+
const rest = properties.filter((prop) => !orderHash[prop]);
|
|
2047
|
+
const restIndex = orderFiltered.indexOf("*");
|
|
2848
2048
|
if (restIndex === -1) {
|
|
2849
2049
|
if (rest.length) {
|
|
2850
2050
|
throw new Error(`uiSchema order list does not contain ${errorPropList(rest)}`);
|
|
2851
2051
|
}
|
|
2852
2052
|
return orderFiltered;
|
|
2853
2053
|
}
|
|
2854
|
-
if (restIndex !== orderFiltered.lastIndexOf(
|
|
2855
|
-
throw new Error(
|
|
2054
|
+
if (restIndex !== orderFiltered.lastIndexOf("*")) {
|
|
2055
|
+
throw new Error("uiSchema order list contains more than one wildcard item");
|
|
2856
2056
|
}
|
|
2857
2057
|
const complete = [...orderFiltered];
|
|
2858
2058
|
complete.splice(restIndex, 1, ...rest);
|
|
2859
2059
|
return complete;
|
|
2860
2060
|
}
|
|
2861
2061
|
|
|
2862
|
-
|
|
2863
|
-
*
|
|
2864
|
-
* @param num - The number to pad
|
|
2865
|
-
* @param width - The width of the string at which no lead padding is necessary
|
|
2866
|
-
* @returns - The number converted to a string with leading zero padding if the number of digits is less than `width`
|
|
2867
|
-
*/
|
|
2062
|
+
// src/pad.ts
|
|
2868
2063
|
function pad(num, width) {
|
|
2869
2064
|
let s = String(num);
|
|
2870
2065
|
while (s.length < width) {
|
|
2871
|
-
s =
|
|
2066
|
+
s = "0" + s;
|
|
2872
2067
|
}
|
|
2873
2068
|
return s;
|
|
2874
2069
|
}
|
|
2875
2070
|
|
|
2876
|
-
|
|
2877
|
-
*
|
|
2878
|
-
* @param dateString - The date string to parse into a DateObject
|
|
2879
|
-
* @param [includeTime=true] - Optional flag, if false, will not include the time data into the object
|
|
2880
|
-
* @returns - The date string converted to a `DateObject`
|
|
2881
|
-
* @throws - Error when the date cannot be parsed from the string
|
|
2882
|
-
*/
|
|
2071
|
+
// src/parseDateString.ts
|
|
2883
2072
|
function parseDateString(dateString, includeTime = true) {
|
|
2884
2073
|
if (!dateString) {
|
|
2885
2074
|
return {
|
|
@@ -2893,11 +2082,12 @@ function parseDateString(dateString, includeTime = true) {
|
|
|
2893
2082
|
}
|
|
2894
2083
|
const date = new Date(dateString);
|
|
2895
2084
|
if (Number.isNaN(date.getTime())) {
|
|
2896
|
-
throw new Error(
|
|
2085
|
+
throw new Error("Unable to parse date " + dateString);
|
|
2897
2086
|
}
|
|
2898
2087
|
return {
|
|
2899
2088
|
year: date.getUTCFullYear(),
|
|
2900
2089
|
month: date.getUTCMonth() + 1,
|
|
2090
|
+
// oh you, javascript.
|
|
2901
2091
|
day: date.getUTCDate(),
|
|
2902
2092
|
hour: includeTime ? date.getUTCHours() : 0,
|
|
2903
2093
|
minute: includeTime ? date.getUTCMinutes() : 0,
|
|
@@ -2905,102 +2095,64 @@ function parseDateString(dateString, includeTime = true) {
|
|
|
2905
2095
|
};
|
|
2906
2096
|
}
|
|
2907
2097
|
|
|
2908
|
-
|
|
2909
|
-
* - `schema.const` is truthy
|
|
2910
|
-
* - `schema.enum` == `[true]`
|
|
2911
|
-
* - `schema.anyOf` or `schema.oneOf` has a single value which recursively returns true
|
|
2912
|
-
* - `schema.allOf` has at least one value which recursively returns true
|
|
2913
|
-
*
|
|
2914
|
-
* @param schema - The schema to check
|
|
2915
|
-
* @returns - True if the schema specifies a value that must be true, false otherwise
|
|
2916
|
-
*/
|
|
2098
|
+
// src/schemaRequiresTrueValue.ts
|
|
2917
2099
|
function schemaRequiresTrueValue(schema) {
|
|
2918
|
-
// Check if const is a truthy value
|
|
2919
2100
|
if (schema.const) {
|
|
2920
2101
|
return true;
|
|
2921
2102
|
}
|
|
2922
|
-
// Check if an enum has a single value of true
|
|
2923
2103
|
if (schema.enum && schema.enum.length === 1 && schema.enum[0] === true) {
|
|
2924
2104
|
return true;
|
|
2925
2105
|
}
|
|
2926
|
-
// If anyOf has a single value, evaluate the subschema
|
|
2927
2106
|
if (schema.anyOf && schema.anyOf.length === 1) {
|
|
2928
2107
|
return schemaRequiresTrueValue(schema.anyOf[0]);
|
|
2929
2108
|
}
|
|
2930
|
-
// If oneOf has a single value, evaluate the subschema
|
|
2931
2109
|
if (schema.oneOf && schema.oneOf.length === 1) {
|
|
2932
2110
|
return schemaRequiresTrueValue(schema.oneOf[0]);
|
|
2933
2111
|
}
|
|
2934
|
-
// Evaluate each subschema in allOf, to see if one of them requires a true value
|
|
2935
2112
|
if (schema.allOf) {
|
|
2936
|
-
const schemaSome = subSchema => schemaRequiresTrueValue(subSchema);
|
|
2113
|
+
const schemaSome = (subSchema) => schemaRequiresTrueValue(subSchema);
|
|
2937
2114
|
return schema.allOf.some(schemaSome);
|
|
2938
2115
|
}
|
|
2939
2116
|
return false;
|
|
2940
2117
|
}
|
|
2941
2118
|
|
|
2942
|
-
|
|
2943
|
-
* against the next set. If either of those two sets are not the same, then the component should be rerendered.
|
|
2944
|
-
*
|
|
2945
|
-
* @param component - A React component being checked
|
|
2946
|
-
* @param nextProps - The next set of props against which to check
|
|
2947
|
-
* @param nextState - The next set of state against which to check
|
|
2948
|
-
* @returns - True if the component should be re-rendered, false otherwise
|
|
2949
|
-
*/
|
|
2119
|
+
// src/shouldRender.ts
|
|
2950
2120
|
function shouldRender(component, nextProps, nextState) {
|
|
2951
|
-
const {
|
|
2952
|
-
props,
|
|
2953
|
-
state
|
|
2954
|
-
} = component;
|
|
2121
|
+
const { props, state } = component;
|
|
2955
2122
|
return !deepEquals(props, nextProps) || !deepEquals(state, nextState);
|
|
2956
2123
|
}
|
|
2957
2124
|
|
|
2958
|
-
|
|
2959
|
-
* removed.
|
|
2960
|
-
*
|
|
2961
|
-
* @param dateObject - The `DateObject` to convert to a date string
|
|
2962
|
-
* @param [time=true] - Optional flag used to remove the time portion of the date string if false
|
|
2963
|
-
* @returns - The UTC date string
|
|
2964
|
-
*/
|
|
2125
|
+
// src/toDateString.ts
|
|
2965
2126
|
function toDateString(dateObject, time = true) {
|
|
2966
|
-
const {
|
|
2967
|
-
year,
|
|
2968
|
-
month,
|
|
2969
|
-
day,
|
|
2970
|
-
hour = 0,
|
|
2971
|
-
minute = 0,
|
|
2972
|
-
second = 0
|
|
2973
|
-
} = dateObject;
|
|
2127
|
+
const { year, month, day, hour = 0, minute = 0, second = 0 } = dateObject;
|
|
2974
2128
|
const utcTime = Date.UTC(year, month - 1, day, hour, minute, second);
|
|
2975
2129
|
const datetime = new Date(utcTime).toJSON();
|
|
2976
2130
|
return time ? datetime : datetime.slice(0, 10);
|
|
2977
2131
|
}
|
|
2978
2132
|
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
* @param errorSchema - The `ErrorSchema` instance to convert
|
|
2982
|
-
* @param [fieldPath=[]] - The current field path, defaults to [] if not specified
|
|
2983
|
-
* @returns - The list of `RJSFValidationErrors` extracted from the `errorSchema`
|
|
2984
|
-
*/
|
|
2133
|
+
// src/toErrorList.ts
|
|
2134
|
+
import isPlainObject2 from "lodash/isPlainObject";
|
|
2985
2135
|
function toErrorList(errorSchema, fieldPath = []) {
|
|
2986
2136
|
if (!errorSchema) {
|
|
2987
2137
|
return [];
|
|
2988
2138
|
}
|
|
2989
2139
|
let errorList = [];
|
|
2990
2140
|
if (ERRORS_KEY in errorSchema) {
|
|
2991
|
-
errorList = errorList.concat(
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2141
|
+
errorList = errorList.concat(
|
|
2142
|
+
errorSchema[ERRORS_KEY].map((message) => {
|
|
2143
|
+
const property = `.${fieldPath.join(".")}`;
|
|
2144
|
+
return {
|
|
2145
|
+
property,
|
|
2146
|
+
message,
|
|
2147
|
+
stack: `${property} ${message}`
|
|
2148
|
+
};
|
|
2149
|
+
})
|
|
2150
|
+
);
|
|
2999
2151
|
}
|
|
3000
2152
|
return Object.keys(errorSchema).reduce((acc, key) => {
|
|
3001
2153
|
if (key !== ERRORS_KEY) {
|
|
3002
2154
|
const childSchema = errorSchema[key];
|
|
3003
|
-
if (
|
|
2155
|
+
if (isPlainObject2(childSchema)) {
|
|
3004
2156
|
acc = acc.concat(toErrorList(childSchema, [...fieldPath, key]));
|
|
3005
2157
|
}
|
|
3006
2158
|
}
|
|
@@ -3008,38 +2160,15 @@ function toErrorList(errorSchema, fieldPath = []) {
|
|
|
3008
2160
|
}, errorList);
|
|
3009
2161
|
}
|
|
3010
2162
|
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
* {property: '.level1.level2[2].level3', message: 'err a'},
|
|
3014
|
-
* {property: '.level1.level2[2].level3', message: 'err b'},
|
|
3015
|
-
* {property: '.level1.level2[4].level3', message: 'err b'},
|
|
3016
|
-
* ]
|
|
3017
|
-
* Into an error tree:
|
|
3018
|
-
* {
|
|
3019
|
-
* level1: {
|
|
3020
|
-
* level2: {
|
|
3021
|
-
* 2: {level3: {errors: ['err a', 'err b']}},
|
|
3022
|
-
* 4: {level3: {errors: ['err b']}},
|
|
3023
|
-
* }
|
|
3024
|
-
* }
|
|
3025
|
-
* };
|
|
3026
|
-
*
|
|
3027
|
-
* @param errors - The list of RJSFValidationError objects
|
|
3028
|
-
* @returns - The `ErrorSchema` built from the list of `RJSFValidationErrors`
|
|
3029
|
-
*/
|
|
2163
|
+
// src/toErrorSchema.ts
|
|
2164
|
+
import toPath from "lodash/toPath";
|
|
3030
2165
|
function toErrorSchema(errors) {
|
|
3031
2166
|
const builder = new ErrorSchemaBuilder();
|
|
3032
2167
|
if (errors.length) {
|
|
3033
|
-
errors.forEach(error => {
|
|
3034
|
-
const {
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
} = error;
|
|
3038
|
-
// When the property is the root element, just use an empty array for the path
|
|
3039
|
-
const path = property === '.' ? [] : toPath(property);
|
|
3040
|
-
// If the property is at the root (.level1) then toPath creates
|
|
3041
|
-
// an empty array element at the first index. Remove it.
|
|
3042
|
-
if (path.length > 0 && path[0] === '') {
|
|
2168
|
+
errors.forEach((error) => {
|
|
2169
|
+
const { property, message } = error;
|
|
2170
|
+
const path = property === "." ? [] : toPath(property);
|
|
2171
|
+
if (path.length > 0 && path[0] === "") {
|
|
3043
2172
|
path.splice(0, 1);
|
|
3044
2173
|
}
|
|
3045
2174
|
if (message) {
|
|
@@ -3050,45 +2179,30 @@ function toErrorSchema(errors) {
|
|
|
3050
2179
|
return builder.ErrorSchema;
|
|
3051
2180
|
}
|
|
3052
2181
|
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
* @param errorHandler - The `FormValidation` error handling structure
|
|
3056
|
-
* @returns - The `ErrorSchema` resulting from the stripping of the `addError()` function
|
|
3057
|
-
*/
|
|
2182
|
+
// src/unwrapErrorHandler.ts
|
|
2183
|
+
import isPlainObject3 from "lodash/isPlainObject";
|
|
3058
2184
|
function unwrapErrorHandler(errorHandler) {
|
|
3059
2185
|
return Object.keys(errorHandler).reduce((acc, key) => {
|
|
3060
|
-
if (key ===
|
|
2186
|
+
if (key === "addError") {
|
|
3061
2187
|
return acc;
|
|
3062
2188
|
} else {
|
|
3063
2189
|
const childSchema = errorHandler[key];
|
|
3064
|
-
if (
|
|
2190
|
+
if (isPlainObject3(childSchema)) {
|
|
3065
2191
|
return {
|
|
3066
2192
|
...acc,
|
|
3067
2193
|
[key]: unwrapErrorHandler(childSchema)
|
|
3068
2194
|
};
|
|
3069
2195
|
}
|
|
3070
|
-
return {
|
|
3071
|
-
...acc,
|
|
3072
|
-
[key]: childSchema
|
|
3073
|
-
};
|
|
2196
|
+
return { ...acc, [key]: childSchema };
|
|
3074
2197
|
}
|
|
3075
2198
|
}, {});
|
|
3076
2199
|
}
|
|
3077
2200
|
|
|
3078
|
-
|
|
3079
|
-
*
|
|
3080
|
-
* @param jsonDate - A UTC date string
|
|
3081
|
-
* @returns - An empty string when `jsonDate` is falsey, otherwise a date string in local format
|
|
3082
|
-
*/
|
|
2201
|
+
// src/utcToLocal.ts
|
|
3083
2202
|
function utcToLocal(jsonDate) {
|
|
3084
2203
|
if (!jsonDate) {
|
|
3085
|
-
return
|
|
2204
|
+
return "";
|
|
3086
2205
|
}
|
|
3087
|
-
// required format of `'yyyy-MM-ddThh:mm' followed by optional ':ss' or ':ss.SSS'
|
|
3088
|
-
// https://html.spec.whatwg.org/multipage/input.html#local-date-and-time-state-(type%3Ddatetime-local)
|
|
3089
|
-
// > should be a _valid local date and time string_ (not GMT)
|
|
3090
|
-
// Note - date constructor passed local ISO-8601 does not correctly
|
|
3091
|
-
// change time to UTC in node pre-8
|
|
3092
2206
|
const date = new Date(jsonDate);
|
|
3093
2207
|
const yyyy = pad(date.getFullYear(), 4);
|
|
3094
2208
|
const MM = pad(date.getMonth() + 1, 2);
|
|
@@ -3100,45 +2214,29 @@ function utcToLocal(jsonDate) {
|
|
|
3100
2214
|
return `${yyyy}-${MM}-${dd}T${hh}:${mm}:${ss}.${SSS}`;
|
|
3101
2215
|
}
|
|
3102
2216
|
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
* `toErrorList()` on the `errors` in the `validationData`. If no `additionalErrorSchema` is passed, then
|
|
3106
|
-
* `validationData` is returned.
|
|
3107
|
-
*
|
|
3108
|
-
* @param validationData - The current `ValidationData` into which to merge the additional errors
|
|
3109
|
-
* @param [additionalErrorSchema] - The optional additional set of errors in an `ErrorSchema`
|
|
3110
|
-
* @returns - The `validationData` with the additional errors from `additionalErrorSchema` merged into it, if provided.
|
|
3111
|
-
*/
|
|
2217
|
+
// src/validationDataMerge.ts
|
|
2218
|
+
import isEmpty3 from "lodash/isEmpty";
|
|
3112
2219
|
function validationDataMerge(validationData, additionalErrorSchema) {
|
|
3113
2220
|
if (!additionalErrorSchema) {
|
|
3114
2221
|
return validationData;
|
|
3115
2222
|
}
|
|
3116
|
-
const {
|
|
3117
|
-
errors: oldErrors,
|
|
3118
|
-
errorSchema: oldErrorSchema
|
|
3119
|
-
} = validationData;
|
|
2223
|
+
const { errors: oldErrors, errorSchema: oldErrorSchema } = validationData;
|
|
3120
2224
|
let errors = toErrorList(additionalErrorSchema);
|
|
3121
2225
|
let errorSchema = additionalErrorSchema;
|
|
3122
|
-
if (!
|
|
2226
|
+
if (!isEmpty3(oldErrorSchema)) {
|
|
3123
2227
|
errorSchema = mergeObjects(oldErrorSchema, additionalErrorSchema, true);
|
|
3124
2228
|
errors = [...oldErrors].concat(errors);
|
|
3125
2229
|
}
|
|
3126
|
-
return {
|
|
3127
|
-
errorSchema,
|
|
3128
|
-
errors
|
|
3129
|
-
};
|
|
2230
|
+
return { errorSchema, errors };
|
|
3130
2231
|
}
|
|
3131
2232
|
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
*
|
|
3135
|
-
* @param node - The object node to which a ROOT_SCHEMA_PREFIX is added when a REF_KEY is part of it
|
|
3136
|
-
*/
|
|
2233
|
+
// src/withIdRefPrefix.ts
|
|
2234
|
+
import isObject3 from "lodash/isObject";
|
|
3137
2235
|
function withIdRefPrefixObject(node) {
|
|
3138
2236
|
for (const key in node) {
|
|
3139
2237
|
const realObj = node;
|
|
3140
2238
|
const value = realObj[key];
|
|
3141
|
-
if (key === REF_KEY && typeof value ===
|
|
2239
|
+
if (key === REF_KEY && typeof value === "string" && value.startsWith("#")) {
|
|
3142
2240
|
realObj[key] = ROOT_SCHEMA_PREFIX + value;
|
|
3143
2241
|
} else {
|
|
3144
2242
|
realObj[key] = withIdRefPrefix(value);
|
|
@@ -3146,246 +2244,271 @@ function withIdRefPrefixObject(node) {
|
|
|
3146
2244
|
}
|
|
3147
2245
|
return node;
|
|
3148
2246
|
}
|
|
3149
|
-
/** Takes a `node` object list and transforms any contained `$ref` node variables with a prefix, recursively calling
|
|
3150
|
-
* `withIdRefPrefix` for any other elements.
|
|
3151
|
-
*
|
|
3152
|
-
* @param node - The list of object nodes to which a ROOT_SCHEMA_PREFIX is added when a REF_KEY is part of it
|
|
3153
|
-
*/
|
|
3154
2247
|
function withIdRefPrefixArray(node) {
|
|
3155
2248
|
for (let i = 0; i < node.length; i++) {
|
|
3156
2249
|
node[i] = withIdRefPrefix(node[i]);
|
|
3157
2250
|
}
|
|
3158
2251
|
return node;
|
|
3159
2252
|
}
|
|
3160
|
-
/** Recursively prefixes all `$ref`s in a schema with the value of the `ROOT_SCHEMA_PREFIX` constant.
|
|
3161
|
-
* This is used in isValid to make references to the rootSchema
|
|
3162
|
-
*
|
|
3163
|
-
* @param schemaNode - The object node to which a ROOT_SCHEMA_PREFIX is added when a REF_KEY is part of it
|
|
3164
|
-
* @returns - A copy of the `schemaNode` with updated `$ref`s
|
|
3165
|
-
*/
|
|
3166
2253
|
function withIdRefPrefix(schemaNode) {
|
|
3167
2254
|
if (Array.isArray(schemaNode)) {
|
|
3168
2255
|
return withIdRefPrefixArray([...schemaNode]);
|
|
3169
2256
|
}
|
|
3170
|
-
if (
|
|
3171
|
-
return withIdRefPrefixObject({
|
|
3172
|
-
...schemaNode
|
|
3173
|
-
});
|
|
2257
|
+
if (isObject3(schemaNode)) {
|
|
2258
|
+
return withIdRefPrefixObject({ ...schemaNode });
|
|
3174
2259
|
}
|
|
3175
2260
|
return schemaNode;
|
|
3176
2261
|
}
|
|
3177
2262
|
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
/**
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
// Strings with replaceable parameters
|
|
3225
|
-
/** Unknown field type reason, where %1 will be replaced with the type as provided by SchemaField */
|
|
3226
|
-
TranslatableString["UnknownFieldType"] = "Unknown field type %1";
|
|
3227
|
-
/** Option prefix, where %1 will be replaced with the option index as provided by MultiSchemaField */
|
|
3228
|
-
TranslatableString["OptionPrefix"] = "Option %1";
|
|
3229
|
-
/** Option prefix, where %1 and %2 will be replaced by the schema title and option index, respectively as provided by
|
|
3230
|
-
* MultiSchemaField
|
|
3231
|
-
*/
|
|
3232
|
-
TranslatableString["TitleOptionPrefix"] = "%1 option %2";
|
|
3233
|
-
/** Key label, where %1 will be replaced by the label as provided by WrapIfAdditionalTemplate */
|
|
3234
|
-
TranslatableString["KeyLabel"] = "%1 Key";
|
|
3235
|
-
// Strings with replaceable parameters AND/OR that support markdown and html
|
|
3236
|
-
/** Invalid object field configuration as provided by the ObjectField */
|
|
3237
|
-
TranslatableString["InvalidObjectField"] = "Invalid \"%1\" object field configuration: <em>%2</em>.";
|
|
3238
|
-
/** Unsupported field schema, used by UnsupportedField */
|
|
3239
|
-
TranslatableString["UnsupportedField"] = "Unsupported field schema.";
|
|
3240
|
-
/** Unsupported field schema, where %1 will be replaced by the idSchema.$id as provided by UnsupportedField */
|
|
3241
|
-
TranslatableString["UnsupportedFieldWithId"] = "Unsupported field schema for field <code>%1</code>.";
|
|
3242
|
-
/** Unsupported field schema, where %1 will be replaced by the reason string as provided by UnsupportedField */
|
|
3243
|
-
TranslatableString["UnsupportedFieldWithReason"] = "Unsupported field schema: <em>%1</em>.";
|
|
3244
|
-
/** Unsupported field schema, where %1 and %2 will be replaced by the idSchema.$id and reason strings, respectively,
|
|
3245
|
-
* as provided by UnsupportedField
|
|
3246
|
-
*/
|
|
3247
|
-
TranslatableString["UnsupportedFieldWithIdAndReason"] = "Unsupported field schema for field <code>%1</code>: <em>%2</em>.";
|
|
3248
|
-
/** File name, type and size info, where %1, %2 and %3 will be replaced by the file name, file type and file size as
|
|
3249
|
-
* provided by FileWidget
|
|
3250
|
-
*/
|
|
3251
|
-
TranslatableString["FilesInfo"] = "<strong>%1</strong> (%2, %3 bytes)";
|
|
3252
|
-
})(TranslatableString || (TranslatableString = {}));
|
|
3253
|
-
|
|
3254
|
-
/** An implementation of the `ValidatorType` interface that is designed for use in capturing schemas used by the
|
|
3255
|
-
* `isValid()` function. The rest of the implementation of the interface throws errors when it is attempted to be used.
|
|
3256
|
-
* An instance of the object allows the caller to capture the schemas used in calls to the `isValid()` function. These
|
|
3257
|
-
* captured schema, along with the root schema used to construct the object are stored in the map of schemas keyed by
|
|
3258
|
-
* the hashed value of the schema. NOTE: After hashing the schema, an $id with the hash value is added to the
|
|
3259
|
-
* schema IF that schema doesn't already have an $id, prior to putting the schema into the map.
|
|
3260
|
-
*/
|
|
3261
|
-
class ParserValidator {
|
|
3262
|
-
/** Construct the ParserValidator for the given `rootSchema`. This `rootSchema` will be stashed in the `schemaMap`
|
|
3263
|
-
* first.
|
|
3264
|
-
*
|
|
3265
|
-
* @param rootSchema - The root schema against which this validator will be executed
|
|
2263
|
+
// src/enums.ts
|
|
2264
|
+
var TranslatableString = /* @__PURE__ */ ((TranslatableString2) => {
|
|
2265
|
+
TranslatableString2["ArrayItemTitle"] = "Item";
|
|
2266
|
+
TranslatableString2["MissingItems"] = "Missing items definition";
|
|
2267
|
+
TranslatableString2["YesLabel"] = "Yes";
|
|
2268
|
+
TranslatableString2["NoLabel"] = "No";
|
|
2269
|
+
TranslatableString2["CloseLabel"] = "Close";
|
|
2270
|
+
TranslatableString2["ErrorsLabel"] = "Errors";
|
|
2271
|
+
TranslatableString2["NewStringDefault"] = "New Value";
|
|
2272
|
+
TranslatableString2["AddButton"] = "Add";
|
|
2273
|
+
TranslatableString2["AddItemButton"] = "Add Item";
|
|
2274
|
+
TranslatableString2["CopyButton"] = "Copy";
|
|
2275
|
+
TranslatableString2["MoveDownButton"] = "Move down";
|
|
2276
|
+
TranslatableString2["MoveUpButton"] = "Move up";
|
|
2277
|
+
TranslatableString2["RemoveButton"] = "Remove";
|
|
2278
|
+
TranslatableString2["NowLabel"] = "Now";
|
|
2279
|
+
TranslatableString2["ClearLabel"] = "Clear";
|
|
2280
|
+
TranslatableString2["AriaDateLabel"] = "Select a date";
|
|
2281
|
+
TranslatableString2["PreviewLabel"] = "Preview";
|
|
2282
|
+
TranslatableString2["DecrementAriaLabel"] = "Decrease value by 1";
|
|
2283
|
+
TranslatableString2["IncrementAriaLabel"] = "Increase value by 1";
|
|
2284
|
+
TranslatableString2["UnknownFieldType"] = "Unknown field type %1";
|
|
2285
|
+
TranslatableString2["OptionPrefix"] = "Option %1";
|
|
2286
|
+
TranslatableString2["TitleOptionPrefix"] = "%1 option %2";
|
|
2287
|
+
TranslatableString2["KeyLabel"] = "%1 Key";
|
|
2288
|
+
TranslatableString2["InvalidObjectField"] = 'Invalid "%1" object field configuration: <em>%2</em>.';
|
|
2289
|
+
TranslatableString2["UnsupportedField"] = "Unsupported field schema.";
|
|
2290
|
+
TranslatableString2["UnsupportedFieldWithId"] = "Unsupported field schema for field <code>%1</code>.";
|
|
2291
|
+
TranslatableString2["UnsupportedFieldWithReason"] = "Unsupported field schema: <em>%1</em>.";
|
|
2292
|
+
TranslatableString2["UnsupportedFieldWithIdAndReason"] = "Unsupported field schema for field <code>%1</code>: <em>%2</em>.";
|
|
2293
|
+
TranslatableString2["FilesInfo"] = "<strong>%1</strong> (%2, %3 bytes)";
|
|
2294
|
+
return TranslatableString2;
|
|
2295
|
+
})(TranslatableString || {});
|
|
2296
|
+
|
|
2297
|
+
// src/parser/schemaParser.ts
|
|
2298
|
+
import forEach from "lodash/forEach";
|
|
2299
|
+
import isEqual6 from "lodash/isEqual";
|
|
2300
|
+
|
|
2301
|
+
// src/parser/ParserValidator.ts
|
|
2302
|
+
import get12 from "lodash/get";
|
|
2303
|
+
import isEqual5 from "lodash/isEqual";
|
|
2304
|
+
var ParserValidator = class {
|
|
2305
|
+
/** Construct the ParserValidator for the given `rootSchema`. This `rootSchema` will be stashed in the `schemaMap`
|
|
2306
|
+
* first.
|
|
2307
|
+
*
|
|
2308
|
+
* @param rootSchema - The root schema against which this validator will be executed
|
|
3266
2309
|
*/
|
|
3267
2310
|
constructor(rootSchema) {
|
|
3268
|
-
/** The rootSchema provided during construction of the class */
|
|
3269
|
-
this.rootSchema = void 0;
|
|
3270
2311
|
/** The map of schemas encountered by the ParserValidator */
|
|
3271
2312
|
this.schemaMap = {};
|
|
3272
2313
|
this.rootSchema = rootSchema;
|
|
3273
2314
|
this.addSchema(rootSchema, hashForSchema(rootSchema));
|
|
3274
2315
|
}
|
|
3275
|
-
/** Adds the given `schema` to the `schemaMap` keyed by the `hash` or `ID_KEY` if present on the `schema`. If the
|
|
3276
|
-
* schema does not have an `ID_KEY`, then the `hash` will be added as the `ID_KEY` to allow the schema to be
|
|
3277
|
-
* associated with it's `hash` for future use (by a schema compiler).
|
|
3278
|
-
*
|
|
3279
|
-
* @param schema - The schema which is to be added to the map
|
|
3280
|
-
* @param hash - The hash value at which to map the schema
|
|
2316
|
+
/** Adds the given `schema` to the `schemaMap` keyed by the `hash` or `ID_KEY` if present on the `schema`. If the
|
|
2317
|
+
* schema does not have an `ID_KEY`, then the `hash` will be added as the `ID_KEY` to allow the schema to be
|
|
2318
|
+
* associated with it's `hash` for future use (by a schema compiler).
|
|
2319
|
+
*
|
|
2320
|
+
* @param schema - The schema which is to be added to the map
|
|
2321
|
+
* @param hash - The hash value at which to map the schema
|
|
3281
2322
|
*/
|
|
3282
2323
|
addSchema(schema, hash) {
|
|
3283
|
-
const key =
|
|
3284
|
-
const identifiedSchema = {
|
|
3285
|
-
...schema,
|
|
3286
|
-
[ID_KEY]: key
|
|
3287
|
-
};
|
|
2324
|
+
const key = get12(schema, ID_KEY, hash);
|
|
2325
|
+
const identifiedSchema = { ...schema, [ID_KEY]: key };
|
|
3288
2326
|
const existing = this.schemaMap[key];
|
|
3289
2327
|
if (!existing) {
|
|
3290
2328
|
this.schemaMap[key] = identifiedSchema;
|
|
3291
|
-
} else if (!
|
|
3292
|
-
console.error(
|
|
3293
|
-
console.error(
|
|
3294
|
-
throw new Error(
|
|
2329
|
+
} else if (!isEqual5(existing, identifiedSchema)) {
|
|
2330
|
+
console.error("existing schema:", JSON.stringify(existing, null, 2));
|
|
2331
|
+
console.error("new schema:", JSON.stringify(identifiedSchema, null, 2));
|
|
2332
|
+
throw new Error(
|
|
2333
|
+
`Two different schemas exist with the same key ${key}! What a bad coincidence. If possible, try adding an $id to one of the schemas`
|
|
2334
|
+
);
|
|
3295
2335
|
}
|
|
3296
2336
|
}
|
|
3297
|
-
/** Returns the current `schemaMap` to the caller
|
|
2337
|
+
/** Returns the current `schemaMap` to the caller
|
|
3298
2338
|
*/
|
|
3299
2339
|
getSchemaMap() {
|
|
3300
2340
|
return this.schemaMap;
|
|
3301
2341
|
}
|
|
3302
|
-
/** Implements the `ValidatorType` `isValid()` method to capture the `schema` in the `schemaMap`. Throws an error when
|
|
3303
|
-
* the `rootSchema` is not the same as the root schema provided during construction.
|
|
3304
|
-
*
|
|
3305
|
-
* @param schema - The schema to record in the `schemaMap`
|
|
3306
|
-
* @param _formData - The formData parameter that is ignored
|
|
3307
|
-
* @param rootSchema - The root schema associated with the schema
|
|
3308
|
-
* @throws - Error when the given `rootSchema` differs from the root schema provided during construction
|
|
2342
|
+
/** Implements the `ValidatorType` `isValid()` method to capture the `schema` in the `schemaMap`. Throws an error when
|
|
2343
|
+
* the `rootSchema` is not the same as the root schema provided during construction.
|
|
2344
|
+
*
|
|
2345
|
+
* @param schema - The schema to record in the `schemaMap`
|
|
2346
|
+
* @param _formData - The formData parameter that is ignored
|
|
2347
|
+
* @param rootSchema - The root schema associated with the schema
|
|
2348
|
+
* @throws - Error when the given `rootSchema` differs from the root schema provided during construction
|
|
3309
2349
|
*/
|
|
3310
2350
|
isValid(schema, _formData, rootSchema) {
|
|
3311
|
-
if (!
|
|
3312
|
-
throw new Error(
|
|
2351
|
+
if (!isEqual5(rootSchema, this.rootSchema)) {
|
|
2352
|
+
throw new Error("Unexpectedly calling isValid() with a rootSchema that differs from the construction rootSchema");
|
|
3313
2353
|
}
|
|
3314
2354
|
this.addSchema(schema, hashForSchema(schema));
|
|
3315
2355
|
return false;
|
|
3316
2356
|
}
|
|
3317
|
-
/** Implements the `ValidatorType` `rawValidation()` method to throw an error since it is never supposed to be called
|
|
3318
|
-
*
|
|
3319
|
-
* @param _schema - The schema parameter that is ignored
|
|
3320
|
-
* @param _formData - The formData parameter that is ignored
|
|
2357
|
+
/** Implements the `ValidatorType` `rawValidation()` method to throw an error since it is never supposed to be called
|
|
2358
|
+
*
|
|
2359
|
+
* @param _schema - The schema parameter that is ignored
|
|
2360
|
+
* @param _formData - The formData parameter that is ignored
|
|
3321
2361
|
*/
|
|
3322
2362
|
rawValidation(_schema, _formData) {
|
|
3323
|
-
throw new Error(
|
|
2363
|
+
throw new Error("Unexpectedly calling the `rawValidation()` method during schema parsing");
|
|
3324
2364
|
}
|
|
3325
|
-
/** Implements the `ValidatorType` `toErrorList()` method to throw an error since it is never supposed to be called
|
|
3326
|
-
*
|
|
3327
|
-
* @param _errorSchema - The error schema parameter that is ignored
|
|
3328
|
-
* @param _fieldPath - The field path parameter that is ignored
|
|
2365
|
+
/** Implements the `ValidatorType` `toErrorList()` method to throw an error since it is never supposed to be called
|
|
2366
|
+
*
|
|
2367
|
+
* @param _errorSchema - The error schema parameter that is ignored
|
|
2368
|
+
* @param _fieldPath - The field path parameter that is ignored
|
|
3329
2369
|
*/
|
|
3330
2370
|
toErrorList(_errorSchema, _fieldPath) {
|
|
3331
|
-
throw new Error(
|
|
3332
|
-
}
|
|
3333
|
-
/** Implements the `ValidatorType` `validateFormData()` method to throw an error since it is never supposed to be
|
|
3334
|
-
* called
|
|
3335
|
-
*
|
|
3336
|
-
* @param _formData - The formData parameter that is ignored
|
|
3337
|
-
* @param _schema - The schema parameter that is ignored
|
|
3338
|
-
* @param _customValidate - The customValidate parameter that is ignored
|
|
3339
|
-
* @param _transformErrors - The transformErrors parameter that is ignored
|
|
3340
|
-
* @param _uiSchema - The uiSchema parameter that is ignored
|
|
2371
|
+
throw new Error("Unexpectedly calling the `toErrorList()` method during schema parsing");
|
|
2372
|
+
}
|
|
2373
|
+
/** Implements the `ValidatorType` `validateFormData()` method to throw an error since it is never supposed to be
|
|
2374
|
+
* called
|
|
2375
|
+
*
|
|
2376
|
+
* @param _formData - The formData parameter that is ignored
|
|
2377
|
+
* @param _schema - The schema parameter that is ignored
|
|
2378
|
+
* @param _customValidate - The customValidate parameter that is ignored
|
|
2379
|
+
* @param _transformErrors - The transformErrors parameter that is ignored
|
|
2380
|
+
* @param _uiSchema - The uiSchema parameter that is ignored
|
|
3341
2381
|
*/
|
|
3342
2382
|
validateFormData(_formData, _schema, _customValidate, _transformErrors, _uiSchema) {
|
|
3343
|
-
throw new Error(
|
|
2383
|
+
throw new Error("Unexpectedly calling the `validateFormData()` method during schema parsing");
|
|
3344
2384
|
}
|
|
3345
|
-
}
|
|
2385
|
+
};
|
|
3346
2386
|
|
|
3347
|
-
|
|
3348
|
-
* capture the sub-schemas that the `isValid()` function is called with. For each schema returned by the
|
|
3349
|
-
* `retrieveSchemaInternal()`, the `resolveAnyOrOneOfSchemas()` function is called. For each of the schemas returned
|
|
3350
|
-
* from THAT call have `properties`, then each of the sub-schema property objects are then recursively parsed.
|
|
3351
|
-
*
|
|
3352
|
-
* @param validator - The `ParserValidator` implementation used to capture `isValid()` calls during parsing
|
|
3353
|
-
* @param recurseList - The list of schemas returned from the `retrieveSchemaInternal`, preventing infinite recursion
|
|
3354
|
-
* @param rootSchema - The root schema from which the schema parsing began
|
|
3355
|
-
* @param schema - The current schema element being parsed
|
|
3356
|
-
*/
|
|
2387
|
+
// src/parser/schemaParser.ts
|
|
3357
2388
|
function parseSchema(validator, recurseList, rootSchema, schema) {
|
|
3358
|
-
const schemas = retrieveSchemaInternal(validator, schema, rootSchema,
|
|
3359
|
-
schemas.forEach(
|
|
3360
|
-
const sameSchemaIndex = recurseList.findIndex(item =>
|
|
2389
|
+
const schemas = retrieveSchemaInternal(validator, schema, rootSchema, void 0, true);
|
|
2390
|
+
schemas.forEach((schema2) => {
|
|
2391
|
+
const sameSchemaIndex = recurseList.findIndex((item) => isEqual6(item, schema2));
|
|
3361
2392
|
if (sameSchemaIndex === -1) {
|
|
3362
|
-
recurseList.push(
|
|
3363
|
-
const allOptions = resolveAnyOrOneOfSchemas(validator,
|
|
3364
|
-
allOptions.forEach(s => {
|
|
2393
|
+
recurseList.push(schema2);
|
|
2394
|
+
const allOptions = resolveAnyOrOneOfSchemas(validator, schema2, rootSchema, true);
|
|
2395
|
+
allOptions.forEach((s) => {
|
|
3365
2396
|
if (PROPERTIES_KEY in s && s[PROPERTIES_KEY]) {
|
|
3366
|
-
forEach(
|
|
2397
|
+
forEach(schema2[PROPERTIES_KEY], (value) => {
|
|
3367
2398
|
parseSchema(validator, recurseList, rootSchema, value);
|
|
3368
2399
|
});
|
|
3369
2400
|
}
|
|
3370
2401
|
});
|
|
3371
|
-
if (ITEMS_KEY in
|
|
3372
|
-
parseSchema(validator, recurseList, rootSchema,
|
|
2402
|
+
if (ITEMS_KEY in schema2 && !Array.isArray(schema2.items) && typeof schema2.items !== "boolean") {
|
|
2403
|
+
parseSchema(validator, recurseList, rootSchema, schema2.items);
|
|
3373
2404
|
}
|
|
3374
2405
|
}
|
|
3375
2406
|
});
|
|
3376
2407
|
}
|
|
3377
|
-
/** Parses the given `rootSchema` to extract out all the sub-schemas that maybe contained within it. Returns a map of
|
|
3378
|
-
* the hash of the schema to schema/sub-schema.
|
|
3379
|
-
*
|
|
3380
|
-
* @param rootSchema - The root schema to parse for sub-schemas used by `isValid()` calls
|
|
3381
|
-
* @returns - The `SchemaMap` of all schemas that were parsed
|
|
3382
|
-
*/
|
|
3383
2408
|
function schemaParser(rootSchema) {
|
|
3384
2409
|
const validator = new ParserValidator(rootSchema);
|
|
3385
2410
|
const recurseList = [];
|
|
3386
2411
|
parseSchema(validator, recurseList, rootSchema, rootSchema);
|
|
3387
2412
|
return validator.getSchemaMap();
|
|
3388
2413
|
}
|
|
3389
|
-
|
|
3390
|
-
|
|
2414
|
+
export {
|
|
2415
|
+
ADDITIONAL_PROPERTIES_KEY,
|
|
2416
|
+
ADDITIONAL_PROPERTY_FLAG,
|
|
2417
|
+
ALL_OF_KEY,
|
|
2418
|
+
ANY_OF_KEY,
|
|
2419
|
+
CONST_KEY,
|
|
2420
|
+
DEFAULT_KEY,
|
|
2421
|
+
DEFINITIONS_KEY,
|
|
2422
|
+
DEPENDENCIES_KEY,
|
|
2423
|
+
ENUM_KEY,
|
|
2424
|
+
ERRORS_KEY,
|
|
2425
|
+
ErrorSchemaBuilder,
|
|
2426
|
+
ID_KEY,
|
|
2427
|
+
IF_KEY,
|
|
2428
|
+
ITEMS_KEY,
|
|
2429
|
+
JUNK_OPTION_ID,
|
|
2430
|
+
NAME_KEY,
|
|
2431
|
+
ONE_OF_KEY,
|
|
2432
|
+
PROPERTIES_KEY,
|
|
2433
|
+
REF_KEY,
|
|
2434
|
+
REQUIRED_KEY,
|
|
2435
|
+
RJSF_ADDITONAL_PROPERTIES_FLAG,
|
|
2436
|
+
ROOT_SCHEMA_PREFIX,
|
|
2437
|
+
SUBMIT_BTN_OPTIONS_KEY,
|
|
2438
|
+
TranslatableString,
|
|
2439
|
+
UI_FIELD_KEY,
|
|
2440
|
+
UI_GLOBAL_OPTIONS_KEY,
|
|
2441
|
+
UI_OPTIONS_KEY,
|
|
2442
|
+
UI_WIDGET_KEY,
|
|
2443
|
+
allowAdditionalItems,
|
|
2444
|
+
ariaDescribedByIds,
|
|
2445
|
+
asNumber,
|
|
2446
|
+
canExpand,
|
|
2447
|
+
createErrorHandler,
|
|
2448
|
+
createSchemaUtils,
|
|
2449
|
+
dataURItoBlob,
|
|
2450
|
+
deepEquals,
|
|
2451
|
+
descriptionId,
|
|
2452
|
+
englishStringTranslator,
|
|
2453
|
+
enumOptionsDeselectValue,
|
|
2454
|
+
enumOptionsIndexForValue,
|
|
2455
|
+
enumOptionsIsSelected,
|
|
2456
|
+
enumOptionsSelectValue,
|
|
2457
|
+
enumOptionsValueForIndex,
|
|
2458
|
+
errorId,
|
|
2459
|
+
examplesId,
|
|
2460
|
+
findSchemaDefinition,
|
|
2461
|
+
getClosestMatchingOption,
|
|
2462
|
+
getDefaultFormState,
|
|
2463
|
+
getDiscriminatorFieldFromSchema,
|
|
2464
|
+
getDisplayLabel,
|
|
2465
|
+
getFirstMatchingOption,
|
|
2466
|
+
getInputProps,
|
|
2467
|
+
getMatchingOption,
|
|
2468
|
+
getSchemaType,
|
|
2469
|
+
getSubmitButtonOptions,
|
|
2470
|
+
getTemplate,
|
|
2471
|
+
getUiOptions,
|
|
2472
|
+
getWidget,
|
|
2473
|
+
guessType,
|
|
2474
|
+
hasWidget,
|
|
2475
|
+
hashForSchema,
|
|
2476
|
+
helpId,
|
|
2477
|
+
isConstant,
|
|
2478
|
+
isCustomWidget,
|
|
2479
|
+
isFilesArray,
|
|
2480
|
+
isFixedItems,
|
|
2481
|
+
isMultiSelect,
|
|
2482
|
+
isObject,
|
|
2483
|
+
isSelect,
|
|
2484
|
+
labelValue,
|
|
2485
|
+
localToUTC,
|
|
2486
|
+
mergeDefaultsWithFormData,
|
|
2487
|
+
mergeObjects,
|
|
2488
|
+
mergeSchemas,
|
|
2489
|
+
mergeValidationData,
|
|
2490
|
+
optionId,
|
|
2491
|
+
optionsList,
|
|
2492
|
+
orderProperties,
|
|
2493
|
+
pad,
|
|
2494
|
+
parseDateString,
|
|
2495
|
+
rangeSpec,
|
|
2496
|
+
replaceStringParameters,
|
|
2497
|
+
retrieveSchema,
|
|
2498
|
+
sanitizeDataForNewSchema,
|
|
2499
|
+
schemaParser,
|
|
2500
|
+
schemaRequiresTrueValue,
|
|
2501
|
+
shouldRender,
|
|
2502
|
+
titleId,
|
|
2503
|
+
toConstant,
|
|
2504
|
+
toDateString,
|
|
2505
|
+
toErrorList,
|
|
2506
|
+
toErrorSchema,
|
|
2507
|
+
toIdSchema,
|
|
2508
|
+
toPathSchema,
|
|
2509
|
+
unwrapErrorHandler,
|
|
2510
|
+
utcToLocal,
|
|
2511
|
+
validationDataMerge,
|
|
2512
|
+
withIdRefPrefix
|
|
2513
|
+
};
|
|
3391
2514
|
//# sourceMappingURL=utils.esm.js.map
|