@rjsf/utils 5.24.10 → 6.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +605 -330
- package/dist/index.js.map +4 -4
- package/dist/utils.esm.js +575 -300
- package/dist/utils.esm.js.map +4 -4
- package/dist/utils.umd.js +519 -268
- package/lib/ErrorSchemaBuilder.d.ts +7 -3
- package/lib/ErrorSchemaBuilder.js +1 -0
- package/lib/ErrorSchemaBuilder.js.map +1 -1
- package/lib/allowAdditionalItems.js.map +1 -1
- package/lib/asNumber.js.map +1 -1
- package/lib/canExpand.js +1 -1
- package/lib/canExpand.js.map +1 -1
- package/lib/constants.d.ts +11 -3
- package/lib/constants.js +11 -3
- package/lib/constants.js.map +1 -1
- package/lib/createErrorHandler.js.map +1 -1
- package/lib/createSchemaUtils.js +31 -27
- package/lib/createSchemaUtils.js.map +1 -1
- package/lib/dataURItoBlob.js.map +1 -1
- package/lib/dateRangeOptions.js.map +1 -1
- package/lib/deepEquals.js.map +1 -1
- package/lib/enumOptionsDeselectValue.js.map +1 -1
- package/lib/enumOptionsIndexForValue.js.map +1 -1
- package/lib/enumOptionsIsSelected.js.map +1 -1
- package/lib/enumOptionsSelectValue.js.map +1 -1
- package/lib/enumOptionsValueForIndex.js.map +1 -1
- package/lib/enums.d.ts +2 -0
- package/lib/enums.js +2 -0
- package/lib/enums.js.map +1 -1
- package/lib/findSchemaDefinition.js.map +1 -1
- package/lib/getChangedFields.js.map +1 -1
- package/lib/getDateElementProps.js.map +1 -1
- package/lib/getDiscriminatorFieldFromSchema.js +2 -1
- package/lib/getDiscriminatorFieldFromSchema.js.map +1 -1
- package/lib/getInputProps.js.map +1 -1
- package/lib/getOptionMatchingSimpleDiscriminator.js.map +1 -1
- package/lib/getSchemaType.d.ts +1 -0
- package/lib/getSchemaType.js +2 -1
- package/lib/getSchemaType.js.map +1 -1
- package/lib/getSubmitButtonOptions.js.map +1 -1
- package/lib/getTemplate.js +9 -0
- package/lib/getTemplate.js.map +1 -1
- package/lib/getTestIds.d.ts +17 -0
- package/lib/getTestIds.js +34 -0
- package/lib/getTestIds.js.map +1 -0
- package/lib/getUiOptions.js.map +1 -1
- package/lib/getWidget.js.map +1 -1
- package/lib/guessType.d.ts +1 -1
- package/lib/guessType.js.map +1 -1
- package/lib/hasWidget.js.map +1 -1
- package/lib/hashForSchema.d.ts +22 -0
- package/lib/hashForSchema.js +24 -6
- package/lib/hashForSchema.js.map +1 -1
- package/lib/idGenerators.d.ts +7 -0
- package/lib/idGenerators.js +9 -0
- package/lib/idGenerators.js.map +1 -1
- package/lib/index.d.ts +5 -3
- package/lib/index.js +5 -3
- package/lib/index.js.map +1 -1
- package/lib/isObject.d.ts +1 -1
- package/lib/isObject.js.map +1 -1
- package/lib/lookupFromFormContext.d.ts +11 -0
- package/lib/lookupFromFormContext.js +20 -0
- package/lib/lookupFromFormContext.js.map +1 -0
- package/lib/mergeDefaultsWithFormData.js.map +1 -1
- package/lib/mergeObjects.js.map +1 -1
- package/lib/mergeSchemas.js.map +1 -1
- package/lib/optionsList.d.ts +8 -6
- package/lib/optionsList.js +29 -18
- package/lib/optionsList.js.map +1 -1
- package/lib/orderProperties.js.map +1 -1
- package/lib/pad.js.map +1 -1
- package/lib/parseDateString.js +1 -1
- package/lib/parseDateString.js.map +1 -1
- package/lib/parser/ParserValidator.js.map +1 -1
- package/lib/parser/schemaParser.js.map +1 -1
- package/lib/rangeSpec.js.map +1 -1
- package/lib/replaceStringParameters.js.map +1 -1
- package/lib/schema/findFieldInSchema.d.ts +19 -0
- package/lib/schema/findFieldInSchema.js +61 -0
- package/lib/schema/findFieldInSchema.js.map +1 -0
- package/lib/schema/findSelectedOptionInXxxOf.d.ts +16 -0
- package/lib/schema/findSelectedOptionInXxxOf.js +34 -0
- package/lib/schema/findSelectedOptionInXxxOf.js.map +1 -0
- package/lib/schema/getClosestMatchingOption.js.map +1 -1
- package/lib/schema/getDefaultFormState.js +2 -3
- package/lib/schema/getDefaultFormState.js.map +1 -1
- package/lib/schema/getDisplayLabel.js.map +1 -1
- package/lib/schema/getFirstMatchingOption.js +70 -2
- package/lib/schema/getFirstMatchingOption.js.map +1 -1
- package/lib/schema/getFromSchema.d.ts +14 -0
- package/lib/schema/getFromSchema.js +39 -0
- package/lib/schema/getFromSchema.js.map +1 -0
- package/lib/schema/index.d.ts +4 -3
- package/lib/schema/index.js +4 -3
- package/lib/schema/index.js.map +1 -1
- package/lib/schema/isFilesArray.js.map +1 -1
- package/lib/schema/isMultiSelect.js.map +1 -1
- package/lib/schema/isSelect.js.map +1 -1
- package/lib/schema/retrieveSchema.d.ts +7 -0
- package/lib/schema/retrieveSchema.js +65 -21
- package/lib/schema/retrieveSchema.js.map +1 -1
- package/lib/schema/sanitizeDataForNewSchema.js.map +1 -1
- package/lib/schema/toIdSchema.js +20 -19
- package/lib/schema/toIdSchema.js.map +1 -1
- package/lib/schema/toPathSchema.js +1 -1
- package/lib/schema/toPathSchema.js.map +1 -1
- package/lib/schemaRequiresTrueValue.js.map +1 -1
- package/lib/toConstant.js.map +1 -1
- package/lib/toErrorList.js.map +1 -1
- package/lib/toErrorSchema.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types.d.ts +127 -128
- package/lib/unwrapErrorHandler.js.map +1 -1
- package/lib/utcToLocal.js.map +1 -1
- package/lib/validationDataMerge.js.map +1 -1
- package/lib/withIdRefPrefix.js.map +1 -1
- package/package.json +35 -25
- package/src/ErrorSchemaBuilder.ts +10 -4
- package/src/canExpand.ts +2 -2
- package/src/constants.ts +12 -3
- package/src/createSchemaUtils.ts +79 -43
- package/src/dataURItoBlob.ts +1 -1
- package/src/dateRangeOptions.ts +1 -1
- package/src/enumOptionsDeselectValue.ts +1 -1
- package/src/enumOptionsIndexForValue.ts +1 -1
- package/src/enumOptionsIsSelected.ts +1 -1
- package/src/enumOptionsSelectValue.ts +1 -1
- package/src/enumOptionsValueForIndex.ts +1 -1
- package/src/enums.ts +2 -0
- package/src/findSchemaDefinition.ts +2 -2
- package/src/getDateElementProps.ts +2 -2
- package/src/getDiscriminatorFieldFromSchema.ts +2 -1
- package/src/getInputProps.ts +2 -2
- package/src/getOptionMatchingSimpleDiscriminator.ts +2 -2
- package/src/getSchemaType.ts +3 -2
- package/src/getSubmitButtonOptions.ts +1 -1
- package/src/getTemplate.ts +12 -1
- package/src/getTestIds.ts +40 -0
- package/src/getUiOptions.ts +2 -2
- package/src/getWidget.tsx +2 -2
- package/src/hasWidget.ts +1 -1
- package/src/hashForSchema.ts +26 -6
- package/src/idGenerators.ts +10 -0
- package/src/index.ts +19 -2
- package/src/isCustomWidget.ts +1 -1
- package/src/isObject.ts +1 -1
- package/src/labelValue.ts +2 -2
- package/src/lookupFromFormContext.ts +26 -0
- package/src/mergeDefaultsWithFormData.ts +3 -3
- package/src/mergeObjects.ts +24 -21
- package/src/optionsList.ts +31 -22
- package/src/parser/ParserValidator.ts +2 -2
- package/src/parser/schemaParser.ts +2 -2
- package/src/schema/findFieldInSchema.ts +138 -0
- package/src/schema/findSelectedOptionInXxxOf.ts +53 -0
- package/src/schema/getClosestMatchingOption.ts +8 -8
- package/src/schema/getDefaultFormState.ts +26 -25
- package/src/schema/getDisplayLabel.ts +2 -2
- package/src/schema/getFirstMatchingOption.ts +79 -4
- package/src/schema/getFromSchema.ts +100 -0
- package/src/schema/index.ts +6 -4
- package/src/schema/isFilesArray.ts +2 -2
- package/src/schema/isMultiSelect.ts +2 -2
- package/src/schema/isSelect.ts +1 -1
- package/src/schema/retrieveSchema.ts +135 -69
- package/src/schema/sanitizeDataForNewSchema.ts +10 -10
- package/src/schema/toIdSchema.ts +45 -44
- package/src/schema/toPathSchema.ts +10 -10
- package/src/toErrorList.ts +2 -2
- package/src/types.ts +233 -173
- package/src/validationDataMerge.ts +1 -1
- package/src/withIdRefPrefix.ts +1 -1
- package/LICENSE.md +0 -201
- package/lib/schema/getMatchingOption.d.ts +0 -14
- package/lib/schema/getMatchingOption.js +0 -85
- package/lib/schema/getMatchingOption.js.map +0 -1
- package/lib/schema/mergeValidationData.d.ts +0 -14
- package/lib/schema/mergeValidationData.js +0 -28
- package/lib/schema/mergeValidationData.js.map +0 -1
- package/src/schema/getMatchingOption.ts +0 -103
- package/src/schema/mergeValidationData.ts +0 -38
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import get from 'lodash/get';
|
|
2
|
+
import isEqual from 'lodash/isEqual';
|
|
3
|
+
|
|
4
|
+
import { CONST_KEY, DEFAULT_KEY, PROPERTIES_KEY } from '../constants';
|
|
5
|
+
import { Experimental_CustomMergeAllOf, FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
|
|
6
|
+
import retrieveSchema from './retrieveSchema';
|
|
7
|
+
import getDiscriminatorFieldFromSchema from '../getDiscriminatorFieldFromSchema';
|
|
8
|
+
|
|
9
|
+
/** Finds the option inside the `schema['any/oneOf']` list which has the `properties[selectorField].default` or
|
|
10
|
+
* `properties[selectorField].const` that matches the `formData[selectorField]` value. For the purposes of this
|
|
11
|
+
* function, `selectorField` is either `schema.discriminator.propertyName` or `fallbackField`. The `LayoutGridField`
|
|
12
|
+
* works directly with schemas in a recursive manner, making this faster than `getFirstMatchingOption()`.
|
|
13
|
+
*
|
|
14
|
+
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
15
|
+
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
16
|
+
* @param schema - The schema element in which to search for the selected anyOf/oneOf option
|
|
17
|
+
* @param fallbackField - The field to use as a backup selector field if the schema does not have a required field
|
|
18
|
+
* @param xxx - Either `anyOf` or `oneOf`, defines which value is being sought
|
|
19
|
+
* @param [formData={}] - The form data that is used to determine which anyOf/oneOf option to descend
|
|
20
|
+
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
|
|
21
|
+
* @returns - The anyOf/oneOf option that matches the selector field in the schema or undefined if nothing is selected
|
|
22
|
+
*/
|
|
23
|
+
export default function findSelectedOptionInXxxOf<
|
|
24
|
+
T = any,
|
|
25
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
26
|
+
F extends FormContextType = any,
|
|
27
|
+
>(
|
|
28
|
+
validator: ValidatorType<T, S, F>,
|
|
29
|
+
rootSchema: S,
|
|
30
|
+
schema: S,
|
|
31
|
+
fallbackField: string,
|
|
32
|
+
xxx: 'anyOf' | 'oneOf',
|
|
33
|
+
formData: T = {} as T,
|
|
34
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
|
|
35
|
+
): S | undefined {
|
|
36
|
+
if (Array.isArray(schema[xxx])) {
|
|
37
|
+
const discriminator = getDiscriminatorFieldFromSchema<S>(schema);
|
|
38
|
+
const selectorField = discriminator || fallbackField;
|
|
39
|
+
const xxxOfs = schema[xxx]!.map((xxxOf) =>
|
|
40
|
+
retrieveSchema<T, S, F>(validator, xxxOf as S, rootSchema, formData, experimental_customMergeAllOf),
|
|
41
|
+
);
|
|
42
|
+
const data = get(formData, selectorField);
|
|
43
|
+
if (data !== undefined) {
|
|
44
|
+
return xxxOfs.find((xxx) => {
|
|
45
|
+
return isEqual(
|
|
46
|
+
get(xxx, [PROPERTIES_KEY, selectorField, DEFAULT_KEY], get(xxx, [PROPERTIES_KEY, selectorField, CONST_KEY])),
|
|
47
|
+
data,
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
@@ -53,7 +53,7 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
|
|
|
53
53
|
rootSchema: S,
|
|
54
54
|
schema?: S,
|
|
55
55
|
formData?: any,
|
|
56
|
-
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S
|
|
56
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
|
|
57
57
|
): number {
|
|
58
58
|
let totalScore = 0;
|
|
59
59
|
if (schema) {
|
|
@@ -71,7 +71,7 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
|
|
|
71
71
|
value as S,
|
|
72
72
|
rootSchema,
|
|
73
73
|
formValue,
|
|
74
|
-
experimental_customMergeAllOf
|
|
74
|
+
experimental_customMergeAllOf,
|
|
75
75
|
);
|
|
76
76
|
return (
|
|
77
77
|
score +
|
|
@@ -80,7 +80,7 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
|
|
|
80
80
|
rootSchema,
|
|
81
81
|
newSchema,
|
|
82
82
|
formValue || {},
|
|
83
|
-
experimental_customMergeAllOf
|
|
83
|
+
experimental_customMergeAllOf,
|
|
84
84
|
)
|
|
85
85
|
);
|
|
86
86
|
}
|
|
@@ -96,7 +96,7 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
|
|
|
96
96
|
get(value, key) as S[],
|
|
97
97
|
-1,
|
|
98
98
|
discriminator,
|
|
99
|
-
experimental_customMergeAllOf
|
|
99
|
+
experimental_customMergeAllOf,
|
|
100
100
|
)
|
|
101
101
|
);
|
|
102
102
|
}
|
|
@@ -127,7 +127,7 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
|
|
|
127
127
|
}
|
|
128
128
|
return score;
|
|
129
129
|
},
|
|
130
|
-
0
|
|
130
|
+
0,
|
|
131
131
|
);
|
|
132
132
|
} else if (isString(schema.type) && schema.type === guessType(formData)) {
|
|
133
133
|
totalScore += 1;
|
|
@@ -162,7 +162,7 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
|
|
|
162
162
|
export default function getClosestMatchingOption<
|
|
163
163
|
T = any,
|
|
164
164
|
S extends StrictRJSFSchema = RJSFSchema,
|
|
165
|
-
F extends FormContextType = any
|
|
165
|
+
F extends FormContextType = any,
|
|
166
166
|
>(
|
|
167
167
|
validator: ValidatorType<T, S, F>,
|
|
168
168
|
rootSchema: S,
|
|
@@ -170,7 +170,7 @@ export default function getClosestMatchingOption<
|
|
|
170
170
|
options: S[],
|
|
171
171
|
selectedOption = -1,
|
|
172
172
|
discriminatorField?: string,
|
|
173
|
-
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S
|
|
173
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
|
|
174
174
|
): number {
|
|
175
175
|
// First resolve any refs in the options
|
|
176
176
|
const resolvedOptions = options.map((option) => {
|
|
@@ -215,7 +215,7 @@ export default function getClosestMatchingOption<
|
|
|
215
215
|
}
|
|
216
216
|
return scoreData;
|
|
217
217
|
},
|
|
218
|
-
{ bestIndex: selectedOption, bestScore: 0 }
|
|
218
|
+
{ bestIndex: selectedOption, bestScore: 0 },
|
|
219
219
|
);
|
|
220
220
|
// if all scores are the same go with selectedOption
|
|
221
221
|
if (scoreCount.size === 1 && selectedOption >= 0) {
|
|
@@ -66,7 +66,7 @@ export enum AdditionalItemsHandling {
|
|
|
66
66
|
export function getInnerSchemaForArrayItem<S extends StrictRJSFSchema = RJSFSchema>(
|
|
67
67
|
schema: S,
|
|
68
68
|
additionalItems: AdditionalItemsHandling = AdditionalItemsHandling.Ignore,
|
|
69
|
-
idx = -1
|
|
69
|
+
idx = -1,
|
|
70
70
|
): S {
|
|
71
71
|
if (idx >= 0) {
|
|
72
72
|
if (Array.isArray(schema.items) && idx < schema.items.length) {
|
|
@@ -112,7 +112,7 @@ function maybeAddDefaultToObject<T = any>(
|
|
|
112
112
|
isParentRequired?: boolean,
|
|
113
113
|
requiredFields: string[] = [],
|
|
114
114
|
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior = {},
|
|
115
|
-
isConst = false
|
|
115
|
+
isConst = false,
|
|
116
116
|
) {
|
|
117
117
|
const { emptyObjectFields = 'populateAllDefaults' } = experimental_defaultFormStateBehavior;
|
|
118
118
|
if (includeUndefinedValues || isConst) {
|
|
@@ -191,7 +191,7 @@ interface ComputeDefaultsProps<T = any, S extends StrictRJSFSchema = RJSFSchema>
|
|
|
191
191
|
export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
|
|
192
192
|
validator: ValidatorType<T, S, F>,
|
|
193
193
|
rawSchema: S,
|
|
194
|
-
computeDefaultsProps: ComputeDefaultsProps<T, S> = {}
|
|
194
|
+
computeDefaultsProps: ComputeDefaultsProps<T, S> = {},
|
|
195
195
|
): T | T[] | undefined {
|
|
196
196
|
const {
|
|
197
197
|
parentDefaults,
|
|
@@ -247,7 +247,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
247
247
|
false,
|
|
248
248
|
[],
|
|
249
249
|
defaultFormData,
|
|
250
|
-
experimental_customMergeAllOf
|
|
250
|
+
experimental_customMergeAllOf,
|
|
251
251
|
);
|
|
252
252
|
schemaToCompute = resolvedSchema[0]; // pick the first element from resolve dependencies
|
|
253
253
|
} else if (isFixedItems(schema)) {
|
|
@@ -262,7 +262,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
262
262
|
rawFormData: formData as T,
|
|
263
263
|
required,
|
|
264
264
|
shouldMergeDefaultsIntoFormData,
|
|
265
|
-
})
|
|
265
|
+
}),
|
|
266
266
|
) as T[];
|
|
267
267
|
} else if (ONE_OF_KEY in schema) {
|
|
268
268
|
const { oneOf, ...remaining } = schema;
|
|
@@ -290,7 +290,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
290
290
|
oneOf as S[],
|
|
291
291
|
0,
|
|
292
292
|
discriminator,
|
|
293
|
-
experimental_customMergeAllOf
|
|
293
|
+
experimental_customMergeAllOf,
|
|
294
294
|
)
|
|
295
295
|
] as S;
|
|
296
296
|
schemaToCompute = mergeSchemas(remaining, schemaToCompute) as S;
|
|
@@ -308,7 +308,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
308
308
|
anyOf as S[],
|
|
309
309
|
0,
|
|
310
310
|
discriminator,
|
|
311
|
-
experimental_customMergeAllOf
|
|
311
|
+
experimental_customMergeAllOf,
|
|
312
312
|
)
|
|
313
313
|
] as S;
|
|
314
314
|
schemaToCompute = mergeSchemas(remaining, schemaToCompute) as S;
|
|
@@ -347,7 +347,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
347
347
|
rootSchema,
|
|
348
348
|
rawFormData,
|
|
349
349
|
experimental_defaultFormStateBehavior,
|
|
350
|
-
experimental_customMergeAllOf
|
|
350
|
+
experimental_customMergeAllOf,
|
|
351
351
|
);
|
|
352
352
|
if (!isObject(rawFormData) || ALL_OF_KEY in schema) {
|
|
353
353
|
// If the formData is not an object which means it's a primitive field, then we need to merge the defaults into the formData.
|
|
@@ -356,7 +356,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
356
356
|
defaultsWithFormData as T,
|
|
357
357
|
matchingFormData as T,
|
|
358
358
|
mergeExtraDefaults,
|
|
359
|
-
true
|
|
359
|
+
true,
|
|
360
360
|
) as T;
|
|
361
361
|
}
|
|
362
362
|
}
|
|
@@ -378,19 +378,20 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
378
378
|
export function ensureFormDataMatchingSchema<
|
|
379
379
|
T = any,
|
|
380
380
|
S extends StrictRJSFSchema = RJSFSchema,
|
|
381
|
-
F extends FormContextType = any
|
|
381
|
+
F extends FormContextType = any,
|
|
382
382
|
>(
|
|
383
383
|
validator: ValidatorType<T, S, F>,
|
|
384
384
|
schema: S,
|
|
385
385
|
rootSchema: S,
|
|
386
386
|
formData: T | undefined,
|
|
387
387
|
experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior,
|
|
388
|
-
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S
|
|
388
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
|
|
389
389
|
): T | T[] | undefined {
|
|
390
|
-
const isSelectField =
|
|
390
|
+
const isSelectField =
|
|
391
|
+
!isConstant<S>(schema) && isSelect<T, S, F>(validator, schema, rootSchema, experimental_customMergeAllOf);
|
|
391
392
|
let validFormData: T | T[] | undefined = formData;
|
|
392
393
|
if (isSelectField) {
|
|
393
|
-
const getOptionsList = optionsList(schema);
|
|
394
|
+
const getOptionsList = optionsList<T, S, F>(schema);
|
|
394
395
|
const isValid = getOptionsList?.some((option) => deepEquals(option.value, formData));
|
|
395
396
|
validFormData = isValid ? formData : undefined;
|
|
396
397
|
}
|
|
@@ -425,7 +426,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
|
|
|
425
426
|
required,
|
|
426
427
|
shouldMergeDefaultsIntoFormData,
|
|
427
428
|
}: ComputeDefaultsProps<T, S> = {},
|
|
428
|
-
defaults?: T | T[] | undefined
|
|
429
|
+
defaults?: T | T[] | undefined,
|
|
429
430
|
): T {
|
|
430
431
|
{
|
|
431
432
|
const formData: T = (isObject(rawFormData) ? rawFormData : {}) as T;
|
|
@@ -439,7 +440,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
|
|
|
439
440
|
const parentConst = retrievedSchema[CONST_KEY];
|
|
440
441
|
const objectDefaults = Object.keys(retrievedSchema.properties || {}).reduce(
|
|
441
442
|
(acc: GenericObjectType, key: string) => {
|
|
442
|
-
const propertySchema = get(retrievedSchema, [PROPERTIES_KEY, key]);
|
|
443
|
+
const propertySchema: S = get(retrievedSchema, [PROPERTIES_KEY, key], {}) as S;
|
|
443
444
|
// Check if the parent schema has a const property defined AND we are supporting const as defaults, then we
|
|
444
445
|
// should always return the computedDefault since it's coming from the const.
|
|
445
446
|
const hasParentConst = isObject(parentConst) && (parentConst as JSONSchema7Object)[key] !== undefined;
|
|
@@ -468,11 +469,11 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
|
|
|
468
469
|
required,
|
|
469
470
|
retrievedSchema.required,
|
|
470
471
|
experimental_defaultFormStateBehavior,
|
|
471
|
-
hasConst
|
|
472
|
+
hasConst,
|
|
472
473
|
);
|
|
473
474
|
return acc;
|
|
474
475
|
},
|
|
475
|
-
{}
|
|
476
|
+
{},
|
|
476
477
|
) as T;
|
|
477
478
|
if (retrievedSchema.additionalProperties) {
|
|
478
479
|
// as per spec additionalProperties may be either schema or boolean
|
|
@@ -512,7 +513,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
|
|
|
512
513
|
computedDefault,
|
|
513
514
|
includeUndefinedValues,
|
|
514
515
|
required,
|
|
515
|
-
formDataRequired
|
|
516
|
+
formDataRequired,
|
|
516
517
|
);
|
|
517
518
|
});
|
|
518
519
|
}
|
|
@@ -540,7 +541,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
|
|
|
540
541
|
required,
|
|
541
542
|
shouldMergeDefaultsIntoFormData,
|
|
542
543
|
}: ComputeDefaultsProps<T, S> = {},
|
|
543
|
-
defaults?: T | T[] | undefined
|
|
544
|
+
defaults?: T | T[] | undefined,
|
|
544
545
|
): T | T[] | undefined {
|
|
545
546
|
const schema: S = rawSchema;
|
|
546
547
|
|
|
@@ -636,7 +637,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
|
|
|
636
637
|
experimental_customMergeAllOf,
|
|
637
638
|
required,
|
|
638
639
|
shouldMergeDefaultsIntoFormData,
|
|
639
|
-
})
|
|
640
|
+
}),
|
|
640
641
|
) as T[];
|
|
641
642
|
// then fill up the rest with either the item default or empty, up to minItems
|
|
642
643
|
return defaultEntries.concat(fillerEntries);
|
|
@@ -653,12 +654,12 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
|
|
|
653
654
|
export function getDefaultBasedOnSchemaType<
|
|
654
655
|
T = any,
|
|
655
656
|
S extends StrictRJSFSchema = RJSFSchema,
|
|
656
|
-
F extends FormContextType = any
|
|
657
|
+
F extends FormContextType = any,
|
|
657
658
|
>(
|
|
658
659
|
validator: ValidatorType<T, S, F>,
|
|
659
660
|
rawSchema: S,
|
|
660
661
|
computeDefaultsProps: ComputeDefaultsProps<T, S> = {},
|
|
661
|
-
defaults?: T | T[] | undefined
|
|
662
|
+
defaults?: T | T[] | undefined,
|
|
662
663
|
): T | T[] | void {
|
|
663
664
|
switch (getSchemaType<S>(rawSchema)) {
|
|
664
665
|
// We need to recurse for object schema inner default values.
|
|
@@ -688,7 +689,7 @@ export function getDefaultBasedOnSchemaType<
|
|
|
688
689
|
export default function getDefaultFormState<
|
|
689
690
|
T = any,
|
|
690
691
|
S extends StrictRJSFSchema = RJSFSchema,
|
|
691
|
-
F extends FormContextType = any
|
|
692
|
+
F extends FormContextType = any,
|
|
692
693
|
>(
|
|
693
694
|
validator: ValidatorType<T, S, F>,
|
|
694
695
|
theSchema: S,
|
|
@@ -696,7 +697,7 @@ export default function getDefaultFormState<
|
|
|
696
697
|
rootSchema?: S,
|
|
697
698
|
includeUndefinedValues: boolean | 'excludeObjectChildren' = false,
|
|
698
699
|
experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior,
|
|
699
|
-
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S
|
|
700
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
|
|
700
701
|
) {
|
|
701
702
|
if (!isObject(theSchema)) {
|
|
702
703
|
throw new Error('Invalid schema: ' + theSchema);
|
|
@@ -725,7 +726,7 @@ export default function getDefaultFormState<
|
|
|
725
726
|
formData,
|
|
726
727
|
true, // set to true to add any additional default array entries.
|
|
727
728
|
defaultSupercedesUndefined,
|
|
728
|
-
true // set to true to override formData with defaults if they exist.
|
|
729
|
+
true, // set to true to override formData with defaults if they exist.
|
|
729
730
|
);
|
|
730
731
|
return result;
|
|
731
732
|
}
|
|
@@ -28,14 +28,14 @@ import isMultiSelect from './isMultiSelect';
|
|
|
28
28
|
export default function getDisplayLabel<
|
|
29
29
|
T = any,
|
|
30
30
|
S extends StrictRJSFSchema = RJSFSchema,
|
|
31
|
-
F extends FormContextType = any
|
|
31
|
+
F extends FormContextType = any,
|
|
32
32
|
>(
|
|
33
33
|
validator: ValidatorType<T, S, F>,
|
|
34
34
|
schema: S,
|
|
35
35
|
uiSchema: UiSchema<T, S, F> = {},
|
|
36
36
|
rootSchema?: S,
|
|
37
37
|
globalOptions?: GlobalUISchemaOptions,
|
|
38
|
-
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S
|
|
38
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
|
|
39
39
|
): boolean {
|
|
40
40
|
const uiOptions = getUiOptions<T, S, F>(uiSchema, globalOptions);
|
|
41
41
|
const { label = true } = uiOptions;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import get from 'lodash/get';
|
|
2
|
+
import has from 'lodash/has';
|
|
3
|
+
import isNumber from 'lodash/isNumber';
|
|
4
|
+
|
|
5
|
+
import { PROPERTIES_KEY } from '../constants';
|
|
6
|
+
import getOptionMatchingSimpleDiscriminator from '../getOptionMatchingSimpleDiscriminator';
|
|
2
7
|
import { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
|
|
3
8
|
|
|
4
9
|
/** Given the `formData` and list of `options`, attempts to find the index of the first option that matches the data.
|
|
@@ -15,13 +20,83 @@ import { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '..
|
|
|
15
20
|
export default function getFirstMatchingOption<
|
|
16
21
|
T = any,
|
|
17
22
|
S extends StrictRJSFSchema = RJSFSchema,
|
|
18
|
-
F extends FormContextType = any
|
|
23
|
+
F extends FormContextType = any,
|
|
19
24
|
>(
|
|
20
25
|
validator: ValidatorType<T, S, F>,
|
|
21
26
|
formData: T | undefined,
|
|
22
27
|
options: S[],
|
|
23
28
|
rootSchema: S,
|
|
24
|
-
discriminatorField?: string
|
|
29
|
+
discriminatorField?: string,
|
|
25
30
|
): number {
|
|
26
|
-
|
|
31
|
+
// For performance, skip validating subschemas if formData is undefined. We just
|
|
32
|
+
// want to get the first option in that case.
|
|
33
|
+
if (formData === undefined) {
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const simpleDiscriminatorMatch = getOptionMatchingSimpleDiscriminator(formData, options, discriminatorField);
|
|
38
|
+
if (isNumber(simpleDiscriminatorMatch)) {
|
|
39
|
+
return simpleDiscriminatorMatch;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (let i = 0; i < options.length; i++) {
|
|
43
|
+
const option = options[i];
|
|
44
|
+
|
|
45
|
+
// If we have a discriminator field, then we will use this to make the determination
|
|
46
|
+
if (discriminatorField && has(option, [PROPERTIES_KEY, discriminatorField])) {
|
|
47
|
+
const value = get(formData, discriminatorField);
|
|
48
|
+
const discriminator: S = get(option, [PROPERTIES_KEY, discriminatorField], {}) as S;
|
|
49
|
+
if (validator.isValid(discriminator, value, rootSchema)) {
|
|
50
|
+
return i;
|
|
51
|
+
}
|
|
52
|
+
} else if (option[PROPERTIES_KEY]) {
|
|
53
|
+
// If the schema describes an object then we need to add slightly more
|
|
54
|
+
// strict matching to the schema, because unless the schema uses the
|
|
55
|
+
// "requires" keyword, an object will match the schema as long as it
|
|
56
|
+
// doesn't have matching keys with a conflicting type. To do this we use an
|
|
57
|
+
// "anyOf" with an array of requires. This augmentation expresses that the
|
|
58
|
+
// schema should match if any of the keys in the schema are present on the
|
|
59
|
+
// object and pass validation.
|
|
60
|
+
//
|
|
61
|
+
// Create an "anyOf" schema that requires at least one of the keys in the
|
|
62
|
+
// "properties" object
|
|
63
|
+
const requiresAnyOf = {
|
|
64
|
+
anyOf: Object.keys(option[PROPERTIES_KEY]).map((key) => ({
|
|
65
|
+
required: [key],
|
|
66
|
+
})),
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
let augmentedSchema;
|
|
70
|
+
|
|
71
|
+
// If the "anyOf" keyword already exists, wrap the augmentation in an "allOf"
|
|
72
|
+
if (option.anyOf) {
|
|
73
|
+
// Create a shallow clone of the option
|
|
74
|
+
const { ...shallowClone } = option;
|
|
75
|
+
|
|
76
|
+
if (!shallowClone.allOf) {
|
|
77
|
+
shallowClone.allOf = [];
|
|
78
|
+
} else {
|
|
79
|
+
// If "allOf" already exists, shallow clone the array
|
|
80
|
+
shallowClone.allOf = shallowClone.allOf.slice();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
shallowClone.allOf.push(requiresAnyOf);
|
|
84
|
+
|
|
85
|
+
augmentedSchema = shallowClone;
|
|
86
|
+
} else {
|
|
87
|
+
augmentedSchema = Object.assign({}, option, requiresAnyOf);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Remove the "required" field as it's likely that not all fields have
|
|
91
|
+
// been filled in yet, which will mean that the schema is not valid
|
|
92
|
+
delete augmentedSchema.required;
|
|
93
|
+
|
|
94
|
+
if (validator.isValid(augmentedSchema, formData, rootSchema)) {
|
|
95
|
+
return i;
|
|
96
|
+
}
|
|
97
|
+
} else if (validator.isValid(option, formData, rootSchema)) {
|
|
98
|
+
return i;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return 0;
|
|
27
102
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import get from 'lodash/get';
|
|
2
|
+
import has from 'lodash/has';
|
|
3
|
+
import isEmpty from 'lodash/isEmpty';
|
|
4
|
+
|
|
5
|
+
import retrieveSchema from './retrieveSchema';
|
|
6
|
+
import { Experimental_CustomMergeAllOf, FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
|
|
7
|
+
import { REF_KEY } from '../constants';
|
|
8
|
+
|
|
9
|
+
/** Internal helper function that acts like lodash's `get` but additionally retrieves `$ref`s as needed to get the path
|
|
10
|
+
* for schemas containing potentially nested `$ref`s.
|
|
11
|
+
*
|
|
12
|
+
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
13
|
+
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
14
|
+
* @param schema - The current node within the JSON schema recursion
|
|
15
|
+
* @param path - The remaining keys in the path to the desired property
|
|
16
|
+
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
|
|
17
|
+
* @returns - The internal schema from the `schema` for the given `path` or undefined if not found
|
|
18
|
+
*/
|
|
19
|
+
function getFromSchemaInternal<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
|
|
20
|
+
validator: ValidatorType<T, S, F>,
|
|
21
|
+
rootSchema: S,
|
|
22
|
+
schema: S,
|
|
23
|
+
path: string | string[],
|
|
24
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
|
|
25
|
+
): T | S | undefined {
|
|
26
|
+
let fieldSchema = schema;
|
|
27
|
+
if (has(schema, REF_KEY)) {
|
|
28
|
+
fieldSchema = retrieveSchema<T, S, F>(validator, schema, rootSchema, undefined, experimental_customMergeAllOf);
|
|
29
|
+
}
|
|
30
|
+
if (isEmpty(path)) {
|
|
31
|
+
return fieldSchema;
|
|
32
|
+
}
|
|
33
|
+
const pathList = Array.isArray(path) ? path : path.split('.');
|
|
34
|
+
const [part, ...nestedPath] = pathList;
|
|
35
|
+
if (part && has(fieldSchema, part)) {
|
|
36
|
+
fieldSchema = get(fieldSchema, part) as S;
|
|
37
|
+
return getFromSchemaInternal<T, S, F>(
|
|
38
|
+
validator,
|
|
39
|
+
rootSchema,
|
|
40
|
+
fieldSchema,
|
|
41
|
+
nestedPath,
|
|
42
|
+
experimental_customMergeAllOf,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Helper that acts like lodash's `get` but additionally retrieves `$ref`s as needed to get the path for schemas
|
|
49
|
+
* containing potentially nested `$ref`s.
|
|
50
|
+
*
|
|
51
|
+
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
52
|
+
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
53
|
+
* @param schema - The current node within the JSON schema recursion
|
|
54
|
+
* @param path - The keys in the path to the desired field
|
|
55
|
+
* @param defaultValue - The value to return if a value is not found for the `pathList` path
|
|
56
|
+
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
|
|
57
|
+
* @returns - The inner schema from the `schema` for the given `path` or the `defaultValue` if not found
|
|
58
|
+
*/
|
|
59
|
+
export default function getFromSchema<
|
|
60
|
+
T = any,
|
|
61
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
62
|
+
F extends FormContextType = any,
|
|
63
|
+
>(
|
|
64
|
+
validator: ValidatorType<T, S, F>,
|
|
65
|
+
rootSchema: S,
|
|
66
|
+
schema: S,
|
|
67
|
+
path: string | string[],
|
|
68
|
+
defaultValue: T,
|
|
69
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
|
|
70
|
+
): T;
|
|
71
|
+
export default function getFromSchema<
|
|
72
|
+
T = any,
|
|
73
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
74
|
+
F extends FormContextType = any,
|
|
75
|
+
>(
|
|
76
|
+
validator: ValidatorType<T, S, F>,
|
|
77
|
+
rootSchema: S,
|
|
78
|
+
schema: S,
|
|
79
|
+
path: string | string[],
|
|
80
|
+
defaultValue: S,
|
|
81
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
|
|
82
|
+
): S;
|
|
83
|
+
export default function getFromSchema<
|
|
84
|
+
T = any,
|
|
85
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
86
|
+
F extends FormContextType = any,
|
|
87
|
+
>(
|
|
88
|
+
validator: ValidatorType<T, S, F>,
|
|
89
|
+
rootSchema: S,
|
|
90
|
+
schema: S,
|
|
91
|
+
path: string | string[],
|
|
92
|
+
defaultValue: T | S,
|
|
93
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
|
|
94
|
+
): T | S {
|
|
95
|
+
const result = getFromSchemaInternal(validator, rootSchema, schema, path, experimental_customMergeAllOf);
|
|
96
|
+
if (result === undefined) {
|
|
97
|
+
return defaultValue;
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
}
|
package/src/schema/index.ts
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
|
+
import findFieldInSchema from './findFieldInSchema';
|
|
2
|
+
import findSelectedOptionInXxxOf from './findSelectedOptionInXxxOf';
|
|
1
3
|
import getDefaultFormState from './getDefaultFormState';
|
|
2
4
|
import getDisplayLabel from './getDisplayLabel';
|
|
3
5
|
import getClosestMatchingOption from './getClosestMatchingOption';
|
|
4
6
|
import getFirstMatchingOption from './getFirstMatchingOption';
|
|
5
|
-
import
|
|
7
|
+
import getFromSchema from './getFromSchema';
|
|
6
8
|
import isFilesArray from './isFilesArray';
|
|
7
9
|
import isMultiSelect from './isMultiSelect';
|
|
8
10
|
import isSelect from './isSelect';
|
|
9
|
-
import mergeValidationData from './mergeValidationData';
|
|
10
11
|
import retrieveSchema from './retrieveSchema';
|
|
11
12
|
import sanitizeDataForNewSchema from './sanitizeDataForNewSchema';
|
|
12
13
|
import toIdSchema from './toIdSchema';
|
|
13
14
|
import toPathSchema from './toPathSchema';
|
|
14
15
|
|
|
15
16
|
export {
|
|
17
|
+
findFieldInSchema,
|
|
18
|
+
findSelectedOptionInXxxOf,
|
|
16
19
|
getDefaultFormState,
|
|
17
20
|
getDisplayLabel,
|
|
18
21
|
getClosestMatchingOption,
|
|
19
22
|
getFirstMatchingOption,
|
|
20
|
-
|
|
23
|
+
getFromSchema,
|
|
21
24
|
isFilesArray,
|
|
22
25
|
isMultiSelect,
|
|
23
26
|
isSelect,
|
|
24
|
-
mergeValidationData,
|
|
25
27
|
retrieveSchema,
|
|
26
28
|
sanitizeDataForNewSchema,
|
|
27
29
|
toIdSchema,
|
|
@@ -23,7 +23,7 @@ export default function isFilesArray<T = any, S extends StrictRJSFSchema = RJSFS
|
|
|
23
23
|
schema: S,
|
|
24
24
|
uiSchema: UiSchema<T, S, F> = {},
|
|
25
25
|
rootSchema?: S,
|
|
26
|
-
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S
|
|
26
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
|
|
27
27
|
) {
|
|
28
28
|
if (uiSchema[UI_WIDGET_KEY] === 'files') {
|
|
29
29
|
return true;
|
|
@@ -34,7 +34,7 @@ export default function isFilesArray<T = any, S extends StrictRJSFSchema = RJSFS
|
|
|
34
34
|
schema.items as S,
|
|
35
35
|
rootSchema,
|
|
36
36
|
undefined,
|
|
37
|
-
experimental_customMergeAllOf
|
|
37
|
+
experimental_customMergeAllOf,
|
|
38
38
|
);
|
|
39
39
|
return itemsSchema.type === 'string' && itemsSchema.format === 'data-url';
|
|
40
40
|
}
|
|
@@ -13,12 +13,12 @@ import isSelect from './isSelect';
|
|
|
13
13
|
export default function isMultiSelect<
|
|
14
14
|
T = any,
|
|
15
15
|
S extends StrictRJSFSchema = RJSFSchema,
|
|
16
|
-
F extends FormContextType = any
|
|
16
|
+
F extends FormContextType = any,
|
|
17
17
|
>(
|
|
18
18
|
validator: ValidatorType<T, S, F>,
|
|
19
19
|
schema: S,
|
|
20
20
|
rootSchema?: S,
|
|
21
|
-
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S
|
|
21
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
|
|
22
22
|
) {
|
|
23
23
|
if (!schema.uniqueItems || !schema.items || typeof schema.items === 'boolean') {
|
|
24
24
|
return false;
|
package/src/schema/isSelect.ts
CHANGED
|
@@ -14,7 +14,7 @@ export default function isSelect<T = any, S extends StrictRJSFSchema = RJSFSchem
|
|
|
14
14
|
validator: ValidatorType<T, S, F>,
|
|
15
15
|
theSchema: S,
|
|
16
16
|
rootSchema: S = {} as S,
|
|
17
|
-
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S
|
|
17
|
+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
|
|
18
18
|
) {
|
|
19
19
|
const schema = retrieveSchema<T, S, F>(validator, theSchema, rootSchema, undefined, experimental_customMergeAllOf);
|
|
20
20
|
const altSchemas = schema.oneOf || schema.anyOf;
|