@rjsf/utils 6.0.0-alpha.0 → 6.0.0-beta.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 (279) hide show
  1. package/dist/index.js +1281 -625
  2. package/dist/index.js.map +4 -4
  3. package/dist/utils.esm.js +1254 -598
  4. package/dist/utils.esm.js.map +4 -4
  5. package/dist/utils.umd.js +1201 -570
  6. package/lib/ErrorSchemaBuilder.d.ts +8 -4
  7. package/lib/ErrorSchemaBuilder.js +10 -8
  8. package/lib/ErrorSchemaBuilder.js.map +1 -1
  9. package/lib/allowAdditionalItems.d.ts +1 -1
  10. package/lib/allowAdditionalItems.js +1 -1
  11. package/lib/allowAdditionalItems.js.map +1 -1
  12. package/lib/asNumber.js.map +1 -1
  13. package/lib/canExpand.d.ts +1 -1
  14. package/lib/canExpand.js +2 -2
  15. package/lib/canExpand.js.map +1 -1
  16. package/lib/constIsAjvDataReference.d.ts +9 -0
  17. package/lib/constIsAjvDataReference.js +15 -0
  18. package/lib/constIsAjvDataReference.js.map +1 -0
  19. package/lib/constants.d.ts +11 -3
  20. package/lib/constants.js +11 -3
  21. package/lib/constants.js.map +1 -1
  22. package/lib/createErrorHandler.d.ts +1 -1
  23. package/lib/createErrorHandler.js +2 -2
  24. package/lib/createErrorHandler.js.map +1 -1
  25. package/lib/createSchemaUtils.d.ts +3 -2
  26. package/lib/createSchemaUtils.js +56 -46
  27. package/lib/createSchemaUtils.js.map +1 -1
  28. package/lib/dataURItoBlob.js.map +1 -1
  29. package/lib/dateRangeOptions.d.ts +1 -1
  30. package/lib/dateRangeOptions.js +1 -1
  31. package/lib/dateRangeOptions.js.map +1 -1
  32. package/lib/deepEquals.js +1 -1
  33. package/lib/deepEquals.js.map +1 -1
  34. package/lib/englishStringTranslator.d.ts +1 -1
  35. package/lib/englishStringTranslator.js +1 -1
  36. package/lib/enumOptionsDeselectValue.d.ts +1 -1
  37. package/lib/enumOptionsDeselectValue.js +4 -4
  38. package/lib/enumOptionsDeselectValue.js.map +1 -1
  39. package/lib/enumOptionsIndexForValue.d.ts +1 -1
  40. package/lib/enumOptionsIndexForValue.js +1 -1
  41. package/lib/enumOptionsIndexForValue.js.map +1 -1
  42. package/lib/enumOptionsIsSelected.d.ts +1 -1
  43. package/lib/enumOptionsIsSelected.js +3 -3
  44. package/lib/enumOptionsIsSelected.js.map +1 -1
  45. package/lib/enumOptionsSelectValue.d.ts +1 -1
  46. package/lib/enumOptionsSelectValue.js +2 -2
  47. package/lib/enumOptionsSelectValue.js.map +1 -1
  48. package/lib/enumOptionsValueForIndex.d.ts +1 -1
  49. package/lib/enumOptionsValueForIndex.js.map +1 -1
  50. package/lib/enums.d.ts +2 -0
  51. package/lib/enums.js +2 -0
  52. package/lib/enums.js.map +1 -1
  53. package/lib/findSchemaDefinition.d.ts +1 -1
  54. package/lib/findSchemaDefinition.js +2 -2
  55. package/lib/findSchemaDefinition.js.map +1 -1
  56. package/lib/getChangedFields.d.ts +17 -0
  57. package/lib/getChangedFields.js +42 -0
  58. package/lib/getChangedFields.js.map +1 -0
  59. package/lib/getDateElementProps.d.ts +1 -1
  60. package/lib/getDateElementProps.js.map +1 -1
  61. package/lib/getDiscriminatorFieldFromSchema.d.ts +1 -1
  62. package/lib/getDiscriminatorFieldFromSchema.js +4 -3
  63. package/lib/getDiscriminatorFieldFromSchema.js.map +1 -1
  64. package/lib/getInputProps.d.ts +1 -1
  65. package/lib/getInputProps.js +4 -1
  66. package/lib/getInputProps.js.map +1 -1
  67. package/lib/getOptionMatchingSimpleDiscriminator.d.ts +1 -1
  68. package/lib/getOptionMatchingSimpleDiscriminator.js +2 -2
  69. package/lib/getOptionMatchingSimpleDiscriminator.js.map +1 -1
  70. package/lib/getSchemaType.d.ts +2 -1
  71. package/lib/getSchemaType.js +3 -2
  72. package/lib/getSchemaType.js.map +1 -1
  73. package/lib/getSubmitButtonOptions.d.ts +1 -1
  74. package/lib/getSubmitButtonOptions.js +2 -2
  75. package/lib/getSubmitButtonOptions.js.map +1 -1
  76. package/lib/getTemplate.d.ts +1 -1
  77. package/lib/getTemplate.js +9 -0
  78. package/lib/getTemplate.js.map +1 -1
  79. package/lib/getTestIds.d.ts +17 -0
  80. package/lib/getTestIds.js +34 -0
  81. package/lib/getTestIds.js.map +1 -0
  82. package/lib/getUiOptions.d.ts +1 -1
  83. package/lib/getUiOptions.js +2 -2
  84. package/lib/getUiOptions.js.map +1 -1
  85. package/lib/getWidget.d.ts +1 -1
  86. package/lib/getWidget.js +3 -3
  87. package/lib/getWidget.js.map +1 -1
  88. package/lib/guessType.d.ts +1 -1
  89. package/lib/guessType.js.map +1 -1
  90. package/lib/hasWidget.d.ts +1 -1
  91. package/lib/hasWidget.js +1 -1
  92. package/lib/hasWidget.js.map +1 -1
  93. package/lib/hashForSchema.d.ts +23 -1
  94. package/lib/hashForSchema.js +24 -6
  95. package/lib/hashForSchema.js.map +1 -1
  96. package/lib/idGenerators.d.ts +8 -1
  97. package/lib/idGenerators.js +11 -2
  98. package/lib/idGenerators.js.map +1 -1
  99. package/lib/index.d.ts +63 -60
  100. package/lib/index.js +63 -60
  101. package/lib/index.js.map +1 -1
  102. package/lib/isConstant.d.ts +1 -1
  103. package/lib/isConstant.js +1 -1
  104. package/lib/isCustomWidget.d.ts +1 -1
  105. package/lib/isCustomWidget.js +1 -1
  106. package/lib/isFixedItems.d.ts +1 -1
  107. package/lib/isFixedItems.js +1 -1
  108. package/lib/isObject.d.ts +2 -2
  109. package/lib/isObject.js +11 -4
  110. package/lib/isObject.js.map +1 -1
  111. package/lib/lookupFromFormContext.d.ts +11 -0
  112. package/lib/lookupFromFormContext.js +20 -0
  113. package/lib/lookupFromFormContext.js.map +1 -0
  114. package/lib/mergeDefaultsWithFormData.d.ts +8 -2
  115. package/lib/mergeDefaultsWithFormData.js +39 -10
  116. package/lib/mergeDefaultsWithFormData.js.map +1 -1
  117. package/lib/mergeObjects.d.ts +1 -1
  118. package/lib/mergeObjects.js +1 -1
  119. package/lib/mergeObjects.js.map +1 -1
  120. package/lib/mergeSchemas.d.ts +1 -1
  121. package/lib/mergeSchemas.js +4 -4
  122. package/lib/mergeSchemas.js.map +1 -1
  123. package/lib/optionsList.d.ts +9 -7
  124. package/lib/optionsList.js +30 -19
  125. package/lib/optionsList.js.map +1 -1
  126. package/lib/orderProperties.js.map +1 -1
  127. package/lib/pad.js.map +1 -1
  128. package/lib/parseDateString.d.ts +1 -1
  129. package/lib/parseDateString.js +1 -1
  130. package/lib/parseDateString.js.map +1 -1
  131. package/lib/parser/ParserValidator.d.ts +1 -1
  132. package/lib/parser/ParserValidator.js +6 -6
  133. package/lib/parser/ParserValidator.js.map +1 -1
  134. package/lib/parser/index.d.ts +2 -2
  135. package/lib/parser/index.js +1 -1
  136. package/lib/parser/schemaParser.d.ts +2 -2
  137. package/lib/parser/schemaParser.js +6 -6
  138. package/lib/parser/schemaParser.js.map +1 -1
  139. package/lib/rangeSpec.d.ts +2 -2
  140. package/lib/rangeSpec.js.map +1 -1
  141. package/lib/replaceStringParameters.js.map +1 -1
  142. package/lib/schema/findFieldInSchema.d.ts +19 -0
  143. package/lib/schema/findFieldInSchema.js +61 -0
  144. package/lib/schema/findFieldInSchema.js.map +1 -0
  145. package/lib/schema/findSelectedOptionInXxxOf.d.ts +16 -0
  146. package/lib/schema/findSelectedOptionInXxxOf.js +34 -0
  147. package/lib/schema/findSelectedOptionInXxxOf.js.map +1 -0
  148. package/lib/schema/getClosestMatchingOption.d.ts +5 -3
  149. package/lib/schema/getClosestMatchingOption.js +28 -20
  150. package/lib/schema/getClosestMatchingOption.js.map +1 -1
  151. package/lib/schema/getDefaultFormState.d.ts +60 -13
  152. package/lib/schema/getDefaultFormState.js +304 -166
  153. package/lib/schema/getDefaultFormState.js.map +1 -1
  154. package/lib/schema/getDisplayLabel.d.ts +3 -2
  155. package/lib/schema/getDisplayLabel.js +10 -9
  156. package/lib/schema/getDisplayLabel.js.map +1 -1
  157. package/lib/schema/getFirstMatchingOption.d.ts +1 -1
  158. package/lib/schema/getFirstMatchingOption.js +70 -2
  159. package/lib/schema/getFirstMatchingOption.js.map +1 -1
  160. package/lib/schema/getFromSchema.d.ts +14 -0
  161. package/lib/schema/getFromSchema.js +39 -0
  162. package/lib/schema/getFromSchema.js.map +1 -0
  163. package/lib/schema/index.d.ts +15 -14
  164. package/lib/schema/index.js +15 -14
  165. package/lib/schema/index.js.map +1 -1
  166. package/lib/schema/isFilesArray.d.ts +3 -2
  167. package/lib/schema/isFilesArray.js +5 -4
  168. package/lib/schema/isFilesArray.js.map +1 -1
  169. package/lib/schema/isMultiSelect.d.ts +3 -2
  170. package/lib/schema/isMultiSelect.js +4 -3
  171. package/lib/schema/isMultiSelect.js.map +1 -1
  172. package/lib/schema/isSelect.d.ts +3 -2
  173. package/lib/schema/isSelect.js +5 -4
  174. package/lib/schema/isSelect.js.map +1 -1
  175. package/lib/schema/retrieveSchema.d.ts +28 -11
  176. package/lib/schema/retrieveSchema.js +142 -66
  177. package/lib/schema/retrieveSchema.js.map +1 -1
  178. package/lib/schema/sanitizeDataForNewSchema.d.ts +3 -2
  179. package/lib/schema/sanitizeDataForNewSchema.js +12 -11
  180. package/lib/schema/sanitizeDataForNewSchema.js.map +1 -1
  181. package/lib/schema/toIdSchema.d.ts +3 -2
  182. package/lib/schema/toIdSchema.js +30 -27
  183. package/lib/schema/toIdSchema.js.map +1 -1
  184. package/lib/schema/toPathSchema.d.ts +3 -2
  185. package/lib/schema/toPathSchema.js +22 -20
  186. package/lib/schema/toPathSchema.js.map +1 -1
  187. package/lib/schemaRequiresTrueValue.d.ts +1 -1
  188. package/lib/schemaRequiresTrueValue.js.map +1 -1
  189. package/lib/shouldRender.js +1 -1
  190. package/lib/toConstant.d.ts +1 -1
  191. package/lib/toConstant.js +1 -1
  192. package/lib/toConstant.js.map +1 -1
  193. package/lib/toDateString.d.ts +1 -1
  194. package/lib/toErrorList.d.ts +1 -1
  195. package/lib/toErrorList.js +2 -2
  196. package/lib/toErrorList.js.map +1 -1
  197. package/lib/toErrorSchema.d.ts +1 -1
  198. package/lib/toErrorSchema.js +2 -2
  199. package/lib/toErrorSchema.js.map +1 -1
  200. package/lib/tsconfig.tsbuildinfo +1 -1
  201. package/lib/types.d.ts +160 -131
  202. package/lib/unwrapErrorHandler.d.ts +1 -1
  203. package/lib/unwrapErrorHandler.js +1 -1
  204. package/lib/unwrapErrorHandler.js.map +1 -1
  205. package/lib/utcToLocal.js +1 -1
  206. package/lib/utcToLocal.js.map +1 -1
  207. package/lib/validationDataMerge.d.ts +1 -1
  208. package/lib/validationDataMerge.js +3 -3
  209. package/lib/validationDataMerge.js.map +1 -1
  210. package/lib/withIdRefPrefix.d.ts +1 -1
  211. package/lib/withIdRefPrefix.js +2 -2
  212. package/lib/withIdRefPrefix.js.map +1 -1
  213. package/package.json +36 -26
  214. package/src/ErrorSchemaBuilder.ts +15 -8
  215. package/src/canExpand.ts +2 -2
  216. package/src/constIsAjvDataReference.ts +17 -0
  217. package/src/constants.ts +12 -3
  218. package/src/createSchemaUtils.ts +140 -50
  219. package/src/dataURItoBlob.ts +1 -1
  220. package/src/dateRangeOptions.ts +1 -1
  221. package/src/enumOptionsDeselectValue.ts +4 -5
  222. package/src/enumOptionsIndexForValue.ts +1 -1
  223. package/src/enumOptionsIsSelected.ts +4 -5
  224. package/src/enumOptionsSelectValue.ts +1 -1
  225. package/src/enumOptionsValueForIndex.ts +1 -1
  226. package/src/enums.ts +2 -0
  227. package/src/findSchemaDefinition.ts +2 -2
  228. package/src/getChangedFields.ts +40 -0
  229. package/src/getDateElementProps.ts +2 -2
  230. package/src/getDiscriminatorFieldFromSchema.ts +2 -1
  231. package/src/getInputProps.ts +6 -2
  232. package/src/getOptionMatchingSimpleDiscriminator.ts +2 -2
  233. package/src/getSchemaType.ts +3 -2
  234. package/src/getSubmitButtonOptions.ts +1 -1
  235. package/src/getTemplate.ts +12 -1
  236. package/src/getTestIds.ts +40 -0
  237. package/src/getUiOptions.ts +2 -2
  238. package/src/getWidget.tsx +2 -2
  239. package/src/hasWidget.ts +1 -1
  240. package/src/hashForSchema.ts +26 -6
  241. package/src/idGenerators.ts +10 -0
  242. package/src/index.ts +21 -2
  243. package/src/isCustomWidget.ts +1 -1
  244. package/src/isObject.ts +12 -5
  245. package/src/labelValue.ts +2 -2
  246. package/src/lookupFromFormContext.ts +26 -0
  247. package/src/mergeDefaultsWithFormData.ts +54 -9
  248. package/src/mergeObjects.ts +24 -21
  249. package/src/optionsList.ts +31 -22
  250. package/src/parser/ParserValidator.ts +5 -5
  251. package/src/parser/schemaParser.ts +6 -6
  252. package/src/schema/findFieldInSchema.ts +138 -0
  253. package/src/schema/findSelectedOptionInXxxOf.ts +53 -0
  254. package/src/schema/getClosestMatchingOption.ts +38 -11
  255. package/src/schema/getDefaultFormState.ts +447 -191
  256. package/src/schema/getDisplayLabel.ts +7 -4
  257. package/src/schema/getFirstMatchingOption.ts +79 -4
  258. package/src/schema/getFromSchema.ts +100 -0
  259. package/src/schema/index.ts +6 -4
  260. package/src/schema/isFilesArray.ts +18 -3
  261. package/src/schema/isMultiSelect.ts +10 -4
  262. package/src/schema/isSelect.ts +5 -3
  263. package/src/schema/retrieveSchema.ts +256 -75
  264. package/src/schema/sanitizeDataForNewSchema.ts +52 -11
  265. package/src/schema/toIdSchema.ts +69 -43
  266. package/src/schema/toPathSchema.ts +49 -16
  267. package/src/toErrorList.ts +2 -2
  268. package/src/types.ts +266 -174
  269. package/src/validationDataMerge.ts +1 -1
  270. package/src/withIdRefPrefix.ts +1 -1
  271. package/LICENSE.md +0 -201
  272. package/lib/schema/getMatchingOption.d.ts +0 -14
  273. package/lib/schema/getMatchingOption.js +0 -85
  274. package/lib/schema/getMatchingOption.js.map +0 -1
  275. package/lib/schema/mergeValidationData.d.ts +0 -14
  276. package/lib/schema/mergeValidationData.js +0 -28
  277. package/lib/schema/mergeValidationData.js.map +0 -1
  278. package/src/schema/getMatchingOption.ts +0 -103
  279. package/src/schema/mergeValidationData.ts +0 -38
