@rjsf/utils 5.11.2 → 5.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (303) hide show
  1. package/dist/index.js +2544 -5
  2. package/dist/index.js.map +7 -0
  3. package/dist/utils.esm.js +1228 -2113
  4. package/dist/utils.esm.js.map +7 -1
  5. package/dist/utils.umd.js +2414 -0
  6. package/lib/ErrorSchemaBuilder.d.ts +60 -0
  7. package/lib/ErrorSchemaBuilder.js +103 -0
  8. package/lib/ErrorSchemaBuilder.js.map +1 -0
  9. package/lib/allowAdditionalItems.d.ts +8 -0
  10. package/lib/allowAdditionalItems.js +14 -0
  11. package/lib/allowAdditionalItems.js.map +1 -0
  12. package/lib/asNumber.d.ts +10 -0
  13. package/lib/asNumber.js +36 -0
  14. package/lib/asNumber.js.map +1 -0
  15. package/lib/canExpand.d.ts +11 -0
  16. package/lib/canExpand.js +26 -0
  17. package/lib/canExpand.js.map +1 -0
  18. package/lib/constants.d.ts +31 -0
  19. package/lib/constants.js +32 -0
  20. package/lib/constants.js.map +1 -0
  21. package/lib/createErrorHandler.d.ts +7 -0
  22. package/lib/createErrorHandler.js +31 -0
  23. package/lib/createErrorHandler.js.map +1 -0
  24. package/lib/createSchemaUtils.d.ts +10 -0
  25. package/lib/createSchemaUtils.js +207 -0
  26. package/lib/createSchemaUtils.js.map +1 -0
  27. package/lib/dataURItoBlob.d.ts +16 -0
  28. package/lib/dataURItoBlob.js +43 -0
  29. package/lib/dataURItoBlob.js.map +1 -0
  30. package/lib/deepEquals.d.ts +8 -0
  31. package/lib/deepEquals.js +19 -0
  32. package/lib/deepEquals.js.map +1 -0
  33. package/lib/englishStringTranslator.d.ts +10 -0
  34. package/lib/englishStringTranslator.js +13 -0
  35. package/lib/englishStringTranslator.js.map +1 -0
  36. package/lib/enumOptionsDeselectValue.d.ts +14 -0
  37. package/lib/enumOptionsDeselectValue.js +22 -0
  38. package/lib/enumOptionsDeselectValue.js.map +1 -0
  39. package/lib/enumOptionsIndexForValue.d.ts +13 -0
  40. package/lib/enumOptionsIndexForValue.js +22 -0
  41. package/lib/enumOptionsIndexForValue.js.map +1 -0
  42. package/lib/enumOptionsIsSelected.d.ts +8 -0
  43. package/lib/enumOptionsIsSelected.js +14 -0
  44. package/lib/enumOptionsIsSelected.js.map +1 -0
  45. package/lib/enumOptionsSelectValue.d.ts +10 -0
  46. package/lib/enumOptionsSelectValue.js +23 -0
  47. package/lib/enumOptionsSelectValue.js.map +1 -0
  48. package/lib/enumOptionsValueForIndex.d.ts +13 -0
  49. package/lib/enumOptionsValueForIndex.js +21 -0
  50. package/lib/enumOptionsValueForIndex.js.map +1 -0
  51. package/lib/enums.d.ts +72 -0
  52. package/lib/enums.js +76 -0
  53. package/lib/enums.js.map +1 -0
  54. package/lib/findSchemaDefinition.d.ts +20 -0
  55. package/lib/findSchemaDefinition.js +49 -0
  56. package/lib/findSchemaDefinition.js.map +1 -0
  57. package/lib/getDiscriminatorFieldFromSchema.d.ts +8 -0
  58. package/lib/getDiscriminatorFieldFromSchema.js +20 -0
  59. package/lib/getDiscriminatorFieldFromSchema.js.map +1 -0
  60. package/lib/getInputProps.d.ts +10 -0
  61. package/lib/getInputProps.js +41 -0
  62. package/lib/getInputProps.js.map +1 -0
  63. package/lib/getSchemaType.d.ts +13 -0
  64. package/lib/getSchemaType.js +29 -0
  65. package/lib/getSchemaType.js.map +1 -0
  66. package/lib/getSubmitButtonOptions.d.ts +10 -0
  67. package/lib/getSubmitButtonOptions.js +25 -0
  68. package/lib/getSubmitButtonOptions.js.map +1 -0
  69. package/lib/getTemplate.d.ts +10 -0
  70. package/lib/getTemplate.js +19 -0
  71. package/lib/getTemplate.js.map +1 -0
  72. package/lib/getUiOptions.d.ts +9 -0
  73. package/lib/getUiOptions.js +25 -0
  74. package/lib/getUiOptions.js.map +1 -0
  75. package/lib/getWidget.d.ts +13 -0
  76. package/lib/getWidget.js +118 -0
  77. package/lib/getWidget.js.map +1 -0
  78. package/lib/guessType.d.ts +7 -0
  79. package/lib/guessType.js +29 -0
  80. package/lib/guessType.js.map +1 -0
  81. package/lib/hasWidget.d.ts +10 -0
  82. package/lib/hasWidget.js +23 -0
  83. package/lib/hasWidget.js.map +1 -0
  84. package/lib/hashForSchema.d.ts +8 -0
  85. package/lib/hashForSchema.js +29 -0
  86. package/lib/hashForSchema.js.map +1 -0
  87. package/lib/idGenerators.d.ts +47 -0
  88. package/lib/idGenerators.js +73 -0
  89. package/lib/idGenerators.js.map +1 -0
  90. package/lib/index.d.ts +57 -0
  91. package/lib/index.js +58 -0
  92. package/lib/index.js.map +1 -0
  93. package/lib/isConstant.d.ts +8 -0
  94. package/lib/isConstant.js +11 -0
  95. package/lib/isConstant.js.map +1 -0
  96. package/lib/isCustomWidget.d.ts +7 -0
  97. package/lib/isCustomWidget.js +13 -0
  98. package/lib/isCustomWidget.js.map +1 -0
  99. package/lib/isFixedItems.d.ts +8 -0
  100. package/lib/isFixedItems.js +11 -0
  101. package/lib/isFixedItems.js.map +1 -0
  102. package/lib/isObject.d.ts +7 -0
  103. package/lib/isObject.js +16 -0
  104. package/lib/isObject.js.map +1 -0
  105. package/lib/labelValue.d.ts +13 -0
  106. package/lib/labelValue.js +4 -0
  107. package/lib/labelValue.js.map +1 -0
  108. package/lib/localToUTC.d.ts +6 -0
  109. package/lib/localToUTC.js +9 -0
  110. package/lib/localToUTC.js.map +1 -0
  111. package/lib/mergeDefaultsWithFormData.d.ts +17 -0
  112. package/lib/mergeDefaultsWithFormData.js +43 -0
  113. package/lib/mergeDefaultsWithFormData.js.map +1 -0
  114. package/lib/mergeObjects.d.ts +11 -0
  115. package/lib/mergeObjects.js +35 -0
  116. package/lib/mergeObjects.js.map +1 -0
  117. package/lib/mergeSchemas.d.ts +10 -0
  118. package/lib/mergeSchemas.js +35 -0
  119. package/lib/mergeSchemas.js.map +1 -0
  120. package/lib/optionsList.d.ts +10 -0
  121. package/lib/optionsList.js +36 -0
  122. package/lib/optionsList.js.map +1 -0
  123. package/lib/orderProperties.d.ts +11 -0
  124. package/lib/orderProperties.js +38 -0
  125. package/lib/orderProperties.js.map +1 -0
  126. package/lib/pad.d.ts +7 -0
  127. package/lib/pad.js +14 -0
  128. package/lib/pad.js.map +1 -0
  129. package/lib/parseDateString.d.ts +9 -0
  130. package/lib/parseDateString.js +32 -0
  131. package/lib/parseDateString.js.map +1 -0
  132. package/lib/parser/ParserValidator.d.ts +70 -0
  133. package/lib/parser/ParserValidator.js +93 -0
  134. package/lib/parser/ParserValidator.js.map +1 -0
  135. package/lib/parser/index.d.ts +4 -0
  136. package/lib/parser/index.js +3 -0
  137. package/lib/parser/index.js.map +1 -0
  138. package/lib/parser/schemaParser.d.ts +9 -0
  139. package/lib/parser/schemaParser.js +48 -0
  140. package/lib/parser/schemaParser.js.map +1 -0
  141. package/lib/rangeSpec.d.ts +9 -0
  142. package/lib/rangeSpec.js +20 -0
  143. package/lib/rangeSpec.js.map +1 -0
  144. package/lib/replaceStringParameters.d.ts +9 -0
  145. package/lib/replaceStringParameters.js +23 -0
  146. package/lib/replaceStringParameters.js.map +1 -0
  147. package/lib/schema/getClosestMatchingOption.d.ts +49 -0
  148. package/lib/schema/getClosestMatchingOption.js +154 -0
  149. package/lib/schema/getClosestMatchingOption.js.map +1 -0
  150. package/lib/schema/getDefaultFormState.d.ts +66 -0
  151. package/lib/schema/getDefaultFormState.js +351 -0
  152. package/lib/schema/getDefaultFormState.js.map +1 -0
  153. package/lib/schema/getDisplayLabel.d.ts +12 -0
  154. package/lib/schema/getDisplayLabel.js +39 -0
  155. package/lib/schema/getDisplayLabel.js.map +1 -0
  156. package/lib/schema/getFirstMatchingOption.d.ts +13 -0
  157. package/lib/schema/getFirstMatchingOption.js +16 -0
  158. package/lib/schema/getFirstMatchingOption.js.map +1 -0
  159. package/lib/schema/getMatchingOption.d.ts +14 -0
  160. package/lib/schema/getMatchingOption.js +80 -0
  161. package/lib/schema/getMatchingOption.js.map +1 -0
  162. package/lib/schema/index.d.ts +14 -0
  163. package/lib/schema/index.js +15 -0
  164. package/lib/schema/index.js.map +1 -0
  165. package/lib/schema/isFilesArray.d.ts +10 -0
  166. package/lib/schema/isFilesArray.js +21 -0
  167. package/lib/schema/isFilesArray.js.map +1 -0
  168. package/lib/schema/isMultiSelect.d.ts +9 -0
  169. package/lib/schema/isMultiSelect.js +15 -0
  170. package/lib/schema/isMultiSelect.js.map +1 -0
  171. package/lib/schema/isSelect.d.ts +9 -0
  172. package/lib/schema/isSelect.js +21 -0
  173. package/lib/schema/isSelect.js.map +1 -0
  174. package/lib/schema/mergeValidationData.d.ts +14 -0
  175. package/lib/schema/mergeValidationData.js +28 -0
  176. package/lib/schema/mergeValidationData.js.map +1 -0
  177. package/lib/schema/retrieveSchema.d.ts +170 -0
  178. package/lib/schema/retrieveSchema.js +437 -0
  179. package/lib/schema/retrieveSchema.js.map +1 -0
  180. package/lib/schema/sanitizeDataForNewSchema.d.ts +49 -0
  181. package/lib/schema/sanitizeDataForNewSchema.js +173 -0
  182. package/lib/schema/sanitizeDataForNewSchema.js.map +1 -0
  183. package/lib/schema/toIdSchema.d.ts +13 -0
  184. package/lib/schema/toIdSchema.js +59 -0
  185. package/lib/schema/toIdSchema.js.map +1 -0
  186. package/lib/schema/toPathSchema.d.ts +11 -0
  187. package/lib/schema/toPathSchema.js +68 -0
  188. package/lib/schema/toPathSchema.js.map +1 -0
  189. package/lib/schemaRequiresTrueValue.d.ts +11 -0
  190. package/lib/schemaRequiresTrueValue.js +34 -0
  191. package/lib/schemaRequiresTrueValue.js.map +1 -0
  192. package/lib/shouldRender.d.ts +10 -0
  193. package/lib/shouldRender.js +14 -0
  194. package/lib/shouldRender.js.map +1 -0
  195. package/lib/toConstant.d.ts +9 -0
  196. package/lib/toConstant.js +18 -0
  197. package/lib/toConstant.js.map +1 -0
  198. package/lib/toDateString.d.ts +9 -0
  199. package/lib/toDateString.js +14 -0
  200. package/lib/toDateString.js.map +1 -0
  201. package/lib/toErrorList.d.ts +8 -0
  202. package/lib/toErrorList.js +34 -0
  203. package/lib/toErrorList.js.map +1 -0
  204. package/lib/toErrorSchema.d.ts +21 -0
  205. package/lib/toErrorSchema.js +41 -0
  206. package/lib/toErrorSchema.js.map +1 -0
  207. package/lib/types.d.ts +982 -0
  208. package/lib/types.js +2 -0
  209. package/lib/types.js.map +1 -0
  210. package/lib/unwrapErrorHandler.d.ts +7 -0
  211. package/lib/unwrapErrorHandler.js +21 -0
  212. package/lib/unwrapErrorHandler.js.map +1 -0
  213. package/lib/utcToLocal.d.ts +6 -0
  214. package/lib/utcToLocal.js +26 -0
  215. package/lib/utcToLocal.js.map +1 -0
  216. package/lib/validationDataMerge.d.ts +11 -0
  217. package/lib/validationDataMerge.js +26 -0
  218. package/lib/validationDataMerge.js.map +1 -0
  219. package/lib/withIdRefPrefix.d.ts +8 -0
  220. package/lib/withIdRefPrefix.js +47 -0
  221. package/lib/withIdRefPrefix.js.map +1 -0
  222. package/package.json +20 -13
  223. package/src/ErrorSchemaBuilder.ts +112 -0
  224. package/src/allowAdditionalItems.ts +15 -0
  225. package/src/asNumber.ts +38 -0
  226. package/src/canExpand.ts +31 -0
  227. package/src/constants.ts +31 -0
  228. package/src/createErrorHandler.ts +33 -0
  229. package/src/createSchemaUtils.ts +298 -0
  230. package/src/dataURItoBlob.ts +42 -0
  231. package/src/deepEquals.ts +19 -0
  232. package/src/englishStringTranslator.ts +14 -0
  233. package/src/enumOptionsDeselectValue.ts +28 -0
  234. package/src/enumOptionsIndexForValue.ts +27 -0
  235. package/src/enumOptionsIsSelected.ts +19 -0
  236. package/src/enumOptionsSelectValue.ts +28 -0
  237. package/src/enumOptionsValueForIndex.ts +26 -0
  238. package/src/enums.ts +74 -0
  239. package/src/findSchemaDefinition.ts +54 -0
  240. package/src/getDiscriminatorFieldFromSchema.ts +21 -0
  241. package/src/getInputProps.ts +55 -0
  242. package/src/getSchemaType.ts +37 -0
  243. package/src/getSubmitButtonOptions.ts +32 -0
  244. package/src/getTemplate.ts +26 -0
  245. package/src/getUiOptions.ts +32 -0
  246. package/src/getWidget.tsx +133 -0
  247. package/src/guessType.ts +28 -0
  248. package/src/hasWidget.ts +27 -0
  249. package/src/hashForSchema.ts +31 -0
  250. package/src/idGenerators.ts +81 -0
  251. package/src/index.ts +118 -0
  252. package/src/isConstant.ts +12 -0
  253. package/src/isCustomWidget.ts +19 -0
  254. package/src/isFixedItems.ts +12 -0
  255. package/src/isObject.ts +15 -0
  256. package/src/labelValue.ts +16 -0
  257. package/src/localToUTC.ts +8 -0
  258. package/src/mergeDefaultsWithFormData.ts +53 -0
  259. package/src/mergeObjects.ts +39 -0
  260. package/src/mergeSchemas.ts +38 -0
  261. package/src/optionsList.ts +41 -0
  262. package/src/orderProperties.ts +44 -0
  263. package/src/pad.ts +13 -0
  264. package/src/parseDateString.ts +33 -0
  265. package/src/parser/ParserValidator.ts +132 -0
  266. package/src/parser/index.ts +6 -0
  267. package/src/parser/schemaParser.ts +60 -0
  268. package/src/rangeSpec.ts +22 -0
  269. package/src/replaceStringParameters.ts +22 -0
  270. package/src/schema/getClosestMatchingOption.ts +191 -0
  271. package/src/schema/getDefaultFormState.ts +447 -0
  272. package/src/schema/getDisplayLabel.ts +59 -0
  273. package/src/schema/getFirstMatchingOption.ts +27 -0
  274. package/src/schema/getMatchingOption.ts +95 -0
  275. package/src/schema/index.ts +29 -0
  276. package/src/schema/isFilesArray.ts +27 -0
  277. package/src/schema/isMultiSelect.ts +21 -0
  278. package/src/schema/isSelect.ts +26 -0
  279. package/src/schema/mergeValidationData.ts +38 -0
  280. package/src/schema/retrieveSchema.ts +614 -0
  281. package/src/schema/sanitizeDataForNewSchema.ts +197 -0
  282. package/src/schema/toIdSchema.ts +105 -0
  283. package/src/schema/toPathSchema.ts +121 -0
  284. package/src/schemaRequiresTrueValue.ts +40 -0
  285. package/src/shouldRender.ts +16 -0
  286. package/src/toConstant.ts +19 -0
  287. package/src/toDateString.ts +15 -0
  288. package/src/toErrorList.ts +41 -0
  289. package/src/toErrorSchema.ts +43 -0
  290. package/src/types.ts +1139 -0
  291. package/src/unwrapErrorHandler.ts +25 -0
  292. package/src/utcToLocal.ts +30 -0
  293. package/src/validationDataMerge.ts +31 -0
  294. package/src/withIdRefPrefix.ts +49 -0
  295. package/dist/index.d.ts +0 -1911
  296. package/dist/utils.cjs.development.js +0 -3522
  297. package/dist/utils.cjs.development.js.map +0 -1
  298. package/dist/utils.cjs.production.min.js +0 -2
  299. package/dist/utils.cjs.production.min.js.map +0 -1
  300. package/dist/utils.umd.development.js +0 -3504
  301. package/dist/utils.umd.development.js.map +0 -1
  302. package/dist/utils.umd.production.min.js +0 -2
  303. package/dist/utils.umd.production.min.js.map +0 -1
