@rjsf/utils 5.11.2 → 5.12.1

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