Skip to content

Commit a7ef82c

Browse files
committed
Pass experimental_customMergeAllOf to missing code branches
1 parent 1e12bfe commit a7ef82c

File tree

11 files changed

+224
-55
lines changed

11 files changed

+224
-55
lines changed

packages/utils/src/createSchemaUtils.ts

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,14 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
133133
* @returns - True if the label should be displayed or false if it should not
134134
*/
135135
getDisplayLabel(schema: S, uiSchema?: UiSchema<T, S, F>, globalOptions?: GlobalUISchemaOptions) {
136-
return getDisplayLabel<T, S, F>(this.validator, schema, uiSchema, this.rootSchema, globalOptions);
136+
return getDisplayLabel<T, S, F>(
137+
this.validator,
138+
schema,
139+
uiSchema,
140+
this.rootSchema,
141+
globalOptions,
142+
this.experimental_customMergeAllOf
143+
);
137144
}
138145

139146
/** Determines which of the given `options` provided most closely matches the `formData`.
@@ -161,7 +168,8 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
161168
formData,
162169
options,
163170
selectedOption,
164-
discriminatorField
171+
discriminatorField,
172+
this.experimental_customMergeAllOf
165173
);
166174
}
167175

@@ -199,7 +207,7 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
199207
* @returns - True if schema/uiSchema contains an array of files, otherwise false
200208
*/
201209
isFilesArray(schema: S, uiSchema?: UiSchema<T, S, F>) {
202-
return isFilesArray<T, S, F>(this.validator, schema, uiSchema, this.rootSchema);
210+
return isFilesArray<T, S, F>(this.validator, schema, uiSchema, this.rootSchema, this.experimental_customMergeAllOf);
203211
}
204212

205213
/** Checks to see if the `schema` combination represents a multi-select
@@ -208,7 +216,7 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
208216
* @returns - True if schema contains a multi-select, otherwise false
209217
*/
210218
isMultiSelect(schema: S) {
211-
return isMultiSelect<T, S, F>(this.validator, schema, this.rootSchema);
219+
return isMultiSelect<T, S, F>(this.validator, schema, this.rootSchema, this.experimental_customMergeAllOf);
212220
}
213221

214222
/** Checks to see if the `schema` combination represents a select
@@ -217,7 +225,7 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
217225
* @returns - True if schema contains a select, otherwise false
218226
*/
219227
isSelect(schema: S) {
220-
return isSelect<T, S, F>(this.validator, schema, this.rootSchema);
228+
return isSelect<T, S, F>(this.validator, schema, this.rootSchema, this.experimental_customMergeAllOf);
221229
}
222230

223231
/** Merges the errors in `additionalErrorSchema` into the existing `validationData` by combining the hierarchies in
@@ -265,7 +273,14 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
265273
* to `undefined`. Will return `undefined` if the new schema is not an object containing properties.
266274
*/
267275
sanitizeDataForNewSchema(newSchema?: S, oldSchema?: S, data?: any): T {
268-
return sanitizeDataForNewSchema(this.validator, this.rootSchema, newSchema, oldSchema, data);
276+
return sanitizeDataForNewSchema(
277+
this.validator,
278+
this.rootSchema,
279+
newSchema,
280+
oldSchema,
281+
data,
282+
this.experimental_customMergeAllOf
283+
);
269284
}
270285

271286
/** Generates an `IdSchema` object for the `schema`, recursively
@@ -298,7 +313,14 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
298313
* @returns - The `PathSchema` object for the `schema`
299314
*/
300315
toPathSchema(schema: S, name?: string, formData?: T): PathSchema<T> {
301-
return toPathSchema<T, S, F>(this.validator, schema, name, this.rootSchema, formData);
316+
return toPathSchema<T, S, F>(
317+
this.validator,
318+
schema,
319+
name,
320+
this.rootSchema,
321+
formData,
322+
this.experimental_customMergeAllOf
323+
);
302324
}
303325
}
304326