@@ -0,0 +1,16 @@
1
+ import { ReactElement } from 'react';
2
+
3
+ /** Helper function that will return the value to use for a widget `label` based on `hideLabel`. The `fallback` is used
4
+ * as the return value from the function when `hideLabel` is true. Due to the implementation of theme components, it
5
+ * may be necessary to return something other than `undefined` to cause the theme component to not render a label. Some
6
+ * themes require may `false` and others may require an empty string.
7
+ *
8
+ * @param [label] - The label string or component to render when not hidden
9
+ * @param [hideLabel] - Flag, if true, will cause the label to be hidden
10
+ * @param [fallback] - One of 3 values, `undefined` (the default), `false` or an empty string
11
+ * @returns - `fallback` if `hideLabel` is true, otherwise `label`
12
+ */
13
+ export function labelValue(label?: string | ReactElement, hideLabel?: boolean, fallback?: ''): undefined | string;
14
+ export default function labelValue(label?: string | ReactElement, hideLabel?: boolean, fallback?: false | '') {
15
+ return hideLabel ? fallback : label;
16
+ }
@@ -0,0 +1,8 @@
1
+ /** Converts a local Date string into a UTC date string
2
+ *
3
+ * @param dateString - The string representation of a date as accepted by the `Date()` constructor
4
+ * @returns - A UTC date string if `dateString` is truthy, otherwise undefined
5
+ */
6
+ export default function localToUTC(dateString: string) {
7
+ return dateString ? new Date(dateString).toJSON() : undefined;
8
+ }
@@ -0,0 +1,53 @@
1
+ import get from 'lodash/get';
2
+
3
+ import isObject from './isObject';
4
+ import { GenericObjectType } from '../src';
5
+
6
+ /** Merges the `defaults` object of type `T` into the `formData` of type `T`
7
+ *
8
+ * When merging defaults and form data, we want to merge in this specific way:
9
+ * - objects are deeply merged
10
+ * - arrays are merged in such a way that:
11
+ * - when the array is set in form data, only array entries set in form data
12
+ * are deeply merged; additional entries from the defaults are ignored unless `mergeExtraArrayDefaults` is true, in
13
+ * which case the extras are appended onto the end of the form data
14
+ * - when the array is not set in form data, the default is copied over
15
+ * - scalars are overwritten/set by form data
16
+ *
17
+ * @param [defaults] - The defaults to merge
18
+ * @param [formData] - The form data into which the defaults will be merged
19
+ * @param [mergeExtraArrayDefaults=false] - If true, any additional default array entries are appended onto the formData
20
+ * @returns - The resulting merged form data with defaults
21
+ */
22
+ export default function mergeDefaultsWithFormData<T = any>(
23
+ defaults?: T,
24
+ formData?: T,
25
+ mergeExtraArrayDefaults = false
26
+ ): T | undefined {
27
+ if (Array.isArray(formData)) {
28
+ const defaultsArray = Array.isArray(defaults) ? defaults : [];
29
+ const mapped = formData.map((value, idx) => {
30
+ if (defaultsArray[idx]) {
31
+ return mergeDefaultsWithFormData<any>(defaultsArray[idx], value, mergeExtraArrayDefaults);
32
+ }
33
+ return value;
34
+ });
35
+ // Merge any extra defaults when mergeExtraArrayDefaults is true
36
+ if (mergeExtraArrayDefaults && mapped.length < defaultsArray.length) {
37
+ mapped.push(...defaultsArray.slice(mapped.length));
38
+ }
39
+ return mapped as unknown as T;
40
+ }
41
+ if (isObject(formData)) {
42
+ const acc: { [key in keyof T]: any } = Object.assign({}, defaults); // Prevent mutation of source object.
43
+ return Object.keys(formData as GenericObjectType).reduce((acc, key) => {
44
+ acc[key as keyof T] = mergeDefaultsWithFormData<T>(
45
+ defaults ? get(defaults, key) : {},
46
+ get(formData, key),
47
+ mergeExtraArrayDefaults
48
+ );
49
+ return acc;
50
+ }, acc);
51
+ }
52
+ return formData;
53
+ }
@@ -0,0 +1,39 @@
1
+ import isObject from './isObject';
2
+ import { GenericObjectType } from './types';
3
+
4
+ /** Recursively merge deeply nested objects.
5
+ *
6
+ * @param obj1 - The first object to merge
7
+ * @param obj2 - The second object to merge
8
+ * @param [concatArrays=false] - Optional flag that, when true, will cause arrays to be concatenated. Use
9
+ * "preventDuplicates" to merge arrays in a manner that prevents any duplicate entries from being merged.
10
+ * NOTE: Uses shallow comparison for the duplicate checking.
11
+ * @returns - A new object that is the merge of the two given objects
12
+ */
13
+ export default function mergeObjects(
14
+ obj1: GenericObjectType,
15
+ obj2: GenericObjectType,
16
+ concatArrays: boolean | 'preventDuplicates' = false
17
+ ) {
18
+ return Object.keys(obj2).reduce((acc, key) => {
19
+ const left = obj1 ? obj1[key] : {},
20
+ right = obj2[key];
21
+ if (obj1 && key in obj1 && isObject(right)) {
22
+ acc[key] = mergeObjects(left, right, concatArrays);
23
+ } else if (concatArrays && Array.isArray(left) && Array.isArray(right)) {
24
+ let toMerge = right;
25
+ if (concatArrays === 'preventDuplicates') {
26
+ toMerge = right.reduce((result, value) => {
27
+ if (!left.includes(value)) {
28
+ result.push(value);
29
+ }
30
+ return result;
31
+ }, []);
32
+ }
33
+ acc[key] = left.concat(toMerge);
34
+ } else {
35
+ acc[key] = right;
36
+ }
37
+ return acc;
38
+ }, Object.assign({}, obj1)); // Prevent mutation of source object.
39
+ }
@@ -0,0 +1,38 @@
1
+ import union from 'lodash/union';
2
+
3
+ import { REQUIRED_KEY } from './constants';
4
+ import getSchemaType from './getSchemaType';
5
+ import isObject from './isObject';
6
+ import { GenericObjectType } from './types';
7
+
8
+ /** Recursively merge deeply nested schemas. The difference between `mergeSchemas` and `mergeObjects` is that
9
+ * `mergeSchemas` only concats arrays for values under the 'required' keyword, and when it does, it doesn't include
10
+ * duplicate values.
11
+ *
12
+ * @param obj1 - The first schema object to merge
13
+ * @param obj2 - The second schema object to merge
14
+ * @returns - The merged schema object
15
+ */
16
+ export default function mergeSchemas(obj1: GenericObjectType, obj2: GenericObjectType) {
17
+ const acc = Object.assign({}, obj1); // Prevent mutation of source object.
18
+ return Object.keys(obj2).reduce((acc, key) => {
19
+ const left = obj1 ? obj1[key] : {},
20
+ right = obj2[key];
21
+ if (obj1 && key in obj1 && isObject(right)) {
22
+ acc[key] = mergeSchemas(left, right);
23
+ } else if (
24
+ obj1 &&
25
+ obj2 &&
26
+ (getSchemaType(obj1) === 'object' || getSchemaType(obj2) === 'object') &&
27
+ key === REQUIRED_KEY &&
28
+ Array.isArray(left) &&
29
+ Array.isArray(right)
30
+ ) {
31
+ // Don't include duplicate values when merging 'required' fields.
32
+ acc[key] = union(left, right);
33
+ } else {
34
+ acc[key] = right;
35
+ }
36
+ return acc;
37
+ }, acc);
38
+ }
@@ -0,0 +1,41 @@
1
+ import toConstant from './toConstant';
2
+ import { RJSFSchema, EnumOptionsType, StrictRJSFSchema } from './types';
3
+
4
+ /** Gets the list of options from the schema. If the schema has an enum list, then those enum values are returned. The
5
+ * labels for the options will be extracted from the non-standard, RJSF-deprecated `enumNames` if it exists, otherwise
6
+ * the label will be the same as the `value`. If the schema has a `oneOf` or `anyOf`, then the value is the list of
7
+ * `const` values from the schema and the label is either the `schema.title` or the value.
8
+ *
9
+ * @param schema - The schema from which to extract the options list
10
+ * @returns - The list of options from the schema
11
+ */
12
+ export default function optionsList<S extends StrictRJSFSchema = RJSFSchema>(
13
+ schema: S
14
+ ): EnumOptionsType<S>[] | undefined {
15
+ // enumNames was deprecated in v5 and is intentionally omitted from the RJSFSchema type.
16
+ // Cast the type to include enumNames so the feature still works.
17
+ const schemaWithEnumNames = schema as S & { enumNames?: string[] };
18
+ if (schemaWithEnumNames.enumNames && process.env.NODE_ENV !== 'production') {
19
+ console.warn('The enumNames property is deprecated and may be removed in a future major release.');
20
+ }
21
+ if (schema.enum) {
22
+ return schema.enum.map((value, i) => {
23
+ const label = (schemaWithEnumNames.enumNames && schemaWithEnumNames.enumNames[i]) || String(value);
24
+ return { label, value };
25
+ });
26
+ }
27
+ const altSchemas = schema.oneOf || schema.anyOf;
28
+ return (
29
+ altSchemas &&
30
+ altSchemas.map((aSchemaDef) => {
31
+ const aSchema = aSchemaDef as S;
32
+ const value = toConstant(aSchema);
33
+ const label = aSchema.title || String(value);
34
+ return {
35
+ schema: aSchema,
36
+ label,
37
+ value,
38
+ };
39
+ })
40
+ );
41
+ }
@@ -0,0 +1,44 @@
1
+ import { GenericObjectType } from './types';
2
+
3
+ /** Given a list of `properties` and an `order` list, returns a list that contains the `properties` ordered correctly.
4
+ * If `order` is not an array, then the untouched `properties` list is returned. Otherwise `properties` is ordered per
5
+ * the `order` list. If `order` contains a '*' then any `properties` that are not mentioned explicity in `order` will be
6
+ * places in the location of the `*`.
7
+ *
8
+ * @param properties - The list of property keys to be ordered
9
+ * @param order - An array of property keys to be ordered first, with an optional '*' property
10
+ * @returns - A list with the `properties` ordered
11
+ * @throws - Error when the properties cannot be ordered correctly
12
+ */
13
+ export default function orderProperties(properties: string[], order?: string[]): string[] {
14
+ if (!Array.isArray(order)) {
15
+ return properties;
16
+ }
17
+
18
+ const arrayToHash = (arr: string[]) =>
19
+ arr.reduce((prev: GenericObjectType, curr) => {
20
+ prev[curr] = true;
21
+ return prev;
22
+ }, {});
23
+ const errorPropList = (arr: string[]) =>
24
+ arr.length > 1 ? `properties '${arr.join("', '")}'` : `property '${arr[0]}'`;
25
+ const propertyHash = arrayToHash(properties);
26
+ const orderFiltered = order.filter((prop) => prop === '*' || propertyHash[prop]);
27
+ const orderHash = arrayToHash(orderFiltered);
28
+
29
+ const rest = properties.filter((prop: string) => !orderHash[prop]);
30
+ const restIndex = orderFiltered.indexOf('*');
31
+ if (restIndex === -1) {
32
+ if (rest.length) {
33
+ throw new Error(`uiSchema order list does not contain ${errorPropList(rest)}`);
34
+ }
35
+ return orderFiltered;
36
+ }
37
+ if (restIndex !== orderFiltered.lastIndexOf('*')) {
38
+ throw new Error('uiSchema order list contains more than one wildcard item');
39
+ }
40
+
41
+ const complete = [...orderFiltered];
42
+ complete.splice(restIndex, 1, ...rest);
43
+ return complete;
44
+ }
package/src/pad.ts ADDED
@@ -0,0 +1,13 @@
1
+ /** Returns a string representation of the `num` that is padded with leading "0"s if necessary
2
+ *
3
+ * @param num - The number to pad
4
+ * @param width - The width of the string at which no lead padding is necessary
5
+ * @returns - The number converted to a string with leading zero padding if the number of digits is less than `width`
6
+ */
7
+ export default function pad(num: number, width: number) {
8
+ let s = String(num);
9
+ while (s.length < width) {
10
+ s = '0' + s;
11
+ }
12
+ return s;
13
+ }
@@ -0,0 +1,33 @@
1
+ import { DateObject } from './types';
2
+
3
+ /** Parses the `dateString` into a `DateObject`, including the time information when `includeTime` is true
4
+ *
5
+ * @param dateString - The date string to parse into a DateObject
6
+ * @param [includeTime=true] - Optional flag, if false, will not include the time data into the object
7
+ * @returns - The date string converted to a `DateObject`
8
+ * @throws - Error when the date cannot be parsed from the string
9
+ */
10
+ export default function parseDateString(dateString?: string, includeTime = true): DateObject {
11
+ if (!dateString) {
12
+ return {
13
+ year: -1,
14
+ month: -1,
15
+ day: -1,
16
+ hour: includeTime ? -1 : 0,
17
+ minute: includeTime ? -1 : 0,
18
+ second: includeTime ? -1 : 0,
19
+ };
20
+ }
21
+ const date = new Date(dateString);
22
+ if (Number.isNaN(date.getTime())) {
23
+ throw new Error('Unable to parse date ' + dateString);
24
+ }
25
+ return {
26
+ year: date.getUTCFullYear(),
27
+ month: date.getUTCMonth() + 1, // oh you, javascript.
28
+ day: date.getUTCDate(),
29
+ hour: includeTime ? date.getUTCHours() : 0,
30
+ minute: includeTime ? date.getUTCMinutes() : 0,
31
+ second: includeTime ? date.getUTCSeconds() : 0,
32
+ };
33
+ }
@@ -0,0 +1,132 @@
1
+ import get from 'lodash/get';
2
+ import isEqual from 'lodash/isEqual';
3
+
4
+ import { ID_KEY } from '../constants';
5
+ import hashForSchema from '../hashForSchema';
6
+ import {
7
+ CustomValidator,
8
+ ErrorSchema,
9
+ ErrorTransformer,
10
+ FormContextType,
11
+ RJSFSchema,
12
+ RJSFValidationError,
13
+ StrictRJSFSchema,
14
+ UiSchema,
15
+ ValidationData,
16
+ ValidatorType,
17
+ } from '../types';
18
+
19
+ /** The type of the map of schema hash to schema
20
+ */
21
+ export type SchemaMap<S extends StrictRJSFSchema = RJSFSchema> = {
22
+ [hash: string]: S;
23
+ };
24
+
25
+ /** An implementation of the `ValidatorType` interface that is designed for use in capturing schemas used by the
26
+ * `isValid()` function. The rest of the implementation of the interface throws errors when it is attempted to be used.
27
+ * An instance of the object allows the caller to capture the schemas used in calls to the `isValid()` function. These
28
+ * captured schema, along with the root schema used to construct the object are stored in the map of schemas keyed by
29
+ * the hashed value of the schema. NOTE: After hashing the schema, an $id with the hash value is added to the
30
+ * schema IF that schema doesn't already have an $id, prior to putting the schema into the map.
31
+ */
32
+ export default class ParserValidator<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>
33
+ implements ValidatorType<T, S, F>
34
+ {
35
+ /** The rootSchema provided during construction of the class */
36
+ readonly rootSchema: S;
37
+
38
+ /** The map of schemas encountered by the ParserValidator */
39
+ schemaMap: SchemaMap<S> = {};
40
+
41
+ /** Construct the ParserValidator for the given `rootSchema`. This `rootSchema` will be stashed in the `schemaMap`
42
+ * first.
43
+ *
44
+ * @param rootSchema - The root schema against which this validator will be executed
45
+ */
46
+ constructor(rootSchema: S) {
47
+ this.rootSchema = rootSchema;
48
+ this.addSchema(rootSchema, hashForSchema<S>(rootSchema));
49
+ }
50
+
51
+ /** Adds the given `schema` to the `schemaMap` keyed by the `hash` or `ID_KEY` if present on the `schema`. If the
52
+ * schema does not have an `ID_KEY`, then the `hash` will be added as the `ID_KEY` to allow the schema to be
53
+ * associated with it's `hash` for future use (by a schema compiler).
54
+ *
55
+ * @param schema - The schema which is to be added to the map
56
+ * @param hash - The hash value at which to map the schema
57
+ */
58
+ addSchema(schema: S, hash: string) {
59
+ const key = get(schema, ID_KEY, hash);
60
+ const identifiedSchema = { ...schema, [ID_KEY]: key };
61
+ const existing = this.schemaMap[key];
62
+ if (!existing) {
63
+ this.schemaMap[key] = identifiedSchema;
64
+ } else if (!isEqual(existing, identifiedSchema)) {
65
+ console.error('existing schema:', JSON.stringify(existing, null, 2));
66
+ console.error('new schema:', JSON.stringify(identifiedSchema, null, 2));
67
+ throw new Error(
68
+ `Two different schemas exist with the same key ${key}! What a bad coincidence. If possible, try adding an $id to one of the schemas`
69
+ );
70
+ }
71
+ }
72
+
73
+ /** Returns the current `schemaMap` to the caller
74
+ */
75
+ getSchemaMap() {
76
+ return this.schemaMap;
77
+ }
78
+
79
+ /** Implements the `ValidatorType` `isValid()` method to capture the `schema` in the `schemaMap`. Throws an error when
80
+ * the `rootSchema` is not the same as the root schema provided during construction.
81
+ *
82
+ * @param schema - The schema to record in the `schemaMap`
83
+ * @param _formData - The formData parameter that is ignored
84
+ * @param rootSchema - The root schema associated with the schema
85
+ * @throws - Error when the given `rootSchema` differs from the root schema provided during construction
86
+ */
87
+ isValid(schema: S, _formData: T, rootSchema: S): boolean {
88
+ if (!isEqual(rootSchema, this.rootSchema)) {
89
+ throw new Error('Unexpectedly calling isValid() with a rootSchema that differs from the construction rootSchema');
90
+ }
91
+ this.addSchema(schema, hashForSchema<S>(schema));
92
+
93
+ return false;
94
+ }
95
+
96
+ /** Implements the `ValidatorType` `rawValidation()` method to throw an error since it is never supposed to be called
97
+ *
98
+ * @param _schema - The schema parameter that is ignored
99
+ * @param _formData - The formData parameter that is ignored
100
+ */
101
+ rawValidation<Result = any>(_schema: S, _formData?: T): { errors?: Result[]; validationError?: Error } {
102
+ throw new Error('Unexpectedly calling the `rawValidation()` method during schema parsing');
103
+ }
104
+
105
+ /** Implements the `ValidatorType` `toErrorList()` method to throw an error since it is never supposed to be called
106
+ *
107
+ * @param _errorSchema - The error schema parameter that is ignored
108
+ * @param _fieldPath - The field path parameter that is ignored
109
+ */
110
+ toErrorList(_errorSchema?: ErrorSchema<T>, _fieldPath?: string[]): RJSFValidationError[] {
111
+ throw new Error('Unexpectedly calling the `toErrorList()` method during schema parsing');
112
+ }
113
+
114
+ /** Implements the `ValidatorType` `validateFormData()` method to throw an error since it is never supposed to be
115
+ * called
116
+ *
117
+ * @param _formData - The formData parameter that is ignored
118
+ * @param _schema - The schema parameter that is ignored
119
+ * @param _customValidate - The customValidate parameter that is ignored
120
+ * @param _transformErrors - The transformErrors parameter that is ignored
121
+ * @param _uiSchema - The uiSchema parameter that is ignored
122
+ */
123
+ validateFormData(
124
+ _formData: T,
125
+ _schema: S,
126
+ _customValidate?: CustomValidator<T, S, F>,
127
+ _transformErrors?: ErrorTransformer<T, S, F>,
128
+ _uiSchema?: UiSchema<T, S, F>
129
+ ): ValidationData<T> {
130
+ throw new Error('Unexpectedly calling the `validateFormData()` method during schema parsing');
131
+ }
132
+ }
@@ -0,0 +1,6 @@
1
+ import schemaParser from './schemaParser';
2
+ import { SchemaMap } from './ParserValidator';
3
+
4
+ export type { SchemaMap };
5
+
6
+ export { schemaParser };
@@ -0,0 +1,60 @@
1
+ import forEach from 'lodash/forEach';
2
+ import isEqual from 'lodash/isEqual';
3
+
4
+ import { FormContextType, RJSFSchema, StrictRJSFSchema } from '../types';
5
+ import { PROPERTIES_KEY, ITEMS_KEY } from '../constants';
6
+ import ParserValidator, { SchemaMap } from './ParserValidator';
7
+ import { retrieveSchemaInternal, resolveAnyOrOneOfSchemas } from '../schema/retrieveSchema';
8
+
9
+ /** Recursive function used to parse the given `schema` belonging to the `rootSchema`. The `validator` is used to
10
+ * capture the sub-schemas that the `isValid()` function is called with. For each schema returned by the
11
+ * `retrieveSchemaInternal()`, the `resolveAnyOrOneOfSchemas()` function is called. For each of the schemas returned
12
+ * from THAT call have `properties`, then each of the sub-schema property objects are then recursively parsed.
13
+ *
14
+ * @param validator - The `ParserValidator` implementation used to capture `isValid()` calls during parsing
15
+ * @param recurseList - The list of schemas returned from the `retrieveSchemaInternal`, preventing infinite recursion
16
+ * @param rootSchema - The root schema from which the schema parsing began
17
+ * @param schema - The current schema element being parsed
18
+ */
19
+ function parseSchema<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
20
+ validator: ParserValidator<T, S, F>,
21
+ recurseList: S[],
22
+ rootSchema: S,
23
+ schema: S
24
+ ) {
25
+ const schemas = retrieveSchemaInternal<T, S, F>(validator, schema, rootSchema, undefined, true);
26
+ schemas.forEach((schema) => {
27
+ const sameSchemaIndex = recurseList.findIndex((item) => isEqual(item, schema));
28
+ if (sameSchemaIndex === -1) {
29
+ recurseList.push(schema);
30
+ const allOptions = resolveAnyOrOneOfSchemas<T, S, F>(validator, schema, rootSchema, true);
31
+ allOptions.forEach((s) => {
32
+ if (PROPERTIES_KEY in s && s[PROPERTIES_KEY]) {
33
+ forEach(schema[PROPERTIES_KEY], (value) => {
34
+ parseSchema<T, S, F>(validator, recurseList, rootSchema, value as S);
35
+ });
36
+ }
37
+ });
38
+ if (ITEMS_KEY in schema && !Array.isArray(schema.items) && typeof schema.items !== 'boolean') {
39
+ parseSchema<T, S, F>(validator, recurseList, rootSchema, schema.items as S);
40
+ }
41
+ }
42
+ });
43
+ }
44
+
45
+ /** Parses the given `rootSchema` to extract out all the sub-schemas that maybe contained within it. Returns a map of
46
+ * the hash of the schema to schema/sub-schema.
47
+ *
48
+ * @param rootSchema - The root schema to parse for sub-schemas used by `isValid()` calls
49
+ * @returns - The `SchemaMap` of all schemas that were parsed
50
+ */
51
+ export default function schemaParser<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
52
+ rootSchema: S
53
+ ): SchemaMap<S> {
54
+ const validator = new ParserValidator<T, S, F>(rootSchema);
55
+ const recurseList: S[] = [];
56
+
57
+ parseSchema(validator, recurseList, rootSchema, rootSchema);
58
+
59
+ return validator.getSchemaMap();
60
+ }
@@ -0,0 +1,22 @@
1
+ import { RangeSpecType, StrictRJSFSchema } from './types';
2
+ import { RJSFSchema } from './types';
3
+
4
+ /** Extracts the range spec information `{ step?: number, min?: number, max?: number }` that can be spread onto an HTML
5
+ * input from the range analog in the schema `{ multipleOf?: number, minimum?: number, maximum?: number }`.
6
+ *
7
+ * @param schema - The schema from which to extract the range spec
8
+ * @returns - A range specification from the schema
9
+ */
10
+ export default function rangeSpec<S extends StrictRJSFSchema = RJSFSchema>(schema: S) {
11
+ const spec: RangeSpecType = {};
12
+ if (schema.multipleOf) {
13
+ spec.step = schema.multipleOf;
14
+ }
15
+ if (schema.minimum || schema.minimum === 0) {
16
+ spec.min = schema.minimum;
17
+ }
18
+ if (schema.maximum || schema.maximum === 0) {
19
+ spec.max = schema.maximum;
20
+ }
21
+ return spec;
22
+ }
@@ -0,0 +1,22 @@
1
+ /** Potentially substitutes all replaceable parameters with the associated value(s) from the `params` if available. When
2
+ * a `params` array is provided, each value in the array is used to replace any of the replaceable parameters in the
3
+ * `inputString` using the `%1`, `%2`, etc. replacement specifiers.
4
+ *
5
+ * @param inputString - The string which will be potentially updated with replacement parameters
6
+ * @param params - The optional list of replaceable parameter values to substitute into the english string
7
+ * @returns - The updated string with any replacement specifiers replaced
8
+ */
9
+ export default function replaceStringParameters(inputString: string, params?: string[]) {
10
+ let output = inputString;
11
+ if (Array.isArray(params)) {
12
+ const parts = output.split(/(%\d)/);
13
+ params.forEach((param, index) => {
14
+ const partIndex = parts.findIndex((part) => part === `%${index + 1}`);
15
+ if (partIndex >= 0) {
16
+ parts[partIndex] = param;
17
+ }
18
+ });
19
+ output = parts.join('');
20
+ }
21
+ return output;
22
+ }