diff --git a/.changeset/lucky-beans-bathe.md b/.changeset/lucky-beans-bathe.md new file mode 100644 index 0000000000..b425a29599 --- /dev/null +++ b/.changeset/lucky-beans-bathe.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Bump to `react-jsonschema-form@v5-beta` for the `NextRouter` under `@alpha` exports diff --git a/packages/app/package.json b/packages/app/package.json index 76e099bace..fa8bb5c5ee 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -83,7 +83,6 @@ }, "devDependencies": { "@backstage/test-utils": "workspace:^", - "@rjsf/core": "^3.2.1", "@testing-library/cypress": "^8.0.2", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index 23b374541b..cf69736bd4 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -15,7 +15,9 @@ import { Extension } from '@backstage/core-plugin-api'; import { ExternalRouteRef } from '@backstage/core-plugin-api'; import { FetchApi } from '@backstage/core-plugin-api'; import { FieldProps } from '@rjsf/core'; +import { FieldProps as FieldProps_2 } from '@rjsf/utils'; import { FieldValidation } from '@rjsf/core'; +import { FieldValidation as FieldValidation_2 } from '@rjsf/utils'; import type { FormProps } from '@rjsf/core'; import { IdentityApi } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; @@ -29,6 +31,16 @@ import { ScmIntegrationRegistry } from '@backstage/integration'; import { TaskSpec } from '@backstage/plugin-scaffolder-common'; import { TaskStep } from '@backstage/plugin-scaffolder-common'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; +import { UIOptionsType } from '@rjsf/utils'; +import { UiSchema } from '@rjsf/utils'; + +// @alpha +export function createNextScaffolderFieldExtension< + TReturnValue = unknown, + TInputProps extends UIOptionsType = {}, +>( + options: NextFieldExtensionOptions, +): Extension>; // @public export function createScaffolderFieldExtension< @@ -155,6 +167,38 @@ export type LogEvent = { taskId: string; }; +// @alpha +export type NextCustomFieldValidator = ( + data: TFieldReturnValue, + field: FieldValidation_2, + context: { + apiHolder: ApiHolder; + }, +) => void | Promise; + +// @alpha +export interface NextFieldExtensionComponentProps< + TFieldReturnValue, + TUiOptions = {}, +> extends PropsWithChildren> { + // (undocumented) + uiSchema?: UiSchema & { + 'ui:options'?: TUiOptions & UIOptionsType; + }; +} + +// @alpha +export type NextFieldExtensionOptions< + TFieldReturnValue = unknown, + TInputProps = unknown, +> = { + name: string; + component: ( + props: NextFieldExtensionComponentProps, + ) => JSX.Element | null; + validation?: NextCustomFieldValidator; +}; + // @alpha export type NextRouterProps = { components?: { diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 9b81d6593a..4508a4b49d 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -55,7 +55,11 @@ "@material-ui/lab": "4.0.0-alpha.57", "@react-hookz/web": "^15.0.0", "@rjsf/core": "^3.2.1", + "@rjsf/core-v5": "npm:@rjsf/core@^5.0.0-beta.10", "@rjsf/material-ui": "^3.2.1", + "@rjsf/material-ui-v5": "npm:@rjsf/material-ui@^5.0.0-beta.10", + "@rjsf/utils": "^5.0.0-beta.10", + "@rjsf/validator-ajv8": "^5.0.0-beta.10", "@types/json-schema": "^7.0.9", "@uiw/react-codemirror": "^4.9.3", "classnames": "^2.2.6", diff --git a/plugins/scaffolder/src/extensions/index.tsx b/plugins/scaffolder/src/extensions/index.tsx index 60b9022053..08075b5b9d 100644 --- a/plugins/scaffolder/src/extensions/index.tsx +++ b/plugins/scaffolder/src/extensions/index.tsx @@ -19,8 +19,12 @@ import { CustomFieldValidator, FieldExtensionOptions, FieldExtensionComponentProps, + NextCustomFieldValidator, + NextFieldExtensionOptions, + NextFieldExtensionComponentProps, } from './types'; import { Extension, attachComponentData } from '@backstage/core-plugin-api'; +import { UIOptionsType } from '@rjsf/utils'; export const FIELD_EXTENSION_WRAPPER_KEY = 'scaffolder.extensions.wrapper.v1'; export const FIELD_EXTENSION_KEY = 'scaffolder.extensions.field.v1'; @@ -58,6 +62,32 @@ export function createScaffolderFieldExtension< }; } +/** + * Method for creating field extensions that can be used in the scaffolder + * frontend form. + * @alpha + */ +export function createNextScaffolderFieldExtension< + TReturnValue = unknown, + TInputProps extends UIOptionsType = {}, +>( + options: NextFieldExtensionOptions, +): Extension> { + return { + expose() { + const FieldExtensionDataHolder: any = () => null; + + attachComponentData( + FieldExtensionDataHolder, + FIELD_EXTENSION_KEY, + options, + ); + + return FieldExtensionDataHolder; + }, + }; +} + /** * The Wrapping component for defining fields extensions inside * @@ -76,6 +106,9 @@ export type { CustomFieldValidator, FieldExtensionOptions, FieldExtensionComponentProps, + NextCustomFieldValidator, + NextFieldExtensionOptions, + NextFieldExtensionComponentProps, }; export { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from './default'; diff --git a/plugins/scaffolder/src/extensions/types.ts b/plugins/scaffolder/src/extensions/types.ts index 9b42ba478b..62f17dff15 100644 --- a/plugins/scaffolder/src/extensions/types.ts +++ b/plugins/scaffolder/src/extensions/types.ts @@ -15,6 +15,14 @@ */ import { ApiHolder } from '@backstage/core-plugin-api'; import { FieldValidation, FieldProps } from '@rjsf/core'; +import { PropsWithChildren } from 'react'; + +import { + UIOptionsType, + FieldProps as FieldPropsV5, + UiSchema as UiSchemaV5, + FieldValidation as FieldValidationV5, +} from '@rjsf/utils'; /** * Field validation type for Custom Field Extensions. @@ -58,3 +66,45 @@ export interface FieldExtensionComponentProps< 'ui:options'?: TUiOptions; }; } + +/** + * Type for Field Extension Props for RJSF v5 + * + * @alpha + */ +export interface NextFieldExtensionComponentProps< + TFieldReturnValue, + TUiOptions = {}, +> extends PropsWithChildren> { + uiSchema?: UiSchemaV5 & { + 'ui:options'?: TUiOptions & UIOptionsType; + }; +} + +/** + * Field validation type for Custom Field Extensions. + * + * @alpha + */ +export type NextCustomFieldValidator = ( + data: TFieldReturnValue, + field: FieldValidationV5, + context: { apiHolder: ApiHolder }, +) => void | Promise; + +/** + * Type for the Custom Field Extension with the + * name and components and validation function. + * + * @alpha + */ +export type NextFieldExtensionOptions< + TFieldReturnValue = unknown, + TInputProps = unknown, +> = { + name: string; + component: ( + props: NextFieldExtensionComponentProps, + ) => JSX.Element | null; + validation?: NextCustomFieldValidator; +}; diff --git a/plugins/scaffolder/src/index.ts b/plugins/scaffolder/src/index.ts index c16e12beb5..e68eece8e5 100644 --- a/plugins/scaffolder/src/index.ts +++ b/plugins/scaffolder/src/index.ts @@ -59,11 +59,17 @@ export { RepoUrlPickerFieldExtension, ScaffolderPage, scaffolderPlugin, - NextScaffolderPage, } from './plugin'; export * from './components'; export type { TaskPageProps } from './components/TaskPage'; /** next exports */ +export { NextScaffolderPage } from './plugin'; export type { NextRouterProps } from './next'; export type { TemplateGroupFilter } from './next'; +export { + createNextScaffolderFieldExtension, + type NextCustomFieldValidator, + type NextFieldExtensionOptions, + type NextFieldExtensionComponentProps, +} from './extensions'; diff --git a/plugins/scaffolder/src/next/Router/Router.tsx b/plugins/scaffolder/src/next/Router/Router.tsx index 758e268cb3..125a0bbbf6 100644 --- a/plugins/scaffolder/src/next/Router/Router.tsx +++ b/plugins/scaffolder/src/next/Router/Router.tsx @@ -18,10 +18,11 @@ import { Routes, Route, useOutlet } from 'react-router'; import { TemplateListPage } from '../TemplateListPage'; import { TemplateWizardPage } from '../TemplateWizardPage'; import { - FieldExtensionOptions, FIELD_EXTENSION_WRAPPER_KEY, FIELD_EXTENSION_KEY, DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS, + NextFieldExtensionOptions, + FieldExtensionOptions, } from '../../extensions'; import { useElementFilter } from '@backstage/core-plugin-api'; @@ -60,7 +61,7 @@ export const Router = (props: PropsWithChildren) => { .selectByComponentData({ key: FIELD_EXTENSION_WRAPPER_KEY, }) - .findComponentData({ + .findComponentData({ key: FIELD_EXTENSION_KEY, }), ); @@ -73,7 +74,7 @@ export const Router = (props: PropsWithChildren) => { customFieldExtension => customFieldExtension.name === name, ), ), - ]; + ] as NextFieldExtensionOptions[]; return ( diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx index f5656092c1..97f21111d3 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx @@ -22,14 +22,15 @@ import { Button, makeStyles, } from '@material-ui/core'; -import { FieldValidation, withTheme } from '@rjsf/core'; -import { Theme as MuiTheme } from '@rjsf/material-ui'; +import { withTheme } from '@rjsf/core-v5'; +import { ErrorSchema, FieldValidation } from '@rjsf/utils'; import React, { useMemo, useState } from 'react'; -import { FieldExtensionOptions } from '../../../extensions'; +import { NextFieldExtensionOptions } from '../../../extensions'; import { TemplateParameterSchema } from '../../../types'; import { createAsyncValidators } from './createAsyncValidators'; import { useTemplateSchema } from './useTemplateSchema'; import { ReviewState } from './ReviewState'; +import validator from '@rjsf/validator-ajv8'; const useStyles = makeStyles(theme => ({ backButton: { @@ -48,10 +49,13 @@ const useStyles = makeStyles(theme => ({ export interface StepperProps { manifest: TemplateParameterSchema; - extensions: FieldExtensionOptions[]; + extensions: NextFieldExtensionOptions[]; } -const Form = withTheme(MuiTheme); +// TODO(blam): We require here, as the types in this package depend on @rjsf/core explicitly +// which is what we're using here as the default types, it needs to depend on @rjsf/core-v5 because +// of the re-writing we're doing. Once we've migrated, we can import this the exact same as before. +const Form = withTheme(require('@rjsf/material-ui-v5').Theme); export const Stepper = (props: StepperProps) => { const { steps } = useTemplateSchema(props.manifest); @@ -92,9 +96,9 @@ export const Stepper = (props: StepperProps) => { const returnedValidation = await validation(formData); - const hasErrors = Object.values(returnedValidation).some(i => { - return i.__errors.length > 0; - }); + const hasErrors = Object.values(returnedValidation).some( + i => i.__errors?.length, + ); if (hasErrors) { setErrors(returnedValidation); @@ -124,7 +128,8 @@ export const Stepper = (props: StepperProps) => {
{activeStep < steps.length ? (
{ @@ -79,13 +79,16 @@ describe('createAsyncValidators', () => { }, }; - const NameField: CustomFieldValidator = (value, { addError }) => { + const NameField: NextCustomFieldValidator = ( + value, + { addError }, + ) => { if (!value) { addError('something is broken here!'); } }; - const AddressField: CustomFieldValidator<{ + const AddressField: NextCustomFieldValidator<{ street?: string; postcode?: string; }> = (value, { addError }) => { @@ -101,8 +104,8 @@ describe('createAsyncValidators', () => { const validate = createAsyncValidators( schema, { - NameField: NameField as CustomFieldValidator, - AddressField: AddressField as CustomFieldValidator, + NameField: NameField as NextCustomFieldValidator, + AddressField: AddressField as NextCustomFieldValidator, }, { apiHolder: { get: jest.fn() }, diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/createAsyncValidators.ts b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/createAsyncValidators.ts index d89f0d4e5f..1355387eda 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/createAsyncValidators.ts +++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/createAsyncValidators.ts @@ -14,16 +14,16 @@ * limitations under the License. */ -import { FieldValidation } from '@rjsf/core'; +import { FieldValidation } from '@rjsf/utils'; import { JsonObject } from '@backstage/types'; import { ApiHolder } from '@backstage/core-plugin-api'; -import { CustomFieldValidator } from '../../../extensions'; +import { NextCustomFieldValidator } from '../../../extensions'; import { Draft07 as JSONSchema } from 'json-schema-library'; import { createFieldValidation } from './schema'; export const createAsyncValidators = ( rootSchema: JsonObject, - validators: Record>, + validators: Record>, context: { apiHolder: ApiHolder; }, diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/schema.ts b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/schema.ts index e2d5e89932..4c647bc045 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/schema.ts +++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/schema.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { JsonObject } from '@backstage/types'; -import { FieldValidation, UiSchema } from '@rjsf/core'; +import { FieldValidation, UiSchema } from '@rjsf/utils'; function isObject(value: unknown): value is JsonObject { return typeof value === 'object' && value !== null && !Array.isArray(value); @@ -119,7 +119,7 @@ export const createFieldValidation = (): FieldValidation => { const fieldValidation: FieldValidation = { __errors: [] as string[], addError: (message: string) => { - fieldValidation.__errors.push(message); + fieldValidation.__errors?.push(message); }, }; diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/useTemplateSchema.ts b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/useTemplateSchema.ts index d0d8590a7b..6aad6baa96 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/useTemplateSchema.ts +++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/useTemplateSchema.ts @@ -15,7 +15,7 @@ */ import { featureFlagsApiRef, useApi } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; -import { UiSchema } from '@rjsf/core'; +import { UiSchema } from '@rjsf/utils'; import { TemplateParameterSchema } from '../../../types'; import { extractSchemaFromStep } from './schema'; diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx index 468db438d5..f6739e6389 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx @@ -22,7 +22,7 @@ import { InfoCard, MarkdownContent, } from '@backstage/core-components'; -import { FieldExtensionOptions } from '../../extensions'; +import { NextFieldExtensionOptions } from '../../extensions'; import { Navigate } from 'react-router'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { @@ -39,7 +39,7 @@ import { BackstageTheme } from '@backstage/theme'; import { nextRouteRef, selectedTemplateRouteRef } from '../../routes'; export interface TemplateWizardPageProps { - customFieldExtensions: FieldExtensionOptions[]; + customFieldExtensions: NextFieldExtensionOptions[]; } const useStyles = makeStyles(() => ({ diff --git a/yarn.lock b/yarn.lock index 8be2e5c8a6..9af65cfa61 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6743,7 +6743,11 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.57 "@react-hookz/web": ^15.0.0 "@rjsf/core": ^3.2.1 + "@rjsf/core-v5": "npm:@rjsf/core@^5.0.0-beta.10" "@rjsf/material-ui": ^3.2.1 + "@rjsf/material-ui-v5": "npm:@rjsf/material-ui@^5.0.0-beta.10" + "@rjsf/utils": ^5.0.0-beta.10 + "@rjsf/validator-ajv8": ^5.0.0-beta.10 "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 @@ -11940,6 +11944,21 @@ __metadata: languageName: node linkType: hard +"@rjsf/core-v5@npm:@rjsf/core@^5.0.0-beta.10": + version: 5.0.0-beta.10 + resolution: "@rjsf/core@npm:5.0.0-beta.10" + dependencies: + lodash: ^4.17.15 + lodash-es: ^4.17.15 + nanoid: ^3.3.4 + prop-types: ^15.7.2 + peerDependencies: + "@rjsf/utils": ^5.0.0-beta.1 + react: ^16.14.0 || >=17 + checksum: c3e8852c8fedc6ae23da610033e0bded1bd198cebf7f54a5cdcf3b42d22a3b3864da9c735300cadc7d756f26055a7e62408d51a5ebdb906be9b1bf85bf3712ed + languageName: node + linkType: hard + "@rjsf/core@npm:^3.2.1": version: 3.2.1 resolution: "@rjsf/core@npm:3.2.1" @@ -11959,6 +11978,19 @@ __metadata: languageName: node linkType: hard +"@rjsf/material-ui-v5@npm:@rjsf/material-ui@^5.0.0-beta.10": + version: 5.0.0-beta.10 + resolution: "@rjsf/material-ui@npm:5.0.0-beta.10" + peerDependencies: + "@material-ui/core": ^4.12.3 + "@material-ui/icons": ^4.11.2 + "@rjsf/core": ^5.0.0-beta.1 + "@rjsf/utils": ^5.0.0-beta.1 + react: ^16.14.0 || >=17 + checksum: c6e602fc331ec37524837123f42e605389c8ea1a9207ed3e9052de380b91fb90365aa962b0020197f0fb2bcbd87baac34bef7dbbb31ea4b57b6587d0fcd81a09 + languageName: node + linkType: hard + "@rjsf/material-ui@npm:^3.2.1": version: 3.2.1 resolution: "@rjsf/material-ui@npm:3.2.1" @@ -11971,6 +12003,35 @@ __metadata: languageName: node linkType: hard +"@rjsf/utils@npm:^5.0.0-beta.10": + version: 5.0.0-beta.10 + resolution: "@rjsf/utils@npm:5.0.0-beta.10" + dependencies: + json-schema-merge-allof: ^0.8.1 + jsonpointer: ^5.0.1 + lodash: ^4.17.15 + lodash-es: ^4.17.15 + react-is: ^18.2.0 + peerDependencies: + react: ^16.14.0 || >=17 + checksum: df5dda5a17ce11df2342ceff8d6ad2b3dad3a1f98d44aa7da378e6cd48387e4af023964b6143836e1ad16ff68f6592c0dcf24ff9f3fc859480b42b2c879406bc + languageName: node + linkType: hard + +"@rjsf/validator-ajv8@npm:^5.0.0-beta.10": + version: 5.0.0-beta.10 + resolution: "@rjsf/validator-ajv8@npm:5.0.0-beta.10" + dependencies: + ajv: ^8.11.0 + ajv-formats: ^2.1.1 + lodash: ^4.17.15 + lodash-es: ^4.17.15 + peerDependencies: + "@rjsf/utils": ^5.0.0-beta.1 + checksum: faa359c9ec58cf0fff35932d4e08a5c42f8449120cae606ebff108814f974e8db8a62df85e90e1fec7b0345388df09b83359ae1cc09103d41e73f298472b846a + languageName: node + linkType: hard + "@roadiehq/backstage-plugin-buildkite@npm:^2.0.8": version: 2.0.9 resolution: "@roadiehq/backstage-plugin-buildkite@npm:2.0.9" @@ -15626,7 +15687,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.6.3, ajv@npm:^8.8.0": +"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0, ajv@npm:^8.6.3, ajv@npm:^8.8.0": version: 8.11.0 resolution: "ajv@npm:8.11.0" dependencies: @@ -18786,13 +18847,20 @@ __metadata: languageName: node linkType: hard -"core-js-pure@npm:^3.20.2, core-js-pure@npm:^3.6.5, core-js-pure@npm:^3.8.1": +"core-js-pure@npm:^3.20.2, core-js-pure@npm:^3.8.1": version: 3.21.1 resolution: "core-js-pure@npm:3.21.1" checksum: 00a5dff599b7fb0b30746a638b9d0edbdc0df24ed1580ca56be595fbe3c78c375d37fc4e1bff23627109229702c9ee8ea2587a66b8280eb33b85160aa4e401e9 languageName: node linkType: hard +"core-js-pure@npm:^3.6.5": + version: 3.25.3 + resolution: "core-js-pure@npm:3.25.3" + checksum: be3097b8e2b541977a08004e433b68adb4951cc7694229e695ae407f296d370c1f360e5fd70fc6910c4427e46e48e087ac455d68cebdf4314370907d2e03eef1 + languageName: node + linkType: hard + "core-js@npm:^2.4.0, core-js@npm:^2.5.0, core-js@npm:^2.6.10": version: 2.6.12 resolution: "core-js@npm:2.6.12" @@ -22077,7 +22145,6 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.57 "@octokit/rest": ^19.0.3 "@oriflame/backstage-plugin-score-card": ^0.5.1 - "@rjsf/core": ^3.2.1 "@roadiehq/backstage-plugin-buildkite": ^2.0.8 "@roadiehq/backstage-plugin-github-insights": ^2.0.5 "@roadiehq/backstage-plugin-github-pull-requests": ^2.2.7 @@ -27359,10 +27426,10 @@ __metadata: languageName: node linkType: hard -"jsonpointer@npm:^5.0.0": - version: 5.0.0 - resolution: "jsonpointer@npm:5.0.0" - checksum: c7ec0b6bb596b81de687bc12945586bbcdc80dfb54919656d2690d76334f796a936270067ee9f1b5bbc2d9ecc551afb366ac35e6685aa61f07b5b68d1e5e857d +"jsonpointer@npm:^5.0.0, jsonpointer@npm:^5.0.1": + version: 5.0.1 + resolution: "jsonpointer@npm:5.0.1" + checksum: 0b40f712900ad0c846681ea2db23b6684b9d5eedf55807b4708c656f5894b63507d0e28ae10aa1bddbea551241035afe62b6df0800fc94c2e2806a7f3adecd7c languageName: node linkType: hard @@ -28097,7 +28164,7 @@ __metadata: languageName: node linkType: hard -"lodash-es@npm:^4.17.21": +"lodash-es@npm:^4.17.15, lodash-es@npm:^4.17.21": version: 4.17.21 resolution: "lodash-es@npm:4.17.21" checksum: 05cbffad6e2adbb331a4e16fbd826e7faee403a1a04873b82b42c0f22090f280839f85b95393f487c1303c8a3d2a010048bf06151a6cbe03eee4d388fb0a12d2 @@ -30062,16 +30129,7 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^3.1.23": - version: 3.3.1 - resolution: "nanoid@npm:3.3.1" - bin: - nanoid: bin/nanoid.cjs - checksum: 4ef0969e1bbe866fc223eb32276cbccb0961900bfe79104fa5abe34361979dead8d0e061410a5c03bc3d47455685adf32c09d6f27790f4a6898fb51f7df7ec86 - languageName: node - linkType: hard - -"nanoid@npm:^3.3.4": +"nanoid@npm:^3.1.23, nanoid@npm:^3.3.4": version: 3.3.4 resolution: "nanoid@npm:3.3.4" bin: @@ -33589,6 +33647,13 @@ __metadata: languageName: node linkType: hard +"react-is@npm:^18.2.0": + version: 18.2.0 + resolution: "react-is@npm:18.2.0" + checksum: e72d0ba81b5922759e4aff17e0252bd29988f9642ed817f56b25a3e217e13eea8a7f2322af99a06edb779da12d5d636e9fda473d620df9a3da0df2a74141d53e + languageName: node + linkType: hard + "react-lifecycles-compat@npm:^3.0.4": version: 3.0.4 resolution: "react-lifecycles-compat@npm:3.0.4"