@rjsf/utils 6.6.1 → 6.7.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 (289) hide show
  1. package/LICENSE.md +201 -0
  2. package/dist/index.cjs +534 -376
  3. package/dist/index.cjs.map +4 -4
  4. package/dist/utils.esm.js +534 -376
  5. package/dist/utils.esm.js.map +4 -4
  6. package/dist/utils.umd.js +561 -400
  7. package/lib/ErrorSchemaBuilder.d.ts +1 -1
  8. package/lib/SelectedOptionDescription.d.ts +4 -0
  9. package/lib/SelectedOptionDescription.js +24 -0
  10. package/lib/SelectedOptionDescription.js.map +1 -0
  11. package/lib/allowAdditionalItems.d.ts +1 -1
  12. package/lib/allowAdditionalItems.js +1 -0
  13. package/lib/allowAdditionalItems.js.map +1 -1
  14. package/lib/asNumber.js +2 -0
  15. package/lib/asNumber.js.map +1 -1
  16. package/lib/canExpand.d.ts +1 -1
  17. package/lib/constIsAjvDataReference.d.ts +1 -1
  18. package/lib/constants.d.ts +8 -5
  19. package/lib/constants.js +10 -7
  20. package/lib/constants.js.map +1 -1
  21. package/lib/createErrorHandler.d.ts +1 -1
  22. package/lib/createErrorHandler.js +2 -6
  23. package/lib/createErrorHandler.js.map +1 -1
  24. package/lib/createSchemaUtils.d.ts +1 -1
  25. package/lib/createSchemaUtils.js +3 -1
  26. package/lib/createSchemaUtils.js.map +1 -1
  27. package/lib/dataURItoBlob.js +3 -3
  28. package/lib/dataURItoBlob.js.map +1 -1
  29. package/lib/dateRangeOptions.d.ts +1 -1
  30. package/lib/dateRangeOptions.js +8 -7
  31. package/lib/dateRangeOptions.js.map +1 -1
  32. package/lib/englishStringTranslator.d.ts +1 -1
  33. package/lib/enumOptionSelectedValue.d.ts +1 -1
  34. package/lib/enumOptionValueDecoder.d.ts +1 -1
  35. package/lib/enumOptionValueDecoder.js +1 -1
  36. package/lib/enumOptionValueDecoder.js.map +1 -1
  37. package/lib/enumOptionValueEncoder.d.ts +1 -1
  38. package/lib/enumOptionsDeselectValue.d.ts +1 -1
  39. package/lib/enumOptionsIndexForValue.d.ts +1 -1
  40. package/lib/enumOptionsIndexForValue.js.map +1 -1
  41. package/lib/enumOptionsIsSelected.d.ts +1 -1
  42. package/lib/enumOptionsSelectValue.d.ts +1 -1
  43. package/lib/enumOptionsValueForIndex.d.ts +2 -2
  44. package/lib/enumOptionsValueForIndex.js.map +1 -1
  45. package/lib/enums.d.ts +4 -0
  46. package/lib/enums.js +4 -0
  47. package/lib/enums.js.map +1 -1
  48. package/lib/findSchemaDefinition.d.ts +1 -1
  49. package/lib/findSchemaDefinition.js +15 -15
  50. package/lib/findSchemaDefinition.js.map +1 -1
  51. package/lib/getChangedFields.js +4 -6
  52. package/lib/getChangedFields.js.map +1 -1
  53. package/lib/getDateElementProps.d.ts +3 -3
  54. package/lib/getDiscriminatorFieldFromSchema.d.ts +1 -1
  55. package/lib/getDiscriminatorFieldFromSchema.js +1 -0
  56. package/lib/getDiscriminatorFieldFromSchema.js.map +1 -1
  57. package/lib/getInputProps.d.ts +1 -1
  58. package/lib/getOptionMatchingSimpleDiscriminator.d.ts +1 -1
  59. package/lib/getOptionMatchingSimpleDiscriminator.js +10 -11
  60. package/lib/getOptionMatchingSimpleDiscriminator.js.map +1 -1
  61. package/lib/getOptionValueFormat.d.ts +1 -1
  62. package/lib/getSchemaType.d.ts +1 -1
  63. package/lib/getSchemaType.js +2 -1
  64. package/lib/getSchemaType.js.map +1 -1
  65. package/lib/getSubmitButtonOptions.d.ts +1 -1
  66. package/lib/getSubmitButtonOptions.js +1 -1
  67. package/lib/getSubmitButtonOptions.js.map +1 -1
  68. package/lib/getTemplate.d.ts +1 -1
  69. package/lib/getTestIds.d.ts +1 -1
  70. package/lib/getUiOptions.d.ts +1 -1
  71. package/lib/getUiOptions.js +2 -1
  72. package/lib/getUiOptions.js.map +1 -1
  73. package/lib/getWidget.d.ts +1 -1
  74. package/lib/getWidget.js +4 -4
  75. package/lib/getWidget.js.map +1 -1
  76. package/lib/guessType.js +1 -1
  77. package/lib/guessType.js.map +1 -1
  78. package/lib/hasWidget.d.ts +1 -1
  79. package/lib/hashForSchema.d.ts +3 -1
  80. package/lib/hashForSchema.js +11 -4
  81. package/lib/hashForSchema.js.map +1 -1
  82. package/lib/idGenerators.d.ts +1 -1
  83. package/lib/index.d.ts +14 -7
  84. package/lib/index.js +5 -2
  85. package/lib/index.js.map +1 -1
  86. package/lib/isConstant.d.ts +1 -1
  87. package/lib/isCustomWidget.d.ts +1 -1
  88. package/lib/isCustomWidget.js +1 -1
  89. package/lib/isCustomWidget.js.map +1 -1
  90. package/lib/isFixedItems.d.ts +3 -3
  91. package/lib/isFixedItems.js +3 -3
  92. package/lib/isFixedItems.js.map +1 -1
  93. package/lib/isRootSchema.d.ts +1 -1
  94. package/lib/isRootSchema.js +2 -3
  95. package/lib/isRootSchema.js.map +1 -1
  96. package/lib/labelValue.d.ts +1 -1
  97. package/lib/logUnsupportedDefaultForEnum.d.ts +9 -0
  98. package/lib/logUnsupportedDefaultForEnum.js +18 -0
  99. package/lib/logUnsupportedDefaultForEnum.js.map +1 -0
  100. package/lib/lookupFromFormContext.d.ts +1 -1
  101. package/lib/mergeDefaultsWithFormData.js +6 -5
  102. package/lib/mergeDefaultsWithFormData.js.map +1 -1
  103. package/lib/mergeObjects.d.ts +4 -2
  104. package/lib/mergeObjects.js +1 -1
  105. package/lib/mergeObjects.js.map +1 -1
  106. package/lib/mergeSchemas.d.ts +4 -2
  107. package/lib/mergeSchemas.js +13 -6
  108. package/lib/mergeSchemas.js.map +1 -1
  109. package/lib/nameGenerators.d.ts +1 -1
  110. package/lib/optionsList.d.ts +1 -1
  111. package/lib/optionsList.js +22 -21
  112. package/lib/optionsList.js.map +1 -1
  113. package/lib/orderProperties.js +3 -3
  114. package/lib/orderProperties.js.map +1 -1
  115. package/lib/pad.js +1 -1
  116. package/lib/pad.js.map +1 -1
  117. package/lib/parseDateString.d.ts +1 -1
  118. package/lib/parseDateString.js +1 -1
  119. package/lib/parseDateString.js.map +1 -1
  120. package/lib/parser/ParserValidator.d.ts +2 -4
  121. package/lib/parser/ParserValidator.js +2 -0
  122. package/lib/parser/ParserValidator.js.map +1 -1
  123. package/lib/parser/index.d.ts +1 -1
  124. package/lib/parser/schemaParser.d.ts +2 -2
  125. package/lib/parser/schemaParser.js +7 -7
  126. package/lib/parser/schemaParser.js.map +1 -1
  127. package/lib/rangeSpec.d.ts +1 -2
  128. package/lib/rangeSpec.js.map +1 -1
  129. package/lib/removeOptionalEmptyObjects.d.ts +1 -1
  130. package/lib/removeOptionalEmptyObjects.js +6 -8
  131. package/lib/removeOptionalEmptyObjects.js.map +1 -1
  132. package/lib/resolveUiSchema.d.ts +1 -1
  133. package/lib/resolveUiSchema.js +16 -16
  134. package/lib/resolveUiSchema.js.map +1 -1
  135. package/lib/schema/findFieldInSchema.d.ts +1 -1
  136. package/lib/schema/findSelectedOptionInXxxOf.d.ts +1 -1
  137. package/lib/schema/findSelectedOptionInXxxOf.js +1 -3
  138. package/lib/schema/findSelectedOptionInXxxOf.js.map +1 -1
  139. package/lib/schema/getClosestMatchingOption.d.ts +1 -1
  140. package/lib/schema/getClosestMatchingOption.js +6 -9
  141. package/lib/schema/getClosestMatchingOption.js.map +1 -1
  142. package/lib/schema/getDefaultFormState.d.ts +4 -4
  143. package/lib/schema/getDefaultFormState.js +81 -43
  144. package/lib/schema/getDefaultFormState.js.map +1 -1
  145. package/lib/schema/getDisplayLabel.d.ts +1 -1
  146. package/lib/schema/getDisplayLabel.js +2 -3
  147. package/lib/schema/getDisplayLabel.js.map +1 -1
  148. package/lib/schema/getFirstMatchingOption.d.ts +1 -1
  149. package/lib/schema/getFirstMatchingOption.js +2 -2
  150. package/lib/schema/getFirstMatchingOption.js.map +1 -1
  151. package/lib/schema/getFromSchema.d.ts +1 -1
  152. package/lib/schema/index.js +9 -3
  153. package/lib/schema/index.js.map +1 -1
  154. package/lib/schema/isFilesArray.d.ts +1 -1
  155. package/lib/schema/isMultiSelect.d.ts +1 -1
  156. package/lib/schema/isMultiSelect.js.map +1 -1
  157. package/lib/schema/isSelect.d.ts +1 -1
  158. package/lib/schema/isSelect.js +1 -1
  159. package/lib/schema/isSelect.js.map +1 -1
  160. package/lib/schema/omitExtraData.d.ts +1 -1
  161. package/lib/schema/omitExtraData.js +66 -52
  162. package/lib/schema/omitExtraData.js.map +1 -1
  163. package/lib/schema/retrieveSchema.d.ts +7 -3
  164. package/lib/schema/retrieveSchema.js +83 -56
  165. package/lib/schema/retrieveSchema.js.map +1 -1
  166. package/lib/schema/sanitizeDataForNewSchema.d.ts +1 -1
  167. package/lib/schema/sanitizeDataForNewSchema.js +48 -7
  168. package/lib/schema/sanitizeDataForNewSchema.js.map +1 -1
  169. package/lib/schema/toPathSchema.d.ts +1 -1
  170. package/lib/schema/toPathSchema.js +9 -5
  171. package/lib/schema/toPathSchema.js.map +1 -1
  172. package/lib/schemaRequiresTrueValue.d.ts +1 -1
  173. package/lib/schemaRequiresTrueValue.js +4 -3
  174. package/lib/schemaRequiresTrueValue.js.map +1 -1
  175. package/lib/shallowEquals.js +2 -2
  176. package/lib/shallowEquals.js.map +1 -1
  177. package/lib/shouldRenderOptionalField.d.ts +1 -1
  178. package/lib/toConstant.d.ts +1 -1
  179. package/lib/toDateString.d.ts +1 -1
  180. package/lib/toErrorList.d.ts +1 -1
  181. package/lib/toErrorList.js +3 -3
  182. package/lib/toErrorList.js.map +1 -1
  183. package/lib/toErrorSchema.d.ts +1 -1
  184. package/lib/toFieldPathId.d.ts +1 -1
  185. package/lib/tsconfig.tsbuildinfo +1 -1
  186. package/lib/types.d.ts +63 -57
  187. package/lib/unwrapErrorHandler.d.ts +1 -1
  188. package/lib/unwrapErrorHandler.js +7 -9
  189. package/lib/unwrapErrorHandler.js.map +1 -1
  190. package/lib/useAltDateWidgetProps.d.ts +6 -6
  191. package/lib/useAltDateWidgetProps.js +3 -3
  192. package/lib/useAltDateWidgetProps.js.map +1 -1
  193. package/lib/useFileWidgetProps.d.ts +2 -2
  194. package/lib/useFileWidgetProps.js +3 -3
  195. package/lib/useFileWidgetProps.js.map +1 -1
  196. package/lib/validationDataMerge.d.ts +1 -1
  197. package/lib/withIdRefPrefix.d.ts +1 -1
  198. package/lib/withIdRefPrefix.js +12 -12
  199. package/lib/withIdRefPrefix.js.map +1 -1
  200. package/package.json +19 -19
  201. package/src/ErrorSchemaBuilder.ts +1 -1
  202. package/src/SelectedOptionDescription.tsx +48 -0
  203. package/src/allowAdditionalItems.ts +2 -1
  204. package/src/asNumber.ts +2 -0
  205. package/src/canExpand.ts +1 -1
  206. package/src/constIsAjvDataReference.ts +2 -2
  207. package/src/constants.ts +10 -7
  208. package/src/createErrorHandler.ts +6 -7
  209. package/src/createSchemaUtils.ts +4 -2
  210. package/src/dataURItoBlob.ts +3 -3
  211. package/src/dateRangeOptions.ts +9 -7
  212. package/src/englishStringTranslator.ts +1 -1
  213. package/src/enumOptionSelectedValue.ts +1 -1
  214. package/src/enumOptionValueDecoder.ts +2 -2
  215. package/src/enumOptionValueEncoder.ts +1 -1
  216. package/src/enumOptionsDeselectValue.ts +1 -1
  217. package/src/enumOptionsIndexForValue.ts +2 -2
  218. package/src/enumOptionsIsSelected.ts +1 -1
  219. package/src/enumOptionsSelectValue.ts +1 -1
  220. package/src/enumOptionsValueForIndex.ts +2 -2
  221. package/src/enums.ts +4 -0
  222. package/src/findSchemaDefinition.ts +18 -17
  223. package/src/getChangedFields.ts +5 -5
  224. package/src/getDateElementProps.ts +3 -3
  225. package/src/getDiscriminatorFieldFromSchema.ts +2 -1
  226. package/src/getInputProps.ts +1 -1
  227. package/src/getOptionMatchingSimpleDiscriminator.ts +11 -15
  228. package/src/getOptionValueFormat.ts +1 -1
  229. package/src/getSchemaType.ts +3 -2
  230. package/src/getSubmitButtonOptions.ts +3 -3
  231. package/src/getTemplate.ts +1 -1
  232. package/src/getTestIds.ts +1 -1
  233. package/src/getUiOptions.ts +10 -2
  234. package/src/getWidget.tsx +5 -6
  235. package/src/guessType.ts +1 -1
  236. package/src/hasWidget.ts +1 -1
  237. package/src/hashForSchema.ts +12 -5
  238. package/src/idGenerators.ts +1 -1
  239. package/src/index.ts +16 -5
  240. package/src/isConstant.ts +1 -1
  241. package/src/isCustomWidget.ts +2 -2
  242. package/src/isFixedItems.ts +4 -4
  243. package/src/isRootSchema.ts +3 -5
  244. package/src/labelValue.ts +1 -1
  245. package/src/logUnsupportedDefaultForEnum.ts +28 -0
  246. package/src/lookupFromFormContext.ts +1 -1
  247. package/src/mergeDefaultsWithFormData.ts +8 -7
  248. package/src/mergeObjects.ts +2 -2
  249. package/src/mergeSchemas.ts +14 -7
  250. package/src/nameGenerators.ts +1 -1
  251. package/src/optionsList.ts +21 -23
  252. package/src/orderProperties.ts +4 -4
  253. package/src/pad.ts +1 -1
  254. package/src/parseDateString.ts +2 -2
  255. package/src/parser/ParserValidator.ts +4 -4
  256. package/src/parser/index.ts +1 -1
  257. package/src/parser/schemaParser.ts +10 -9
  258. package/src/rangeSpec.ts +1 -2
  259. package/src/removeOptionalEmptyObjects.ts +8 -11
  260. package/src/resolveUiSchema.ts +32 -25
  261. package/src/schema/findFieldInSchema.ts +1 -1
  262. package/src/schema/findSelectedOptionInXxxOf.ts +17 -7
  263. package/src/schema/getClosestMatchingOption.ts +17 -11
  264. package/src/schema/getDefaultFormState.ts +104 -43
  265. package/src/schema/getDisplayLabel.ts +4 -5
  266. package/src/schema/getFirstMatchingOption.ts +3 -3
  267. package/src/schema/getFromSchema.ts +1 -1
  268. package/src/schema/index.ts +3 -0
  269. package/src/schema/isFilesArray.ts +1 -1
  270. package/src/schema/isMultiSelect.ts +7 -1
  271. package/src/schema/isSelect.ts +8 -2
  272. package/src/schema/omitExtraData.ts +73 -60
  273. package/src/schema/retrieveSchema.ts +131 -83
  274. package/src/schema/sanitizeDataForNewSchema.ts +57 -8
  275. package/src/schema/toPathSchema.ts +11 -7
  276. package/src/schemaRequiresTrueValue.ts +4 -4
  277. package/src/shallowEquals.ts +2 -2
  278. package/src/shouldRenderOptionalField.ts +1 -1
  279. package/src/toConstant.ts +1 -1
  280. package/src/toDateString.ts +1 -1
  281. package/src/toErrorList.ts +4 -4
  282. package/src/toErrorSchema.ts +1 -1
  283. package/src/toFieldPathId.ts +1 -1
  284. package/src/types.ts +92 -63
  285. package/src/unwrapErrorHandler.ts +11 -12
  286. package/src/useAltDateWidgetProps.tsx +10 -8
  287. package/src/useFileWidgetProps.ts +7 -7
  288. package/src/validationDataMerge.ts +1 -1
  289. package/src/withIdRefPrefix.ts +12 -12