@@ -2,6 +2,7 @@ import get from 'lodash/get';
2
2
 
3
3
  import isObject from './isObject';
4
4
  import { GenericObjectType } from '../src';
5
+ import isNil from 'lodash/isNil';
5
6
 
6
7
  /** Merges the `defaults` object of type `T` into the `formData` of type `T`
7
8
  *
@@ -12,42 +13,86 @@ import { GenericObjectType } from '../src';
12
13
  * are deeply merged; additional entries from the defaults are ignored unless `mergeExtraArrayDefaults` is true, in
13
14
  * which case the extras are appended onto the end of the form data
14
15
  * - when the array is not set in form data, the default is copied over
15
- * - scalars are overwritten/set by form data
16
+ * - scalars are overwritten/set by form data unless undefined and there is a default AND `defaultSupercedesUndefined`
17
+ * is true
16
18
  *
17
19
  * @param [defaults] - The defaults to merge
18
20
  * @param [formData] - The form data into which the defaults will be merged
19
21
  * @param [mergeExtraArrayDefaults=false] - If true, any additional default array entries are appended onto the formData
22
+ * @param [defaultSupercedesUndefined=false] - If true, an explicit undefined value will be overwritten by the default value
23
+ * @param [overrideFormDataWithDefaults=false] - If true, the default value will overwrite the form data value. If the value
24
+ * doesn't exist in the default, we take it from formData and in the case where the value is set to undefined in formData.
25
+ * This is useful when we have already merged formData with defaults and want to add an additional field from formData
26
+ * that does not exist in defaults.
20
27
  * @returns - The resulting merged form data with defaults
21
28
  */
