@rjsf/utils
Version:
Utility functions for @rjsf/core
89 lines • 5.37 kB
JavaScript
import get from 'lodash-es/get.js';
import set from 'lodash-es/set.js';
import { ADDITIONAL_PROPERTIES_KEY, ALL_OF_KEY, ANY_OF_KEY, DEPENDENCIES_KEY, ITEMS_KEY, NAME_KEY, ONE_OF_KEY, PROPERTIES_KEY, REF_KEY, RJSF_ADDITIONAL_PROPERTIES_FLAG, } from '../constants.js';
import getDiscriminatorFieldFromSchema from '../getDiscriminatorFieldFromSchema.js';
import getClosestMatchingOption from './getClosestMatchingOption.js';
import retrieveSchema from './retrieveSchema.js';
import deepEquals from '../deepEquals.js';
/** An internal helper that generates an `PathSchema` object for the `schema`, recursively with protection against
* infinite recursion
*
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
* @param schema - The schema for which the `PathSchema` is desired
* @param [name=''] - The base name for the schema
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
* @param [formData] - The current formData, if any, to assist retrieving a schema
* @param [_recurseList=[]] - The list of retrieved schemas currently being recursed, used to prevent infinite recursion
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
* @returns - The `PathSchema` object for the `schema`
*/
function toPathSchemaInternal(validator, schema, name, rootSchema, formData, _recurseList = [], experimental_customMergeAllOf) {
if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) {
const _schema = retrieveSchema(validator, schema, rootSchema, formData, experimental_customMergeAllOf);
const sameSchemaIndex = _recurseList.findIndex((item) => deepEquals(item, _schema));
if (sameSchemaIndex === -1) {
return toPathSchemaInternal(validator, _schema, name, rootSchema, formData, _recurseList.concat(_schema), experimental_customMergeAllOf);
}
}
let pathSchema = {
[NAME_KEY]: name.replace(/^\./, ''),
};
if (ONE_OF_KEY in schema || ANY_OF_KEY in schema) {
const xxxOf = ONE_OF_KEY in schema ? schema.oneOf : schema.anyOf;
const discriminator = getDiscriminatorFieldFromSchema(schema);
const index = getClosestMatchingOption(validator, rootSchema, formData, xxxOf, 0, discriminator, experimental_customMergeAllOf);
const _schema = xxxOf[index];
pathSchema = {
...pathSchema,
...toPathSchemaInternal(validator, _schema, name, rootSchema, formData, _recurseList, experimental_customMergeAllOf),
};
}
if (ADDITIONAL_PROPERTIES_KEY in schema && schema[ADDITIONAL_PROPERTIES_KEY] !== false) {
set(pathSchema, RJSF_ADDITIONAL_PROPERTIES_FLAG, true);
}
if (ITEMS_KEY in schema && Array.isArray(formData)) {
const { items: schemaItems, additionalItems: schemaAdditionalItems } = schema;
if (Array.isArray(schemaItems)) {
formData.forEach((element, i) => {
if (schemaItems[i]) {
pathSchema[i] = toPathSchemaInternal(validator, schemaItems[i], `${name}.${i}`, rootSchema, element, _recurseList, experimental_customMergeAllOf);
}
else if (schemaAdditionalItems) {
pathSchema[i] = toPathSchemaInternal(validator, schemaAdditionalItems, `${name}.${i}`, rootSchema, element, _recurseList, experimental_customMergeAllOf);
}
else {
console.warn(`Unable to generate path schema for "${name}.${i}". No schema defined for it`);
}
});
}
else {
formData.forEach((element, i) => {
pathSchema[i] = toPathSchemaInternal(validator, schemaItems, `${name}.${i}`, rootSchema, element, _recurseList, experimental_customMergeAllOf);
});
}
}
else if (PROPERTIES_KEY in schema) {
for (const property in schema.properties) {
const field = get(schema, [PROPERTIES_KEY, property]);
pathSchema[property] = toPathSchemaInternal(validator, field, `${name}.${property}`, rootSchema,
// It's possible that formData is not an object -- this can happen if an
// array item has just been added, but not populated with data yet
get(formData, [property]), _recurseList, experimental_customMergeAllOf);
}
}
return pathSchema;
}
/** Generates an `PathSchema` object for the `schema`, recursively
*
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
* @param schema - The schema for which the `PathSchema` is desired
* @param [name=''] - The base name for the schema
* @param [rootSchema] - The root schema, used to primarily to look up `$ref`s
* @param [formData] - The current formData, if any, to assist retrieving a schema
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
* @returns - The `PathSchema` object for the `schema`
*/
export default function toPathSchema(validator, schema, name = '', rootSchema, formData, experimental_customMergeAllOf) {
return toPathSchemaInternal(validator, schema, name, rootSchema, formData, undefined, experimental_customMergeAllOf);
}
//# sourceMappingURL=toPathSchema.js.map