@rjsf/utils 5.11.2 → 5.12.0

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