diff --git a/packages/utils/src/createSchemaUtils.ts b/packages/utils/src/createSchemaUtils.ts index 69dc9fa0a2..b7e1c73b06 100644 --- a/packages/utils/src/createSchemaUtils.ts +++ b/packages/utils/src/createSchemaUtils.ts @@ -1,4 +1,4 @@ -import deepEquals from "./deepEquals"; +import deepEquals from './deepEquals'; import { ErrorSchema, Experimental_DefaultFormStateBehavior, @@ -12,7 +12,7 @@ import { UiSchema, ValidationData, ValidatorType, -} from "./types"; +} from './types'; import { getClosestMatchingOption, getDefaultFormState, @@ -27,18 +27,16 @@ import { sanitizeDataForNewSchema, toIdSchema, toPathSchema, -} from "./schema"; +} from './schema'; /** The `SchemaUtils` class provides a wrapper around the publicly exported APIs in the `utils/schema` directory such * that one does not have to explicitly pass the `validator`, `rootSchema`, or `experimental_defaultFormStateBehavior` to each method. * Since these generally do not change across a `Form`, this allows for providing a simplified set of APIs to the * `@rjsf/core` components and the various themes as well. This class implements the `SchemaUtilsType` interface. */ -class SchemaUtils< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, -> implements SchemaUtilsType { +class SchemaUtils + implements SchemaUtilsType +{ rootSchema: S; validator: ValidatorType; experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior; @@ -52,13 +50,11 @@ class SchemaUtils< constructor( validator: ValidatorType, rootSchema: S, - experimental_defaultFormStateBehavior: - Experimental_DefaultFormStateBehavior, + experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior ) { this.rootSchema = rootSchema; this.validator = validator; - this.experimental_defaultFormStateBehavior = - experimental_defaultFormStateBehavior; + this.experimental_defaultFormStateBehavior = experimental_defaultFormStateBehavior; } /** Returns the `ValidatorType` in the `SchemaUtilsType` @@ -81,7 +77,7 @@ class SchemaUtils< doesSchemaUtilsDiffer( validator: ValidatorType, rootSchema: S, - experimental_defaultFormStateBehavior = {}, + experimental_defaultFormStateBehavior = {} ): boolean { if (!validator || !rootSchema) { return false; @@ -89,10 +85,7 @@ class SchemaUtils< return ( this.validator !== validator || !deepEquals(this.rootSchema, rootSchema) || - !deepEquals( - this.experimental_defaultFormStateBehavior, - experimental_defaultFormStateBehavior, - ) + !deepEquals(this.experimental_defaultFormStateBehavior, experimental_defaultFormStateBehavior) ); } @@ -109,7 +102,7 @@ class SchemaUtils< getDefaultFormState( schema: S, formData?: T, - includeUndefinedValues: boolean | "excludeObjectChildren" = false, + includeUndefinedValues: boolean | 'excludeObjectChildren' = false ): T | T[] | undefined { return getDefaultFormState( this.validator, @@ -117,7 +110,7 @@ class SchemaUtils< formData, this.rootSchema, includeUndefinedValues, - this.experimental_defaultFormStateBehavior, + this.experimental_defaultFormStateBehavior ); } @@ -129,18 +122,8 @@ class SchemaUtils< * @param [globalOptions={}] - The optional Global UI Schema from which to get any fallback `xxx` options * @returns - True if the label should be displayed or false if it should not */ - getDisplayLabel( - schema: S, - uiSchema?: UiSchema, - globalOptions?: GlobalUISchemaOptions, - ) { - return getDisplayLabel( - this.validator, - schema, - uiSchema, - this.rootSchema, - globalOptions, - ); + getDisplayLabel(schema: S, uiSchema?: UiSchema, globalOptions?: GlobalUISchemaOptions) { + return getDisplayLabel(this.validator, schema, uiSchema, this.rootSchema, globalOptions); } /** Determines which of the given `options` provided most closely matches the `formData`. @@ -160,7 +143,7 @@ class SchemaUtils< formData: T | undefined, options: S[], selectedOption?: number, - discriminatorField?: string, + discriminatorField?: string ): number { return getClosestMatchingOption( this.validator, @@ -168,7 +151,7 @@ class SchemaUtils< formData, options, selectedOption, - discriminatorField, + discriminatorField ); } @@ -181,18 +164,8 @@ class SchemaUtils< * determine which option is selected * @returns - The firstindex of the matched option or 0 if none is available */ - getFirstMatchingOption( - formData: T | undefined, - options: S[], - discriminatorField?: string, - ): number { - return getFirstMatchingOption( - this.validator, - formData, - options, - this.rootSchema, - discriminatorField, - ); + getFirstMatchingOption(formData: T | undefined, options: S[], discriminatorField?: string): number { + return getFirstMatchingOption(this.validator, formData, options, this.rootSchema, discriminatorField); } /** Given the `formData` and list of `options`, attempts to find the index of the option that best matches the data. @@ -205,18 +178,8 @@ class SchemaUtils< * @returns - The index of the matched option or 0 if none is available * @deprecated */ - getMatchingOption( - formData: T | undefined, - options: S[], - discriminatorField?: string, - ) { - return getMatchingOption( - this.validator, - formData, - options, - this.rootSchema, - discriminatorField, - ); + getMatchingOption(formData: T | undefined, options: S[], discriminatorField?: string) { + return getMatchingOption(this.validator, formData, options, this.rootSchema, discriminatorField); } /** Checks to see if the `schema` and `uiSchema` combination represents an array of files @@ -226,12 +189,7 @@ class SchemaUtils< * @returns - True if schema/uiSchema contains an array of files, otherwise false */ isFilesArray(schema: S, uiSchema?: UiSchema) { - return isFilesArray( - this.validator, - schema, - uiSchema, - this.rootSchema, - ); + return isFilesArray(this.validator, schema, uiSchema, this.rootSchema); } /** Checks to see if the `schema` combination represents a multi-select @@ -263,15 +221,8 @@ class SchemaUtils< * @deprecated - Use the `validationDataMerge()` function exported from `@rjsf/utils` instead. This function will be * removed in the next major release. */ - mergeValidationData( - validationData: ValidationData, - additionalErrorSchema?: ErrorSchema, - ): ValidationData { - return mergeValidationData( - this.validator, - validationData, - additionalErrorSchema, - ); + mergeValidationData(validationData: ValidationData, additionalErrorSchema?: ErrorSchema): ValidationData { + return mergeValidationData(this.validator, validationData, additionalErrorSchema); } /** Retrieves an expanded schema that has had all of its conditions, additional properties, references and @@ -283,12 +234,7 @@ class SchemaUtils< * @returns - The schema having its conditions, additional properties, references and dependencies resolved */ retrieveSchema(schema: S, rawFormData?: T) { - return retrieveSchema( - this.validator, - schema, - this.rootSchema, - rawFormData, - ); + return retrieveSchema(this.validator, schema, this.rootSchema, rawFormData); } /** Sanitize the `data` associated with the `oldSchema` so it is considered appropriate for the `newSchema`. If the @@ -303,13 +249,7 @@ class SchemaUtils< * to `undefined`. Will return `undefined` if the new schema is not an object containing properties. */ sanitizeDataForNewSchema(newSchema?: S, oldSchema?: S, data?: any): T { - return sanitizeDataForNewSchema( - this.validator, - this.rootSchema, - newSchema, - oldSchema, - data, - ); + return sanitizeDataForNewSchema(this.validator, this.rootSchema, newSchema, oldSchema, data); } /** Generates an `IdSchema` object for the `schema`, recursively @@ -321,22 +261,8 @@ class SchemaUtils< * @param [idSeparator='_'] - The separator to use for the path segments in the id * @returns - The `IdSchema` object for the `schema` */ - toIdSchema( - schema: S, - id?: string | null, - formData?: T, - idPrefix = "root", - idSeparator = "_", - ): IdSchema { - return toIdSchema( - this.validator, - schema, - id, - this.rootSchema, - formData, - idPrefix, - idSeparator, - ); + toIdSchema(schema: S, id?: string | null, formData?: T, idPrefix = 'root', idSeparator = '_'): IdSchema { + return toIdSchema(this.validator, schema, id, this.rootSchema, formData, idPrefix, idSeparator); } /** Generates an `PathSchema` object for the `schema`, recursively @@ -347,13 +273,7 @@ class SchemaUtils< * @returns - The `PathSchema` object for the `schema` */ toPathSchema(schema: S, name?: string, formData?: T): PathSchema { - return toPathSchema( - this.validator, - schema, - name, - this.rootSchema, - formData, - ); + return toPathSchema(this.validator, schema, name, this.rootSchema, formData); } } @@ -368,15 +288,11 @@ class SchemaUtils< export default function createSchemaUtils< T = any, S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, + F extends FormContextType = any >( validator: ValidatorType, rootSchema: S, - experimental_defaultFormStateBehavior = {}, + experimental_defaultFormStateBehavior = {} ): SchemaUtilsType { - return new SchemaUtils( - validator, - rootSchema, - experimental_defaultFormStateBehavior, - ); + return new SchemaUtils(validator, rootSchema, experimental_defaultFormStateBehavior); } diff --git a/packages/utils/src/enumOptionsDeselectValue.ts b/packages/utils/src/enumOptionsDeselectValue.ts index e89c1153fd..88384321e5 100644 --- a/packages/utils/src/enumOptionsDeselectValue.ts +++ b/packages/utils/src/enumOptionsDeselectValue.ts @@ -1,6 +1,6 @@ -import { EnumOptionsType, RJSFSchema, StrictRJSFSchema } from "./types"; -import enumOptionsValueForIndex from "./enumOptionsValueForIndex"; -import deepEquals from "./deepEquals"; +import { EnumOptionsType, RJSFSchema, StrictRJSFSchema } from './types'; +import enumOptionsValueForIndex from './enumOptionsValueForIndex'; +import deepEquals from './deepEquals'; /** Removes the enum option value at the `valueIndex` from the currently `selected` (list of) value(s). If `selected` is * a list, then that list is updated to remove the enum option value with the `valueIndex` in `allEnumOptions`. If it is @@ -14,13 +14,11 @@ import deepEquals from "./deepEquals"; * unless `selected` is a single value. In that case, if the `valueIndex` value matches `selected`, returns * undefined, otherwise `selected`. */ -export default function enumOptionsDeselectValue< - S extends StrictRJSFSchema = RJSFSchema, ->( +export default function enumOptionsDeselectValue( valueIndex: string | number, - selected?: EnumOptionsType["value"] | EnumOptionsType["value"][], - allEnumOptions: EnumOptionsType[] = [], -): EnumOptionsType["value"] | EnumOptionsType["value"][] | undefined { + selected?: EnumOptionsType['value'] | EnumOptionsType['value'][], + allEnumOptions: EnumOptionsType[] = [] +): EnumOptionsType['value'] | EnumOptionsType['value'][] | undefined { const value = enumOptionsValueForIndex(valueIndex, allEnumOptions); if (Array.isArray(selected)) { return selected.filter((v) => !deepEquals(v, value)); diff --git a/packages/utils/src/enumOptionsIsSelected.ts b/packages/utils/src/enumOptionsIsSelected.ts index af6fe076be..e7c782bade 100644 --- a/packages/utils/src/enumOptionsIsSelected.ts +++ b/packages/utils/src/enumOptionsIsSelected.ts @@ -1,5 +1,5 @@ -import deepEquals from "./deepEquals"; -import { EnumOptionsType, RJSFSchema, StrictRJSFSchema } from "./types"; +import deepEquals from './deepEquals'; +import { EnumOptionsType, RJSFSchema, StrictRJSFSchema } from './types'; /** Determines whether the given `value` is (one of) the `selected` value(s). * @@ -7,11 +7,9 @@ import { EnumOptionsType, RJSFSchema, StrictRJSFSchema } from "./types"; * @param selected - The current selected value or list of values * @returns - true if the `value` is one of the `selected` ones, false otherwise */ -export default function enumOptionsIsSelected< - S extends StrictRJSFSchema = RJSFSchema, ->( - value: EnumOptionsType["value"], - selected: EnumOptionsType["value"] | EnumOptionsType["value"][], +export default function enumOptionsIsSelected( + value: EnumOptionsType['value'], + selected: EnumOptionsType['value'] | EnumOptionsType['value'][] ) { if (Array.isArray(selected)) { return selected.some((sel) => deepEquals(sel, value)); diff --git a/packages/utils/src/parser/ParserValidator.ts b/packages/utils/src/parser/ParserValidator.ts index 5e14b0a0b8..d6411a85f7 100644 --- a/packages/utils/src/parser/ParserValidator.ts +++ b/packages/utils/src/parser/ParserValidator.ts @@ -1,7 +1,7 @@ -import get from "lodash/get"; +import get from 'lodash/get'; -import { ID_KEY } from "../constants"; -import hashForSchema from "../hashForSchema"; +import { ID_KEY } from '../constants'; +import hashForSchema from '../hashForSchema'; import { CustomValidator, ErrorSchema, @@ -13,8 +13,8 @@ import { UiSchema, ValidationData, ValidatorType, -} from "../types"; -import deepEquals from "../deepEquals"; +} from '../types'; +import deepEquals from '../deepEquals'; /** The type of the map of schema hash to schema */ @@ -29,11 +29,9 @@ export type SchemaMap = { * the hashed value of the schema. NOTE: After hashing the schema, an $id with the hash value is added to the * schema IF that schema doesn't already have an $id, prior to putting the schema into the map. */ -export default class ParserValidator< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, -> implements ValidatorType { +export default class ParserValidator + implements ValidatorType +{ /** The rootSchema provided during construction of the class */ readonly rootSchema: S; @@ -70,10 +68,10 @@ export default class ParserValidator< if (!existing) { this.schemaMap[key] = identifiedSchema; } else if (!deepEquals(existing, identifiedSchema)) { - console.error("existing schema:", JSON.stringify(existing, null, 2)); - console.error("new schema:", JSON.stringify(identifiedSchema, null, 2)); + console.error('existing schema:', JSON.stringify(existing, null, 2)); + console.error('new schema:', JSON.stringify(identifiedSchema, null, 2)); throw new Error( - `Two different schemas exist with the same key ${key}! What a bad coincidence. If possible, try adding an $id to one of the schemas`, + `Two different schemas exist with the same key ${key}! What a bad coincidence. If possible, try adding an $id to one of the schemas` ); } } @@ -94,9 +92,7 @@ export default class ParserValidator< */ isValid(schema: S, _formData: T, rootSchema: S): boolean { if (!deepEquals(rootSchema, this.rootSchema)) { - throw new Error( - "Unexpectedly calling isValid() with a rootSchema that differs from the construction rootSchema", - ); + throw new Error('Unexpectedly calling isValid() with a rootSchema that differs from the construction rootSchema'); } this.addSchema(schema, hashForSchema(schema)); @@ -108,13 +104,8 @@ export default class ParserValidator< * @param _schema - The schema parameter that is ignored * @param _formData - The formData parameter that is ignored */ - rawValidation( - _schema: S, - _formData?: T, - ): { errors?: Result[]; validationError?: Error } { - throw new Error( - "Unexpectedly calling the `rawValidation()` method during schema parsing", - ); + rawValidation(_schema: S, _formData?: T): { errors?: Result[]; validationError?: Error } { + throw new Error('Unexpectedly calling the `rawValidation()` method during schema parsing'); } /** Implements the `ValidatorType` `toErrorList()` method to throw an error since it is never supposed to be called @@ -122,13 +113,8 @@ export default class ParserValidator< * @param _errorSchema - The error schema parameter that is ignored * @param _fieldPath - The field path parameter that is ignored */ - toErrorList( - _errorSchema?: ErrorSchema, - _fieldPath?: string[], - ): RJSFValidationError[] { - throw new Error( - "Unexpectedly calling the `toErrorList()` method during schema parsing", - ); + toErrorList(_errorSchema?: ErrorSchema, _fieldPath?: string[]): RJSFValidationError[] { + throw new Error('Unexpectedly calling the `toErrorList()` method during schema parsing'); } /** Implements the `ValidatorType` `validateFormData()` method to throw an error since it is never supposed to be @@ -145,10 +131,8 @@ export default class ParserValidator< _schema: S, _customValidate?: CustomValidator, _transformErrors?: ErrorTransformer, - _uiSchema?: UiSchema, + _uiSchema?: UiSchema ): ValidationData { - throw new Error( - "Unexpectedly calling the `validateFormData()` method during schema parsing", - ); + throw new Error('Unexpectedly calling the `validateFormData()` method during schema parsing'); } } diff --git a/packages/utils/src/parser/schemaParser.ts b/packages/utils/src/parser/schemaParser.ts index 5ec57b029a..f7e8ffa538 100644 --- a/packages/utils/src/parser/schemaParser.ts +++ b/packages/utils/src/parser/schemaParser.ts @@ -1,13 +1,10 @@ -import forEach from "lodash/forEach"; +import forEach from 'lodash/forEach'; -import { FormContextType, RJSFSchema, StrictRJSFSchema } from "../types"; -import { ITEMS_KEY, PROPERTIES_KEY } from "../constants"; -import ParserValidator, { SchemaMap } from "./ParserValidator"; -import { - resolveAnyOrOneOfSchemas, - retrieveSchemaInternal, -} from "../schema/retrieveSchema"; -import deepEquals from "../deepEquals"; +import { FormContextType, RJSFSchema, StrictRJSFSchema } from '../types'; +import { ITEMS_KEY, PROPERTIES_KEY } from '../constants'; +import ParserValidator, { SchemaMap } from './ParserValidator'; +import { resolveAnyOrOneOfSchemas, retrieveSchemaInternal } from '../schema/retrieveSchema'; +import deepEquals from '../deepEquals'; /** Recursive function used to parse the given `schema` belonging to the `rootSchema`. The `validator` is used to * capture the sub-schemas that the `isValid()` function is called with. For each schema returned by the @@ -19,57 +16,27 @@ import deepEquals from "../deepEquals"; * @param rootSchema - The root schema from which the schema parsing began * @param schema - The current schema element being parsed */ -function parseSchema< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( +function parseSchema( validator: ParserValidator, recurseList: S[], rootSchema: S, - schema: S, + schema: S ) { - const schemas = retrieveSchemaInternal( - validator, - schema, - rootSchema, - undefined, - true, - ); + const schemas = retrieveSchemaInternal(validator, schema, rootSchema, undefined, true); schemas.forEach((schema) => { - const sameSchemaIndex = recurseList.findIndex((item) => - deepEquals(item, schema) - ); + const sameSchemaIndex = recurseList.findIndex((item) => deepEquals(item, schema)); if (sameSchemaIndex === -1) { recurseList.push(schema); - const allOptions = resolveAnyOrOneOfSchemas( - validator, - schema, - rootSchema, - true, - ); + const allOptions = resolveAnyOrOneOfSchemas(validator, schema, rootSchema, true); allOptions.forEach((s) => { if (PROPERTIES_KEY in s && s[PROPERTIES_KEY]) { forEach(schema[PROPERTIES_KEY], (value) => { - parseSchema( - validator, - recurseList, - rootSchema, - value as S, - ); + parseSchema(validator, recurseList, rootSchema, value as S); }); } }); - if ( - ITEMS_KEY in schema && !Array.isArray(schema.items) && - typeof schema.items !== "boolean" - ) { - parseSchema( - validator, - recurseList, - rootSchema, - schema.items as S, - ); + if (ITEMS_KEY in schema && !Array.isArray(schema.items) && typeof schema.items !== 'boolean') { + parseSchema(validator, recurseList, rootSchema, schema.items as S); } } }); @@ -81,12 +48,8 @@ function parseSchema< * @param rootSchema - The root schema to parse for sub-schemas used by `isValid()` calls * @returns - The `SchemaMap` of all schemas that were parsed */ -export default function schemaParser< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( - rootSchema: S, +export default function schemaParser( + rootSchema: S ): SchemaMap { const validator = new ParserValidator(rootSchema); const recurseList: S[] = []; diff --git a/packages/utils/src/schema/retrieveSchema.ts b/packages/utils/src/schema/retrieveSchema.ts index 4ecabc468e..7a66f47f56 100644 --- a/packages/utils/src/schema/retrieveSchema.ts +++ b/packages/utils/src/schema/retrieveSchema.ts @@ -1,11 +1,11 @@ -import get from "lodash/get"; -import set from "lodash/set"; -import times from "lodash/times"; -import transform from "lodash/transform"; -import merge from "lodash/merge"; -import flattenDeep from "lodash/flattenDeep"; -import uniq from "lodash/uniq"; -import mergeAllOf, { Options } from "json-schema-merge-allof"; +import get from 'lodash/get'; +import set from 'lodash/set'; +import times from 'lodash/times'; +import transform from 'lodash/transform'; +import merge from 'lodash/merge'; +import flattenDeep from 'lodash/flattenDeep'; +import uniq from 'lodash/uniq'; +import mergeAllOf, { Options } from 'json-schema-merge-allof'; import { ADDITIONAL_PROPERTIES_KEY, @@ -18,23 +18,15 @@ import { ONE_OF_KEY, PROPERTIES_KEY, REF_KEY, -} from "../constants"; -import findSchemaDefinition, { - splitKeyElementFromObject, -} from "../findSchemaDefinition"; -import getDiscriminatorFieldFromSchema from "../getDiscriminatorFieldFromSchema"; -import guessType from "../guessType"; -import isObject from "../isObject"; -import mergeSchemas from "../mergeSchemas"; -import { - FormContextType, - GenericObjectType, - RJSFSchema, - StrictRJSFSchema, - ValidatorType, -} from "../types"; -import getFirstMatchingOption from "./getFirstMatchingOption"; -import deepEquals from "../deepEquals"; +} from '../constants'; +import findSchemaDefinition, { splitKeyElementFromObject } from '../findSchemaDefinition'; +import getDiscriminatorFieldFromSchema from '../getDiscriminatorFieldFromSchema'; +import guessType from '../guessType'; +import isObject from '../isObject'; +import mergeSchemas from '../mergeSchemas'; +import { FormContextType, GenericObjectType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types'; +import getFirstMatchingOption from './getFirstMatchingOption'; +import deepEquals from '../deepEquals'; /** Retrieves an expanded schema that has had all of its conditions, additional properties, references and dependencies * resolved and merged into the `schema` given a `validator`, `rootSchema` and `rawFormData` that is used to do the @@ -49,19 +41,9 @@ import deepEquals from "../deepEquals"; export default function retrieveSchema< T = any, S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( - validator: ValidatorType, - schema: S, - rootSchema: S = {} as S, - rawFormData?: T, -): S { - return retrieveSchemaInternal( - validator, - schema, - rootSchema, - rawFormData, - )[0]; + F extends FormContextType = any +>(validator: ValidatorType, schema: S, rootSchema: S = {} as S, rawFormData?: T): S { + return retrieveSchemaInternal(validator, schema, rootSchema, rawFormData)[0]; } /** Resolves a conditional block (if/else/then) by removing the condition and merging the appropriate conditional branch @@ -77,60 +59,33 @@ export default function retrieveSchema< * @param [formData] - The current formData to assist retrieving a schema * @returns - A list of schemas with the appropriate conditions resolved, possibly with all branches expanded */ -export function resolveCondition< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( +export function resolveCondition( validator: ValidatorType, schema: S, rootSchema: S, expandAllBranches: boolean, recurseList: string[], - formData?: T, + formData?: T ): S[] { - const { - if: expression, - then, - else: otherwise, - ...resolvedSchemaLessConditional - } = schema; + const { if: expression, then, else: otherwise, ...resolvedSchemaLessConditional } = schema; - const conditionValue = validator.isValid( - expression as S, - formData || ({} as T), - rootSchema, - ); + const conditionValue = validator.isValid(expression as S, formData || ({} as T), rootSchema); let resolvedSchemas = [resolvedSchemaLessConditional as S]; let schemas: S[] = []; if (expandAllBranches) { - if (then && typeof then !== "boolean") { + if (then && typeof then !== 'boolean') { schemas = schemas.concat( - retrieveSchemaInternal( - validator, - then as S, - rootSchema, - formData, - expandAllBranches, - recurseList, - ), + retrieveSchemaInternal(validator, then as S, rootSchema, formData, expandAllBranches, recurseList) ); } - if (otherwise && typeof otherwise !== "boolean") { + if (otherwise && typeof otherwise !== 'boolean') { schemas = schemas.concat( - retrieveSchemaInternal( - validator, - otherwise as S, - rootSchema, - formData, - expandAllBranches, - recurseList, - ), + retrieveSchemaInternal(validator, otherwise as S, rootSchema, formData, expandAllBranches, recurseList) ); } } else { const conditionalSchema = conditionValue ? then : otherwise; - if (conditionalSchema && typeof conditionalSchema !== "boolean") { + if (conditionalSchema && typeof conditionalSchema !== 'boolean') { schemas = schemas.concat( retrieveSchemaInternal( validator, @@ -138,25 +93,16 @@ export function resolveCondition< rootSchema, formData, expandAllBranches, - recurseList, - ), + recurseList + ) ); } } if (schemas.length) { - resolvedSchemas = schemas.map((s) => - mergeSchemas(resolvedSchemaLessConditional, s) as S - ); + resolvedSchemas = schemas.map((s) => mergeSchemas(resolvedSchemaLessConditional, s) as S); } return resolvedSchemas.flatMap((s) => - retrieveSchemaInternal( - validator, - s, - rootSchema, - formData, - expandAllBranches, - recurseList, - ) + retrieveSchemaInternal(validator, s, rootSchema, formData, expandAllBranches, recurseList) ); } @@ -174,25 +120,18 @@ export function resolveCondition< * @param listOfLists - The list of lists of elements that represent the allOf, anyOf or oneOf resolved values in order * @returns - The list of all permutations of schemas for a set of `xxxOf`s */ -export function getAllPermutationsOfXxxOf< - S extends StrictRJSFSchema = RJSFSchema, ->(listOfLists: S[][]) { +export function getAllPermutationsOfXxxOf(listOfLists: S[][]) { const allPermutations: S[][] = listOfLists.reduce( (permutations, list) => { // When there are more than one set of schemas for a row, duplicate the set of permutations and add in the values if (list.length > 1) { - return list.flatMap((element) => - times( - permutations.length, - (i) => [...permutations[i]].concat(element), - ) - ); + return list.flatMap((element) => times(permutations.length, (i) => [...permutations[i]].concat(element))); } // Otherwise just push in the single value into the current set of permutations permutations.forEach((permutation) => permutation.push(list[0])); return permutations; }, - [[]] as S[][], // Start with an empty list + [[]] as S[][] // Start with an empty list ); return allPermutations; @@ -211,17 +150,13 @@ export function getAllPermutationsOfXxxOf< * @param [formData] - The current formData, if any, to assist retrieving a schema * @returns - The list of schemas having its references, dependencies and allOf schemas resolved */ -export function resolveSchema< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( +export function resolveSchema( validator: ValidatorType, schema: S, rootSchema: S, expandAllBranches: boolean, recurseList: string[], - formData?: T, + formData?: T ): S[] { const updatedSchemas = resolveReference( validator, @@ -229,7 +164,7 @@ export function resolveSchema< rootSchema, expandAllBranches, recurseList, - formData, + formData ); if (updatedSchemas.length > 1 || updatedSchemas[0] !== schema) { // return the updatedSchemas array if it has either multiple schemas within it @@ -243,17 +178,10 @@ export function resolveSchema< rootSchema, expandAllBranches, recurseList, - formData, + formData ); return resolvedSchemas.flatMap((s) => { - return retrieveSchemaInternal( - validator, - s, - rootSchema, - formData, - expandAllBranches, - recurseList, - ); + return retrieveSchemaInternal(validator, s, rootSchema, formData, expandAllBranches, recurseList); }); } if (ALL_OF_KEY in schema && Array.isArray(schema.allOf)) { @@ -264,7 +192,7 @@ export function resolveSchema< rootSchema, formData, expandAllBranches, - recurseList, + recurseList ) ); const allPermutations = getAllPermutationsOfXxxOf(allOfSchemaElements); @@ -290,23 +218,15 @@ export function resolveSchema< * @param [formData] - The current formData, if any, to assist retrieving a schema * @returns - The list schemas retrieved after having all references resolved */ -export function resolveReference< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( +export function resolveReference( validator: ValidatorType, schema: S, rootSchema: S, expandAllBranches: boolean, recurseList: string[], - formData?: T, + formData?: T ): S[] { - const updatedSchema = resolveAllReferences( - schema, - rootSchema, - recurseList, - ); + const updatedSchema = resolveAllReferences(schema, rootSchema, recurseList); if (updatedSchema !== schema) { // Only call this if the schema was actually changed by the `resolveAllReferences()` function return retrieveSchemaInternal( @@ -315,7 +235,7 @@ export function resolveReference< rootSchema, formData, expandAllBranches, - recurseList, + recurseList ); } return [schema]; @@ -331,7 +251,7 @@ export function resolveReference< export function resolveAllReferences( schema: S, rootSchema: S, - recurseList: string[], + recurseList: string[] ): S { if (!isObject(schema)) { return schema; @@ -359,7 +279,7 @@ export function resolveAllReferences( result[key] = resolveAllReferences(value as S, rootSchema, childList); childrenLists.push(childList); }, - {} as RJSFSchema, + {} as RJSFSchema ); merge(recurseList, uniq(flattenDeep(childrenLists))); resolvedSchema = { ...resolvedSchema, [PROPERTIES_KEY]: updatedProps }; @@ -368,15 +288,11 @@ export function resolveAllReferences( if ( ITEMS_KEY in resolvedSchema && !Array.isArray(resolvedSchema.items) && - typeof resolvedSchema.items !== "boolean" + typeof resolvedSchema.items !== 'boolean' ) { resolvedSchema = { ...resolvedSchema, - items: resolveAllReferences( - resolvedSchema.items as S, - rootSchema, - recurseList, - ), + items: resolveAllReferences(resolvedSchema.items as S, rootSchema, recurseList), }; } @@ -394,13 +310,8 @@ export function resolveAllReferences( export function stubExistingAdditionalProperties< T = any, S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( - validator: ValidatorType, - theSchema: S, - rootSchema?: S, - aFormData?: T, -): S { + F extends FormContextType = any +>(validator: ValidatorType, theSchema: S, rootSchema?: S, aFormData?: T): S { // Clone the schema so that we don't ruin the consumer's original const schema = { ...theSchema, @@ -408,32 +319,27 @@ export function stubExistingAdditionalProperties< }; // make sure formData is an object - const formData: GenericObjectType = aFormData && isObject(aFormData) - ? aFormData - : {}; + const formData: GenericObjectType = aFormData && isObject(aFormData) ? aFormData : {}; Object.keys(formData).forEach((key) => { if (key in schema.properties) { // No need to stub, our schema already has the property return; } - let additionalProperties: S["additionalProperties"] = {}; - if (typeof schema.additionalProperties !== "boolean") { + let additionalProperties: S['additionalProperties'] = {}; + if (typeof schema.additionalProperties !== 'boolean') { if (REF_KEY in schema.additionalProperties!) { additionalProperties = retrieveSchema( validator, { $ref: get(schema.additionalProperties, [REF_KEY]) } as S, rootSchema, - formData as T, + formData as T ); - } else if ("type" in schema.additionalProperties!) { + } else if ('type' in schema.additionalProperties!) { additionalProperties = { ...schema.additionalProperties }; - } else if ( - ANY_OF_KEY in schema.additionalProperties! || - ONE_OF_KEY in schema.additionalProperties! - ) { + } else if (ANY_OF_KEY in schema.additionalProperties! || ONE_OF_KEY in schema.additionalProperties!) { additionalProperties = { - type: "object", + type: 'object', ...schema.additionalProperties, }; } else { @@ -470,14 +376,14 @@ export function stubExistingAdditionalProperties< export function retrieveSchemaInternal< T = any, S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, + F extends FormContextType = any >( validator: ValidatorType, schema: S, rootSchema: S, rawFormData?: T, expandAllBranches = false, - recurseList: string[] = [], + recurseList: string[] = [] ): S[] { if (!isObject(schema)) { return [{} as S]; @@ -488,7 +394,7 @@ export function retrieveSchemaInternal< rootSchema, expandAllBranches, recurseList, - rawFormData, + rawFormData ); return resolvedSchemas.flatMap((s: S) => { let resolvedSchema = s; @@ -499,7 +405,7 @@ export function retrieveSchemaInternal< rootSchema, expandAllBranches, recurseList, - rawFormData as T, + rawFormData as T ); } if (ALL_OF_KEY in resolvedSchema) { @@ -513,21 +419,15 @@ export function retrieveSchemaInternal< deep: false, } as Options) as S; } catch (e) { - console.warn("could not merge subschemas in allOf:\n", e); + console.warn('could not merge subschemas in allOf:\n', e); const { allOf, ...resolvedSchemaWithoutAllOf } = resolvedSchema; return resolvedSchemaWithoutAllOf as S; } } const hasAdditionalProperties = - ADDITIONAL_PROPERTIES_KEY in resolvedSchema && - resolvedSchema.additionalProperties !== false; + ADDITIONAL_PROPERTIES_KEY in resolvedSchema && resolvedSchema.additionalProperties !== false; if (hasAdditionalProperties) { - return stubExistingAdditionalProperties( - validator, - resolvedSchema, - rootSchema, - rawFormData as T, - ); + return stubExistingAdditionalProperties(validator, resolvedSchema, rootSchema, rawFormData as T); } return resolvedSchema; @@ -549,14 +449,8 @@ export function retrieveSchemaInternal< export function resolveAnyOrOneOfSchemas< T = any, S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( - validator: ValidatorType, - schema: S, - rootSchema: S, - expandAllBranches: boolean, - rawFormData?: T, -) { + F extends FormContextType = any +>(validator: ValidatorType, schema: S, rootSchema: S, expandAllBranches: boolean, rawFormData?: T) { let anyOrOneOf: S[] | undefined; const { oneOf, anyOf, ...remaining } = schema; if (Array.isArray(oneOf)) { @@ -566,9 +460,7 @@ export function resolveAnyOrOneOfSchemas< } if (anyOrOneOf) { // Ensure that during expand all branches we pass an object rather than undefined so that all options are interrogated - const formData = rawFormData === undefined && expandAllBranches - ? ({} as T) - : rawFormData; + const formData = rawFormData === undefined && expandAllBranches ? ({} as T) : rawFormData; const discriminator = getDiscriminatorFieldFromSchema(schema); anyOrOneOf = anyOrOneOf.map((s) => { // Due to anyOf/oneOf possibly using the same $ref we always pass a fresh recurse list array so that each option @@ -576,13 +468,7 @@ export function resolveAnyOrOneOfSchemas< return resolveAllReferences(s, rootSchema, []); }); // Call this to trigger the set of isValid() calls that the schema parser will need - const option = getFirstMatchingOption( - validator, - formData, - anyOrOneOf, - rootSchema, - discriminator, - ); + const option = getFirstMatchingOption(validator, formData, anyOrOneOf, rootSchema, discriminator); if (expandAllBranches) { return anyOrOneOf.map((item) => mergeSchemas(remaining, item) as S); } @@ -603,17 +489,13 @@ export function resolveAnyOrOneOfSchemas< * @param [formData] - The current formData, if any, to assist retrieving a schema * @returns - The list of schemas with their dependencies resolved */ -export function resolveDependencies< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( +export function resolveDependencies( validator: ValidatorType, schema: S, rootSchema: S, expandAllBranches: boolean, recurseList: string[], - formData?: T, + formData?: T ): S[] { // Drop the dependencies from the source schema. const { dependencies, ...remainingSchema } = schema; @@ -622,7 +504,7 @@ export function resolveDependencies< remainingSchema as S, rootSchema, expandAllBranches, - formData, + formData ); return resolvedSchemas.flatMap((resolvedSchema) => processDependencies( @@ -632,7 +514,7 @@ export function resolveDependencies< rootSchema, expandAllBranches, recurseList, - formData, + formData ) ); } @@ -650,18 +532,14 @@ export function resolveDependencies< * @param [formData] - The current formData, if any, to assist retrieving a schema * @returns - The schema with the `dependencies` resolved into it */ -export function processDependencies< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( +export function processDependencies( validator: ValidatorType, - dependencies: S["dependencies"], + dependencies: S['dependencies'], resolvedSchema: S, rootSchema: S, expandAllBranches: boolean, recurseList: string[], - formData?: T, + formData?: T ): S[] { let schemas = [resolvedSchema]; // Process dependencies updating the local schema properties as appropriate. @@ -671,14 +549,12 @@ export function processDependencies< continue; } // Skip this dependency if it is not included in the schema (such as when dependencyKey is itself a hidden dependency.) - if ( - resolvedSchema.properties && !(dependencyKey in resolvedSchema.properties) - ) { + if (resolvedSchema.properties && !(dependencyKey in resolvedSchema.properties)) { continue; } const [remainingDependencies, dependencyValue] = splitKeyElementFromObject( dependencyKey, - dependencies as GenericObjectType, + dependencies as GenericObjectType ); if (Array.isArray(dependencyValue)) { schemas[0] = withDependentProperties(resolvedSchema, dependencyValue); @@ -691,7 +567,7 @@ export function processDependencies< dependencyValue as S, expandAllBranches, recurseList, - formData, + formData ); } return schemas.flatMap((schema) => @@ -702,7 +578,7 @@ export function processDependencies< rootSchema, expandAllBranches, recurseList, - formData, + formData ) ); } @@ -715,11 +591,9 @@ export function processDependencies< * @param [additionallyRequired] - An optional array of additionally required names * @returns - The schema with the additional required values merged in */ -export function withDependentProperties< - S extends StrictRJSFSchema = RJSFSchema, ->( +export function withDependentProperties( schema: S, - additionallyRequired?: string[], + additionallyRequired?: string[] ) { if (!additionallyRequired) { return schema; @@ -744,11 +618,7 @@ export function withDependentProperties< * @param [formData]- The current formData to assist retrieving a schema * @returns - The list of schemas with the dependent schema resolved into them */ -export function withDependentSchema< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( +export function withDependentSchema( validator: ValidatorType, schema: S, rootSchema: S, @@ -756,7 +626,7 @@ export function withDependentSchema< dependencyValue: S, expandAllBranches: boolean, recurseList: string[], - formData?: T, + formData?: T ): S[] { const dependentSchemas = retrieveSchemaInternal( validator, @@ -764,7 +634,7 @@ export function withDependentSchema< rootSchema, formData, expandAllBranches, - recurseList, + recurseList ); return dependentSchemas.flatMap((dependent) => { const { oneOf, ...dependentSchema } = dependent; @@ -775,17 +645,10 @@ export function withDependentSchema< } // Resolve $refs inside oneOf. const resolvedOneOfs = oneOf.map((subschema) => { - if (typeof subschema === "boolean" || !(REF_KEY in subschema)) { + if (typeof subschema === 'boolean' || !(REF_KEY in subschema)) { return [subschema as S]; } - return resolveReference( - validator, - subschema as S, - rootSchema, - expandAllBranches, - recurseList, - formData, - ); + return resolveReference(validator, subschema as S, rootSchema, expandAllBranches, recurseList, formData); }); const allPermutations = getAllPermutationsOfXxxOf(resolvedOneOfs); return allPermutations.flatMap((resolvedOneOf) => @@ -797,7 +660,7 @@ export function withDependentSchema< resolvedOneOf, expandAllBranches, recurseList, - formData, + formData ) ); }); @@ -821,47 +684,41 @@ export function withDependentSchema< export function withExactlyOneSubschema< T = any, S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, + F extends FormContextType = any >( validator: ValidatorType, schema: S, rootSchema: S, dependencyKey: string, - oneOf: S["oneOf"], + oneOf: S['oneOf'], expandAllBranches: boolean, recurseList: string[], - formData?: T, + formData?: T ): S[] { const validSubschemas = oneOf!.filter((subschema) => { - if (typeof subschema === "boolean" || !subschema || !subschema.properties) { + if (typeof subschema === 'boolean' || !subschema || !subschema.properties) { return false; } const { [dependencyKey]: conditionPropertySchema } = subschema.properties; if (conditionPropertySchema) { const conditionSchema: S = { - type: "object", + type: 'object', properties: { [dependencyKey]: conditionPropertySchema, }, } as S; - return validator.isValid(conditionSchema, formData, rootSchema) || - expandAllBranches; + return validator.isValid(conditionSchema, formData, rootSchema) || expandAllBranches; } return false; }); if (!expandAllBranches && validSubschemas!.length !== 1) { - console.warn( - "ignoring oneOf in dependencies because there isn't exactly one subschema that is valid", - ); + console.warn("ignoring oneOf in dependencies because there isn't exactly one subschema that is valid"); return [schema]; } return validSubschemas.flatMap((s) => { const subschema: S = s as S; - const [dependentSubschema] = splitKeyElementFromObject( - dependencyKey, - subschema.properties as GenericObjectType, - ); + const [dependentSubschema] = splitKeyElementFromObject(dependencyKey, subschema.properties as GenericObjectType); const dependentSchema = { ...subschema, properties: dependentSubschema }; const schemas = retrieveSchemaInternal( validator, @@ -869,7 +726,7 @@ export function withExactlyOneSubschema< rootSchema, formData, expandAllBranches, - recurseList, + recurseList ); return schemas.map((s) => mergeSchemas(schema, s) as S); }); diff --git a/packages/utils/src/schema/toIdSchema.ts b/packages/utils/src/schema/toIdSchema.ts index c8821ceda8..eaeb8dd5f7 100644 --- a/packages/utils/src/schema/toIdSchema.ts +++ b/packages/utils/src/schema/toIdSchema.ts @@ -1,25 +1,11 @@ -import get from "lodash/get"; +import get from 'lodash/get'; -import { - ALL_OF_KEY, - DEPENDENCIES_KEY, - ID_KEY, - ITEMS_KEY, - PROPERTIES_KEY, - REF_KEY, -} from "../constants"; -import isObject from "../isObject"; -import { - FormContextType, - GenericObjectType, - IdSchema, - RJSFSchema, - StrictRJSFSchema, - ValidatorType, -} from "../types"; -import retrieveSchema from "./retrieveSchema"; -import getSchemaType from "../getSchemaType"; -import deepEquals from "../deepEquals"; +import { ALL_OF_KEY, DEPENDENCIES_KEY, ID_KEY, ITEMS_KEY, PROPERTIES_KEY, REF_KEY } from '../constants'; +import isObject from '../isObject'; +import { FormContextType, GenericObjectType, IdSchema, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types'; +import retrieveSchema from './retrieveSchema'; +import getSchemaType from '../getSchemaType'; +import deepEquals from '../deepEquals'; /** An internal helper that generates an `IdSchema` object for the `schema`, recursively with protection against * infinite recursion @@ -34,11 +20,7 @@ import deepEquals from "../deepEquals"; * @param [_recurseList=[]] - The list of retrieved schemas currently being recursed, used to prevent infinite recursion * @returns - The `IdSchema` object for the `schema` */ -function toIdSchemaInternal< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( +function toIdSchemaInternal( validator: ValidatorType, schema: S, idPrefix: string, @@ -46,18 +28,11 @@ function toIdSchemaInternal< id?: string | null, rootSchema?: S, formData?: T, - _recurseList: S[] = [], + _recurseList: S[] = [] ): IdSchema { if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) { - const _schema = retrieveSchema( - validator, - schema, - rootSchema, - formData, - ); - const sameSchemaIndex = _recurseList.findIndex((item) => - deepEquals(item, _schema) - ); + const _schema = retrieveSchema(validator, schema, rootSchema, formData); + const sameSchemaIndex = _recurseList.findIndex((item) => deepEquals(item, _schema)); if (sameSchemaIndex === -1) { return toIdSchemaInternal( validator, @@ -67,7 +42,7 @@ function toIdSchemaInternal< id, rootSchema, formData, - _recurseList.concat(_schema), + _recurseList.concat(_schema) ); } } @@ -80,20 +55,16 @@ function toIdSchemaInternal< id, rootSchema, formData, - _recurseList, + _recurseList ); } const $id = id || idPrefix; const idSchema: IdSchema = { $id } as IdSchema; - if (getSchemaType(schema) === "object" && PROPERTIES_KEY in schema) { + if (getSchemaType(schema) === 'object' && PROPERTIES_KEY in schema) { for (const name in schema.properties) { const field = get(schema, [PROPERTIES_KEY, name]); const fieldId = idSchema[ID_KEY] + idSeparator + name; - (idSchema as IdSchema)[name] = toIdSchemaInternal< - T, - S, - F - >( + (idSchema as IdSchema)[name] = toIdSchemaInternal( validator, isObject(field) ? field : {}, idPrefix, @@ -103,7 +74,7 @@ function toIdSchemaInternal< // 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, [name]), - _recurseList, + _recurseList ); } } @@ -121,26 +92,14 @@ function toIdSchemaInternal< * @param [idSeparator='_'] - The separator to use for the path segments in the id * @returns - The `IdSchema` object for the `schema` */ -export default function toIdSchema< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( +export default function toIdSchema( validator: ValidatorType, schema: S, id?: string | null, rootSchema?: S, formData?: T, - idPrefix = "root", - idSeparator = "_", + idPrefix = 'root', + idSeparator = '_' ): IdSchema { - return toIdSchemaInternal( - validator, - schema, - idPrefix, - idSeparator, - id, - rootSchema, - formData, - ); + return toIdSchemaInternal(validator, schema, idPrefix, idSeparator, id, rootSchema, formData); } diff --git a/packages/utils/src/schema/toPathSchema.ts b/packages/utils/src/schema/toPathSchema.ts index 49cb6663dc..a33ee03c7a 100644 --- a/packages/utils/src/schema/toPathSchema.ts +++ b/packages/utils/src/schema/toPathSchema.ts @@ -1,5 +1,5 @@ -import get from "lodash/get"; -import set from "lodash/set"; +import get from 'lodash/get'; +import set from 'lodash/set'; import { ADDITIONAL_PROPERTIES_KEY, @@ -12,19 +12,12 @@ import { PROPERTIES_KEY, REF_KEY, RJSF_ADDITIONAL_PROPERTIES_FLAG, -} from "../constants"; -import getDiscriminatorFieldFromSchema from "../getDiscriminatorFieldFromSchema"; -import { - FormContextType, - GenericObjectType, - PathSchema, - RJSFSchema, - StrictRJSFSchema, - ValidatorType, -} from "../types"; -import getClosestMatchingOption from "./getClosestMatchingOption"; -import retrieveSchema from "./retrieveSchema"; -import deepEquals from "../deepEquals"; +} from '../constants'; +import getDiscriminatorFieldFromSchema from '../getDiscriminatorFieldFromSchema'; +import { FormContextType, GenericObjectType, PathSchema, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types'; +import getClosestMatchingOption from './getClosestMatchingOption'; +import retrieveSchema from './retrieveSchema'; +import deepEquals from '../deepEquals'; /** An internal helper that generates an `PathSchema` object for the `schema`, recursively with protection against * infinite recursion @@ -37,28 +30,17 @@ import deepEquals from "../deepEquals"; * @param [_recurseList=[]] - The list of retrieved schemas currently being recursed, used to prevent infinite recursion * @returns - The `PathSchema` object for the `schema` */ -function toPathSchemaInternal< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( +function toPathSchemaInternal( validator: ValidatorType, schema: S, name: string, rootSchema?: S, formData?: T, - _recurseList: S[] = [], + _recurseList: S[] = [] ): PathSchema { if (REF_KEY in schema || DEPENDENCIES_KEY in schema || ALL_OF_KEY in schema) { - const _schema = retrieveSchema( - validator, - schema, - rootSchema, - formData, - ); - const sameSchemaIndex = _recurseList.findIndex((item) => - deepEquals(item, _schema) - ); + const _schema = retrieveSchema(validator, schema, rootSchema, formData); + const sameSchemaIndex = _recurseList.findIndex((item) => deepEquals(item, _schema)); if (sameSchemaIndex === -1) { return toPathSchemaInternal( validator, @@ -66,52 +48,32 @@ function toPathSchemaInternal< name, rootSchema, formData, - _recurseList.concat(_schema), + _recurseList.concat(_schema) ); } } let pathSchema: PathSchema = { - [NAME_KEY]: name.replace(/^\./, ""), + [NAME_KEY]: name.replace(/^\./, ''), } as PathSchema; if (ONE_OF_KEY in schema || ANY_OF_KEY in schema) { - const xxxOf: S[] = ONE_OF_KEY in schema - ? (schema.oneOf as S[]) - : (schema.anyOf as S[]); + const xxxOf: S[] = ONE_OF_KEY in schema ? (schema.oneOf as S[]) : (schema.anyOf as S[]); const discriminator = getDiscriminatorFieldFromSchema(schema); - const index = getClosestMatchingOption( - validator, - rootSchema!, - formData, - xxxOf, - 0, - discriminator, - ); + const index = getClosestMatchingOption(validator, rootSchema!, formData, xxxOf, 0, discriminator); const _schema: S = xxxOf![index] as S; pathSchema = { ...pathSchema, - ...toPathSchemaInternal( - validator, - _schema, - name, - rootSchema, - formData, - _recurseList, - ), + ...toPathSchemaInternal(validator, _schema, name, rootSchema, formData, _recurseList), }; } - if ( - ADDITIONAL_PROPERTIES_KEY in schema && - schema[ADDITIONAL_PROPERTIES_KEY] !== false - ) { + 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; + const { items: schemaItems, additionalItems: schemaAdditionalItems } = schema; if (Array.isArray(schemaItems)) { formData.forEach((element, i: number) => { @@ -122,7 +84,7 @@ function toPathSchemaInternal< `${name}.${i}`, rootSchema, element, - _recurseList, + _recurseList ); } else if (schemaAdditionalItems) { (pathSchema as PathSchema)[i] = toPathSchemaInternal( @@ -131,12 +93,10 @@ function toPathSchemaInternal< `${name}.${i}`, rootSchema, element, - _recurseList, + _recurseList ); } else { - console.warn( - `Unable to generate path schema for "${name}.${i}". No schema defined for it`, - ); + console.warn(`Unable to generate path schema for "${name}.${i}". No schema defined for it`); } }); } else { @@ -147,24 +107,23 @@ function toPathSchemaInternal< `${name}.${i}`, rootSchema, element, - _recurseList, + _recurseList ); }); } } else if (PROPERTIES_KEY in schema) { for (const property in schema.properties) { const field = get(schema, [PROPERTIES_KEY, property]); - (pathSchema as 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, - ); + (pathSchema as 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 + ); } } return pathSchema; @@ -179,16 +138,12 @@ function toPathSchemaInternal< * @param [formData] - The current formData, if any, to assist retrieving a schema * @returns - The `PathSchema` object for the `schema` */ -export default function toPathSchema< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( +export default function toPathSchema( validator: ValidatorType, schema: S, - name = "", + name = '', rootSchema?: S, - formData?: T, + formData?: T ): PathSchema { return toPathSchemaInternal(validator, schema, name, rootSchema, formData); } diff --git a/packages/validator-ajv8/src/precompiledValidator.ts b/packages/validator-ajv8/src/precompiledValidator.ts index 4997ebeba7..648d52d274 100644 --- a/packages/validator-ajv8/src/precompiledValidator.ts +++ b/packages/validator-ajv8/src/precompiledValidator.ts @@ -1,5 +1,5 @@ -import { ErrorObject } from "ajv"; -import get from "lodash/get"; +import { ErrorObject } from 'ajv'; +import get from 'lodash/get'; import { CustomValidator, deepEquals, @@ -16,16 +16,10 @@ import { UiSchema, ValidationData, ValidatorType, -} from "@rjsf/utils"; +} from '@rjsf/utils'; -import { - CompiledValidateFunction, - Localizer, - ValidatorFunctions, -} from "./types"; -import processRawValidationErrors, { - RawValidationErrorsType, -} from "./processRawValidationErrors"; +import { CompiledValidateFunction, Localizer, ValidatorFunctions } from './types'; +import processRawValidationErrors, { RawValidationErrorsType } from './processRawValidationErrors'; /** `ValidatorType` implementation that uses an AJV 8 precompiled validator as created by the * `compileSchemaValidators()` function provided by the `@rjsf/validator-ajv8` library. @@ -33,8 +27,9 @@ import processRawValidationErrors, { export default class AJV8PrecompiledValidator< T = any, S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, -> implements ValidatorType { + F extends FormContextType = any +> implements ValidatorType +{ /** The root schema object used to construct this validator * * @private @@ -66,11 +61,7 @@ export default class AJV8PrecompiledValidator< * @param [localizer] - If provided, is used to localize a list of Ajv `ErrorObject`s * @throws - Error when the base schema of the precompiled validator does not have a matching validator function */ - constructor( - validateFns: ValidatorFunctions, - rootSchema: S, - localizer?: Localizer, - ) { + constructor(validateFns: ValidatorFunctions, rootSchema: S, localizer?: Localizer) { this.rootSchema = rootSchema; this.validateFns = validateFns; this.localizer = localizer; @@ -87,9 +78,7 @@ export default class AJV8PrecompiledValidator< const key = get(schema, ID_KEY) || hashForSchema(schema); const validator = this.validateFns[key]; if (!validator) { - throw new Error( - `No precompiled validator function was found for the given schema for "${key}"`, - ); + throw new Error(`No precompiled validator function was found for the given schema for "${key}"`); } return validator; } @@ -105,15 +94,10 @@ export default class AJV8PrecompiledValidator< ensureSameRootSchema(schema: S, formData?: T) { if (!deepEquals(schema, this.rootSchema)) { // Resolve the root schema with the passed in form data since that may affect the resolution - const resolvedRootSchema = retrieveSchema( - this, - this.rootSchema, - this.rootSchema, - formData, - ); + const resolvedRootSchema = retrieveSchema(this, this.rootSchema, this.rootSchema, formData); if (!deepEquals(schema, resolvedRootSchema)) { throw new Error( - "The schema associated with the precompiled validator differs from the rootSchema provided for validation", + 'The schema associated with the precompiled validator differs from the rootSchema provided for validation' ); } } @@ -138,14 +122,11 @@ export default class AJV8PrecompiledValidator< * @param [formData] - The form data to validate, if any * @throws - Error when the schema provided does not match the base schema of the precompiled validator */ - rawValidation( - schema: S, - formData?: T, - ): RawValidationErrorsType { + rawValidation(schema: S, formData?: T): RawValidationErrorsType { this.ensureSameRootSchema(schema, formData); this.mainValidator(formData); - if (typeof this.localizer === "function") { + if (typeof this.localizer === 'function') { this.localizer(this.mainValidator.errors); } const errors = this.mainValidator.errors || undefined; @@ -172,18 +153,10 @@ export default class AJV8PrecompiledValidator< schema: S, customValidate?: CustomValidator, transformErrors?: ErrorTransformer, - uiSchema?: UiSchema, + uiSchema?: UiSchema ): ValidationData { const rawErrors = this.rawValidation(schema, formData); - return processRawValidationErrors( - this, - rawErrors, - formData, - schema, - customValidate, - transformErrors, - uiSchema, - ); + return processRawValidationErrors(this, rawErrors, formData, schema, customValidate, transformErrors, uiSchema); } /** Validates data against a schema, returning true if the data is valid, or false otherwise. If the schema is