22
29
  export default function mergeDefaultsWithFormData<T = any>(
23
30
  defaults?: T,
24
31
  formData?: T,
25
- mergeExtraArrayDefaults = false
32
+ mergeExtraArrayDefaults = false,
33
+ defaultSupercedesUndefined = false,
34
+ overrideFormDataWithDefaults = false,
26
35
  ): T | undefined {
27
36
  if (Array.isArray(formData)) {
28
37
  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);
38
+
39
+ // If overrideFormDataWithDefaults is true, we want to override the formData with the defaults
40
+ const overrideArray = overrideFormDataWithDefaults ? defaultsArray : formData;
41
+ const overrideOppositeArray = overrideFormDataWithDefaults ? formData : defaultsArray;
42
+
43
+ const mapped = overrideArray.map((value, idx) => {
44
+ // We want to explicitly make sure that the value is NOT undefined since null, 0 and empty space are valid values
45
+ if (overrideOppositeArray[idx] !== undefined) {
46
+ return mergeDefaultsWithFormData<any>(
47
+ defaultsArray[idx],
48
+ formData[idx],
49
+ mergeExtraArrayDefaults,
50
+ defaultSupercedesUndefined,
51
+ overrideFormDataWithDefaults,
52
+ );
32
53
  }
33
54
  return value;
34
55
  });
56
+
35
57
  // Merge any extra defaults when mergeExtraArrayDefaults is true
36
- if (mergeExtraArrayDefaults && mapped.length < defaultsArray.length) {
37
- mapped.push(...defaultsArray.slice(mapped.length));
58
+ // Or when overrideFormDataWithDefaults is true and the default array is shorter than the formData array
59
+ if ((mergeExtraArrayDefaults || overrideFormDataWithDefaults) && mapped.length < overrideOppositeArray.length) {
60
+ mapped.push(...overrideOppositeArray.slice(mapped.length));
38
61
  }
39
62
  return mapped as unknown as T;
40
63
  }
41
64
  if (isObject(formData)) {
42
65
  const acc: { [key in keyof T]: any } = Object.assign({}, defaults); // Prevent mutation of source object.
43
66
  return Object.keys(formData as GenericObjectType).reduce((acc, key) => {
67
+ const keyValue = get(formData, key);
68
+ const keyExistsInDefaults = isObject(defaults) && key in (defaults as GenericObjectType);
69
+ const keyExistsInFormData = key in (formData as GenericObjectType);
44
70
  acc[key as keyof T] = mergeDefaultsWithFormData<T>(
45
71
  defaults ? get(defaults, key) : {},
46
- get(formData, key),
47
- mergeExtraArrayDefaults
72
+ keyValue,
73
+ mergeExtraArrayDefaults,
74
+ defaultSupercedesUndefined,
75
+ // overrideFormDataWithDefaults can be true only when the key value exists in defaults
76
+ // Or if the key value doesn't exist in formData
77
+ overrideFormDataWithDefaults && (keyExistsInDefaults || !keyExistsInFormData),
48
78
  );
49
79
  return acc;
50
80
  }, acc);
51
81
  }
82
+
83
+ /**
84
+ * If the defaultSupercedesUndefined flag is true
85
+ * And formData is set to undefined or null and defaults are defined
86
+ * Or if formData is a number and is NaN return defaults
87
+ * Or if overrideFormDataWithDefaults flag is true and formData is set to not undefined/null return defaults
88
+ */
89
+ if (
90
+ (defaultSupercedesUndefined &&
91
+ ((!isNil(defaults) && isNil(formData)) || (typeof formData === 'number' && isNaN(formData)))) ||
92
+ (overrideFormDataWithDefaults && !isNil(formData))
93
+ ) {
94
+ return defaults;
95
+ }
96
+
52
97
  return formData;
53
98
  }
