@rjsf/utils 5.21.2 → 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.
- package/dist/index.js +184 -61
- package/dist/index.js.map +2 -2
- package/dist/utils.esm.js +184 -61
- package/dist/utils.esm.js.map +2 -2
- package/dist/utils.umd.js +179 -64
- package/lib/createSchemaUtils.d.ts +3 -2
- package/lib/createSchemaUtils.js +17 -11
- package/lib/createSchemaUtils.js.map +1 -1
- package/lib/mergeDefaultsWithFormData.d.ts +4 -2
- package/lib/mergeDefaultsWithFormData.js +9 -4
- package/lib/mergeDefaultsWithFormData.js.map +1 -1
- package/lib/schema/getClosestMatchingOption.js +6 -2
- package/lib/schema/getClosestMatchingOption.js.map +1 -1
- package/lib/schema/getDefaultFormState.d.ts +6 -3
- package/lib/schema/getDefaultFormState.js +43 -22
- package/lib/schema/getDefaultFormState.js.map +1 -1
- package/lib/schema/retrieveSchema.d.ts +19 -10
- package/lib/schema/retrieveSchema.js +38 -27
- package/lib/schema/retrieveSchema.js.map +1 -1
- package/lib/schema/toIdSchema.d.ts +3 -2
- package/lib/schema/toIdSchema.js +8 -6
- package/lib/schema/toIdSchema.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types.d.ts +19 -3
- package/package.json +2 -2
- package/src/createSchemaUtils.ts +43 -11
- package/src/mergeDefaultsWithFormData.ts +16 -4
- package/src/schema/getClosestMatchingOption.ts +6 -2
- package/src/schema/getDefaultFormState.ts +58 -19
- package/src/schema/retrieveSchema.ts +110 -28
- package/src/schema/toIdSchema.ts +32 -7
- package/src/types.ts +20 -2
package/src/createSchemaUtils.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import deepEquals from './deepEquals';
|
|
2
2
|
import {
|
|
3
3
|
ErrorSchema,
|
|
4
|
+
Experimental_CustomMergeAllOf,
|
|
4
5
|
Experimental_DefaultFormStateBehavior,
|
|
5
6
|
FormContextType,
|
|
6
7
|
GlobalUISchemaOptions,
|
|
@@ -30,9 +31,10 @@ import {
|
|
|
30
31
|
} from './schema';
|
|
31
32
|
|
|
32
33
|
/** The `SchemaUtils` class provides a wrapper around the publicly exported APIs in the `utils/schema` directory such
|
|
33
|
-
* that one does not have to explicitly pass the `validator`, `rootSchema`,
|
|
34
|
-
* Since these generally do not change across a `Form`, this allows for
|
|
35
|
-
* `@rjsf/core` components and the various themes as well. This class
|
|
34
|
+
* that one does not have to explicitly pass the `validator`, `rootSchema`, `experimental_defaultFormStateBehavior` or
|
|
35
|
+
* `experimental_customMergeAllOf` to each method. Since these generally do not change across a `Form`, this allows for
|
|
36
|
+
* providing a simplified set of APIs to the `@rjsf/core` components and the various themes as well. This class
|
|
37
|
+
* implements the `SchemaUtilsType` interface.
|
|
36
38
|
*/
|
|
37
39
|
class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>
|
|
38
40
|
implements SchemaUtilsType<T, S, F>
|
|
@@ -40,21 +42,25 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
|
|
|
40
42
|
rootSchema: S;
|
|
41
43
|
validator: ValidatorType<T, S, F>;
|
|
42
44
|
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior;
|
|
45
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>;
|
|
43
46
|
|
|
44
47
|
/** Constructs the `SchemaUtils` instance with the given `validator` and `rootSchema` stored as instance variables
|
|
45
48
|
*
|
|
46
49
|
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
47
50
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
48
51
|
* @param experimental_defaultFormStateBehavior - Configuration flags to allow users to override default form state behavior
|
|
52
|
+
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
|
|
49
53
|
*/
|
|
50
54
|
constructor(
|
|
51
55
|
validator: ValidatorType<T, S, F>,
|
|
52
56
|
rootSchema: S,
|
|
53
|
-
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior
|
|
57
|
+
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior,
|
|
58
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
|
|
54
59
|
) {
|
|
55
60
|
this.rootSchema = rootSchema;
|
|
56
61
|
this.validator = validator;
|
|
57
62
|
this.experimental_defaultFormStateBehavior = experimental_defaultFormStateBehavior;
|
|
63
|
+
this.experimental_customMergeAllOf = experimental_customMergeAllOf;
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
/** Returns the `ValidatorType` in the `SchemaUtilsType`
|
|
@@ -72,12 +78,14 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
|
|
|
72
78
|
* @param validator - An implementation of the `ValidatorType` interface that will be compared against the current one
|
|
73
79
|
* @param rootSchema - The root schema that will be compared against the current one
|
|
74
80
|
* @param [experimental_defaultFormStateBehavior] Optional configuration object, if provided, allows users to override default form state behavior
|
|
81
|
+
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
|
|
75
82
|
* @returns - True if the `SchemaUtilsType` differs from the given `validator` or `rootSchema`
|
|
76
83
|
*/
|
|
77
84
|
doesSchemaUtilsDiffer(
|
|
78
85
|
validator: ValidatorType<T, S, F>,
|
|
79
86
|
rootSchema: S,
|
|
80
|
-
experimental_defaultFormStateBehavior = {}
|
|
87
|
+
experimental_defaultFormStateBehavior = {},
|
|
88
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
|
|
81
89
|
): boolean {
|
|
82
90
|
if (!validator || !rootSchema) {
|
|
83
91
|
return false;
|
|
@@ -85,7 +93,8 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
|
|
|
85
93
|
return (
|
|
86
94
|
this.validator !== validator ||
|
|
87
95
|
!deepEquals(this.rootSchema, rootSchema) ||
|
|
88
|
-
!deepEquals(this.experimental_defaultFormStateBehavior, experimental_defaultFormStateBehavior)
|
|
96
|
+
!deepEquals(this.experimental_defaultFormStateBehavior, experimental_defaultFormStateBehavior) ||
|
|
97
|
+
this.experimental_customMergeAllOf !== experimental_customMergeAllOf
|
|
89
98
|
);
|
|
90
99
|
}
|
|
91
100
|
|
|
@@ -110,7 +119,8 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
|
|
|
110
119
|
formData,
|
|
111
120
|
this.rootSchema,
|
|
112
121
|
includeUndefinedValues,
|
|
113
|
-
this.experimental_defaultFormStateBehavior
|
|
122
|
+
this.experimental_defaultFormStateBehavior,
|
|
123
|
+
this.experimental_customMergeAllOf
|
|
114
124
|
);
|
|
115
125
|
}
|
|
116
126
|
|
|
@@ -234,7 +244,13 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
|
|
|
234
244
|
* @returns - The schema having its conditions, additional properties, references and dependencies resolved
|
|
235
245
|
*/
|
|
236
246
|
retrieveSchema(schema: S, rawFormData?: T) {
|
|
237
|
-
return retrieveSchema<T, S, F>(
|
|
247
|
+
return retrieveSchema<T, S, F>(
|
|
248
|
+
this.validator,
|
|
249
|
+
schema,
|
|
250
|
+
this.rootSchema,
|
|
251
|
+
rawFormData,
|
|
252
|
+
this.experimental_customMergeAllOf
|
|
253
|
+
);
|
|
238
254
|
}
|
|
239
255
|
|
|
240
256
|
/** Sanitize the `data` associated with the `oldSchema` so it is considered appropriate for the `newSchema`. If the
|
|
@@ -262,7 +278,16 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
|
|
|
262
278
|
* @returns - The `IdSchema` object for the `schema`
|
|
263
279
|
*/
|
|
264
280
|
toIdSchema(schema: S, id?: string | null, formData?: T, idPrefix = 'root', idSeparator = '_'): IdSchema<T> {
|
|
265
|
-
return toIdSchema<T, S, F>(
|
|
281
|
+
return toIdSchema<T, S, F>(
|
|
282
|
+
this.validator,
|
|
283
|
+
schema,
|
|
284
|
+
id,
|
|
285
|
+
this.rootSchema,
|
|
286
|
+
formData,
|
|
287
|
+
idPrefix,
|
|
288
|
+
idSeparator,
|
|
289
|
+
this.experimental_customMergeAllOf
|
|
290
|
+
);
|
|
266
291
|
}
|
|
267
292
|
|
|
268
293
|
/** Generates an `PathSchema` object for the `schema`, recursively
|
|
@@ -283,6 +308,7 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
|
|
|
283
308
|
* @param validator - an implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
284
309
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
285
310
|
* @param [experimental_defaultFormStateBehavior] Optional configuration object, if provided, allows users to override default form state behavior
|
|
311
|
+
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
|
|
286
312
|
* @returns - An implementation of a `SchemaUtilsType` interface
|
|
287
313
|
*/
|
|
288
314
|
export default function createSchemaUtils<
|
|
@@ -292,7 +318,13 @@ export default function createSchemaUtils<
|
|
|
292
318
|
>(
|
|
293
319
|
validator: ValidatorType<T, S, F>,
|
|
294
320
|
rootSchema: S,
|
|
295
|
-
experimental_defaultFormStateBehavior = {}
|
|
321
|
+
experimental_defaultFormStateBehavior = {},
|
|
322
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
|
|
296
323
|
): SchemaUtilsType<T, S, F> {
|
|
297
|
-
return new SchemaUtils<T, S, F>(
|
|
324
|
+
return new SchemaUtils<T, S, F>(
|
|
325
|
+
validator,
|
|
326
|
+
rootSchema,
|
|
327
|
+
experimental_defaultFormStateBehavior,
|
|
328
|
+
experimental_customMergeAllOf
|
|
329
|
+
);
|
|
298
330
|
}
|
|
@@ -12,23 +12,31 @@ import { GenericObjectType } from '../src';
|
|
|
12
12
|
* are deeply merged; additional entries from the defaults are ignored unless `mergeExtraArrayDefaults` is true, in
|
|
13
13
|
* which case the extras are appended onto the end of the form data
|
|
14
14
|
* - when the array is not set in form data, the default is copied over
|
|
15
|
-
* - scalars are overwritten/set by form data
|
|
15
|
+
* - scalars are overwritten/set by form data unless undefined and there is a default AND `defaultSupercedesUndefined`
|
|
16
|
+
* is true
|
|
16
17
|
*
|
|
17
18
|
* @param [defaults] - The defaults to merge
|
|
18
19
|
* @param [formData] - The form data into which the defaults will be merged
|
|
19
20
|
* @param [mergeExtraArrayDefaults=false] - If true, any additional default array entries are appended onto the formData
|
|
21
|
+
* @param [defaultSupercedesUndefined=false] - If true, an explicit undefined value will be overwritten by the default value
|
|
20
22
|
* @returns - The resulting merged form data with defaults
|
|
21
23
|
*/
|
|
22
24
|
export default function mergeDefaultsWithFormData<T = any>(
|
|
23
25
|
defaults?: T,
|
|
24
26
|
formData?: T,
|
|
25
|
-
mergeExtraArrayDefaults = false
|
|
27
|
+
mergeExtraArrayDefaults = false,
|
|
28
|
+
defaultSupercedesUndefined = false
|
|
26
29
|
): T | undefined {
|
|
27
30
|
if (Array.isArray(formData)) {
|
|
28
31
|
const defaultsArray = Array.isArray(defaults) ? defaults : [];
|
|
29
32
|
const mapped = formData.map((value, idx) => {
|
|
30
33
|
if (defaultsArray[idx]) {
|
|
31
|
-
return mergeDefaultsWithFormData<any>(
|
|
34
|
+
return mergeDefaultsWithFormData<any>(
|
|
35
|
+
defaultsArray[idx],
|
|
36
|
+
value,
|
|
37
|
+
mergeExtraArrayDefaults,
|
|
38
|
+
defaultSupercedesUndefined
|
|
39
|
+
);
|
|
32
40
|
}
|
|
33
41
|
return value;
|
|
34
42
|
});
|
|
@@ -44,10 +52,14 @@ export default function mergeDefaultsWithFormData<T = any>(
|
|
|
44
52
|
acc[key as keyof T] = mergeDefaultsWithFormData<T>(
|
|
45
53
|
defaults ? get(defaults, key) : {},
|
|
46
54
|
get(formData, key),
|
|
47
|
-
mergeExtraArrayDefaults
|
|
55
|
+
mergeExtraArrayDefaults,
|
|
56
|
+
defaultSupercedesUndefined
|
|
48
57
|
);
|
|
49
58
|
return acc;
|
|
50
59
|
}, acc);
|
|
51
60
|
}
|
|
61
|
+
if (defaultSupercedesUndefined && formData === undefined) {
|
|
62
|
+
return defaults;
|
|
63
|
+
}
|
|
52
64
|
return formData;
|
|
53
65
|
}
|
|
@@ -51,7 +51,7 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
|
|
|
51
51
|
validator: ValidatorType<T, S, F>,
|
|
52
52
|
rootSchema: S,
|
|
53
53
|
schema?: S,
|
|
54
|
-
formData
|
|
54
|
+
formData?: any
|
|
55
55
|
): number {
|
|
56
56
|
let totalScore = 0;
|
|
57
57
|
if (schema) {
|
|
@@ -83,7 +83,11 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
|
|
|
83
83
|
);
|
|
84
84
|
}
|
|
85
85
|
if (value.type === 'object') {
|
|
86
|
-
|
|
86
|
+
if (isObject(formValue)) {
|
|
87
|
+
// If the structure is matching then give it a little boost in score
|
|
88
|
+
score += 1;
|
|
89
|
+
}
|
|
90
|
+
return score + calculateIndexScore<T, S, F>(validator, rootSchema, value as S, formValue);
|
|
87
91
|
}
|
|
88
92
|
if (value.type === guessType(formValue)) {
|
|
89
93
|
// If the types match, then we bump the score by one
|
|
@@ -3,6 +3,7 @@ import isEmpty from 'lodash/isEmpty';
|
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
ANY_OF_KEY,
|
|
6
|
+
CONST_KEY,
|
|
6
7
|
DEFAULT_KEY,
|
|
7
8
|
DEPENDENCIES_KEY,
|
|
8
9
|
PROPERTIES_KEY,
|
|
@@ -20,6 +21,7 @@ import mergeDefaultsWithFormData from '../mergeDefaultsWithFormData';
|
|
|
20
21
|
import mergeObjects from '../mergeObjects';
|
|
21
22
|
import mergeSchemas from '../mergeSchemas';
|
|
22
23
|
import {
|
|
24
|
+
Experimental_CustomMergeAllOf,
|
|
23
25
|
Experimental_DefaultFormStateBehavior,
|
|
24
26
|
FormContextType,
|
|
25
27
|
GenericObjectType,
|
|
@@ -29,6 +31,8 @@ import {
|
|
|
29
31
|
} from '../types';
|
|
30
32
|
import isMultiSelect from './isMultiSelect';
|
|
31
33
|
import retrieveSchema, { resolveDependencies } from './retrieveSchema';
|
|
34
|
+
import isConstant from '../isConstant';
|
|
35
|
+
import { JSONSchema7Object } from 'json-schema';
|
|
32
36
|
|
|
33
37
|
/** Enum that indicates how `schema.additionalItems` should be handled by the `getInnerSchemaForArrayItem()` function.
|
|
34
38
|
*/
|
|
@@ -92,6 +96,7 @@ export function getInnerSchemaForArrayItem<S extends StrictRJSFSchema = RJSFSche
|
|
|
92
96
|
* @param requiredFields - The list of fields that are required
|
|
93
97
|
* @param experimental_defaultFormStateBehavior - Optional configuration object, if provided, allows users to override
|
|
94
98
|
* default form state behavior
|
|
99
|
+
* @param isConst - Optional flag, if true, indicates that the schema has a const property defined, thus we should always return the computedDefault since it's coming from the const.
|
|
95
100
|
*/
|
|
96
101
|
function maybeAddDefaultToObject<T = any>(
|
|
97
102
|
obj: GenericObjectType,
|
|
@@ -100,10 +105,13 @@ function maybeAddDefaultToObject<T = any>(
|
|
|
100
105
|
includeUndefinedValues: boolean | 'excludeObjectChildren',
|
|
101
106
|
isParentRequired?: boolean,
|
|
102
107
|
requiredFields: string[] = [],
|
|
103
|
-
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior = {}
|
|
108
|
+
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior = {},
|
|
109
|
+
isConst = false
|
|
104
110
|
) {
|
|
105
111
|
const { emptyObjectFields = 'populateAllDefaults' } = experimental_defaultFormStateBehavior;
|
|
106
|
-
if (includeUndefinedValues) {
|
|
112
|
+
if (includeUndefinedValues || isConst) {
|
|
113
|
+
// If includeUndefinedValues
|
|
114
|
+
// Or if the schema has a const property defined, then we should always return the computedDefault since it's coming from the const.
|
|
107
115
|
obj[key] = computedDefault;
|
|
108
116
|
} else if (emptyObjectFields !== 'skipDefaults') {
|
|
109
117
|
if (isObject(computedDefault)) {
|
|
@@ -156,6 +164,8 @@ interface ComputeDefaultsProps<T = any, S extends StrictRJSFSchema = RJSFSchema>
|
|
|
156
164
|
_recurseList?: string[];
|
|
157
165
|
/** Optional configuration object, if provided, allows users to override default form state behavior */
|
|
158
166
|
experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior;
|
|
167
|
+
/** Optional function that allows for custom merging of `allOf` schemas */
|
|
168
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>;
|
|
159
169
|
/** Optional flag, if true, indicates this schema was required in the parent schema. */
|
|
160
170
|
required?: boolean;
|
|
161
171
|
}
|
|
@@ -180,6 +190,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
180
190
|
includeUndefinedValues = false,
|
|
181
191
|
_recurseList = [],
|
|
182
192
|
experimental_defaultFormStateBehavior = undefined,
|
|
193
|
+
experimental_customMergeAllOf = undefined,
|
|
183
194
|
required,
|
|
184
195
|
} = computeDefaultsProps;
|
|
185
196
|
const formData: T = (isObject(rawFormData) ? rawFormData : {}) as T;
|
|
@@ -190,7 +201,9 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
190
201
|
let schemaToCompute: S | null = null;
|
|
191
202
|
let updatedRecurseList = _recurseList;
|
|
192
203
|
|
|
193
|
-
if (
|
|
204
|
+
if (isConstant(schema)) {
|
|
205
|
+
defaults = schema.const as unknown as T;
|
|
206
|
+
} else if (isObject(defaults) && isObject(schema.default)) {
|
|
194
207
|
// For object defaults, only override parent defaults that are defined in
|
|
195
208
|
// schema.default.
|
|
196
209
|
defaults = mergeObjects(defaults!, schema.default as GenericObjectType) as T;
|
|
@@ -209,7 +222,15 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
209
222
|
...formData,
|
|
210
223
|
...getDefaultBasedOnSchemaType(validator, schema, computeDefaultsProps, defaults),
|
|
211
224
|
};
|
|
212
|
-
const resolvedSchema = resolveDependencies<T, S, F>(
|
|
225
|
+
const resolvedSchema = resolveDependencies<T, S, F>(
|
|
226
|
+
validator,
|
|
227
|
+
schema,
|
|
228
|
+
rootSchema,
|
|
229
|
+
false,
|
|
230
|
+
[],
|
|
231
|
+
defaultFormData,
|
|
232
|
+
experimental_customMergeAllOf
|
|
233
|
+
);
|
|
213
234
|
schemaToCompute = resolvedSchema[0]; // pick the first element from resolve dependencies
|
|
214
235
|
} else if (isFixedItems(schema)) {
|
|
215
236
|
defaults = (schema.items! as S[]).map((itemSchema: S, idx: number) =>
|
|
@@ -298,6 +319,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
|
|
|
298
319
|
includeUndefinedValues = false,
|
|
299
320
|
_recurseList = [],
|
|
300
321
|
experimental_defaultFormStateBehavior = undefined,
|
|
322
|
+
experimental_customMergeAllOf = undefined,
|
|
301
323
|
required,
|
|
302
324
|
}: ComputeDefaultsProps<T, S> = {},
|
|
303
325
|
defaults?: T | T[] | undefined
|
|
@@ -309,16 +331,22 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
|
|
|
309
331
|
// https://github.com/rjsf-team/react-jsonschema-form/issues/3832
|
|
310
332
|
const retrievedSchema =
|
|
311
333
|
experimental_defaultFormStateBehavior?.allOf === 'populateDefaults' && ALL_OF_KEY in schema
|
|
312
|
-
? retrieveSchema<T, S, F>(validator, schema, rootSchema, formData)
|
|
334
|
+
? retrieveSchema<T, S, F>(validator, schema, rootSchema, formData, experimental_customMergeAllOf)
|
|
313
335
|
: schema;
|
|
336
|
+
const parentConst = retrievedSchema[CONST_KEY];
|
|
314
337
|
const objectDefaults = Object.keys(retrievedSchema.properties || {}).reduce(
|
|
315
338
|
(acc: GenericObjectType, key: string) => {
|
|
339
|
+
const propertySchema = get(retrievedSchema, [PROPERTIES_KEY, key]);
|
|
340
|
+
// Check if the parent schema has a const property defined, then we should always return the computedDefault since it's coming from the const.
|
|
341
|
+
const hasParentConst = isObject(parentConst) && (parentConst as JSONSchema7Object)[key] !== undefined;
|
|
342
|
+
const hasConst = (isObject(propertySchema) && CONST_KEY in propertySchema) || hasParentConst;
|
|
316
343
|
// Compute the defaults for this node, with the parent defaults we might
|
|
317
344
|
// have from a previous run: defaults[key].
|
|
318
|
-
const computedDefault = computeDefaults<T, S, F>(validator,
|
|
345
|
+
const computedDefault = computeDefaults<T, S, F>(validator, propertySchema, {
|
|
319
346
|
rootSchema,
|
|
320
347
|
_recurseList,
|
|
321
348
|
experimental_defaultFormStateBehavior,
|
|
349
|
+
experimental_customMergeAllOf,
|
|
322
350
|
includeUndefinedValues: includeUndefinedValues === true,
|
|
323
351
|
parentDefaults: get(defaults, [key]),
|
|
324
352
|
rawFormData: get(formData, [key]),
|
|
@@ -331,7 +359,8 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
|
|
|
331
359
|
includeUndefinedValues,
|
|
332
360
|
required,
|
|
333
361
|
retrievedSchema.required,
|
|
334
|
-
experimental_defaultFormStateBehavior
|
|
362
|
+
experimental_defaultFormStateBehavior,
|
|
363
|
+
hasConst
|
|
335
364
|
);
|
|
336
365
|
return acc;
|
|
337
366
|
},
|
|
@@ -444,13 +473,17 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
|
|
|
444
473
|
}
|
|
445
474
|
}
|
|
446
475
|
|
|
447
|
-
if
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
476
|
+
// Check if the schema has a const property defined, then we should always return the computedDefault since it's coming from the const.
|
|
477
|
+
const hasConst = isObject(schema) && CONST_KEY in schema;
|
|
478
|
+
if (hasConst === false) {
|
|
479
|
+
if (neverPopulate) {
|
|
480
|
+
return defaults ?? emptyDefault;
|
|
481
|
+
}
|
|
482
|
+
if (ignoreMinItemsFlagSet && !required) {
|
|
483
|
+
// If no form data exists or defaults are set leave the field empty/non-existent, otherwise
|
|
484
|
+
// return form data/defaults
|
|
485
|
+
return defaults ? defaults : undefined;
|
|
486
|
+
}
|
|
454
487
|
}
|
|
455
488
|
|
|
456
489
|
const defaultsLength = Array.isArray(defaults) ? defaults.length : 0;
|
|
@@ -521,6 +554,7 @@ export function getDefaultBasedOnSchemaType<
|
|
|
521
554
|
* If "excludeObjectChildren", cause undefined values for this object and pass `includeUndefinedValues` as
|
|
522
555
|
* false when computing defaults for any nested object properties.
|
|
523
556
|
* @param [experimental_defaultFormStateBehavior] Optional configuration object, if provided, allows users to override default form state behavior
|
|
557
|
+
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
|
|
524
558
|
* @returns - The resulting `formData` with all the defaults provided
|
|
525
559
|
*/
|
|
526
560
|
export default function getDefaultFormState<
|
|
@@ -533,28 +567,33 @@ export default function getDefaultFormState<
|
|
|
533
567
|
formData?: T,
|
|
534
568
|
rootSchema?: S,
|
|
535
569
|
includeUndefinedValues: boolean | 'excludeObjectChildren' = false,
|
|
536
|
-
experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior
|
|
570
|
+
experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior,
|
|
571
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
|
|
537
572
|
) {
|
|
538
573
|
if (!isObject(theSchema)) {
|
|
539
574
|
throw new Error('Invalid schema: ' + theSchema);
|
|
540
575
|
}
|
|
541
|
-
const schema = retrieveSchema<T, S, F>(validator, theSchema, rootSchema, formData);
|
|
576
|
+
const schema = retrieveSchema<T, S, F>(validator, theSchema, rootSchema, formData, experimental_customMergeAllOf);
|
|
542
577
|
const defaults = computeDefaults<T, S, F>(validator, schema, {
|
|
543
578
|
rootSchema,
|
|
544
579
|
includeUndefinedValues,
|
|
545
580
|
experimental_defaultFormStateBehavior,
|
|
581
|
+
experimental_customMergeAllOf,
|
|
546
582
|
rawFormData: formData,
|
|
547
583
|
});
|
|
584
|
+
|
|
548
585
|
if (formData === undefined || formData === null || (typeof formData === 'number' && isNaN(formData))) {
|
|
549
586
|
// No form data? Use schema defaults.
|
|
550
587
|
return defaults;
|
|
551
588
|
}
|
|
552
|
-
const {
|
|
589
|
+
const { mergeDefaultsIntoFormData, arrayMinItems = {} } = experimental_defaultFormStateBehavior || {};
|
|
590
|
+
const { mergeExtraDefaults } = arrayMinItems;
|
|
591
|
+
const defaultSupercedesUndefined = mergeDefaultsIntoFormData === 'useDefaultIfFormDataUndefined';
|
|
553
592
|
if (isObject(formData)) {
|
|
554
|
-
return mergeDefaultsWithFormData<T>(defaults as T, formData, mergeExtraDefaults);
|
|
593
|
+
return mergeDefaultsWithFormData<T>(defaults as T, formData, mergeExtraDefaults, defaultSupercedesUndefined);
|
|
555
594
|
}
|
|
556
595
|
if (Array.isArray(formData)) {
|
|
557
|
-
return mergeDefaultsWithFormData<T[]>(defaults as T[], formData, mergeExtraDefaults);
|
|
596
|
+
return mergeDefaultsWithFormData<T[]>(defaults as T[], formData, mergeExtraDefaults, defaultSupercedesUndefined);
|
|
558
597
|
}
|
|
559
598
|
return formData;
|
|
560
599
|
}
|