@rjsf/utils 5.21.1 → 5.22.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 (36) hide show
  1. package/dist/index.js +201 -62
  2. package/dist/index.js.map +3 -3
  3. package/dist/utils.esm.js +201 -62
  4. package/dist/utils.esm.js.map +2 -2
  5. package/dist/utils.umd.js +199 -69
  6. package/lib/ErrorSchemaBuilder.d.ts +3 -3
  7. package/lib/ErrorSchemaBuilder.js +2 -1
  8. package/lib/ErrorSchemaBuilder.js.map +1 -1
  9. package/lib/createSchemaUtils.d.ts +3 -2
  10. package/lib/createSchemaUtils.js +17 -11
  11. package/lib/createSchemaUtils.js.map +1 -1
  12. package/lib/mergeDefaultsWithFormData.d.ts +4 -2
  13. package/lib/mergeDefaultsWithFormData.js +9 -4
  14. package/lib/mergeDefaultsWithFormData.js.map +1 -1
  15. package/lib/schema/getClosestMatchingOption.js +6 -2
  16. package/lib/schema/getClosestMatchingOption.js.map +1 -1
  17. package/lib/schema/getDefaultFormState.d.ts +6 -3
  18. package/lib/schema/getDefaultFormState.js +43 -22
  19. package/lib/schema/getDefaultFormState.js.map +1 -1
  20. package/lib/schema/retrieveSchema.d.ts +19 -10
  21. package/lib/schema/retrieveSchema.js +54 -26
  22. package/lib/schema/retrieveSchema.js.map +1 -1
  23. package/lib/schema/toIdSchema.d.ts +3 -2
  24. package/lib/schema/toIdSchema.js +8 -6
  25. package/lib/schema/toIdSchema.js.map +1 -1
  26. package/lib/tsconfig.tsbuildinfo +1 -1
  27. package/lib/types.d.ts +19 -3
  28. package/package.json +2 -2
  29. package/src/ErrorSchemaBuilder.ts +6 -5
  30. package/src/createSchemaUtils.ts +43 -11
  31. package/src/mergeDefaultsWithFormData.ts +16 -4
  32. package/src/schema/getClosestMatchingOption.ts +6 -2
  33. package/src/schema/getDefaultFormState.ts +58 -19
  34. package/src/schema/retrieveSchema.ts +125 -28
  35. package/src/schema/toIdSchema.ts +32 -7
  36. package/src/types.ts +20 -2
@@ -25,7 +25,14 @@ import getDiscriminatorFieldFromSchema from '../getDiscriminatorFieldFromSchema'
25
25
  import guessType from '../guessType';
26
26
  import isObject from '../isObject';
27
27
  import mergeSchemas from '../mergeSchemas';