@@ -13,27 +13,30 @@ import { GenericObjectType } from './types';
13
13
  export default function mergeObjects(
14
14
  obj1: GenericObjectType,
15
15
  obj2: GenericObjectType,
16
- concatArrays: boolean | 'preventDuplicates' = false
16
+ concatArrays: boolean | 'preventDuplicates' = false,
17
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
- }, []);
18
+ return Object.keys(obj2).reduce(
19
+ (acc, key) => {
20
+ const left = obj1 ? obj1[key] : {},
21
+ right = obj2[key];
22
+ if (obj1 && key in obj1 && isObject(right)) {
23
+ acc[key] = mergeObjects(left, right, concatArrays);
24
+ } else if (concatArrays && Array.isArray(left) && Array.isArray(right)) {
25
+ let toMerge = right;
26
+ if (concatArrays === 'preventDuplicates') {
27
+ toMerge = right.reduce((result, value) => {
28
+ if (!left.includes(value)) {
29
+ result.push(value);
30
+ }
31
+ return result;
32
+ }, []);
33
+ }
34
+ acc[key] = left.concat(toMerge);
35
+ } else {
36
+ acc[key] = right;
32
37
  }
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.
38
+ return acc;
39
+ },
40
+ Object.assign({}, obj1),
41
+ ); // Prevent mutation of source object.
39
42
  }
