diff --git a/CHANGELOG_v6.md b/CHANGELOG_v6.md index 963be814fa..6ffec62927 100644 --- a/CHANGELOG_v6.md +++ b/CHANGELOG_v6.md @@ -40,6 +40,7 @@ should change the heading of the (upcoming) version to include a major version b - Updated the `ArrayFieldTemplate`, `ObjectFieldTemplate`, and `WrapIfAdditionalTemplate` to a unique id using the `buttonId()` function and adding consistent marker classes - Implemented the `GridTemplate` component, adding it to the `templates` for the theme - Implemented the new `LayoutGridField`, `LayoutMultiSchemaField` and `LayoutHeaderField` fields, adding them to the `fields` list +- BREAKING CHANGE: Removed support for the deprecated `schema.enumNames` and `uiSchema.classNames` as well as the deprecated `acceptcharset` prop on `Form` ## @rjsf/daisyui @@ -91,12 +92,19 @@ should change the heading of the (upcoming) version to include a major version b - `findFieldInSchema(validator: ValidatorType, rootSchema: S, path: string | string[], schema: S, formData?: T, experimental_customMergeAllOf?: Experimental_CustomMergeAllOf): FoundFieldType`: Finds the field specified by the `path` within the root or recursed `schema` - `findSelectedOptionInXxxOf(validator: ValidatorType, rootSchema: S, schema: S, fallbackField: string,xxx: 'anyOf' | 'oneOf', formData?: T, experimental_customMergeAllOf?: Experimental_CustomMergeAllOf): S | undefined`: Finds the option that matches the selector field in the `schema` or undefined if nothing is selected - `getFromSchema(validator: ValidatorType, rootSchema: S, schema: S, path: string | string[], defaultValue: T | S, experimental_customMergeAllOf?: Experimental_CustomMergeAllOf): T | S`: Helper that acts like lodash's `get` but additionally retrieves `$ref`s as needed to get the path for schemas -- Exported a `browser` version of the libraries with a browser-safe version of `getTestIds()` +- BREAKING CHANGE: Removed support for the deprecated `schema.enumNames` from `getOptionsList()` while switching the order of its generic types +- BREAKING CHANGE: Removed the deprecated `getMatchingOption()` and `mergeValidationData()` from the library export and the `SchemaUtilsType` interface +- BREAKING CHANGE: Removed the deprecated `toErrorList()` function from the `ValidatorType` interface +- BREAKING CHANGE: Removed the deprecated `RJSF_ADDITONAL_PROPERTIES_FLAG` constant ## @rjsf/validator-ajv6 - BREAKING CHANGE: This deprecated validator has been removed +## @rjsf/validator-ajv8 + +- BREAKING CHANGE: Removed the implementation of the deprecated `toErrorList()` function from the validator implementations + ## Dev / docs / playground - Updated the playground to remove `fluent-ui` theme @@ -105,6 +113,7 @@ should change the heading of the (upcoming) version to include a major version b - Added the `v6.x upgrade guide.md` documentation - Updated the `playground` to add a `Layout Grid` example and made the selected example now be part of the shared export - Replaced Lerna with Nx, updated all lerna commands to use the Nx CLI +- BREAKING CHANGE: Updated all `peerDependencies` to change minimal `React` support to `>=18` # 6.0.0-alpha.0 diff --git a/package-lock.json b/package-lock.json index b5e53005ec..9d400bc36d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27503,7 +27503,7 @@ "@rjsf/utils": "^6.x", "antd": "^5.8.5", "dayjs": "^1.8.0", - "react": "^16.14.0 || >=17" + "react": ">=18" } }, "packages/antd/node_modules/date-fns": { @@ -27642,7 +27642,7 @@ "@rjsf/utils": "^6.x", "chakra-react-select": ">=3.3.8 <6.0.0", "framer-motion": ">=5.6.0", - "react": "^16.14.0 || >=17" + "react": ">=18" } }, "packages/chakra-ui/node_modules/chakra-react-select": { @@ -27803,7 +27803,7 @@ }, "peerDependencies": { "@rjsf/utils": "^6.x", - "react": "^16.14.0 || >=17" + "react": ">=18" } }, "packages/core/node_modules/@testing-library/react": { @@ -27888,7 +27888,6 @@ "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/react-fontawesome": "^0.2.2", "daisyui": "^5.0.19", - "react": ">=17", "react-day-picker": "^9.5.1", "tailwindcss": "^4.1.3" }, @@ -27911,6 +27910,7 @@ "babel-jest": "^29.7.0", "jest": "^29.6.4", "jest-environment-jsdom": "^29.6.4", + "react": "^18.2.0", "react-test-renderer": "^18.2.0", "typescript": "^4.9.5" }, @@ -27921,7 +27921,7 @@ "@rjsf/core": "^6.x", "@rjsf/utils": "^6.x", "@rjsf/validator-ajv8": "^6.x", - "react": ">=17", + "react": ">=18", "react-i18next": "^14.x" } }, @@ -27990,7 +27990,7 @@ }, "peerDependencies": { "@rjsf/utils": "^6.x", - "react": "^16.14.0 || >=17" + "react": ">=18" } }, "packages/fluentui-rc/node_modules/glob": { @@ -28086,7 +28086,7 @@ "@mui/material": "^6.0.0", "@rjsf/core": "^6.x", "@rjsf/utils": "^6.x", - "react": ">=17" + "react": ">=18" } }, "packages/mui/node_modules/glob": { @@ -28391,7 +28391,7 @@ "peerDependencies": { "@rjsf/core": "^6.x", "@rjsf/utils": "^6.x", - "react": "^16.14.0 || >=17", + "react": ">=18", "react-bootstrap": "^2.0.0" } }, @@ -28539,7 +28539,7 @@ "peerDependencies": { "@rjsf/core": "^6.x", "@rjsf/utils": "^6.x", - "react": "^16.14.0 || >=17", + "react": ">=18", "semantic-ui-react": "^1.3.1 || ^2.1.3" } }, @@ -28651,7 +28651,7 @@ "peerDependencies": { "@rjsf/core": "^6.x", "@rjsf/utils": "^6.x", - "react": "^16.14.0 || >=17" + "react": ">=18" } }, "packages/shadcn/node_modules/glob": { @@ -28769,7 +28769,7 @@ "node": ">=20" }, "peerDependencies": { - "react": "^16.14.0 || >=17", + "react": ">=18", "react-test-renderer": "^17.0.2" } }, @@ -28814,7 +28814,7 @@ "node": ">=20" }, "peerDependencies": { - "react": "^16.14.0 || >=17" + "react": ">=18" } }, "packages/utils/node_modules/glob": { diff --git a/packages/antd/package.json b/packages/antd/package.json index 2cd404f4eb..399e09cc6b 100644 --- a/packages/antd/package.json +++ b/packages/antd/package.json @@ -67,7 +67,7 @@ "@rjsf/utils": "^6.x", "antd": "^5.8.5", "dayjs": "^1.8.0", - "react": "^16.14.0 || >=17" + "react": ">=18" }, "dependencies": { "classnames": "^2.5.1", diff --git a/packages/chakra-ui/package.json b/packages/chakra-ui/package.json index f587d1be09..6e1680c9b0 100644 --- a/packages/chakra-ui/package.json +++ b/packages/chakra-ui/package.json @@ -69,7 +69,7 @@ "@rjsf/utils": "^6.x", "chakra-react-select": ">=3.3.8 <6.0.0", "framer-motion": ">=5.6.0", - "react": "^16.14.0 || >=17" + "react": ">=18" }, "publishConfig": { "access": "public" diff --git a/packages/core/package.json b/packages/core/package.json index 5b0779ed44..80690959d5 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -67,7 +67,7 @@ }, "peerDependencies": { "@rjsf/utils": "^6.x", - "react": "^16.14.0 || >=17" + "react": ">=18" }, "dependencies": { "lodash": "^4.17.21", diff --git a/packages/core/src/components/Form.tsx b/packages/core/src/components/Form.tsx index a6da14306e..c4d66081c3 100644 --- a/packages/core/src/components/Form.tsx +++ b/packages/core/src/components/Form.tsx @@ -116,11 +116,6 @@ export interface FormProps void; - //
HTML attributes - /** The value of this prop will be passed to the `accept-charset` HTML attribute on the form - * @deprecated replaced with `acceptCharset` which will supercede this value if both are specified - */ - acceptcharset?: string; /** The value of this prop will be passed to the `accept-charset` HTML attribute on the form */ acceptCharset?: string; /** The value of this prop will be passed to the `action` HTML attribute on the form @@ -349,9 +344,6 @@ export default class Form< * If an update is required, it applies the next state and, if needed, triggers the `onChange` handler to inform about * changes. * - * This method effectively replaces the deprecated `UNSAFE_componentWillReceiveProps`, providing a safer alternative - * to handle prop changes and state updates. - * * @param _ - The previous set of props. * @param prevState - The previous state of the component before the update. * @param snapshot - The value returned from `getSnapshotBeforeUpdate`. @@ -1029,7 +1021,6 @@ export default class Form< action, autoComplete, enctype, - acceptcharset, acceptCharset, noHtml5Validate = false, disabled, @@ -1065,7 +1056,7 @@ export default class Form< action={action} autoComplete={autoComplete} encType={enctype} - acceptCharset={acceptCharset || acceptcharset} + acceptCharset={acceptCharset} noValidate={noHtml5Validate} onSubmit={this.onSubmit} as={as} diff --git a/packages/core/src/components/fields/BooleanField.tsx b/packages/core/src/components/fields/BooleanField.tsx index 6e0dce3e3c..4ff48ce058 100644 --- a/packages/core/src/components/fields/BooleanField.tsx +++ b/packages/core/src/components/fields/BooleanField.tsx @@ -44,6 +44,7 @@ function BooleanField(uiSchema, globalUiOptions); const Widget = getWidget(schema, widget, widgets); @@ -69,10 +70,8 @@ function BooleanField typeof v === 'boolean')) { + if (!enumNames && enums.length === 2 && enums.every((v: any) => typeof v === 'boolean')) { enumOptions = [ { value: enums[0], @@ -84,14 +83,7 @@ function BooleanField( - { - enum: enums, - // NOTE: enumNames is deprecated, but still supported for now. - enumNames: schemaWithEnumNames.enumNames, - } as unknown as S, - uiSchema, - ); + enumOptions = optionsList({ enum: enums } as S, uiSchema); } } diff --git a/packages/core/src/components/fields/SchemaField.tsx b/packages/core/src/components/fields/SchemaField.tsx index 8a78f38998..5f27dc3fe0 100644 --- a/packages/core/src/components/fields/SchemaField.tsx +++ b/packages/core/src/components/fields/SchemaField.tsx @@ -213,14 +213,6 @@ function SchemaFieldRender 0) { classNames.push('field-error has-error has-danger'); } - if (uiSchema?.classNames) { - if (process.env.NODE_ENV !== 'production') { - console.warn( - "'uiSchema.classNames' is deprecated and may be removed in a major release; Use 'ui:classNames' instead.", - ); - } - classNames.push(uiSchema.classNames); - } if (uiOptions.classNames) { classNames.push(uiOptions.classNames); } diff --git a/packages/core/test/.eslintrc b/packages/core/test/.eslintrc index 84074d7ac2..a114c20962 100644 --- a/packages/core/test/.eslintrc +++ b/packages/core/test/.eslintrc @@ -11,6 +11,7 @@ { "varsIgnorePattern": "^d$" } - ] + ], + "@typescript-eslint/no-unused-expressions": "off" } } diff --git a/packages/core/test/ArrayFieldTemplate.test.jsx b/packages/core/test/ArrayFieldTemplate.test.jsx index 668fe18383..46e5501afd 100644 --- a/packages/core/test/ArrayFieldTemplate.test.jsx +++ b/packages/core/test/ArrayFieldTemplate.test.jsx @@ -1,6 +1,8 @@ import { PureComponent } from 'react'; import { expect } from 'chai'; import { Simulate } from 'react-dom/test-utils'; +import { getUiOptions } from '@rjsf/utils'; + import { createFormComponent, createSandbox } from './test_utils'; describe('ArrayFieldTemplate', () => { @@ -18,8 +20,9 @@ describe('ArrayFieldTemplate', () => { describe('Custom ArrayFieldTemplate of string array', () => { function ArrayFieldTemplate(props) { + const { classNames } = getUiOptions(props.uiSchema); return ( -
+
{props.canAdd &&
, - document.getElementById('app') + document.getElementById('app'), ); ``` @@ -184,7 +180,7 @@ render( emptyObjectFields: 'populateRequiredDefaults', }} />, - document.getElementById('app') + document.getElementById('app'), ); ``` @@ -247,7 +243,7 @@ render( allOf: 'populateDefaults', }} />, - document.getElementById('app') + document.getElementById('app'), ); ``` @@ -294,7 +290,7 @@ const customMergeAllOf = (schema: RJSFSchema): RJSFSchema => { render(
, - document.getElementById('app') + document.getElementById('app'), ); ``` diff --git a/packages/docs/docs/api-reference/utility-functions.md b/packages/docs/docs/api-reference/utility-functions.md index 37a99c8703..79979a1348 100644 --- a/packages/docs/docs/api-reference/utility-functions.md +++ b/packages/docs/docs/api-reference/utility-functions.md @@ -1140,39 +1140,6 @@ Always returns the first option if there is nothing that matches. - number: The index of the first matched option or 0 if none is available -### getMatchingOption() - -Given the `formData` and list of `options`, attempts to find the index of the option that best matches the data. -Deprecated, use `getFirstMatchingOption()` instead. - -#### Parameters - -- validator: ValidatorType - An implementation of the `ValidatorType` interface that will be used when necessary -- [formData]: T | undefined - The current formData, if any, used to figure out a match -- options: S[] - The list of options to find a matching options from -- rootSchema: S - The root schema, used to primarily to look up `$ref`s -- [discriminatorField]: string | undefined - The optional name of the field within the options object whose value is used to determine which option is selected - -#### Returns - -- number: The index of the matched option or 0 if none is available - -### isFilesArray() - -Checks to see if the `schema` and `uiSchema` combination represents an array of files - -#### Parameters - -- validator: ValidatorType - An implementation of the `ValidatorType` interface that will be used when necessary -- schema: S - The schema for which check for array of files flag is desired -- [uiSchema={}]: UiSchema - The UI schema from which to check the widget -- [rootSchema]: S | undefined - The root schema, used to primarily to look up `$ref`s -- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf<S> - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop - -#### Returns - -- boolean: True if schema/uiSchema contains an array of files, otherwise false - ### isMultiSelect() Checks to see if the `schema` combination represents a multi-select @@ -1203,24 +1170,6 @@ Checks to see if the `schema` combination represents a select - boolean: True if schema contains a select, otherwise false -### mergeValidationData() - -Merges the errors in `additionalErrorSchema` into the existing `validationData` by combining the hierarchies in the two `ErrorSchema`s and then appending the error list from the `additionalErrorSchema` obtained by calling `validator.toErrorList()` onto the `errors` in the `validationData`. -If no `additionalErrorSchema` is passed, then `validationData` is returned. - -> NOTE: This is function is deprecated. Use the `validationDataMerge()` function exported from `@rjsf/utils` instead. This function will be -> removed in the next major release. - -#### Parameters - -- validator: ValidatorType<T, S, F> - An implementation of the `ValidatorType` interface that will be used to convert an ErrorSchema to a list of errors -- validationData: ValidationData<T> - The current `ValidationData` into which to merge the additional errors -- [additionalErrorSchema]: ErrorSchema<T> | undefined - The additional set of errors in an `ErrorSchema` - -#### Returns - -- ValidationData<T>: The `validationData` with the additional errors from `additionalErrorSchema` merged into it, if provided. - ### retrieveSchema() Retrieves an expanded schema that has had all of its conditions, additional properties, references and dependencies diff --git a/packages/docs/docs/migration-guides/v6.x upgrade guide.md b/packages/docs/docs/migration-guides/v6.x upgrade guide.md index 91f412cf2e..dfb1250b04 100644 --- a/packages/docs/docs/migration-guides/v6.x upgrade guide.md +++ b/packages/docs/docs/migration-guides/v6.x upgrade guide.md @@ -1,5 +1,13 @@ # 6.x Upgrade Guide +## New packages + +There are 3 new packages added in RJSF version 6: + +- `@rjsf/daisyui`: This is new theme based on the `daisyui` toolkit +- `@rjsf/react-bootstrap`: This is rename of the `bootstrap-4` theme with an upgrade to the latest version of `react-bootstrap` +- `@rjsf/shadcn`: This is new theme based on the `shadcn` toolkit + ## Breaking changes ### Theme removals @@ -40,19 +48,11 @@ All PR and branch builds are running against Node 20 and 22. ### React version -RJSF is no longer actively supporting React version < 16.14.x. -React 18 is officially supported on all the themes where the underlying theme library also supports React 18. +RJSF is no longer actively supporting React version < 18.x. +React 18 is officially supported on all the themes. React 19 support is expected before the end of beta (although several developers have already upgraded with no problems). -### New packages - -There are 3 new packages added in RJSF version 6: - -- `@rjsf/daisyui`: This is new theme based on the `daisyui` toolkit -- `@rjsf/react-bootstrap`: This is rename of the `bootstrap-4` theme with an upgrade to the latest version of `react-bootstrap` -- `@rjsf/shadcn`: This is new theme based on the `shadcn` toolkit - ### Templates BREAKING CHANGES #### ArrayFieldTemplateItemType @@ -94,6 +94,183 @@ The following new functions match the 5 new validator-based utility API function - `getFromSchema(schema: S, path: string | string[], defaultValue: S): S;` - `getFromSchema(schema: S, path: string | string[], defaultValue: T | S): S | T;` +### Removed deprecations + +The following deprecations were removed from the code base in v6 + +#### FormProps.acceptcharset + +The `acceptcharset` prop on `Form` was removed. Use the `acceptCharset` prop instead. I.e.: + +```tsx + +``` + +#### getMatchingOption() + +The `getMatchingOption()` function in `@rjsf/utils` was removed. Use the `getFirstMatchingOption()` function instead. +I.e.: + +```ts +import { getFirstMatchingOption, RJSFSchema } from '@rjsf/utils'; +import validator from '@rjsf/validator-ajv8'; + +const schema: RJSFSchema = { + // your schema goes here +}; + +const formData = { + /* your form data goes here */ +}; +const options: RJSFSchema[] = [ + /* your options extracted from the schema go here */ +]; + +const option = getFirstMatchingOption(validator, formData, options, schema); +``` + +#### SchemaUtilsType.getMatchingOption() + +The `getMatchingOption()` function in the `SchemaUtilsType` was removed. Use the `getFirstMatchingOption()` funciton on +the type instead. I.e.: + +```ts +import { createSchemaUtils, RJSFSchema } from '@rjsf/utils'; +import validator from '@rjsf/validator-ajv8'; + +const schema: RJSFSchema = { + // your schema goes here +}; + +const formData = { + /* your form data goes here */ +}; +const options: RJSFSchema[] = [ + /* your options extracted from the schema go here */ +]; +const schemaUtils = createSchemaUtils(validator, schema); + +const option = schemaUtils.getFirstMatchingOption(formData, options); +``` + +#### mergeValidationData() + +The `mergeValidationData()` function from `@rjsf/utils` was removed. Use the `validationDataMerge()` function instead. +I.e.: + +```ts +import { validationDataMerge, ValidationData, ErrorSchema } from '@rjsf/utils'; + +const validationData: ValidationData = { + errors: [ + /* Your validation errors go here */ + ], + errorSchema: { + /* Your error schema goes here */ + }, +}; + +const additionalErrorSchema: ErrorSchema = { + /* Your additional error schema goes here */ +}; + +const merged = validationDataMerge(validationData, additionalErrorSchema); +``` + +#### SchemaUtilsType.mergeValidationData() + +The `mergeValidationData()` function in the `SchemaUtilsType` was removed. Use the standalone `validationDataMerge()` +function instead. I.e.: + +```ts +import { toErrorList } from '@rjsf/utils'; + +const validationData: ValidationData = { + errors: [ + /* Your validation errors go here */ + ], + errorSchema: { + /* Your error schema goes here */ + }, +}; + +const additionalErrorSchema: ErrorSchema = { + /* Your additional error schema goes here */ +}; + +const merged = validationDataMerge(validationData, additionalErrorSchema); +``` + +#### ValidatorType.toErrorList() + +The `toErrorList()` function on the `ValidatorType` interface was removed. Use the standalone `toErrorList()` function +from `@rjsf/utils` instead. I.e.: + +```ts +import { validationDataMerge, ErrorSchema, RJSFValidationError, toErrorList } from '@rjsf/utils'; + +const errorSchema: ErrorSchema = { + /* Your error schema goes here */ +}; + +const validationErrors: RJSFValidationError[] = toErrorList(errorSchema); +``` + +#### RJSF_ADDITONAL_PROPERTIES_FLAG + +The constant `RJSF_ADDITONAL_PROPERTIES_FLAG` was removed from `@rjsf/utils`. Use the `RJSF_ADDITIONAL_PROPERTIES_FLAG` +constant instead. I.e.: + +```ts +import { RJSF_ADDITIONAL_PROPERTIES_FLAG } from '@rjsf/utils'; +``` + +#### UiSchema.classNames + +The `classNames` notation on `UiSchema` was removed. Use the `ui:classNames` notation instead. I.e.: + +```json +{ + "someField": { + "ui:classNames": "someCustomClass" + } +} +``` + +#### schema.enumNames + +The custom `enumNames` property support on a JSON Schema that RJSF invented has been removed. Please use the `UiSchema` +replacement, `ui:enumNames` instead. I.e.: + +```ts +import { UiSchema, RJSFSchema } from '@rjsf/utils'; + +const schema: RJSFSchema = { + type: 'object', + properties: { + attendance: { + title: 'How did you attend the event?', + enum: ['person', 'phone', 'video'], + }, + rating: { + title: 'How would you rate this event?', + enum: ['0', '1', '2', '3', '4'], + }, + }, +}; + +const uiSchema: UiSchema = { + attendance: { + 'ui:enumNames': ['I joined in person', 'I called in using the phone number', 'I joined using the video link'], + }, + rating: { + 'ui:enumNames': ["I did't like it", 'It was meh', 'It was ok', 'I liked it', 'I loved it'], + }, +}; +``` + +Use the `ui:enumNames` in the `UiSchema` instead. + ### Other BREAKING CHANGES #### optionsList diff --git a/packages/fluentui-rc/package.json b/packages/fluentui-rc/package.json index f63da9509f..0361892c8c 100644 --- a/packages/fluentui-rc/package.json +++ b/packages/fluentui-rc/package.json @@ -66,7 +66,7 @@ }, "peerDependencies": { "@rjsf/utils": "^6.x", - "react": "^16.14.0 || >=17" + "react": ">=18" }, "dependencies": { "@fluentui/react-components": "^9.46.3", diff --git a/packages/mui/package.json b/packages/mui/package.json index 460daccefb..a3fb7d85f7 100644 --- a/packages/mui/package.json +++ b/packages/mui/package.json @@ -67,7 +67,7 @@ "@mui/material": "^6.0.0", "@rjsf/core": "^6.x", "@rjsf/utils": "^6.x", - "react": ">=17" + "react": ">=18" }, "devDependencies": { "@babel/core": "^7.23.9", diff --git a/packages/playground/src/samples/enumObjects.ts b/packages/playground/src/samples/enumObjects.ts index 8ded8bdf06..5e193892ef 100644 --- a/packages/playground/src/samples/enumObjects.ts +++ b/packages/playground/src/samples/enumObjects.ts @@ -1,11 +1,13 @@ import { Sample } from './Sample'; +const ENUM_NAMES = { + 'ui:enumNames': ['New York', 'Amsterdam', 'Hong Kong'], +}; + const enumObjects: Sample = { schema: { definitions: { locations: { - // @ts-expect-error -- enumNames an RJSF keyword and is not in the JSON Schema spec - enumNames: ['New York', 'Amsterdam', 'Hong Kong'], enum: [ { name: 'New York', @@ -54,11 +56,17 @@ const enumObjects: Sample = { }, }, uiSchema: { + location: ENUM_NAMES, locationRadio: { 'ui:widget': 'RadioWidget', + ...ENUM_NAMES, + }, + multiSelect: { + ...ENUM_NAMES, }, checkboxes: { 'ui:widget': 'CheckboxesWidget', + ...ENUM_NAMES, }, }, formData: { diff --git a/packages/react-bootstrap/package.json b/packages/react-bootstrap/package.json index 9ef94c9f05..afb7d352c2 100644 --- a/packages/react-bootstrap/package.json +++ b/packages/react-bootstrap/package.json @@ -63,7 +63,7 @@ "peerDependencies": { "@rjsf/core": "^6.x", "@rjsf/utils": "^6.x", - "react": "^16.14.0 || >=17", + "react": ">=18", "react-bootstrap": "^2.0.0" }, "engineStrict": false, diff --git a/packages/semantic-ui/package.json b/packages/semantic-ui/package.json index 72e70824d7..0739abc464 100644 --- a/packages/semantic-ui/package.json +++ b/packages/semantic-ui/package.json @@ -63,7 +63,7 @@ "peerDependencies": { "@rjsf/core": "^6.x", "@rjsf/utils": "^6.x", - "react": "^16.14.0 || >=17", + "react": ">=18", "semantic-ui-react": "^1.3.1 || ^2.1.3" }, "devDependencies": { diff --git a/packages/shadcn/package.json b/packages/shadcn/package.json index cc7b3d747c..1980421602 100644 --- a/packages/shadcn/package.json +++ b/packages/shadcn/package.json @@ -64,7 +64,7 @@ "peerDependencies": { "@rjsf/core": "^6.x", "@rjsf/utils": "^6.x", - "react": "^16.14.0 || >=17" + "react": ">=18" }, "engineStrict": false, "engines": { diff --git a/packages/snapshot-tests/package.json b/packages/snapshot-tests/package.json index 4681662999..3fb4aad9c5 100644 --- a/packages/snapshot-tests/package.json +++ b/packages/snapshot-tests/package.json @@ -28,7 +28,7 @@ "node": ">=20" }, "peerDependencies": { - "react": "^16.14.0 || >=17", + "react": ">=18", "react-test-renderer": "^17.0.2" }, "dependencies": { diff --git a/packages/utils/package.json b/packages/utils/package.json index 77556b0267..80eb9c1f6b 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -62,7 +62,7 @@ ] }, "peerDependencies": { - "react": "^16.14.0 || >=17" + "react": ">=18" }, "dependencies": { "json-schema-merge-allof": "^0.8.1", diff --git a/packages/utils/src/constants.ts b/packages/utils/src/constants.ts index b01f21851d..3114d3d2a4 100644 --- a/packages/utils/src/constants.ts +++ b/packages/utils/src/constants.ts @@ -35,10 +35,6 @@ export const FORM_CONTEXT_NAME = 'formContext'; /** The name of the `layoutGridLookupMap` attribute in the form context */ export const LOOKUP_MAP_NAME = 'layoutGridLookupMap'; -/** - * @deprecated Replace with correctly spelled constant `RJSF_ADDITIONAL_PROPERTIES_FLAG` - */ -export const RJSF_ADDITONAL_PROPERTIES_FLAG = '__rjsf_additionalProperties'; export const RJSF_ADDITIONAL_PROPERTIES_FLAG = '__rjsf_additionalProperties'; export const ROOT_SCHEMA_PREFIX = '__rjsf_rootSchema'; export const UI_FIELD_KEY = 'ui:field'; diff --git a/packages/utils/src/createSchemaUtils.ts b/packages/utils/src/createSchemaUtils.ts index 3b59ac0078..f44687b43a 100644 --- a/packages/utils/src/createSchemaUtils.ts +++ b/packages/utils/src/createSchemaUtils.ts @@ -1,6 +1,5 @@ import deepEquals from './deepEquals'; import { - ErrorSchema, Experimental_CustomMergeAllOf, Experimental_DefaultFormStateBehavior, FormContextType, @@ -12,7 +11,6 @@ import { SchemaUtilsType, StrictRJSFSchema, UiSchema, - ValidationData, ValidatorType, } from './types'; import { @@ -23,11 +21,9 @@ import { getClosestMatchingOption, getFirstMatchingOption, getFromSchema, - getMatchingOption, isFilesArray, isMultiSelect, isSelect, - mergeValidationData, retrieveSchema, sanitizeDataForNewSchema, toIdSchema, @@ -233,20 +229,6 @@ class SchemaUtils(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. - * Deprecated, use `getFirstMatchingOption()` instead. - * - * @param formData - The current formData, if any, onto which to provide any missing defaults - * @param options - The list of options to find a matching options from - * @param [discriminatorField] - The optional name of the field within the options object whose value is used to - * determine which option is selected - * @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); - } - /** Helper that acts like lodash's `get` but additionally retrieves `$ref`s as needed to get the path for schemas * containing potentially nested `$ref`s. * @@ -297,21 +279,6 @@ class SchemaUtils(this.validator, schema, this.rootSchema, this.experimental_customMergeAllOf); } - /** Merges the errors in `additionalErrorSchema` into the existing `validationData` by combining the hierarchies in - * the two `ErrorSchema`s and then appending the error list from the `additionalErrorSchema` obtained by calling - * `getValidator().toErrorList()` onto the `errors` in the `validationData`. If no `additionalErrorSchema` is passed, - * then `validationData` is returned. - * - * @param validationData - The current `ValidationData` into which to merge the additional errors - * @param [additionalErrorSchema] - The additional set of errors - * @returns - The `validationData` with the additional errors from `additionalErrorSchema` merged into it, if provided. - * @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); - } - /** Retrieves an expanded schema that has had all of its conditions, additional properties, references and * dependencies resolved and merged into the `schema` given a `rawFormData` that is used to do the potentially * recursive resolution. diff --git a/packages/utils/src/optionsList.ts b/packages/utils/src/optionsList.ts index 98536d476b..5f661fdf74 100644 --- a/packages/utils/src/optionsList.ts +++ b/packages/utils/src/optionsList.ts @@ -7,8 +7,7 @@ import toConstant from './toConstant'; import { RJSFSchema, EnumOptionsType, StrictRJSFSchema, FormContextType, UiSchema } from './types'; /** Gets the list of options from the `schema`. If the schema has an enum list, then those enum values are returned. The - * labels for the options will be extracted from the non-standard, RJSF-deprecated `enumNames` if it exists, otherwise - * the label will be the same as the `value`. + * label will be the same as the `value`. * * If the schema has a `oneOf` or `anyOf`, then the value is the list of either: * - The `const` values from the schema if present @@ -24,23 +23,12 @@ export default function optionsList, ): EnumOptionsType[] | undefined { - const schemaWithEnumNames = schema as S & { enumNames?: string[] }; if (schema.enum) { let enumNames: string[] | undefined; if (uiSchema) { const { enumNames: uiEnumNames } = getUiOptions(uiSchema); enumNames = uiEnumNames; } - if (!enumNames && schemaWithEnumNames.enumNames) { - // enumNames was deprecated in v5 and is intentionally omitted from the RJSFSchema type. - // Cast the type to include enumNames so the feature still works. - if (process.env.NODE_ENV !== 'production') { - console.warn( - 'The "enumNames" property in the schema is deprecated and will be removed in a future major release. Use the "ui:enumNames" property in the uiSchema instead.', - ); - } - enumNames = schemaWithEnumNames.enumNames; - } return schema.enum.map((value, i) => { const label = enumNames?.[i] || String(value); return { label, value }; diff --git a/packages/utils/src/schema/getFirstMatchingOption.ts b/packages/utils/src/schema/getFirstMatchingOption.ts index 8afdcc255b..636db46410 100644 --- a/packages/utils/src/schema/getFirstMatchingOption.ts +++ b/packages/utils/src/schema/getFirstMatchingOption.ts @@ -1,4 +1,9 @@ -import getMatchingOption from './getMatchingOption'; +import get from 'lodash/get'; +import has from 'lodash/has'; +import isNumber from 'lodash/isNumber'; + +import { PROPERTIES_KEY } from '../constants'; +import getOptionMatchingSimpleDiscriminator from '../getOptionMatchingSimpleDiscriminator'; import { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types'; /** Given the `formData` and list of `options`, attempts to find the index of the first option that matches the data. @@ -23,5 +28,75 @@ export default function getFirstMatchingOption< rootSchema: S, discriminatorField?: string, ): number { - return getMatchingOption(validator, formData, options, rootSchema, discriminatorField); + // For performance, skip validating subschemas if formData is undefined. We just + // want to get the first option in that case. + if (formData === undefined) { + return 0; + } + + const simpleDiscriminatorMatch = getOptionMatchingSimpleDiscriminator(formData, options, discriminatorField); + if (isNumber(simpleDiscriminatorMatch)) { + return simpleDiscriminatorMatch; + } + + for (let i = 0; i < options.length; i++) { + const option = options[i]; + + // If we have a discriminator field, then we will use this to make the determination + if (discriminatorField && has(option, [PROPERTIES_KEY, discriminatorField])) { + const value = get(formData, discriminatorField); + const discriminator = get(option, [PROPERTIES_KEY, discriminatorField], {}); + if (validator.isValid(discriminator, value, rootSchema)) { + return i; + } + } else if (option[PROPERTIES_KEY]) { + // If the schema describes an object then we need to add slightly more + // strict matching to the schema, because unless the schema uses the + // "requires" keyword, an object will match the schema as long as it + // doesn't have matching keys with a conflicting type. To do this we use an + // "anyOf" with an array of requires. This augmentation expresses that the + // schema should match if any of the keys in the schema are present on the + // object and pass validation. + // + // Create an "anyOf" schema that requires at least one of the keys in the + // "properties" object + const requiresAnyOf = { + anyOf: Object.keys(option[PROPERTIES_KEY]).map((key) => ({ + required: [key], + })), + }; + + let augmentedSchema; + + // If the "anyOf" keyword already exists, wrap the augmentation in an "allOf" + if (option.anyOf) { + // Create a shallow clone of the option + const { ...shallowClone } = option; + + if (!shallowClone.allOf) { + shallowClone.allOf = []; + } else { + // If "allOf" already exists, shallow clone the array + shallowClone.allOf = shallowClone.allOf.slice(); + } + + shallowClone.allOf.push(requiresAnyOf); + + augmentedSchema = shallowClone; + } else { + augmentedSchema = Object.assign({}, option, requiresAnyOf); + } + + // Remove the "required" field as it's likely that not all fields have + // been filled in yet, which will mean that the schema is not valid + delete augmentedSchema.required; + + if (validator.isValid(augmentedSchema, formData, rootSchema)) { + return i; + } + } else if (validator.isValid(option, formData, rootSchema)) { + return i; + } + } + return 0; } diff --git a/packages/utils/src/schema/getMatchingOption.ts b/packages/utils/src/schema/getMatchingOption.ts deleted file mode 100644 index 8c23d2e140..0000000000 --- a/packages/utils/src/schema/getMatchingOption.ts +++ /dev/null @@ -1,103 +0,0 @@ -import get from 'lodash/get'; -import has from 'lodash/has'; -import isNumber from 'lodash/isNumber'; - -import { PROPERTIES_KEY } from '../constants'; -import { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types'; -import getOptionMatchingSimpleDiscriminator from '../getOptionMatchingSimpleDiscriminator'; - -/** Given the `formData` and list of `options`, attempts to find the index of the option that best matches the data. - * Deprecated, use `getFirstMatchingOption()` instead. - * - * @param validator - An implementation of the `ValidatorType` interface that will be used when necessary - * @param formData - The current formData, if any, used to figure out a match - * @param options - The list of options to find a matching options from - * @param rootSchema - The root schema, used to primarily to look up `$ref`s - * @param [discriminatorField] - The optional name of the field within the options object whose value is used to - * determine which option is selected - * @returns - The index of the matched option or 0 if none is available - * @deprecated - */ -export default function getMatchingOption< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( - validator: ValidatorType, - formData: T | undefined, - options: S[], - rootSchema: S, - discriminatorField?: string, -): number { - // For performance, skip validating subschemas if formData is undefined. We just - // want to get the first option in that case. - if (formData === undefined) { - return 0; - } - - const simpleDiscriminatorMatch = getOptionMatchingSimpleDiscriminator(formData, options, discriminatorField); - if (isNumber(simpleDiscriminatorMatch)) { - return simpleDiscriminatorMatch; - } - - for (let i = 0; i < options.length; i++) { - const option = options[i]; - - // If we have a discriminator field, then we will use this to make the determination - if (discriminatorField && has(option, [PROPERTIES_KEY, discriminatorField])) { - const value = get(formData, discriminatorField); - const discriminator = get(option, [PROPERTIES_KEY, discriminatorField], {}); - if (validator.isValid(discriminator, value, rootSchema)) { - return i; - } - } else if (option[PROPERTIES_KEY]) { - // If the schema describes an object then we need to add slightly more - // strict matching to the schema, because unless the schema uses the - // "requires" keyword, an object will match the schema as long as it - // doesn't have matching keys with a conflicting type. To do this we use an - // "anyOf" with an array of requires. This augmentation expresses that the - // schema should match if any of the keys in the schema are present on the - // object and pass validation. - // - // Create an "anyOf" schema that requires at least one of the keys in the - // "properties" object - const requiresAnyOf = { - anyOf: Object.keys(option[PROPERTIES_KEY]).map((key) => ({ - required: [key], - })), - }; - - let augmentedSchema; - - // If the "anyOf" keyword already exists, wrap the augmentation in an "allOf" - if (option.anyOf) { - // Create a shallow clone of the option - const { ...shallowClone } = option; - - if (!shallowClone.allOf) { - shallowClone.allOf = []; - } else { - // If "allOf" already exists, shallow clone the array - shallowClone.allOf = shallowClone.allOf.slice(); - } - - shallowClone.allOf.push(requiresAnyOf); - - augmentedSchema = shallowClone; - } else { - augmentedSchema = Object.assign({}, option, requiresAnyOf); - } - - // Remove the "required" field as it's likely that not all fields have - // been filled in yet, which will mean that the schema is not valid - delete augmentedSchema.required; - - if (validator.isValid(augmentedSchema, formData, rootSchema)) { - return i; - } - } else if (validator.isValid(option, formData, rootSchema)) { - return i; - } - } - return 0; -} diff --git a/packages/utils/src/schema/index.ts b/packages/utils/src/schema/index.ts index febb3ecad6..cfe5fd6271 100644 --- a/packages/utils/src/schema/index.ts +++ b/packages/utils/src/schema/index.ts @@ -5,11 +5,9 @@ import getDisplayLabel from './getDisplayLabel'; import getClosestMatchingOption from './getClosestMatchingOption'; import getFirstMatchingOption from './getFirstMatchingOption'; import getFromSchema from './getFromSchema'; -import getMatchingOption from './getMatchingOption'; import isFilesArray from './isFilesArray'; import isMultiSelect from './isMultiSelect'; import isSelect from './isSelect'; -import mergeValidationData from './mergeValidationData'; import retrieveSchema from './retrieveSchema'; import sanitizeDataForNewSchema from './sanitizeDataForNewSchema'; import toIdSchema from './toIdSchema'; @@ -23,11 +21,9 @@ export { getClosestMatchingOption, getFirstMatchingOption, getFromSchema, - getMatchingOption, isFilesArray, isMultiSelect, isSelect, - mergeValidationData, retrieveSchema, sanitizeDataForNewSchema, toIdSchema, diff --git a/packages/utils/src/schema/mergeValidationData.ts b/packages/utils/src/schema/mergeValidationData.ts deleted file mode 100644 index 3e0dc36856..0000000000 --- a/packages/utils/src/schema/mergeValidationData.ts +++ /dev/null @@ -1,38 +0,0 @@ -import isEmpty from 'lodash/isEmpty'; - -import mergeObjects from '../mergeObjects'; -import { ErrorSchema, FormContextType, RJSFSchema, StrictRJSFSchema, ValidationData, ValidatorType } from '../types'; - -/** Merges the errors in `additionalErrorSchema` into the existing `validationData` by combining the hierarchies in the - * two `ErrorSchema`s and then appending the error list from the `additionalErrorSchema` obtained by calling - * `validator.toErrorList()` onto the `errors` in the `validationData`. If no `additionalErrorSchema` is passed, then - * `validationData` is returned. - * - * @param validator - The validator used to convert an ErrorSchema to a list of errors - * @param validationData - The current `ValidationData` into which to merge the additional errors - * @param [additionalErrorSchema] - The additional set of errors in an `ErrorSchema` - * @returns - The `validationData` with the additional errors from `additionalErrorSchema` merged into it, if provided. - * @deprecated - Use the `validationDataMerge()` function exported from `@rjsf/utils` instead. This function will be - * removed in the next major release. - */ -export default function mergeValidationData< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->( - validator: ValidatorType, - validationData: ValidationData, - additionalErrorSchema?: ErrorSchema, -): ValidationData { - if (!additionalErrorSchema) { - return validationData; - } - const { errors: oldErrors, errorSchema: oldErrorSchema } = validationData; - let errors = validator.toErrorList(additionalErrorSchema); - let errorSchema = additionalErrorSchema; - if (!isEmpty(oldErrorSchema)) { - errorSchema = mergeObjects(oldErrorSchema, additionalErrorSchema, true) as ErrorSchema; - errors = [...oldErrors].concat(errors); - } - return { errorSchema, errors }; -} diff --git a/packages/utils/src/types.ts b/packages/utils/src/types.ts index d9cf2ec295..f6da70f637 100644 --- a/packages/utils/src/types.ts +++ b/packages/utils/src/types.ts @@ -1074,14 +1074,6 @@ export interface ValidatorType, uiSchema?: UiSchema, ): ValidationData; - /** Converts an `errorSchema` into a list of `RJSFValidationErrors` - * - * @param errorSchema - The `ErrorSchema` instance to convert - * @param [fieldPath=[]] - The current field path, defaults to [] if not specified - * @deprecated - Use the `toErrorList()` function provided by `@rjsf/utils` instead. This function will be removed in - * the next major release. - */ - toErrorList(errorSchema?: ErrorSchema, fieldPath?: string[]): RJSFValidationError[]; /** Validates data against a schema, returning true if the data is valid, or * false otherwise. If the schema is invalid, then this function will return * false. @@ -1215,17 +1207,6 @@ export interface SchemaUtilsType, additionalErrorSchema?: ErrorSchema): ValidationData; /** Retrieves an expanded schema that has had all of its conditions, additional properties, references and * dependencies resolved and merged into the `schema` given a `rawFormData` that is used to do the potentially * recursive resolution. diff --git a/packages/utils/test/optionsList.test.ts b/packages/utils/test/optionsList.test.ts index cb53f1a9c2..63d7842837 100644 --- a/packages/utils/test/optionsList.test.ts +++ b/packages/utils/test/optionsList.test.ts @@ -44,69 +44,6 @@ describe('optionsList()', () => { }), ); }); - it('generates options and favors uiSchema if schema.enumNames is present', () => { - const enumSchema: RJSFSchema = { - type: 'string', - enum: ['Opt1', 'Opt2', 'Opt3'], - }; - const uiSchema: UiSchema = { - 'ui:enumNames': ['Option1', 'Option2', 'Option3'], - }; - - const enumNameSchema = { - ...enumSchema, - enumNames: ['Option One', 'Option Two', 'Option Three'], - }; - - expect(optionsList(enumNameSchema, uiSchema)).toEqual( - enumNameSchema.enum!.map((opt, index) => { - const label: string = uiSchema['ui:enumNames']![index] ?? opt; - return { label, value: opt }; - }), - ); - expect(console.warn).not.toHaveBeenCalled(); - }); - it('generates options and does not emit a deprecation warning for a schema with enumNames in production', () => { - process.env.NODE_ENV = 'production'; - const enumSchema: RJSFSchema = { - type: 'string', - enum: ['Opt1', 'Opt2', 'Opt3'], - }; - - const enumNameSchema = { - ...enumSchema, - enumNames: ['Option1', 'Option2', 'Option3'], - }; - - expect(optionsList(enumNameSchema)).toEqual( - enumNameSchema.enum!.map((opt, index) => { - const label = enumNameSchema.enumNames[index] || opt; - return { label, value: opt }; - }), - ); - expect(console.warn).not.toHaveBeenCalled(); - }); - it('generates options and emits a deprecation warning for a schema with enumNames', () => { - const enumSchema: RJSFSchema = { - type: 'string', - enum: ['Opt1', 'Opt2', 'Opt3'], - }; - - const enumNameSchema = { - ...enumSchema, - enumNames: ['Option1', 'Option2', 'Option3'], - }; - - expect(optionsList(enumNameSchema)).toEqual( - enumNameSchema.enum!.map((opt, index) => { - const label = enumNameSchema.enumNames[index] || opt; - return { label, value: opt }; - }), - ); - expect(console.warn).toHaveBeenCalledWith( - expect.stringMatching(/The "enumNames" property in the schema is deprecated/), - ); - }); }); describe('anyOf', () => { it('should generate options for an anyOf schema', () => { diff --git a/packages/utils/test/schema.test.ts b/packages/utils/test/schema.test.ts index 395ec74e3f..e400f50dcd 100644 --- a/packages/utils/test/schema.test.ts +++ b/packages/utils/test/schema.test.ts @@ -10,7 +10,6 @@ import { isFilesArrayTest, isMultiSelectTest, isSelectTest, - mergeValidationDataTest, retrieveSchemaTest, sanitizeDataForNewSchemaTest, toIdSchemaTest, @@ -30,7 +29,6 @@ getFromSchemaTest(testValidator); isFilesArrayTest(testValidator); isMultiSelectTest(testValidator); isSelectTest(testValidator); -mergeValidationDataTest(testValidator); retrieveSchemaTest(testValidator); sanitizeDataForNewSchemaTest(testValidator); toIdSchemaTest(testValidator); diff --git a/packages/utils/test/schema/getFirstMatchingOptionTest.ts b/packages/utils/test/schema/getFirstMatchingOptionTest.ts index 379c70e437..df1c8267fb 100644 --- a/packages/utils/test/schema/getFirstMatchingOptionTest.ts +++ b/packages/utils/test/schema/getFirstMatchingOptionTest.ts @@ -1,7 +1,6 @@ import { createSchemaUtils, getFirstMatchingOption, RJSFSchema } from '../../src'; import { TestValidatorType } from './types'; -// Since getFirstMatchingOption() simply calls getMatchingOption() there is no need to have tests for that export default function getFirstMatchingOptionTest(testValidator: TestValidatorType) { describe('getFirstMatchingOption()', () => { let rootSchema: RJSFSchema; @@ -95,8 +94,7 @@ export default function getFirstMatchingOptionTest(testValidator: TestValidatorT expect(schemaUtils.getFirstMatchingOption(formData, options)).toEqual(1); // Mock again isValid fail the first non-nested value testValidator.setReturnValues({ isValid: [false, true] }); - // Test getMatchingOption call from `schemaUtils` to maintain coverage, delete when getMatchingOption is removed - expect(schemaUtils.getMatchingOption(formData, options)).toEqual(1); + expect(schemaUtils.getFirstMatchingOption(formData, options)).toEqual(1); }); it('should return 0 when schema has discriminator but no matching data', () => { // Mock isValid to fail both values diff --git a/packages/utils/test/schema/index.ts b/packages/utils/test/schema/index.ts index b2551c20fa..e96d9b0a93 100644 --- a/packages/utils/test/schema/index.ts +++ b/packages/utils/test/schema/index.ts @@ -8,7 +8,6 @@ import getFromSchemaTest from './getFromSchemaTest'; import isFilesArrayTest from './isFilesArrayTest'; import isMultiSelectTest from './isMultiSelectTest'; import isSelectTest from './isSelectTest'; -import mergeValidationDataTest from './mergeValidationDataTest'; import retrieveSchemaTest from './retrieveSchemaTest'; import sanitizeDataForNewSchemaTest from './sanitizeDataForNewSchemaTest'; import toIdSchemaTest from './toIdSchemaTest'; @@ -27,7 +26,6 @@ export { isFilesArrayTest, isMultiSelectTest, isSelectTest, - mergeValidationDataTest, retrieveSchemaTest, sanitizeDataForNewSchemaTest, toIdSchemaTest, diff --git a/packages/utils/test/schema/mergeValidationDataTest.ts b/packages/utils/test/schema/mergeValidationDataTest.ts deleted file mode 100644 index 70200972b8..0000000000 --- a/packages/utils/test/schema/mergeValidationDataTest.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { ERRORS_KEY, mergeValidationData, createSchemaUtils, ErrorSchema, ValidationData } from '../../src'; -import { TestValidatorType } from './types'; - -export default function mergeValidationDataTest(testValidator: TestValidatorType) { - describe('mergeValidationDataTest()', () => { - it('Returns validationData when no additionalErrorSchema is passed', () => { - const validationData: ValidationData = { - errorSchema: {}, - errors: [], - }; - expect(mergeValidationData(testValidator, validationData)).toBe(validationData); - }); - it('Returns only additionalErrorSchema when additionalErrorSchema is passed and no validationData', () => { - const validationData: ValidationData = { - errorSchema: {}, - errors: [], - }; - const errors = ['custom errors']; - const customErrors = [{ property: '.', message: errors[0], stack: `. ${errors[0]}` }]; - testValidator.setReturnValues({ errorList: [customErrors] }); - const errorSchema: ErrorSchema = { [ERRORS_KEY]: errors } as ErrorSchema; - const expected = { - errorSchema, - errors: customErrors, - }; - expect(mergeValidationData(testValidator, validationData, errorSchema)).toEqual(expected); - }); - it('Returns merged data when additionalErrorSchema is passed', () => { - const schemaUtils = createSchemaUtils(testValidator, {}); - const oldError = 'ajv error'; - const validationData: ValidationData = { - errorSchema: { [ERRORS_KEY]: [oldError] } as ErrorSchema, - errors: [{ stack: oldError, name: 'foo', schemaPath: '.foo' }], - }; - const errors = ['custom errors']; - const customErrors = [{ property: '.', message: errors[0], stack: `. ${errors[0]}` }]; - testValidator.setReturnValues({ errorList: [customErrors] }); - const errorSchema: ErrorSchema = { [ERRORS_KEY]: errors } as ErrorSchema; - const expected = { - errorSchema: { [ERRORS_KEY]: [oldError, ...errors] }, - errors: [...validationData.errors, ...customErrors], - }; - expect(schemaUtils.mergeValidationData(validationData, errorSchema)).toEqual(expected); - }); - }); -} diff --git a/packages/utils/test/testUtils/getTestValidator.ts b/packages/utils/test/testUtils/getTestValidator.ts index 75496a7633..ff790581cb 100644 --- a/packages/utils/test/testUtils/getTestValidator.ts +++ b/packages/utils/test/testUtils/getTestValidator.ts @@ -39,13 +39,6 @@ export default function getTestValidator({ } return true; }), - toErrorList: jest.fn().mockImplementation(() => { - // console.warn('isValid', JSON.stringify(args)); - if (Array.isArray(testValidator._errorList) && testValidator._errorList.length > 0) { - return testValidator._errorList.shift(); - } - return []; - }), rawValidation: jest.fn().mockImplementation(() => {}), setReturnValues({ isValid, data, errorList }: TestValidatorParams) { if (isValid !== undefined) { diff --git a/packages/utils/test/validationDataMerge.test.ts b/packages/utils/test/validationDataMerge.test.ts index 4ecac12434..5432f8d408 100644 --- a/packages/utils/test/validationDataMerge.test.ts +++ b/packages/utils/test/validationDataMerge.test.ts @@ -1,6 +1,6 @@ import { ERRORS_KEY, ErrorSchema, validationDataMerge, ValidationData } from '../src'; -describe('mergeValidationDataTest()', () => { +describe('validationDataMerge()', () => { it('Returns validationData when no additionalErrorSchema is passed', () => { const validationData: ValidationData = { errorSchema: {}, diff --git a/packages/validator-ajv8/src/precompiledValidator.ts b/packages/validator-ajv8/src/precompiledValidator.ts index 0e24b638fa..78de48de38 100644 --- a/packages/validator-ajv8/src/precompiledValidator.ts +++ b/packages/validator-ajv8/src/precompiledValidator.ts @@ -3,7 +3,6 @@ import get from 'lodash/get'; import { CustomValidator, deepEquals, - ErrorSchema, ErrorTransformer, FormContextType, hashForSchema, @@ -12,7 +11,6 @@ import { retrieveSchema, RJSFSchema, StrictRJSFSchema, - toErrorList, UiSchema, ValidationData, ValidatorType, @@ -104,17 +102,6 @@ export default class AJV8PrecompiledValidator< return true; } - /** Converts an `errorSchema` into a list of `RJSFValidationErrors` - * - * @param errorSchema - The `ErrorSchema` instance to convert - * @param [fieldPath=[]] - The current field path, defaults to [] if not specified - * @deprecated - Use the `toErrorList()` function provided by `@rjsf/utils` instead. This function will be removed in - * the next major release. - */ - toErrorList(errorSchema?: ErrorSchema, fieldPath: string[] = []) { - return toErrorList(errorSchema, fieldPath); - } - /** Runs the pure validation of the `schema` and `formData` without any of the RJSF functionality. Provided for use * by the playground. Returns the `errors` from the validation * diff --git a/packages/validator-ajv8/src/validator.ts b/packages/validator-ajv8/src/validator.ts index cb2547d3c9..cfe7ee78d1 100644 --- a/packages/validator-ajv8/src/validator.ts +++ b/packages/validator-ajv8/src/validator.ts @@ -2,14 +2,12 @@ import Ajv, { ErrorObject, ValidateFunction } from 'ajv'; import { CustomValidator, deepEquals, - ErrorSchema, ErrorTransformer, FormContextType, ID_KEY, RJSFSchema, ROOT_SCHEMA_PREFIX, StrictRJSFSchema, - toErrorList, UiSchema, ValidationData, ValidatorType, @@ -55,17 +53,6 @@ export default class AJV8Validator, fieldPath: string[] = []) { - return toErrorList(errorSchema, fieldPath); - } - /** Runs the pure validation of the `schema` and `formData` without any of the RJSF functionality. Provided for use * by the playground. Returns the `errors` from the validation * diff --git a/packages/validator-ajv8/test/precompiledValidator.test.ts b/packages/validator-ajv8/test/precompiledValidator.test.ts index fab27bfd60..006ec6769b 100644 --- a/packages/validator-ajv8/test/precompiledValidator.test.ts +++ b/packages/validator-ajv8/test/precompiledValidator.test.ts @@ -122,24 +122,6 @@ describe('AJV8PrecompiledValidator', () => { ); }); }); - describe('validator.toErrorList()', () => { - it('should return empty list for unspecified errorSchema', () => { - expect(validator.toErrorList()).toEqual([]); - }); - it('should convert an errorSchema into a flat list', () => { - const errorSchema = builder - .addErrors(['err1', 'err2']) - .addErrors(['err3', 'err4'], 'a.b') - .addErrors(['err5'], 'c').ErrorSchema; - expect(validator.toErrorList(errorSchema)).toEqual([ - { property: '.', message: 'err1', stack: '. err1' }, - { property: '.', message: 'err2', stack: '. err2' }, - { property: '.a.b', message: 'err3', stack: '.a.b err3' }, - { property: '.a.b', message: 'err4', stack: '.a.b err4' }, - { property: '.c', message: 'err5', stack: '.c err5' }, - ]); - }); - }); describe('validator.validateFormData()', () => { it('throws an error when the schemas differ', () => { const schema: RJSFSchema = { diff --git a/packages/validator-ajv8/test/utilsTests/getTestValidator.ts b/packages/validator-ajv8/test/utilsTests/getTestValidator.ts index 89dde13d64..1f2e9589f5 100644 --- a/packages/validator-ajv8/test/utilsTests/getTestValidator.ts +++ b/packages/validator-ajv8/test/utilsTests/getTestValidator.ts @@ -1,11 +1,4 @@ -import { - CustomValidator, - ErrorSchema, - ErrorTransformer, - RJSFSchema, - RJSFValidationError, - ValidationData, -} from '@rjsf/utils'; +import { CustomValidator, ErrorTransformer, RJSFSchema, ValidationData } from '@rjsf/utils'; // With Lerna active, the test world has access to the test suite via the symlink import { TestValidatorType } from '@rjsf/utils/test/schema'; import { customizeValidator, CustomValidatorOptionsType } from '../../src'; @@ -27,9 +20,6 @@ export default function getTestValidator(options: CustomValidatorOption ): ValidationData { return validator.validateFormData(formData, schema, customValidate, transformErrors); }, - toErrorList(errorSchema?: ErrorSchema, fieldPath?: string[]): RJSFValidationError[] { - return validator.toErrorList(errorSchema, fieldPath); - }, isValid(schema: RJSFSchema, formData: T | undefined, rootSchema: RJSFSchema): boolean { return validator.isValid(schema, formData, rootSchema); }, diff --git a/packages/validator-ajv8/test/utilsTests/schema.test.ts b/packages/validator-ajv8/test/utilsTests/schema.test.ts index fed29f886f..92715a62e0 100644 --- a/packages/validator-ajv8/test/utilsTests/schema.test.ts +++ b/packages/validator-ajv8/test/utilsTests/schema.test.ts @@ -12,7 +12,6 @@ import { isFilesArrayTest, isMultiSelectTest, isSelectTest, - mergeValidationDataTest, retrieveSchemaTest, sanitizeDataForNewSchemaTest, toIdSchemaTest, @@ -33,7 +32,6 @@ getFromSchemaTest(testValidator); isFilesArrayTest(testValidator); isMultiSelectTest(testValidator); isSelectTest(testValidator); -mergeValidationDataTest(testValidator); retrieveSchemaTest(testValidator); sanitizeDataForNewSchemaTest(testValidator); toIdSchemaTest(testValidator); @@ -54,7 +52,6 @@ getFromSchemaTest(testValidatorDiscriminated); isFilesArrayTest(testValidatorDiscriminated); isMultiSelectTest(testValidatorDiscriminated); isSelectTest(testValidatorDiscriminated); -mergeValidationDataTest(testValidatorDiscriminated); retrieveSchemaTest(testValidatorDiscriminated); sanitizeDataForNewSchemaTest(testValidatorDiscriminated); toIdSchemaTest(testValidatorDiscriminated); @@ -73,7 +70,6 @@ getFromSchemaTest(testValidator2019); isFilesArrayTest(testValidator2019); isMultiSelectTest(testValidator2019); isSelectTest(testValidator2019); -mergeValidationDataTest(testValidator2019); retrieveSchemaTest(testValidator2019); sanitizeDataForNewSchemaTest(testValidator2019); toIdSchemaTest(testValidator2019); @@ -92,7 +88,6 @@ getFromSchemaTest(testValidator2020); isFilesArrayTest(testValidator2020); isMultiSelectTest(testValidator2020); isSelectTest(testValidator2020); -mergeValidationDataTest(testValidator2020); retrieveSchemaTest(testValidator2020); retrieveSchemaTest(testValidator2020); toIdSchemaTest(testValidator2020); diff --git a/packages/validator-ajv8/test/validator.test.ts b/packages/validator-ajv8/test/validator.test.ts index 62d74451b2..861b0ab72f 100644 --- a/packages/validator-ajv8/test/validator.test.ts +++ b/packages/validator-ajv8/test/validator.test.ts @@ -145,24 +145,6 @@ describe('AJV8Validator', () => { expect(compileSpy).toHaveBeenCalledTimes(1); }); }); - describe('validator.toErrorList()', () => { - it('should return empty list for unspecified errorSchema', () => { - expect(validator.toErrorList()).toEqual([]); - }); - it('should convert an errorSchema into a flat list', () => { - const errorSchema = builder - .addErrors(['err1', 'err2']) - .addErrors(['err3', 'err4'], 'a.b') - .addErrors(['err5'], 'c').ErrorSchema; - expect(validator.toErrorList(errorSchema)).toEqual([ - { property: '.', message: 'err1', stack: '. err1' }, - { property: '.', message: 'err2', stack: '. err2' }, - { property: '.a.b', message: 'err3', stack: '.a.b err3' }, - { property: '.a.b', message: 'err4', stack: '.a.b err4' }, - { property: '.c', message: 'err5', stack: '.c err5' }, - ]); - }); - }); describe('validator.validateFormData()', () => { describe('No custom validate function, single value', () => { let errors: RJSFValidationError[]; @@ -599,24 +581,6 @@ describe('AJV8Validator', () => { expect(addSchemaSpy).toHaveBeenNthCalledWith(2, expect.objectContaining(schema), schema.$id); }); }); - describe('validator.toErrorList()', () => { - it('should return empty list for unspecified errorSchema', () => { - expect(validator.toErrorList()).toEqual([]); - }); - it('should convert an errorSchema into a flat list', () => { - const errorSchema = builder - .addErrors(['err1', 'err2']) - .addErrors(['err3', 'err4'], 'a.b') - .addErrors(['err5'], 'c').ErrorSchema; - expect(validator.toErrorList(errorSchema)).toEqual([ - { property: '.', message: 'err1', stack: '. err1' }, - { property: '.', message: 'err2', stack: '. err2' }, - { property: '.a.b', message: 'err3', stack: '.a.b err3' }, - { property: '.a.b', message: 'err4', stack: '.a.b err4' }, - { property: '.c', message: 'err5', stack: '.c err5' }, - ]); - }); - }); describe('validator.validateFormData()', () => { describe('No custom validate function, single value', () => { let errors: RJSFValidationError[]; @@ -1054,24 +1018,6 @@ describe('AJV8Validator', () => { expect(addSchemaSpy).toHaveBeenNthCalledWith(2, expect.objectContaining(schema), schema.$id); }); }); - describe('validator.toErrorList()', () => { - it('should return empty list for unspecified errorSchema', () => { - expect(validator.toErrorList()).toEqual([]); - }); - it('should convert an errorSchema into a flat list', () => { - const errorSchema = builder - .addErrors(['err1', 'err2']) - .addErrors(['err3', 'err4'], 'a.b') - .addErrors(['err5'], 'c').ErrorSchema; - expect(validator.toErrorList(errorSchema)).toEqual([ - { property: '.', message: 'err1', stack: '. err1' }, - { property: '.', message: 'err2', stack: '. err2' }, - { property: '.a.b', message: 'err3', stack: '.a.b err3' }, - { property: '.a.b', message: 'err4', stack: '.a.b err4' }, - { property: '.c', message: 'err5', stack: '.c err5' }, - ]); - }); - }); describe('validator.validateFormData()', () => { describe('No custom validate function, single value', () => { let errors: RJSFValidationError[];