28
- import { FormContextType, GenericObjectType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
28
+ import {
29
+ Experimental_CustomMergeAllOf,
30
+ FormContextType,
31
+ GenericObjectType,
32
+ RJSFSchema,
33
+ StrictRJSFSchema,
34
+ ValidatorType,
35
+ } from '../types';
29
36
  import getFirstMatchingOption from './getFirstMatchingOption';
30
37
 
31
38
  /** Retrieves an expanded schema that has had all of its conditions, additional properties, references and dependencies
@@ -36,14 +43,29 @@ import getFirstMatchingOption from './getFirstMatchingOption';
36
43
  * @param schema - The schema for which retrieving a schema is desired
37
44
  * @param [rootSchema={}] - The root schema that will be forwarded to all the APIs
38
45
  * @param [rawFormData] - The current formData, if any, to assist retrieving a schema
46
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
39
47
  * @returns - The schema having its conditions, additional properties, references and dependencies resolved
40
48
  */
41
49
  export default function retrieveSchema<
42
50
  T = any,
43
51
  S extends StrictRJSFSchema = RJSFSchema,
44
52
  F extends FormContextType = any
45
- >(validator: ValidatorType<T, S, F>, schema: S, rootSchema: S = {} as S, rawFormData?: T): S {
46
- return retrieveSchemaInternal<T, S, F>(validator, schema, rootSchema, rawFormData)[0];
53
+ >(
54
+ validator: ValidatorType<T, S, F>,
55
+ schema: S,
56
+ rootSchema: S = {} as S,
57
+ rawFormData?: T,
58
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
59
+ ): S {
60
+ return retrieveSchemaInternal<T, S, F>(
61
+ validator,
62
+ schema,
63
+ rootSchema,
64
+ rawFormData,
65
+ undefined,
66
+ undefined,
67
+ experimental_customMergeAllOf
68
+ )[0];
47
69
  }
48
70
 
49
71
  /** Resolves a conditional block (if/else/then) by removing the condition and merging the appropriate conditional branch
@@ -57,6 +79,7 @@ export default function retrieveSchema<
57
79
  * dependencies as a list of schemas
58
80
  * @param recurseList - The list of recursive references already processed
59
81
  * @param [formData] - The current formData to assist retrieving a schema
82
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
60
83
  * @returns - A list of schemas with the appropriate conditions resolved, possibly with all branches expanded
61
84
  */
62
85
  export function resolveCondition<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
@@ -65,7 +88,8 @@ export function resolveCondition<T = any, S extends StrictRJSFSchema = RJSFSchem
65
88
  rootSchema: S,
66
89
  expandAllBranches: boolean,
67
90
  recurseList: string[],
68
- formData?: T
91
+ formData?: T,
92
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
69
93
  ): S[] {
70
94
  const { if: expression, then, else: otherwise, ...resolvedSchemaLessConditional } = schema;
71
95
 
@@ -75,12 +99,28 @@ export function resolveCondition<T = any, S extends StrictRJSFSchema = RJSFSchem
75
99
  if (expandAllBranches) {
76
100
  if (then && typeof then !== 'boolean') {
77
101
  schemas = schemas.concat(
78
- retrieveSchemaInternal<T, S, F>(validator, then as S, rootSchema, formData, expandAllBranches, recurseList)
102
+ retrieveSchemaInternal<T, S, F>(
103
+ validator,
104
+ then as S,
105
+ rootSchema,
106
+ formData,
107
+ expandAllBranches,
108
+ recurseList,
109
+ experimental_customMergeAllOf
110
+ )
79
111
  );
80
112
  }
81
113
  if (otherwise && typeof otherwise !== 'boolean') {
82
114
  schemas = schemas.concat(
83
- retrieveSchemaInternal<T, S, F>(validator, otherwise as S, rootSchema, formData, expandAllBranches, recurseList)
115
+ retrieveSchemaInternal<T, S, F>(
116
+ validator,
117
+ otherwise as S,
118
+ rootSchema,
119
+ formData,
120
+ expandAllBranches,
121
+ recurseList,
122
+ experimental_customMergeAllOf
123
+ )
84
124
  );
85
125
  }
86
126
  } else {
@@ -93,7 +133,8 @@ export function resolveCondition<T = any, S extends StrictRJSFSchema = RJSFSchem
93
133
  rootSchema,
94
134
  formData,
95
135
  expandAllBranches,
96
- recurseList
136
+ recurseList,
137
+ experimental_customMergeAllOf
97
138
  )
98
139
  );
99
140
  }
@@ -102,7 +143,15 @@ export function resolveCondition<T = any, S extends StrictRJSFSchema = RJSFSchem
102
143
  resolvedSchemas = schemas.map((s) => mergeSchemas(resolvedSchemaLessConditional, s) as S);
103
144
  }
104
145
  return resolvedSchemas.flatMap((s) =>
105
- retrieveSchemaInternal<T, S, F>(validator, s, rootSchema, formData, expandAllBranches, recurseList)
146
+ retrieveSchemaInternal<T, S, F>(
147
+ validator,
148
+ s,
149
+ rootSchema,
150
+ formData,
151
+ expandAllBranches,
152
+ recurseList,
153
+ experimental_customMergeAllOf
154
+ )
106
155
  );