@@ -1,40 +1,34 @@
1
+ import get from 'lodash/get';
2
+
3
+ import { CONST_KEY, DEFAULT_KEY, PROPERTIES_KEY } from './constants';
4
+ import getDiscriminatorFieldFromSchema from './getDiscriminatorFieldFromSchema';
5
+ import getUiOptions from './getUiOptions';
1
6
  import toConstant from './toConstant';
2
7
  import { RJSFSchema, EnumOptionsType, StrictRJSFSchema, FormContextType, UiSchema } from './types';
3
- import getUiOptions from './getUiOptions';
4
8
 
5
9
  /** Gets the list of options from the `schema`. If the schema has an enum list, then those enum values are returned. The
6
- * labels for the options will be extracted from the non-standard, RJSF-deprecated `enumNames` if it exists, otherwise
7
- * the label will be the same as the `value`. If the schema has a `oneOf` or `anyOf`, then the value is the list of
8
- * `const` values from the schema and the label is either the `schema.title` or the value. If a `uiSchema` is provided
9
- * and it has the `ui:enumNames` matched with `enum` or it has an associated `oneOf` or `anyOf` with a list of objects
10
- * containing `ui:title` then the UI schema values will replace the values from the schema.
10
+ * label will be the same as the `value`.
11
+ *
12
+ * If the schema has a `oneOf` or `anyOf`, then the value is the list of either:
13
+ * - The `const` values from the schema if present
14
+ * - If the schema has a discriminator and the label using either the `schema.title` or the value. If a `uiSchema` is
15
+ * provided, and it has the `ui:enumNames` matched with `enum` or it has an associated `oneOf` or `anyOf` with a list of
16
+ * objects containing `ui:title` then the UI schema values will replace the values from the schema.
11
17
  *
12
18
  * @param schema - The schema from which to extract the options list
13
19
  * @param [uiSchema] - The optional uiSchema from which to get alternate labels for the options
14
20
  * @returns - The list of options from the schema
15
21
  */
