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