107
156
  }
108
157
 
@@ -148,6 +197,7 @@ export function getAllPermutationsOfXxxOf<S extends StrictRJSFSchema = RJSFSchem
148
197
  * as a list of schemas
149
198
  * @param recurseList - The list of recursive references already processed
150
199
  * @param [formData] - The current formData, if any, to assist retrieving a schema
200
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
151
201
  * @returns - The list of schemas having its references, dependencies and allOf schemas resolved
152
202
  */
153
203
  export function resolveSchema<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
@@ -156,7 +206,8 @@ export function resolveSchema<T = any, S extends StrictRJSFSchema = RJSFSchema,
156
206
  rootSchema: S,
157
207
  expandAllBranches: boolean,
158
208
  recurseList: string[],
159
- formData?: T
209
+ formData?: T,
210
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
160
211
  ): S[] {
161
212
  const updatedSchemas = resolveReference<T, S, F>(
162
213
  validator,
@@ -181,7 +232,15 @@ export function resolveSchema<T = any, S extends StrictRJSFSchema = RJSFSchema,
181
232
  formData
182
233
  );
183
234
  return resolvedSchemas.flatMap((s) => {
184
- return retrieveSchemaInternal<T, S, F>(validator, s, rootSchema, formData, expandAllBranches, recurseList);
235
+ return retrieveSchemaInternal<T, S, F>(
236
+ validator,
237
+ s,
238
+ rootSchema,
239
+ formData,
240
+ expandAllBranches,
241
+ recurseList,
242
+ experimental_customMergeAllOf
243
+ );
185
244
  });
186
245
  }
187
246
  if (ALL_OF_KEY in schema && Array.isArray(schema.allOf)) {
@@ -192,7 +251,8 @@ export function resolveSchema<T = any, S extends StrictRJSFSchema = RJSFSchema,
192
251
  rootSchema,
193
252
  formData,
194
253
  expandAllBranches,
195
- recurseList
254
+ recurseList,
255
+ experimental_customMergeAllOf
196
256
  )
197
257
  );
198
258
  const allPermutations = getAllPermutationsOfXxxOf<S>(allOfSchemaElements);
@@ -213,6 +273,7 @@ export function resolveSchema<T = any, S extends StrictRJSFSchema = RJSFSchema,
213
273
  * as a list of schemas
214
274
  * @param recurseList - The list of recursive references already processed
215
275
  * @param [formData] - The current formData, if any, to assist retrieving a schema
276
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
216
277
  * @returns - The list schemas retrieved after having all references resolved
217
278
  */
218
279
  export function resolveReference<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
@@ -221,7 +282,8 @@ export function resolveReference<T = any, S extends StrictRJSFSchema = RJSFSchem
221
282
  rootSchema: S,
222
283
  expandAllBranches: boolean,
223
284
  recurseList: string[],
224
- formData?: T
285
+ formData?: T,
286
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
225
287
  ): S[] {
226
288
  const updatedSchema = resolveAllReferences<S>(schema, rootSchema, recurseList);
227
289
  if (updatedSchema !== schema) {
@@ -232,7 +294,8 @@ export function resolveReference<T = any, S extends StrictRJSFSchema = RJSFSchem
232
294
  rootSchema,
233
295
  formData,
234
296
  expandAllBranches,
235
- recurseList
297
+ recurseList,
298
+ experimental_customMergeAllOf
236
299
  );
237
300
  }
238
301
  return [schema];
@@ -367,6 +430,7 @@ export function stubExistingAdditionalProperties<
367
430
  * @param [expandAllBranches=false] - Flag, if true, will return all possible branches of conditions, any/oneOf and
368
431
  * dependencies as a list of schemas
369
432
  * @param [recurseList=[]] - The optional, list of recursive references already processed
433
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
370
434
  * @returns - The schema(s) resulting from having its conditions, additional properties, references and dependencies