packages/utils/src/schema/getClosestMatchingOption.ts

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import getFirstMatchingOption from './getFirstMatchingOption';
1010
import retrieveSchema, { resolveAllReferences } from './retrieveSchema';
1111
import { ONE_OF_KEY, REF_KEY, JUNK_OPTION_ID, ANY_OF_KEY } from '../constants';
1212
import guessType from '../guessType';
13-
import { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
13+
import { Experimental_CustomMergeAllOf, FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
1414
import getDiscriminatorFieldFromSchema from '../getDiscriminatorFieldFromSchema';
1515
import getOptionMatchingSimpleDiscriminator from '../getOptionMatchingSimpleDiscriminator';
1616

@@ -45,13 +45,15 @@ export const JUNK_OPTION: StrictRJSFSchema = {
4545
* @param rootSchema - The root JSON schema of the entire form
4646
* @param schema - The schema for which the score is being calculated
4747
* @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
4849
* @returns - The score a schema against the formData
4950
*/
5051
export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
5152
validator: ValidatorType<T, S, F>,
5253
rootSchema: S,
5354
schema?: S,
54-
formData?: any
55+
formData?: any,
56+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
5557
): number {
5658
let totalScore = 0;
5759
if (schema) {
@@ -64,8 +66,23 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
6466
return score;
6567
}
6668
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+
);
6986
}
7087
if ((has(value, ONE_OF_KEY) || has(value, ANY_OF_KEY)) && formValue) {
7188
const key = has(value, ONE_OF_KEY) ? ONE_OF_KEY : ANY_OF_KEY;
@@ -78,7 +95,8 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
7895
formValue,
7996
get(value, key) as S[],
8097
-1,
81-
discriminator
98+
discriminator,
99+
experimental_customMergeAllOf
82100
)
83101
);
84102
}
@@ -87,7 +105,10 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
87105
// If the structure is matching then give it a little boost in score
88106
score += 1;
89107
}
90-
return score + calculateIndexScore<T, S, F>(validator, rootSchema, value as S, formValue);
108+
return (
109+
score +
110+
calculateIndexScore<T, S, F>(validator, rootSchema, value as S, formValue, experimental_customMergeAllOf)
111+
);
91112
}
92113
if (value.type === guessType(formValue)) {
93114
// If the types match, then we bump the score by one
@@ -135,6 +156,7 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
135156
* @param [selectedOption=-1] - The index of the currently selected option, defaulted to -1 if not specified
136157
* @param [discriminatorField] - The optional name of the field within the options object whose value is used to
137158
* determine which option is selected
159+
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
138160
* @returns - The index of the option that is the closest match to the `formData` or the `selectedOption` if no match
139161
*/
140162
export default function getClosestMatchingOption<
@@ -147,7 +169,8 @@ export default function getClosestMatchingOption<
147169
formData: T | undefined,
148170
options: S[],
149171
selectedOption = -1,
150-
discriminatorField?: string
172+
discriminatorField?: string,
173+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
151174
): number {
152175
// First resolve any refs in the options
153176
const resolvedOptions = options.map((option) => {
@@ -185,7 +208,7 @@ export default function getClosestMatchingOption<
185208
(scoreData: BestType, index: number) => {
186209
const { bestScore } = scoreData;
187210
const option = resolvedOptions[index];
188-
const score = calculateIndexScore(validator, rootSchema, option, formData);
211+
const score = calculateIndexScore(validator, rootSchema, option, formData, experimental_customMergeAllOf);
189212
scoreCount.add(score);
190213
if (score > bestScore) {
191214
return { bestIndex: index, bestScore: score };

packages/utils/src/schema/getDefaultFormState.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
239239
includeUndefinedValues,
240240
_recurseList,
241241
experimental_defaultFormStateBehavior,
242+
experimental_customMergeAllOf,
242243
parentDefaults: Array.isArray(parentDefaults) ? parentDefaults[idx] : undefined,
243244
rawFormData: formData as T,
244245
required,
@@ -257,7 +258,8 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
257258
isEmpty(formData) ? undefined : formData,
258259
oneOf as S[],
259260
0,
260-
discriminator
261+
discriminator,
262+
experimental_customMergeAllOf
261263
)
262264
] as S;
263265
schemaToCompute = mergeSchemas(remaining, schemaToCompute) as S;
@@ -274,7 +276,8 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
274276
isEmpty(formData) ? undefined : formData,
275277
anyOf as S[],
276278
0,
277-
discriminator
279+
discriminator,
280+
experimental_customMergeAllOf
278281
)
279282
] as S;
280283
schemaToCompute = mergeSchemas(remaining, schemaToCompute) as S;
@@ -286,6 +289,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
286289
includeUndefinedValues,
287290
_recurseList: updatedRecurseList,
288291
experimental_defaultFormStateBehavior,
292+
experimental_customMergeAllOf,
289293
parentDefaults: defaults as T | undefined,
290294
rawFormData: formData as T,
291295
required,
@@ -390,6 +394,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
390394
rootSchema,
391395
_recurseList,
392396
experimental_defaultFormStateBehavior,
397+
experimental_customMergeAllOf,
393398
includeUndefinedValues: includeUndefinedValues === true,
394399
parentDefaults: get(defaults, [key]),
395400
rawFormData: get(formData, [key]),
@@ -426,6 +431,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
426431
rootSchema = {} as S,
427432
_recurseList = [],
428433
experimental_defaultFormStateBehavior = undefined,
434+
experimental_customMergeAllOf = undefined,
429435
required,
430436
}: ComputeDefaultsProps<T, S> = {},
431437
defaults?: T | T[] | undefined
@@ -451,6 +457,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
451457
rootSchema,
452458
_recurseList,
453459
experimental_defaultFormStateBehavior,
460+
experimental_customMergeAllOf,
454461
parentDefaults: item,
455462
required,
456463
});
@@ -468,6 +475,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
468475
rootSchema,
469476
_recurseList,
470477
experimental_defaultFormStateBehavior,
478+
experimental_customMergeAllOf,
471479
rawFormData: item,
472480
parentDefaults: get(defaults, [idx]),
473481
required,
@@ -497,7 +505,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
497505
const defaultsLength = Array.isArray(defaults) ? defaults.length : 0;
498506
if (
499507
!schema.minItems ||
500-
isMultiSelect<T, S, F>(validator, schema, rootSchema) ||
508+
isMultiSelect<T, S, F>(validator, schema, rootSchema, experimental_customMergeAllOf) ||
501509
computeSkipPopulate<T, S, F>(validator, schema, rootSchema) ||
502510
schema.minItems <= defaultsLength
503511
) {
@@ -515,6 +523,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
515523
rootSchema,
516524
_recurseList,
517525
experimental_defaultFormStateBehavior,
526+
experimental_customMergeAllOf,
518527
required,
519528
})
520529
) as T[];

