@rjsf/utils 5.11.1 → 5.12.0

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