371
435
  * resolved. Multiple schemas may be returned if `expandAllBranches` is true.
372
436
  */
@@ -380,7 +444,8 @@ export function retrieveSchemaInternal<
380
444
  rootSchema: S,
381
445
  rawFormData?: T,
382
446
  expandAllBranches = false,
383
- recurseList: string[] = []
447
+ recurseList: string[] = [],
448
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
384
449
  ): S[] {
385
450
  if (!isObject(schema)) {
386
451
  return [{} as S];
@@ -402,7 +467,8 @@ export function retrieveSchemaInternal<
402
467
  rootSchema,
403
468
  expandAllBranches,
404
469
  recurseList,
405
- rawFormData as T
470
+ rawFormData as T,
471
+ experimental_customMergeAllOf
406
472
  );
407
473
  }
408
474
  if (ALL_OF_KEY in resolvedSchema) {
@@ -412,9 +478,26 @@ export function retrieveSchemaInternal<
412
478
  return [...(allOf as S[]), restOfSchema as S];
413
479
  }
414
480
  try {
415
- resolvedSchema = mergeAllOf(resolvedSchema, {
416
- deep: false,
417
- } as Options) as S;
481
+ const withContainsSchemas = [] as S[];
482
+ const withoutContainsSchemas = [] as S[];
483
+ resolvedSchema.allOf?.forEach((s) => {
484
+ if (typeof s === 'object' && s.contains) {
485
+ withContainsSchemas.push(s as S);
486
+ } else {
487
+ withoutContainsSchemas.push(s as S);
488
+ }
489
+ });
490
+ if (withContainsSchemas.length) {
491
+ resolvedSchema = { ...resolvedSchema, allOf: withoutContainsSchemas };
492
+ }
493
+ resolvedSchema = experimental_customMergeAllOf
494
+ ? experimental_customMergeAllOf(resolvedSchema)
495
+ : (mergeAllOf(resolvedSchema, {
496
+ deep: false,
497
+ } as Options) as S);
498
+ if (withContainsSchemas.length) {
499
+ resolvedSchema.allOf = withContainsSchemas;
500
+ }
418
501
  } catch (e) {
419
502
  console.warn('could not merge subschemas in allOf:\n', e);
420
503
  const { allOf, ...resolvedSchemaWithoutAllOf } = resolvedSchema;
@@ -484,6 +567,7 @@ export function resolveAnyOrOneOfSchemas<
484
567
  * as a list of schemas
485
568
  * @param recurseList - The list of recursive references already processed
486
569
  * @param [formData] - The current formData, if any, to assist retrieving a schema
570
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
487
571
  * @returns - The list of schemas with their dependencies resolved
488
572
  */
489
573
  export function resolveDependencies<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
@@ -492,7 +576,8 @@ export function resolveDependencies<T = any, S extends StrictRJSFSchema = RJSFSc
492
576
  rootSchema: S,
493
577
  expandAllBranches: boolean,
494
578
  recurseList: string[],
495
- formData?: T
579
+ formData?: T,
580
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
496
581
  ): S[] {
497
582
  // Drop the dependencies from the source schema.
498
583
  const { dependencies, ...remainingSchema } = schema;
@@ -511,7 +596,8 @@ export function resolveDependencies<T = any, S extends StrictRJSFSchema = RJSFSc
511
596
  rootSchema,
512
597
  expandAllBranches,
513
598
  recurseList,
514
- formData
599
+ formData,
600
+ experimental_customMergeAllOf
515
601
  )
516
602
  );
517
603
  }
@@ -527,6 +613,7 @@ export function resolveDependencies<T = any, S extends StrictRJSFSchema = RJSFSc
527
613
  * as a list of schemas
528
614
  * @param recurseList - The list of recursive references already processed
529
615
  * @param [formData] - The current formData, if any, to assist retrieving a schema
616
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
530
617
  * @returns - The schema with the `dependencies` resolved into it
531
618
  */
532
619
  export function processDependencies<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