packages/utils/src/schema/getDisplayLabel.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
StrictRJSFSchema,
1010
UiSchema,
1111
ValidatorType,
12+
Experimental_CustomMergeAllOf,
1213
} from '../types';
1314
import isFilesArray from './isFilesArray';
1415
import isMultiSelect from './isMultiSelect';
@@ -21,6 +22,7 @@ import isMultiSelect from './isMultiSelect';
2122
* @param [uiSchema={}] - The UI schema from which to derive potentially displayable information
2223
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
2324
* @param [globalOptions={}] - The optional Global UI Schema from which to get any fallback `xxx` options
25+
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
2426
* @returns - True if the label should be displayed or false if it should not
2527
*/
2628
export default function getDisplayLabel<
@@ -32,7 +34,8 @@ export default function getDisplayLabel<
3234
schema: S,
3335
uiSchema: UiSchema<T, S, F> = {},
3436
rootSchema?: S,
35-
globalOptions?: GlobalUISchemaOptions
37+
globalOptions?: GlobalUISchemaOptions,
38+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
3639
): boolean {
3740
const uiOptions = getUiOptions<T, S, F>(uiSchema, globalOptions);
3841
const { label = true } = uiOptions;
@@ -41,8 +44,8 @@ export default function getDisplayLabel<
4144

4245
if (schemaType === 'array') {
4346
displayLabel =
44-
isMultiSelect<T, S, F>(validator, schema, rootSchema) ||
45-
isFilesArray<T, S, F>(validator, schema, uiSchema, rootSchema) ||
47+
isMultiSelect<T, S, F>(validator, schema, rootSchema, experimental_customMergeAllOf) ||
48+
isFilesArray<T, S, F>(validator, schema, uiSchema, rootSchema, experimental_customMergeAllOf) ||
4649
isCustomWidget(uiSchema);
4750
}
4851

packages/utils/src/schema/isFilesArray.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { UI_WIDGET_KEY } from '../constants';
2-
import { FormContextType, RJSFSchema, StrictRJSFSchema, UiSchema, ValidatorType } from '../types';
2+
import {
3+
Experimental_CustomMergeAllOf,
4+
FormContextType,
5+
RJSFSchema,
6+
StrictRJSFSchema,
7+
UiSchema,
8+
ValidatorType,
9+
} from '../types';
310
import retrieveSchema from './retrieveSchema';
411

512
/** Checks to see if the `schema` and `uiSchema` combination represents an array of files
@@ -8,19 +15,27 @@ import retrieveSchema from './retrieveSchema';
815
* @param schema - The schema for which check for array of files flag is desired
916
* @param [uiSchema={}] - The UI schema from which to check the widget
1017
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
18+
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
1119
* @returns - True if schema/uiSchema contains an array of files, otherwise false
1220
*/
1321
export default function isFilesArray<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
1422
validator: ValidatorType<T, S, F>,
1523
schema: S,
1624
uiSchema: UiSchema<T, S, F> = {},
17-
rootSchema?: S
25+
rootSchema?: S,
26+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
1827
) {
1928
if (uiSchema[UI_WIDGET_KEY] === 'files') {
2029
return true;
2130
}
2231
if (schema.items) {
23-
const itemsSchema = retrieveSchema<T, S, F>(validator, schema.items as S, rootSchema);
32+
const itemsSchema = retrieveSchema<T, S, F>(
33+
validator,
34+
schema.items as S,
35+
rootSchema,
36+
undefined,
37+
experimental_customMergeAllOf
38+
);
2439
return itemsSchema.type === 'string' && itemsSchema.format === 'data-url';
2540
}
2641
return false;
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
1+
import { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType, Experimental_CustomMergeAllOf } from '../types';
22

33
import isSelect from './isSelect';
44

@@ -7,15 +7,21 @@ import isSelect from './isSelect';
77
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
88
* @param schema - The schema for which check for a multi-select flag is desired
99
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
10+
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
1011
* @returns - True if schema contains a multi-select, otherwise false
1112
*/
1213
export default function isMultiSelect<
1314
T = any,
1415
S extends StrictRJSFSchema = RJSFSchema,
1516
F extends FormContextType = any
16-
>(validator: ValidatorType<T, S, F>, schema: S, rootSchema?: S) {
17+
>(
18+
validator: ValidatorType<T, S, F>,
19+
schema: S,
20+
rootSchema?: S,
21+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
22+
) {
1723
if (!schema.uniqueItems || !schema.items || typeof schema.items === 'boolean') {
1824
return false;
1925
}
20-
return isSelect<T, S, F>(validator, schema.items as S, rootSchema);
26+
return isSelect<T, S, F>(validator, schema.items as S, rootSchema, experimental_customMergeAllOf);
2127
}

0 commit comments

Comments
 (0)