@rjsf/utils 5.11.1 → 5.12.0

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