@@ -536,7 +623,8 @@ export function processDependencies<T = any, S extends StrictRJSFSchema = RJSFSc
536
623
  rootSchema: S,
537
624
  expandAllBranches: boolean,
538
625
  recurseList: string[],
539
- formData?: T
626
+ formData?: T,
627
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
540
628
  ): S[] {
541
629
  let schemas = [resolvedSchema];
542
630
  // Process dependencies updating the local schema properties as appropriate.
@@ -564,7 +652,8 @@ export function processDependencies<T = any, S extends StrictRJSFSchema = RJSFSc
564
652
  dependencyValue as S,
565
653
  expandAllBranches,
566
654
  recurseList,
567
- formData
655
+ formData,
656
+ experimental_customMergeAllOf
568
657
  );
569
658
  }
570
659
  return schemas.flatMap((schema) =>
@@ -575,7 +664,8 @@ export function processDependencies<T = any, S extends StrictRJSFSchema = RJSFSc
575
664
  rootSchema,
576
665
  expandAllBranches,
577
666
  recurseList,
578
- formData
667
+ formData,
668
+ experimental_customMergeAllOf
579
669
  )
580
670
  );
581
671
  }
@@ -613,6 +703,7 @@ export function withDependentProperties<S extends StrictRJSFSchema = RJSFSchema>
613
703
  * as a list of schemas
614
704
  * @param recurseList - The list of recursive references already processed
615
705
  * @param [formData]- The current formData to assist retrieving a schema
706
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
616
707
  * @returns - The list of schemas with the dependent schema resolved into them
617
708
  */
618
709
  export function withDependentSchema<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
@@ -623,7 +714,8 @@ export function withDependentSchema<T = any, S extends StrictRJSFSchema = RJSFSc
623
714
  dependencyValue: S,
624
715
  expandAllBranches: boolean,
625
716
  recurseList: string[],
626
- formData?: T
717
+ formData?: T,
718
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
627
719
  ): S[] {
628
720
  const dependentSchemas = retrieveSchemaInternal<T, S, F>(
629
721
  validator,
@@ -631,7 +723,8 @@ export function withDependentSchema<T = any, S extends StrictRJSFSchema = RJSFSc
631
723
  rootSchema,
632
724
  formData,
633
725
  expandAllBranches,
634
- recurseList
726
+ recurseList,
727
+ experimental_customMergeAllOf
635
728
  );
636
729
  return dependentSchemas.flatMap((dependent) => {
637
730
  const { oneOf, ...dependentSchema } = dependent;
@@ -657,7 +750,8 @@ export function withDependentSchema<T = any, S extends StrictRJSFSchema = RJSFSc
657
750
  resolvedOneOf,
658
751
  expandAllBranches,
659
752
  recurseList,
660
- formData
753
+ formData,
754
+ experimental_customMergeAllOf
661
755
  )
662
756
  );
663
757
  });
@@ -676,6 +770,7 @@ export function withDependentSchema<T = any, S extends StrictRJSFSchema = RJSFSc
676
770
  * as a list of schemas
677
771
  * @param recurseList - The list of recursive references already processed
678
772
  * @param [formData] - The current formData to assist retrieving a schema
773
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
679
774
  * @returns - Either an array containing the best matching option or all options if `expandAllBranches` is true
680
775
  */
681
776
  export function withExactlyOneSubschema<
@@ -690,7 +785,8 @@ export function withExactlyOneSubschema<
690
785
  oneOf: S['oneOf'],
691
786
  expandAllBranches: boolean,
692
787
  recurseList: string[],