@@ -1,4 +1,4 @@
1
- import { JSONSchema7Object } from 'json-schema';
1
+ import type { JSONSchema7Object } from 'json-schema';
2
2
  import get from 'lodash/get';
3
3
  import isEmpty from 'lodash/isEmpty';
4
4
 
@@ -25,7 +25,7 @@ import mergeDefaultsWithFormData from '../mergeDefaultsWithFormData';
25
25
  import mergeObjects from '../mergeObjects';
26
26
  import mergeSchemas from '../mergeSchemas';
27
27
  import optionsList from '../optionsList';
28
- import {
28
+ import type {
29
29
  Experimental_CustomMergeAllOf,
30
30
  Experimental_DefaultFormStateBehavior,
31
31
  FormContextType,
@@ -109,7 +109,7 @@ export function computeDefaultBasedOnSchemaTypeAndDefaults<T = any, S extends St
109
109
  * includeUndefinedValues` is false and `emptyObjectFields` is not "skipDefaults", then non-undefined and non-empty-object
110
110
  * values will be added based on certain conditions.
111
111
  *
112
- * @param obj - The object into which the computed default may be added
112
+ * @param acc - The object into which the computed default may be added
113
113
  * @param key - The key into the object at which the computed default may be added
114
114
  * @param computedDefault - The computed default value that maybe should be added to the obj
115
115
  * @param includeUndefinedValues - Optional flag, if true, cause undefined values to be added as defaults.
@@ -125,7 +125,7 @@ export function computeDefaultBasedOnSchemaTypeAndDefaults<T = any, S extends St
125
125
  * @param isNullType - The type of the schema is null
126
126
  */
127
127
  function maybeAddDefaultToObject<T = any>(
128
- obj: GenericObjectType,
128
+ acc: GenericObjectType,
129
129
  key: string,
130
130
  computedDefault: T | T[] | undefined,
131
131
  includeUndefinedValues: boolean | 'excludeObjectChildren',
@@ -140,12 +140,12 @@ function maybeAddDefaultToObject<T = any>(
140
140
  if (includeUndefinedValues === true || isConst) {
141
141
  // If includeUndefinedValues is explicitly true
142
142
  // Or if the schema has a const property defined, then we should always return the computedDefault since it's coming from the const.
143
- obj[key] = computedDefault;
143
+ acc[key] = computedDefault;
144
144
  } else if (includeUndefinedValues === 'excludeObjectChildren') {
145
145
  // Fix for Issue #4709: When in 'excludeObjectChildren' mode, don't set primitive fields to empty objects
146
146
  // Only add the computed default if it's not an empty object placeholder for a primitive field
147
147
  if ((isNullType && computedDefault !== undefined) || !isObject(computedDefault) || !isEmpty(computedDefault)) {
148
- obj[key] = computedDefault;
148
+ acc[key] = computedDefault;
149
149
  }
150
150
  // If computedDefault is an empty object {}, don't add it - let the field stay undefined
151
151
  } else if (emptyObjectFields !== 'skipDefaults') {
@@ -157,7 +157,7 @@ function maybeAddDefaultToObject<T = any>(
157
157
  // If emptyObjectFields 'skipEmptyDefaults' store computedDefault if it's a non-empty object(e.g. not {})
158
158
  if (emptyObjectFields === 'skipEmptyDefaults') {
159
159
  if (!isEmpty(computedDefault)) {
160
- obj[key] = computedDefault;
160
+ acc[key] = computedDefault;
161
161
  }
162
162
  } // Else store computedDefault if it's a non-empty object(e.g. not {}) and satisfies certain conditions
163
163
  // Condition 1: If computedDefault is not empty or if the key is a required field
@@ -166,7 +166,7 @@ function maybeAddDefaultToObject<T = any>(
166
166
  (!isEmpty(computedDefault) || requiredFields.includes(key)) &&
167
167
  (isSelfOrParentRequired || emptyObjectFields !== 'populateRequiredDefaults')
168
168
  ) {
169
- obj[key] = computedDefault;
169
+ acc[key] = computedDefault;
170
170
  }
171
171
  } else if (
172
172
  // Store computedDefault if it's a defined primitive (e.g., true) and satisfies certain conditions
@@ -178,7 +178,7 @@ function maybeAddDefaultToObject<T = any>(
178
178
  emptyObjectFields === 'skipEmptyDefaults' ||
179
179
  (isSelfOrParentRequired && requiredFields.includes(key)))
180
180
  ) {
181
- obj[key] = computedDefault;
181
+ acc[key] = computedDefault;
182
182
  }
183
183
  }
184
184
  }
@@ -232,16 +232,18 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
232
232
  rootSchema = {} as S,
233
233
  includeUndefinedValues = false,
234
234
  _recurseList = [],
235
- experimental_defaultFormStateBehavior = undefined,
236
- experimental_customMergeAllOf = undefined,
235
+ experimental_defaultFormStateBehavior,
236
+ experimental_customMergeAllOf,
237
237
  required,
238
238
  shouldMergeDefaultsIntoFormData = false,
239
239
  initialDefaultsGenerated,
240
240
  } = computeDefaultsProps;
241
241
  let formData: T = (isObject(rawFormData) ? rawFormData : {}) as T;
242
242
  const schema: S = isObject(rawSchema) ? rawSchema : ({} as S);
243
- // Compute the defaults recursively: give highest priority to deepest nodes.
243
+ // Compute the defaults recursively: give highest priority to deepest nodes unless nestedDefaultsPrecedence is ancestorWins.
244
244
  let defaults: T | T[] | undefined = parentDefaults;
245
+ const preferParentDefaults =
246
+ defaults && experimental_defaultFormStateBehavior?.nestedDefaultsPrecedence === 'ancestorWins';
245
247
  // If we get a new schema, then we need to recompute defaults again for the new schema found.
246
248
  let schemaToCompute: S | null = null;
247
249
  let experimental_dfsb_to_compute = experimental_defaultFormStateBehavior;
@@ -259,12 +261,25 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
259
261
  !schema[ONE_OF_KEY] &&
260
262
  !schema[REF_KEY]
261
263
  ) {
262
- // For object defaults, only override parent defaults that are defined in
263
- // schema.default. Skip this for anyOf/oneOf/$ref schemas - they need special handling.
264
- defaults = mergeObjects(defaults!, schema.default as GenericObjectType) as T;
265
- } else if (DEFAULT_KEY in schema && !schema[ANY_OF_KEY] && !schema[ONE_OF_KEY] && !schema[REF_KEY]) {
266
- // If the schema has a default value, then we should use it as the default.
267
- // And if the schema does not have anyOf or oneOf, this is done because we need to merge the defaults with the formData.
264
+ // For object defaults, merge defaults by precedence setting.
265
+ // Skip this for anyOf/oneOf/$ref schemas - they need special handling.
266
+ if (preferParentDefaults) {
267
+ // Use schema.default as the base and only override values that are defined in parent defaults.
268
+ defaults = mergeObjects(schema.default as GenericObjectType, defaults) as T;
269
+ } else {
270
+ // Only override parent defaults that are defined in schema.default.
271
+ defaults = mergeObjects(defaults, schema.default as GenericObjectType) as T;
272
+ }
273
+ } else if (
274
+ DEFAULT_KEY in schema &&
275
+ !preferParentDefaults &&
276
+ !schema[ANY_OF_KEY] &&
277
+ !schema[ONE_OF_KEY] &&
278
+ !schema[REF_KEY]
279
+ ) {
280
+ // If the schema has a default value and parentDefaults does not have precedence
281
+ // And if the schema does not have anyOf or oneOf (since we need to merge the defaults with the formData)
282
+ // Then we should use it as the default.
268
283
  defaults = schema.default as unknown as T;
269
284
  } else if (REF_KEY in schema) {
270
285
  const refName = schema[REF_KEY];
@@ -304,8 +319,10 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
304
319
  defaultFormData,
305
320
  experimental_customMergeAllOf,
306
321
  );
307
- schemaToCompute = resolvedSchema[0]; // pick the first element from resolve dependencies
308
- } else if (isFixedItems(schema)) {
322
+ [schemaToCompute] = resolvedSchema; // pick the first element from resolve dependencies
323
+ } else if (isFixedItems(schema) && !preferParentDefaults) {
324
+ // If the schema contains fixed items and parentDefaults does not have precedence
325
+ // Then construct defaults from defaults of array items.
309
326
  defaults = (schema.items! as S[]).map((itemSchema: S, idx: number) =>
310
327
  computeDefaults<T, S>(validator, itemSchema, {
311
328
  rootSchema,
@@ -314,7 +331,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
314
331
  experimental_defaultFormStateBehavior,
315
332
  experimental_customMergeAllOf,
316
333
  parentDefaults: Array.isArray(parentDefaults) ? parentDefaults[idx] : undefined,
317
- rawFormData: formData as T,
334
+ rawFormData: formData,
318
335
  required,
319
336
  shouldMergeDefaultsIntoFormData,
320
337
  }),
@@ -377,7 +394,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
377
394
  experimental_defaultFormStateBehavior: experimental_dfsb_to_compute,
378
395
  experimental_customMergeAllOf,
379
396
  parentDefaults: defaults as T | undefined,
380
- rawFormData: (rawFormData ?? formData) as T,
397
+ rawFormData: rawFormData ?? formData,
381
398
  required,
382
399
  shouldMergeDefaultsIntoFormData,
383
400
  initialDefaultsGenerated,
@@ -443,19 +460,44 @@ export function ensureFormDataMatchingSchema<
443
460
  experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior,
444
461
  experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
445
462
  ): T | T[] | undefined {
463
+ const shouldRetrieveAllOf =
464
+ experimental_defaultFormStateBehavior?.allOf === 'populateDefaults' && ALL_OF_KEY in schema;
465
+ const schemaToMatch = shouldRetrieveAllOf
466
+ ? retrieveSchema<T, S, F>(validator, schema, rootSchema, formData, experimental_customMergeAllOf)
467
+ : schema;
446
468
  const isSelectField =
447
- !isConstant<S>(schema) && isSelect<T, S, F>(validator, schema, rootSchema, experimental_customMergeAllOf);
469
+ !isConstant<S>(schemaToMatch) &&
470
+ isSelect<T, S, F>(validator, schemaToMatch, rootSchema, experimental_customMergeAllOf);
448
471
  let validFormData: T | T[] | undefined = formData;
449
472
  if (isSelectField) {
450
- const getOptionsList = optionsList<T, S, F>(schema);
473
+ const getOptionsList = optionsList<T, S, F>(schemaToMatch);
451
474
  const isValid = getOptionsList?.some((option) => deepEquals(option.value, formData));
452
475
  validFormData = isValid ? formData : undefined;
453
476
  }
454
477
 
455
478
  // Override the formData with the const if the constAsDefaults is set to always
456
- const constTakesPrecedence = schema[CONST_KEY] && experimental_defaultFormStateBehavior?.constAsDefaults === 'always';
479
+ const constTakesPrecedence =
480
+ schemaToMatch[CONST_KEY] && experimental_defaultFormStateBehavior?.constAsDefaults === 'always';
457
481
  if (constTakesPrecedence) {
458
- validFormData = schema.const as T;
482
+ validFormData = schemaToMatch.const as T;
483
+ } else if (isObject(validFormData) && isObject(schemaToMatch.properties)) {
484
+ validFormData = Object.keys(schemaToMatch.properties).reduce(
485
+ (acc: GenericObjectType, key: string) => {
486
+ const propertySchema: S = get(schemaToMatch, [PROPERTIES_KEY, key], {}) as S;
487
+ if (key in acc && (shouldRetrieveAllOf || (isObject(propertySchema) && ALL_OF_KEY in propertySchema))) {
488
+ acc[key] = ensureFormDataMatchingSchema<T, S, F>(
489
+ validator,
490
+ propertySchema,
491
+ rootSchema,
492
+ get(acc, key),
493
+ experimental_defaultFormStateBehavior,
494
+ experimental_customMergeAllOf,
495
+ );
496
+ }
497
+ return acc;
498
+ },
499
+ { ...(validFormData as GenericObjectType) },
500
+ ) as T;
459
501
  }
460
502
 
461
503
  return validFormData;
@@ -477,8 +519,8 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
477
519
  rootSchema = {} as S,
478
520
  includeUndefinedValues = false,
479
521
  _recurseList = [],
480
- experimental_defaultFormStateBehavior = undefined,
481
- experimental_customMergeAllOf = undefined,
522
+ experimental_defaultFormStateBehavior,
523
+ experimental_customMergeAllOf,
482
524
  required,
483
525
  shouldMergeDefaultsIntoFormData,
484
526
  initialDefaultsGenerated,
@@ -595,7 +637,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
595
637
  * @param validator - an implementation of the `ValidatorType` interface that will be used when necessary
596
638
  * @param rawSchema - The schema for which the default state is desired
597
639
  * @param computeDefaultsProps - Optional props for this function
598
- * @param defaults - Optional props for this function
640
+ * @param initialDefaults - Optional props for this function
599
641
  * @returns - The default value based on the schema type if they are defined for object or array schemas.
600
642
  */
601
643
  export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
@@ -605,15 +647,16 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
605
647
  rawFormData,
606
648
  rootSchema = {} as S,
607
649
  _recurseList = [],
608
- experimental_defaultFormStateBehavior = undefined,
609
- experimental_customMergeAllOf = undefined,
650
+ experimental_defaultFormStateBehavior,
651
+ experimental_customMergeAllOf,
610
652
  required,
611
653
  requiredAsRoot = false,
612
654
  shouldMergeDefaultsIntoFormData,
613
655
  initialDefaultsGenerated,
614
656
  }: ComputeDefaultsProps<T, S> = {},
615
- defaults?: T[],
657
+ initialDefaults?: T[],
616
658
  ): T[] | undefined {
659
+ let defaults = initialDefaults;
617
660
  const schema: S = rawSchema;
618
661
 
619
662
  const arrayMinItemsStateBehavior = experimental_defaultFormStateBehavior?.arrayMinItems ?? {};
@@ -652,8 +695,8 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
652
695
  if (neverPopulate) {
653
696
  defaults = rawFormData as typeof defaults;
654
697
  } else {
655
- const itemDefaults = rawFormData.map((item: T, idx: number) => {
656
- return computeDefaults<T, S, F>(validator, schemaItem, {
698
+ const itemDefaults = rawFormData.map((item: T, idx: number) =>
699
+ computeDefaults<T, S, F>(validator, schemaItem, {
657
700
  rootSchema,
658
701
  _recurseList,
659
702
  experimental_defaultFormStateBehavior,
@@ -663,8 +706,8 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
663
706
  required,
664
707
  shouldMergeDefaultsIntoFormData,
665
708
  initialDefaultsGenerated,
666
- });
667
- }) as T[];
709
+ }),
710
+ ) as T[];
668
711
 
669
712
  // If the populate 'requiredOnly' flag is set then we only merge and include extra defaults if they are required.
670
713
  // Or if populate 'all' is set we merge and include extra defaults.
@@ -673,17 +716,25 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
673
716
  }
674
717
  }
675
718
 
719
+ const defaultsLength = Array.isArray(defaults) ? defaults.length : 0;
720
+
676
721
  if (neverPopulate) {
722
+ if (shouldMergeDefaultsIntoFormData) {
723
+ if (schema.minItems && schema.minItems > defaultsLength) {
724
+ const fillerEntries = Array.from({ length: schema.minItems - defaultsLength }, () => null) as T[];
725
+ return (defaults ?? []).concat(fillerEntries);
726
+ }
727
+ return defaults;
728
+ }
677
729
  return defaults ?? emptyDefault;
678
730
  }
679
731
  if (ignoreMinItemsFlagSet && !required) {
680
732
  // If no form data exists or defaults are set leave the field empty/non-existent, otherwise
681
733
  // return form data/defaults
682
- return defaults ? defaults : undefined;
734
+ return defaults || undefined;
683
735
  }
684
736
 
685
737
  let arrayDefault: T[] | undefined;
686
- const defaultsLength = Array.isArray(defaults) ? defaults.length : 0;
687
738
  if (
688
739
  !schema.minItems ||
689
740
  isMultiSelect<T, S, F>(validator, schema, rootSchema, experimental_customMergeAllOf) ||
@@ -693,7 +744,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
693
744
  // we don't want undefined defaults unless it is both not required or not required as root
694
745
  arrayDefault = defaults || (!required && !requiredAsRoot) ? defaults : emptyDefault;
695
746
  } else {
696
- const defaultEntries: T[] = (defaults || []) as T[];
747
+ const defaultEntries: T[] = defaults || [];
697
748
  const fillerSchema: S = getInnerSchemaForArrayItem<S>(schema, AdditionalItemsHandling.Invert);
698
749
  const fillerDefault = fillerSchema.default;
699
750
 
@@ -732,8 +783,8 @@ export function getDefaultBasedOnSchemaType<
732
783
  validator: ValidatorType<T, S, F>,
733
784
  rawSchema: S,
734
785
  computeDefaultsProps: ComputeDefaultsProps<T, S> = {},
735
- defaults?: T | T[] | undefined,
736
- ): T | T[] | void {
786
+ defaults?: T | T[],
787
+ ): T | T[] | undefined {
737
788
  switch (getSchemaType<S>(rawSchema)) {
738
789
  // We need to recurse for object schema inner default values.
739
790
  case 'object': {
@@ -742,6 +793,8 @@ export function getDefaultBasedOnSchemaType<
742
793
  case 'array': {
743
794
  return getArrayDefaults(validator, rawSchema, computeDefaultsProps, defaults as T[]);
744
795
  }
796
+ default:
797
+ return undefined;
745
798
  }
746
799
  }
747
800
 
@@ -775,7 +828,7 @@ export default function getDefaultFormState<
775
828
  initialDefaultsGenerated?: boolean,
776
829
  ) {
777
830
  if (!isObject(theSchema)) {
778
- throw new Error('Invalid schema: ' + theSchema);
831
+ throw new Error(`Invalid schema: ${theSchema}`);
779
832
  }
780
833
  const schema = retrieveSchema<T, S, F>(validator, theSchema, rootSchema, formData, experimental_customMergeAllOf);
781
834
 
@@ -805,9 +858,17 @@ export default function getDefaultFormState<
805
858
  if (isObject(formData) || Array.isArray(formData)) {
806
859
  const { mergeDefaultsIntoFormData } = experimental_defaultFormStateBehavior || {};
807
860
  const defaultSupercedesUndefined = mergeDefaultsIntoFormData === 'useDefaultIfFormDataUndefined';
861
+ const matchingFormData = ensureFormDataMatchingSchema<T, S, F>(
862
+ validator,
863
+ schema,
864
+ rootSchema ?? schema,
865
+ formData,
866
+ experimental_defaultFormStateBehavior,
867
+ experimental_customMergeAllOf,
868
+ );
808
869
  const result = mergeDefaultsWithFormData<T | T[]>(
809
870
  defaults,
810
- formData,
871
+ matchingFormData,
811
872
  true, // set to true to add any additional default array entries.
812
873
  defaultSupercedesUndefined,
813
874
  true, // set to true to override formData with defaults if they exist.
@@ -1,12 +1,11 @@
1
- import get from 'lodash/get';
2
-
3
1
  import { ADDITIONAL_PROPERTY_FLAG, UI_FIELD_KEY, UI_WIDGET_KEY } from '../constants';
4
2
  import getSchemaType from '../getSchemaType';
5
3
  import getUiOptions from '../getUiOptions';
6
4
  import isCustomWidget from '../isCustomWidget';
7
- import {
5
+ import type {
8
6
  FormContextType,
9
7
  GlobalUISchemaOptions,
8
+ RJSFMarkedSchema,
10
9
  RJSFSchema,
11
10
  StrictRJSFSchema,
12
11
  UiSchema,
@@ -44,7 +43,7 @@ export default function getDisplayLabel<
44
43
  let displayLabel = Boolean(label);
45
44
  if (displayLabel) {
46
45
  const schemaType = getSchemaType<S>(schema);
47
- const addedByAdditionalProperty = get(schema, ADDITIONAL_PROPERTY_FLAG, false);
46
+ const addedByAdditionalProperty = Boolean((schema as RJSFMarkedSchema)[ADDITIONAL_PROPERTY_FLAG]);
48
47
 
49
48
  if (schemaType === 'array') {
50
49
  displayLabel =
@@ -60,7 +59,7 @@ export default function getDisplayLabel<
60
59
  if (schemaType === 'boolean' && uiSchema && !uiSchema[UI_WIDGET_KEY]) {
61
60
  displayLabel = false;
62
61
  }
63
- if (uiSchema && uiSchema[UI_FIELD_KEY]) {
62
+ if (uiSchema?.[UI_FIELD_KEY]) {
64
63
  displayLabel = false;
65
64
  }
66
65
  }
@@ -4,7 +4,7 @@ import isNumber from 'lodash/isNumber';
4
4
 
5
5
  import { PROPERTIES_KEY } from '../constants';
6
6
  import getOptionMatchingSimpleDiscriminator from '../getOptionMatchingSimpleDiscriminator';
7
- import { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
7
+ import type { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
8
8
 
9
9
  /** Given the `formData` and list of `options`, attempts to find the index of the first option that matches the data.
10
10
  * Always returns the first option if there is nothing that matches.
@@ -39,7 +39,7 @@ export default function getFirstMatchingOption<
39
39
  return simpleDiscriminatorMatch;
40
40
  }
41
41
 
42
- for (let i = 0; i < options.length; i++) {
42
+ for (let i = 0; i < options.length; i += 1) {
43
43
  const option = options[i];
44
44
 
45
45
  // If we have a discriminator field, then we will use this to make the determination
@@ -84,7 +84,7 @@ export default function getFirstMatchingOption<
84
84
 
85
85
  augmentedSchema = shallowClone;
86
86
  } else {
87
- augmentedSchema = Object.assign({}, option, requiresAnyOf);
87
+ augmentedSchema = { ...option, ...requiresAnyOf };
88
88
  }
89
89
 
90
90
  // Remove the "required" field as it's likely that not all fields have
@@ -3,7 +3,7 @@ import has from 'lodash/has';
3
3
  import isEmpty from 'lodash/isEmpty';
4
4
 
5
5
  import { REF_KEY } from '../constants';
6
- import {
6
+ import type {
7
7
  Experimental_CustomMergeAllOf,
8
8
  FormContextType,
9
9
  RJSFSchema,
@@ -18,10 +18,12 @@ export {
18
18
  findSelectedOptionInXxxOf,
19
19
  getDefaultFormState,
20
20
  getDisplayLabel,
21
+ // oxlint-disable-next-line typescript/no-deprecated
21
22
  getFieldNames, // Exported only to prevent breaking change in core
22
23
  getClosestMatchingOption,
23
24
  getFirstMatchingOption,
24
25
  getFromSchema,
26
+ // oxlint-disable-next-line typescript/no-deprecated
25
27
  getUsedFormData, // Exported only to prevent breaking change in core
26
28
  isFilesArray,
27
29
  isMultiSelect,
@@ -31,5 +33,6 @@ export {
31
33
  relaxOptionsForScoring,
32
34
  retrieveSchema,
33
35
  sanitizeDataForNewSchema,
36
+ // oxlint-disable-next-line typescript/no-deprecated
34
37
  toPathSchema,
35
38
  };
@@ -1,5 +1,5 @@
1
1
  import { UI_WIDGET_KEY } from '../constants';
2
- import {
2
+ import type {
3
3
  Experimental_CustomMergeAllOf,
4
4
  FormContextType,
5
5
  RJSFSchema,
@@ -1,4 +1,10 @@
1
- import { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType, Experimental_CustomMergeAllOf } from '../types';
1
+ import type {
2
+ FormContextType,
3
+ RJSFSchema,
4
+ StrictRJSFSchema,
5
+ ValidatorType,
6
+ Experimental_CustomMergeAllOf,
7
+ } from '../types';
2
8
  import isSelect from './isSelect';
3
9
 
4
10
  /** Checks to see if the `schema` combination represents a multi-select
@@ -1,5 +1,11 @@
1
1
  import isConstant from '../isConstant';
2
- import { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType, Experimental_CustomMergeAllOf } from '../types';
2
+ import type {
3
+ FormContextType,
4
+ RJSFSchema,
5
+ StrictRJSFSchema,
6
+ ValidatorType,
7
+ Experimental_CustomMergeAllOf,
8
+ } from '../types';
3
9
  import retrieveSchema from './retrieveSchema';
4
10
 
5
11
  /** Checks to see if the `schema` combination represents a select
@@ -22,7 +28,7 @@ export default function isSelect<T = any, S extends StrictRJSFSchema = RJSFSchem
22
28
  return true;
23
29
  }
24
30
  if (Array.isArray(altSchemas)) {
25
- return altSchemas.every((altSchemas) => typeof altSchemas !== 'boolean' && isConstant(altSchemas));
31
+ return altSchemas.every((altSchema) => typeof altSchema !== 'boolean' && isConstant(altSchema));
26
32
  }
27
33
  return false;
28
34
  }