16
- export default function optionsList<S extends StrictRJSFSchema = RJSFSchema, T = any, F extends FormContextType = any>(
22
+ export default function optionsList<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
17
23
  schema: S,
18
- uiSchema?: UiSchema<T, S, F>
24
+ uiSchema?: UiSchema<T, S, F>,
19
25
  ): EnumOptionsType<S>[] | undefined {
20
- // TODO flip generics to move T first in v6
21
- const schemaWithEnumNames = schema as S & { enumNames?: string[] };
22
26
  if (schema.enum) {
23
27
  let enumNames: string[] | undefined;
24
28
  if (uiSchema) {
25
29
  const { enumNames: uiEnumNames } = getUiOptions<T, S, F>(uiSchema);
26
30
  enumNames = uiEnumNames;
27
31
  }
28
- if (!enumNames && schemaWithEnumNames.enumNames) {
29
- // enumNames was deprecated in v5 and is intentionally omitted from the RJSFSchema type.
30
- // Cast the type to include enumNames so the feature still works.
31
- if (process.env.NODE_ENV !== 'production') {
32
- console.warn(
33
- 'The "enumNames" property in the schema is deprecated and will be removed in a future major release. Use the "ui:enumNames" property in the uiSchema instead.'
34
- );
35
- }
36
- enumNames = schemaWithEnumNames.enumNames;
37
- }
38
32
  return schema.enum.map((value, i) => {
39
33
  const label = enumNames?.[i] || String(value);
40
34
  return { label, value };
@@ -49,13 +43,28 @@ export default function optionsList<S extends StrictRJSFSchema = RJSFSchema, T =
49
43
  altSchemas = schema.oneOf;
50
44
  altUiSchemas = uiSchema?.oneOf;
51
45
  }
46
+ // See if there is a discriminator path specified in the schema, and if so, use it as the selectorField, otherwise
47
+ // pull one from the uiSchema
48
+ let selectorField = getDiscriminatorFieldFromSchema<S>(schema);
49
+ if (uiSchema) {
50
+ const { optionsSchemaSelector = selectorField } = getUiOptions<T, S, F>(uiSchema);
51
+ selectorField = optionsSchemaSelector;
52
+ }
52
53
  return (
53
54
  altSchemas &&
54
55
  altSchemas.map((aSchemaDef, index) => {
55
56
  const { title } = getUiOptions<T, S, F>(altUiSchemas?.[index]);
56
57
  const aSchema = aSchemaDef as S;
57
- const value = toConstant(aSchema);
58
- const label = title || aSchema.title || String(value);
58
+ let value: EnumOptionsType<S>['value'];
59
+ let label = title;
60
+ if (selectorField) {
61
+ const innerSchema: S = get(aSchema, [PROPERTIES_KEY, selectorField], {}) as S;
62
+ value = get(innerSchema, DEFAULT_KEY, get(innerSchema, CONST_KEY));
63
+ label = label || innerSchema?.title || aSchema.title || String(value);
64
+ } else {
65
+ value = toConstant(aSchema);
66
+ label = label || aSchema.title || String(value);
67
+ }
59
68
  return {
60
69
  schema: aSchema,
61
70
  label,
@@ -1,5 +1,4 @@
1
1
  import get from 'lodash/get';
2
- import isEqual from 'lodash/isEqual';
3
2
 
4
3
  import { ID_KEY } from '../constants';
5
4
  import hashForSchema from '../hashForSchema';
@@ -15,6 +14,7 @@ import {
15
14
  ValidationData,
16
15
  ValidatorType,
17
16
  } from '../types';
17
+ import deepEquals from '../deepEquals';
18
18
 
19
19
  /** The type of the map of schema hash to schema
20
20
  */
@@ -67,11 +67,11 @@ export default class ParserValidator<T = any, S extends StrictRJSFSchema = RJSFS
67
67
  const existing = this.schemaMap[key];
68
68
  if (!existing) {
69
69
  this.schemaMap[key] = identifiedSchema;
70
- } else if (!isEqual(existing, identifiedSchema)) {
70
+ } else if (!deepEquals(existing, identifiedSchema)) {
71
71
  console.error('existing schema:', JSON.stringify(existing, null, 2));
72
72
  console.error('new schema:', JSON.stringify(identifiedSchema, null, 2));
73
73
  throw new Error(
74
- `Two different schemas exist with the same key ${key}! What a bad coincidence. If possible, try adding an $id to one of the schemas`
74
+ `Two different schemas exist with the same key ${key}! What a bad coincidence. If possible, try adding an $id to one of the schemas`,
75
75
  );
76
76
  }
77
77
  }
@@ -91,7 +91,7 @@ export default class ParserValidator<T = any, S extends StrictRJSFSchema = RJSFS
91
91
  * @throws - Error when the given `rootSchema` differs from the root schema provided during construction
92
92
  */
93
93
  isValid(schema: S, _formData: T, rootSchema: S): boolean {
94
- if (!isEqual(rootSchema, this.rootSchema)) {
94
+ if (!deepEquals(rootSchema, this.rootSchema)) {
95
95
  throw new Error('Unexpectedly calling isValid() with a rootSchema that differs from the construction rootSchema');
96
96
  }
97
97
  this.addSchema(schema, hashForSchema<S>(schema));
@@ -131,7 +131,7 @@ export default class ParserValidator<T = any, S extends StrictRJSFSchema = RJSFS
131
131
  _schema: S,
132
132
  _customValidate?: CustomValidator<T, S, F>,
133
133
  _transformErrors?: ErrorTransformer<T, S, F>,
134
- _uiSchema?: UiSchema<T, S, F>
134
+ _uiSchema?: UiSchema<T, S, F>,
135
135
  ): ValidationData<T> {
136
136
  throw new Error('Unexpectedly calling the `validateFormData()` method during schema parsing');
137
137
  }
@@ -1,10 +1,10 @@
1
1
  import forEach from 'lodash/forEach';
2
- import isEqual from 'lodash/isEqual';
3
2
 
4
3
  import { FormContextType, RJSFSchema, StrictRJSFSchema } from '../types';
5
- import { PROPERTIES_KEY, ITEMS_KEY } from '../constants';
4
+ import { ITEMS_KEY, PROPERTIES_KEY } from '../constants';
6
5
  import ParserValidator, { SchemaMap } from './ParserValidator';
7
- import { retrieveSchemaInternal, resolveAnyOrOneOfSchemas } from '../schema/retrieveSchema';
6
+ import { resolveAnyOrOneOfSchemas, retrieveSchemaInternal } from '../schema/retrieveSchema';
7
+ import deepEquals from '../deepEquals';
8
8
 
9
9
  /** Recursive function used to parse the given `schema` belonging to the `rootSchema`. The `validator` is used to
10
10
  * capture the sub-schemas that the `isValid()` function is called with. For each schema returned by the
@@ -20,11 +20,11 @@ function parseSchema<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends
20
20
  validator: ParserValidator<T, S, F>,
21
21
  recurseList: S[],
22
22
  rootSchema: S,
23
- schema: S
23
+ schema: S,
24
24
  ) {
25
25
  const schemas = retrieveSchemaInternal<T, S, F>(validator, schema, rootSchema, undefined, true);
26
26
  schemas.forEach((schema) => {
27
- const sameSchemaIndex = recurseList.findIndex((item) => isEqual(item, schema));
27
+ const sameSchemaIndex = recurseList.findIndex((item) => deepEquals(item, schema));
28
28
  if (sameSchemaIndex === -1) {
29
29
  recurseList.push(schema);
30
30
  const allOptions = resolveAnyOrOneOfSchemas<T, S, F>(validator, schema, rootSchema, true);
@@ -49,7 +49,7 @@ function parseSchema<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends
49
49
  * @returns - The `SchemaMap` of all schemas that were parsed
50
50
  */
51
51
  export default function schemaParser<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
52
- rootSchema: S
52
+ rootSchema: S,
53
53
  ): SchemaMap<S> {
54
54
  const validator = new ParserValidator<T, S, F>(rootSchema);
55
55
  const recurseList: S[] = [];
@@ -0,0 +1,138 @@
1
+ import get from 'lodash/get';
2
+ import has from 'lodash/has';
3
+
4
+ import findSelectedOptionInXxxOf from './findSelectedOptionInXxxOf';
5
+ import getFromSchema from './getFromSchema';
6
+ import { ANY_OF_KEY, ONE_OF_KEY, PROPERTIES_KEY, REQUIRED_KEY } from '../constants';
7
+ import {
8
+ Experimental_CustomMergeAllOf,
9
+ FormContextType,
10
+ FoundFieldType,
11
+ RJSFSchema,
12
+ StrictRJSFSchema,
13
+ ValidatorType,
14
+ } from '../types';
15
+
16
+ /** Unique schema that represents no schema was found, exported for testing purposes */
17
+ export const NOT_FOUND_SCHEMA = { title: '!@#$_UNKNOWN_$#@!' };
18
+
19
+ /** Finds the field specified by the `path` within the root or recursed `schema`. If there is no field for the specified
20
+ * `path`, then the default `{ field: undefined, isRequired: undefined }` is returned. It determines whether a leaf
21
+ * field is in the `required` list for its parent and if so, it is marked as required on return.
22
+ *
23
+ * @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
24
+ * @param rootSchema - The root schema that will be forwarded to all the APIs
25
+ // * @param schema - The node within the JSON schema in which to search
26
+ * @param path - The keys in the path to the desired field
27
+ * @param [formData={}] - The form data that is used to determine which anyOf/oneOf option to descend
28
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
29
+ * @returns - An object that contains the field and its required state. If no field can be found then
30
+ * `{ field: undefined, isRequired: undefined }` is returned.
31
+ */
32
+ export default function findFieldInSchema<
33
+ T = undefined,
34
+ S extends StrictRJSFSchema = RJSFSchema,
35
+ F extends FormContextType = any,
36
+ >(
37
+ validator: ValidatorType<T, S, F>,
38
+ rootSchema: S,
39
+ schema: S,
40
+ path: string | string[],
41
+ formData: T = {} as T,
42
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
43
+ ): FoundFieldType<S> {
44
+ const pathList = Array.isArray(path) ? [...path] : path.split('.');
45
+ let parentField = schema;
46
+
47
+ // store the desired field into a variable and removing it from the `pathList`
48
+ const fieldName = pathList.pop()!;
49
+
50
+ if (pathList.length) {
51
+ // drilling into the schema for each sub-path and taking into account of the any/oneOfs
52
+ pathList.forEach((subPath) => {
53
+ parentField = getFromSchema<T, S, F>(
54
+ validator,
55
+ rootSchema,
56
+ parentField,
57
+ [PROPERTIES_KEY, subPath],
58
+ {} as S,
59
+ experimental_customMergeAllOf,
60
+ );
61
+ if (has(parentField, ONE_OF_KEY)) {
62
+ // if this sub-path has a `oneOf` then use the formData to drill into the schema with the selected option
63
+ parentField = findSelectedOptionInXxxOf(
64
+ validator,
65
+ rootSchema,
66
+ parentField,
67
+ fieldName,
68
+ ONE_OF_KEY,
69
+ get(formData, subPath),
70
+ experimental_customMergeAllOf,
71
+ )!;
72
+ } else if (has(parentField, ANY_OF_KEY)) {
73
+ // if this sub-path has a `anyOf` then use the formData to drill into the schema with the selected option
74
+ parentField = findSelectedOptionInXxxOf(
75
+ validator,
76
+ rootSchema,
77
+ parentField,
78
+ fieldName,
79
+ ANY_OF_KEY,
80
+ get(formData, subPath),
81
+ experimental_customMergeAllOf,
82
+ )!;
83
+ }
84
+ });
85
+ }
86
+
87
+ if (has(parentField, ONE_OF_KEY)) {
88
+ // When oneOf is in the root schema, use the formData to drill into the schema with the selected option
89
+ parentField = findSelectedOptionInXxxOf(
90
+ validator,
91
+ rootSchema,
92
+ parentField,
93
+ fieldName,
94
+ ONE_OF_KEY,
95
+ formData,
96
+ experimental_customMergeAllOf,
97
+ )!;
98
+ } else if (has(parentField, ANY_OF_KEY)) {
99
+ // When anyOf is in the root schema, use the formData to drill into the schema with the selected option
100
+ parentField = findSelectedOptionInXxxOf(
101
+ validator,
102
+ rootSchema,
103
+ parentField,
104
+ fieldName,
105
+ ANY_OF_KEY,
106
+ formData,
107
+ experimental_customMergeAllOf,
108
+ )!;
109
+ }
110
+
111
+ // taking the most updated `parentField`, get our desired field
112
+ let field: S | undefined = getFromSchema<T, S, F>(
113
+ validator,
114
+ rootSchema,
115
+ parentField,
116
+ [PROPERTIES_KEY, fieldName],
117
+ NOT_FOUND_SCHEMA as S,
118
+ experimental_customMergeAllOf,
119
+ );
120
+ if (field === NOT_FOUND_SCHEMA) {
121
+ field = undefined;
122
+ }
123
+ // check to see if our desired field is in the `required` list for its parent
124
+ const requiredArray = getFromSchema<T, S, F>(
125
+ validator,
126
+ rootSchema,
127
+ parentField,
128
+ REQUIRED_KEY,
129
+ [] as T,
130
+ experimental_customMergeAllOf,
131
+ );
132
+ let isRequired: boolean | undefined;
133
+ if (field && Array.isArray(requiredArray)) {
134
+ isRequired = requiredArray.includes(fieldName);
135
+ }
136
+
137
+ return { field, isRequired };
138
+ }
@@ -0,0 +1,53 @@
1
+ import get from 'lodash/get';
2
+ import isEqual from 'lodash/isEqual';
3
+
4
+ import { CONST_KEY, DEFAULT_KEY, PROPERTIES_KEY } from '../constants';
5
+ import { Experimental_CustomMergeAllOf, FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
6
+ import retrieveSchema from './retrieveSchema';
7
+ import getDiscriminatorFieldFromSchema from '../getDiscriminatorFieldFromSchema';
8
+
9
+ /** Finds the option inside the `schema['any/oneOf']` list which has the `properties[selectorField].default` or
10
+ * `properties[selectorField].const` that matches the `formData[selectorField]` value. For the purposes of this
11
+ * function, `selectorField` is either `schema.discriminator.propertyName` or `fallbackField`. The `LayoutGridField`
12
+ * works directly with schemas in a recursive manner, making this faster than `getFirstMatchingOption()`.
13
+ *
14
+ * @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
15
+ * @param rootSchema - The root schema that will be forwarded to all the APIs
16
+ * @param schema - The schema element in which to search for the selected anyOf/oneOf option
17
+ * @param fallbackField - The field to use as a backup selector field if the schema does not have a required field
18
+ * @param xxx - Either `anyOf` or `oneOf`, defines which value is being sought
19
+ * @param [formData={}] - The form data that is used to determine which anyOf/oneOf option to descend
20
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
21
+ * @returns - The anyOf/oneOf option that matches the selector field in the schema or undefined if nothing is selected
22
+ */
23
+ export default function findSelectedOptionInXxxOf<
24
+ T = any,
25
+ S extends StrictRJSFSchema = RJSFSchema,
26
+ F extends FormContextType = any,
27
+ >(
28
+ validator: ValidatorType<T, S, F>,
29
+ rootSchema: S,
30
+ schema: S,
31
+ fallbackField: string,
32
+ xxx: 'anyOf' | 'oneOf',
33
+ formData: T = {} as T,
34
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
35
+ ): S | undefined {
36
+ if (Array.isArray(schema[xxx])) {
37
+ const discriminator = getDiscriminatorFieldFromSchema<S>(schema);
38
+ const selectorField = discriminator || fallbackField;
39
+ const xxxOfs = schema[xxx]!.map((xxxOf) =>
40
+ retrieveSchema<T, S, F>(validator, xxxOf as S, rootSchema, formData, experimental_customMergeAllOf),
41
+ );
42
+ const data = get(formData, selectorField);
43
+ if (data !== undefined) {
44
+ return xxxOfs.find((xxx) => {
45
+ return isEqual(
46
+ get(xxx, [PROPERTIES_KEY, selectorField, DEFAULT_KEY], get(xxx, [PROPERTIES_KEY, selectorField, CONST_KEY])),
47
+ data,
48
+ );
49
+ });
50
+ }
51
+ }
52
+ return undefined;
53
+ }
@@ -10,7 +10,7 @@ import getFirstMatchingOption from './getFirstMatchingOption';
10
10
  import retrieveSchema, { resolveAllReferences } from './retrieveSchema';
11
11
  import { ONE_OF_KEY, REF_KEY, JUNK_OPTION_ID, ANY_OF_KEY } from '../constants';
12
12
  import guessType from '../guessType';
13
- import { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
13
+ import { Experimental_CustomMergeAllOf, FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
14
14
  import getDiscriminatorFieldFromSchema from '../getDiscriminatorFieldFromSchema';
15
15
  import getOptionMatchingSimpleDiscriminator from '../getOptionMatchingSimpleDiscriminator';
16
16
 
@@ -45,13 +45,15 @@ export const JUNK_OPTION: StrictRJSFSchema = {
45
45
  * @param rootSchema - The root JSON schema of the entire form
46
46
  * @param schema - The schema for which the score is being calculated
47
47
  * @param formData - The form data associated with the schema, used to calculate the score
48
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
48
49
  * @returns - The score a schema against the formData
49
50
  */
50
51
  export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
51
52
  validator: ValidatorType<T, S, F>,
52
53
  rootSchema: S,
53
54
  schema?: S,
54
- formData: any = {}
55
+ formData?: any,
56
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
55
57
  ): number {
56
58
  let totalScore = 0;
57
59
  if (schema) {
@@ -64,8 +66,23 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
64
66
  return score;
65
67
  }
66
68
  if (has(value, REF_KEY)) {
67
- const newSchema = retrieveSchema<T, S, F>(validator, value as S, rootSchema, formValue);
68
- return score + calculateIndexScore<T, S, F>(validator, rootSchema, newSchema, formValue || {});
69
+ const newSchema = retrieveSchema<T, S, F>(
70
+ validator,
71
+ value as S,
72
+ rootSchema,
73
+ formValue,
74
+ experimental_customMergeAllOf,
75
+ );
76
+ return (
77
+ score +
78
+ calculateIndexScore<T, S, F>(
79
+ validator,
80
+ rootSchema,
81
+ newSchema,
82
+ formValue || {},
83
+ experimental_customMergeAllOf,
84
+ )
85
+ );
69
86
  }
70
87
  if ((has(value, ONE_OF_KEY) || has(value, ANY_OF_KEY)) && formValue) {
71
88
  const key = has(value, ONE_OF_KEY) ? ONE_OF_KEY : ANY_OF_KEY;
@@ -78,12 +95,20 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
78
95
  formValue,
79
96
  get(value, key) as S[],
80
97
  -1,
81
- discriminator
98
+ discriminator,
99
+ experimental_customMergeAllOf,
82
100
  )
83
101
  );
84
102
  }
85
103
  if (value.type === 'object') {
86
- return score + calculateIndexScore<T, S, F>(validator, rootSchema, value as S, formValue || {});
104
+ if (isObject(formValue)) {
105
+ // If the structure is matching then give it a little boost in score
106
+ score += 1;
107
+ }
108
+ return (
109
+ score +
110
+ calculateIndexScore<T, S, F>(validator, rootSchema, value as S, formValue, experimental_customMergeAllOf)
111
+ );
87
112
  }
88
113
  if (value.type === guessType(formValue)) {
89
114
  // If the types match, then we bump the score by one
@@ -102,7 +127,7 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
102
127
  }
103
128
  return score;
104
129
  },
105
- 0
130
+ 0,
106
131
  );
107
132
  } else if (isString(schema.type) && schema.type === guessType(formData)) {
108
133
  totalScore += 1;
@@ -131,19 +156,21 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
131
156
  * @param [selectedOption=-1] - The index of the currently selected option, defaulted to -1 if not specified
132
157
  * @param [discriminatorField] - The optional name of the field within the options object whose value is used to
133
158
  * determine which option is selected
159
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
134
160
  * @returns - The index of the option that is the closest match to the `formData` or the `selectedOption` if no match
135
161
  */
136
162
  export default function getClosestMatchingOption<
137
163
  T = any,
138
164
  S extends StrictRJSFSchema = RJSFSchema,
139
- F extends FormContextType = any
165
+ F extends FormContextType = any,
140
166
  >(
141
167
  validator: ValidatorType<T, S, F>,
142
168
  rootSchema: S,
143
169
  formData: T | undefined,
144
170
  options: S[],
145
171
  selectedOption = -1,
146
- discriminatorField?: string
172
+ discriminatorField?: string,
173
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
147
174
  ): number {
148
175
  // First resolve any refs in the options
149
176
  const resolvedOptions = options.map((option) => {
@@ -181,14 +208,14 @@ export default function getClosestMatchingOption<
181
208
  (scoreData: BestType, index: number) => {
182
209
  const { bestScore } = scoreData;
183
210
  const option = resolvedOptions[index];
184
- const score = calculateIndexScore(validator, rootSchema, option, formData);
211
+ const score = calculateIndexScore(validator, rootSchema, option, formData, experimental_customMergeAllOf);
185
212
  scoreCount.add(score);
186
213
  if (score > bestScore) {
187
214
  return { bestIndex: index, bestScore: score };
188
215
  }
189
216
  return scoreData;
190
217
  },
191
- { bestIndex: selectedOption, bestScore: 0 }
218
+ { bestIndex: selectedOption, bestScore: 0 },
192
219
  );
193
220
  // if all scores are the same go with selectedOption
194
221
  if (scoreCount.size === 1 && selectedOption >= 0) {