693
- formData?: T
788
+ formData?: T,
789
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
694
790
  ): S[] {
695
791
  const validSubschemas = oneOf!.filter((subschema) => {
696
792
  if (typeof subschema === 'boolean' || !subschema || !subschema.properties) {
@@ -723,7 +819,8 @@ export function withExactlyOneSubschema<
723
819
  rootSchema,
724
820
  formData,
725
821
  expandAllBranches,
726
- recurseList
822
+ recurseList,
823
+ experimental_customMergeAllOf
727
824
  );
728
825
  return schemas.map((s) => mergeSchemas(schema, s) as S);
729
826
  });
@@ -3,7 +3,15 @@ import isEqual from 'lodash/isEqual';
3
3
 
4
4
  import { ALL_OF_KEY, DEPENDENCIES_KEY, ID_KEY, ITEMS_KEY, PROPERTIES_KEY, REF_KEY } from '../constants';
5
5
  import isObject from '../isObject';
6
- import { FormContextType, GenericObjectType, IdSchema, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
6
+ import {
7
+ Experimental_CustomMergeAllOf,
8
+ FormContextType,
9
+ GenericObjectType,
10
+ IdSchema,
11
+ RJSFSchema,
12
+ StrictRJSFSchema,
13
+ ValidatorType,
14
+ } from '../types';
7
15
  import retrieveSchema from './retrieveSchema';
8
16
  import getSchemaType from '../getSchemaType';
9
17
 
@@ -18,6 +26,7 @@ import getSchemaType from '../getSchemaType';
18
26
  * @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
19
27
  * @param [formData] - The current formData, if any, to assist retrieving a schema
20
28
  * @param [_recurseList=[]] - The list of retrieved schemas currently being recursed, used to prevent infinite recursion
29
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
21
30
  * @returns - The `IdSchema` object for the `schema`
22
31
  */
23
32
  function toIdSchemaInternal<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
@@ -28,7 +37,8 @@ function toIdSchemaInternal<T = any, S extends StrictRJSFSchema = RJSFSchema, F
28
37
  id?: string | null,
29
38
  rootSchema?: S,
30
39
  formData?: T,
31
- _recurseList: S[] = []
40
+ _recurseList: S[] = [],
41
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
32
42
  ): IdSchema<T> {
33
43
  if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
34
44
  const _schema = retrieveSchema<T, S, F>(validator, schema, rootSchema, formData);
@@ -42,7 +52,8 @@ function toIdSchemaInternal<T = any, S extends StrictRJSFSchema = RJSFSchema, F
42
52
  id,
43
53
  rootSchema,
44
54
  formData,
45
- _recurseList.concat(_schema)
55
+ _recurseList.concat(_schema),
56
+ experimental_customMergeAllOf
46
57
  );
47
58
  }
48
59
  }
@@ -55,7 +66,8 @@ function toIdSchemaInternal<T = any, S extends StrictRJSFSchema = RJSFSchema, F
55
66
  id,
56
67
  rootSchema,
57
68
  formData,
58
- _recurseList
69
+ _recurseList,
70
+ experimental_customMergeAllOf
59
71
  );
60
72
  }
61
73
  const $id = id || idPrefix;
@@ -74,7 +86,8 @@ function toIdSchemaInternal<T = any, S extends StrictRJSFSchema = RJSFSchema, F
74
86
  // It's possible that formData is not an object -- this can happen if an
75
87
  // array item has just been added, but not populated with data yet
76
88
  get(formData, [name]),
77
- _recurseList
89
+ _recurseList,
90
+ experimental_customMergeAllOf
78
91
  );
79
92
  }
80
93
  }
@@ -90,6 +103,7 @@ function toIdSchemaInternal<T = any, S extends StrictRJSFSchema = RJSFSchema, F
90
103
  * @param [formData] - The current formData, if any, to assist retrieving a schema
91
104
  * @param [idPrefix='root'] - The prefix to use for the id
92
105
  * @param [idSeparator='_'] - The separator to use for the path segments in the id
106
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
93
107
  * @returns - The `IdSchema` object for the `schema`
94
108
  */
95
109
  export default function toIdSchema<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
@@ -99,7 +113,18 @@ export default function toIdSchema<T = any, S extends StrictRJSFSchema = RJSFSch
99
113
  rootSchema?: S,
100
114
  formData?: T,
101
115
  idPrefix = 'root',
102
- idSeparator = '_'
116
+ idSeparator = '_',
117
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
103
118
  ): IdSchema<T> {
104
- return toIdSchemaInternal<T, S, F>(validator, schema, idPrefix, idSeparator, id, rootSchema, formData);
119
+ return toIdSchemaInternal<T, S, F>(
120
+ validator,
121
+ schema,
122
+ idPrefix,
123
+ idSeparator,
124
+ id,
125
+ rootSchema,
126
+ formData,
127
+ undefined,
128
+ experimental_customMergeAllOf
129
+ );
105
130
  }
package/src/types.ts CHANGED
@@ -66,7 +66,8 @@ export type Experimental_ArrayMinItems = {
66
66
 
67
67
  /** Experimental features to specify different default form state behaviors. Currently, this affects the
68
68
  * handling of optional array fields where `minItems` is set and handling of setting defaults based on the
69
- * value of `emptyObjectFields`.
69
+ * value of `emptyObjectFields`. It also affects how `allOf` fields are handled and how to handle merging defaults into
70
+ * the formData in relation to explicit `undefined` values via `mergeDefaultsIntoFormData`.
70
71
  */
71
72
  export type Experimental_DefaultFormStateBehavior = {
72
73
  /** Optional object, that controls how the default form state for arrays with `minItems` is handled. When not provided
@@ -86,8 +87,23 @@ export type Experimental_DefaultFormStateBehavior = {
86
87
  * Optional flag to compute the default form state using allOf and if/then/else schemas. Defaults to `skipDefaults'.
87
88
  */
88
89
  allOf?: 'populateDefaults' | 'skipDefaults';
90
+ /** Optional enumerated flag controlling how the defaults are merged into the form data when dealing with undefined
91
+ * values, defaulting to `useFormDataIfPresent`.
92
+ * NOTE: If there is a default for a field and the `formData` is unspecified, the default ALWAYS merges.
93
+ * - `useFormDataIfPresent`: Legacy behavior - Do not merge defaults if there is a value for a field in `formData`,
94
+ * even if that value is explicitly set to `undefined`
95
+ * - `useDefaultIfFormDataUndefined`: - If the value of a field within the `formData` is `undefined`, then use the
96
+ * default value instead
97
+ */
98
+ mergeDefaultsIntoFormData?: 'useFormDataIfPresent' | 'useDefaultIfFormDataUndefined';
89
99
  };
90
100
 
101
+ /** Optional function that allows for custom merging of `allOf` schemas
102
+ * @param schema - Schema with `allOf` that needs to be merged
103
+ * @returns The merged schema
104
+ */
105
+ export type Experimental_CustomMergeAllOf<S extends StrictRJSFSchema = RJSFSchema> = (schema: S) => S;
106
+
91
107
  /** The interface representing a Date object that contains an optional time */
92
108
  export interface DateObject {
93
109
  /** The year of the Date */
@@ -1030,12 +1046,14 @@ export interface SchemaUtilsType<T = any, S extends StrictRJSFSchema = RJSFSchem
1030
1046
  * @param validator - An implementation of the `ValidatorType` interface that will be compared against the current one
1031
1047
  * @param rootSchema - The root schema that will be compared against the current one
1032
1048
  * @param [experimental_defaultFormStateBehavior] - Optional configuration object, if provided, allows users to override default form state behavior
1049
+ * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
1033
1050
  * @returns - True if the `SchemaUtilsType` differs from the given `validator` or `rootSchema`
1034
1051
  */
1035
1052
  doesSchemaUtilsDiffer(
1036
1053
  validator: ValidatorType<T, S, F>,
1037
1054
  rootSchema: S,
1038
- experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior
1055
+ experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior,
1056
+ experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
1039
1057
  ): boolean;
1040
1058
  /** Returns the superset of `formData` that includes the given set updated to include any missing fields that have
1041
1059
  * computed to have defaults provided in the `schema`.