From bc77b01b4c10f8739f147facdcb92fef4a5ad025 Mon Sep 17 00:00:00 2001 From: Banks Nussman <115251059+bnussman-akamai@users.noreply.github.com> Date: Wed, 21 Aug 2024 10:16:33 -0400 Subject: [PATCH 01/19] refactor: [M3-8459] - Remove `patch-package` package (#10800) * remove `patch-package` package * Added changeset: Remove `patch-package` package --------- Co-authored-by: Banks Nussman --- .../01-repository-structure.md | 2 -- package.json | 2 -- .../pr-10800-tech-stories-1724094117438.md | 5 +++++ packages/manager/package.json | 2 -- yarn.lock | 20 ------------------- 5 files changed, 5 insertions(+), 26 deletions(-) create mode 100644 packages/manager/.changeset/pr-10800-tech-stories-1724094117438.md diff --git a/docs/development-guide/01-repository-structure.md b/docs/development-guide/01-repository-structure.md index fee00a5cc03..a8b5caa2c0c 100644 --- a/docs/development-guide/01-repository-structure.md +++ b/docs/development-guide/01-repository-structure.md @@ -59,8 +59,6 @@ A few notable directories in the root level of the manager package: - end-to-end tests - **/e2e** - old end-to-end tests [deprecated] -- **/patches** - - patches applied to dependencies via patch-package - **/public** - assets, fonts, HTML, and third-party JS - **/scripts** diff --git a/package.json b/package.json index 2804917ccba..1ab0fb56d7b 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,6 @@ "devDependencies": { "husky": "^3.0.1", "npm-run-all": "^4.1.5", - "patch-package": "^7.0.0", "postinstall": "^0.6.0", "typescript": "^5.4.5" }, @@ -19,7 +18,6 @@ "cost-of-modules": "yarn global add cost-of-modules && cost-of-modules --less --no-install --include-dev", "install:all": "yarn install --frozen-lockfile", "upgrade:sdk": "yarn workspace @linode/api-v4 version --no-git-tag-version --no-commit-hooks && yarn workspace linode-manager upgrade @linode/api-v4", - "postinstall": "echo \"Skipping Patching: yarn workspaces run postinstall && patch-package\"", "build:sdk": "yarn workspace @linode/api-v4 build", "build:validation": "yarn workspace @linode/validation build", "build": "yarn build:validation && yarn build:sdk && yarn workspace linode-manager build", diff --git a/packages/manager/.changeset/pr-10800-tech-stories-1724094117438.md b/packages/manager/.changeset/pr-10800-tech-stories-1724094117438.md new file mode 100644 index 00000000000..0886b75b4b2 --- /dev/null +++ b/packages/manager/.changeset/pr-10800-tech-stories-1724094117438.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Tech Stories +--- + +Remove `patch-package` package ([#10800](https://github.com/linode/manager/pull/10800)) diff --git a/packages/manager/package.json b/packages/manager/package.json index 4baf75abd75..2ac52547032 100644 --- a/packages/manager/package.json +++ b/packages/manager/package.json @@ -55,7 +55,6 @@ "markdown-it": "^12.3.2", "md5": "^2.2.1", "notistack": "^3.0.1", - "patch-package": "^7.0.0", "qrcode.react": "^0.8.0", "ramda": "~0.25.0", "react": "^18.2.0", @@ -86,7 +85,6 @@ "zxcvbn": "^4.4.2" }, "scripts": { - "postinstall": "patch-package", "start": "concurrently --raw \"vite\" \"tsc --watch --preserveWatchOutput\"", "start:expose": "concurrently --raw \"vite --host\" \"tsc --watch --preserveWatchOutput\"", "start:ci": "yarn serve ./build -p 3000 -s --cors", diff --git a/yarn.lock b/yarn.lock index 5a0696c50ca..db0eb12fd97 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11036,26 +11036,6 @@ parseurl@~1.3.3: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -patch-package@^7.0.0: - version "7.0.2" - resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-7.0.2.tgz#c01589bb6964854b5210506a5845d47900641f5a" - integrity sha512-PMYfL8LXxGIRmxXLqlEaBxzKPu7/SdP13ld6GSfAUJUZRmBDPp8chZs0dpzaAFn9TSPnFiMwkC6PJt6pBiAl8Q== - dependencies: - "@yarnpkg/lockfile" "^1.1.0" - chalk "^4.1.2" - ci-info "^3.7.0" - cross-spawn "^7.0.3" - find-yarn-workspace-root "^2.0.0" - fs-extra "^9.0.0" - klaw-sync "^6.0.0" - minimist "^1.2.6" - open "^7.4.2" - rimraf "^2.6.3" - semver "^7.5.3" - slash "^2.0.0" - tmp "^0.0.33" - yaml "^2.2.2" - patch-package@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-8.0.0.tgz#d191e2f1b6e06a4624a0116bcb88edd6714ede61" From 8812d3333f761fc499b27955692d9db2fbaac930 Mon Sep 17 00:00:00 2001 From: Jaalah Ramos <125309814+jaalah-akamai@users.noreply.github.com> Date: Thu, 22 Aug 2024 09:54:11 -0400 Subject: [PATCH 02/19] upcoming: [M3-8187] - Add useRegionQuery and cleanup bucket landing page (#10801) Co-authored-by: Jaalah Ramos Co-authored-by: Connie Liu <139280159+coliu-akamai@users.noreply.github.com> Co-authored-by: Banks Nussman <115251059+bnussman-akamai@users.noreply.github.com> --- .../pr-10801-changed-1724274276545.md | 5 + .../api-v4/src/object-storage/clusters.ts | 6 +- ...r-10801-upcoming-features-1724274214381.md | 5 + .../BucketDetailsDrawer.test.tsx | 202 ++++++++++++++++++ .../BucketLanding/BucketDetailsDrawer.tsx | 102 +++++---- .../BucketLanding/BucketLanding.tsx | 23 +- .../BucketLanding/BucketRateLimitTable.tsx | 8 +- .../BucketLanding/OMC_BucketLanding.tsx | 69 ++---- .../src/queries/object-storage/queries.ts | 4 + .../src/queries/object-storage/requests.ts | 3 + .../manager/src/queries/regions/regions.ts | 17 +- 11 files changed, 317 insertions(+), 127 deletions(-) create mode 100644 packages/api-v4/.changeset/pr-10801-changed-1724274276545.md create mode 100644 packages/manager/.changeset/pr-10801-upcoming-features-1724274214381.md create mode 100644 packages/manager/src/features/ObjectStorage/BucketLanding/BucketDetailsDrawer.test.tsx diff --git a/packages/api-v4/.changeset/pr-10801-changed-1724274276545.md b/packages/api-v4/.changeset/pr-10801-changed-1724274276545.md new file mode 100644 index 00000000000..d52b1ff5d74 --- /dev/null +++ b/packages/api-v4/.changeset/pr-10801-changed-1724274276545.md @@ -0,0 +1,5 @@ +--- +"@linode/api-v4": Changed +--- + +Deprecated `getClusters` ([#10801](https://github.com/linode/manager/pull/10801)) diff --git a/packages/api-v4/src/object-storage/clusters.ts b/packages/api-v4/src/object-storage/clusters.ts index 843832c1928..58ff3893fca 100644 --- a/packages/api-v4/src/object-storage/clusters.ts +++ b/packages/api-v4/src/object-storage/clusters.ts @@ -4,9 +4,9 @@ import { Filter, Params, ResourcePage as Page } from '../types'; import { ObjectStorageCluster } from './types'; /** - * getClusters - * - * Gets a list of available clusters + * @deprecated This method returns legacy clusterId values representing regions + * used in older API versions. It is maintained for backward compatibility only. + * Please use the "getRegions" endpoint instead for up-to-date information. */ export const getClusters = (params?: Params, filters?: Filter) => Request>( diff --git a/packages/manager/.changeset/pr-10801-upcoming-features-1724274214381.md b/packages/manager/.changeset/pr-10801-upcoming-features-1724274214381.md new file mode 100644 index 00000000000..a8a7db694ee --- /dev/null +++ b/packages/manager/.changeset/pr-10801-upcoming-features-1724274214381.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Upcoming Features +--- + +Add useRegionQuery and cleanup bucket landing page ([#10801](https://github.com/linode/manager/pull/10801)) diff --git a/packages/manager/src/features/ObjectStorage/BucketLanding/BucketDetailsDrawer.test.tsx b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketDetailsDrawer.test.tsx new file mode 100644 index 00000000000..12fa33d91f1 --- /dev/null +++ b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketDetailsDrawer.test.tsx @@ -0,0 +1,202 @@ +import { screen, waitFor } from '@testing-library/react'; +import React from 'react'; +import { vi } from 'vitest'; + +import { + objectStorageBucketFactory, + profileFactory, + regionFactory, +} from 'src/factories'; +import { formatDate } from 'src/utilities/formatDate'; +import { renderWithThemeAndHookFormContext } from 'src/utilities/testHelpers'; +import { truncateMiddle } from 'src/utilities/truncate'; +import { readableBytes } from 'src/utilities/unitConversions'; + +import { BucketDetailsDrawer } from './BucketDetailsDrawer'; + +// Mock utility functions +vi.mock('src/utilities/formatDate'); +vi.mock('src/utilities/truncate'); +vi.mock('src/utilities/unitConversions'); + +// Hoist query mocks +const queryMocks = vi.hoisted(() => ({ + useObjectStorageClusters: vi.fn().mockReturnValue({}), + useProfile: vi.fn().mockReturnValue({}), + useRegionQuery: vi.fn().mockReturnValue({}), + useRegionsQuery: vi.fn().mockReturnValue({}), +})); + +// Mock the queries +vi.mock('src/queries/profile/profile', async () => { + const actual = await vi.importActual('src/queries/profile/profile'); + return { + ...actual, + useProfile: queryMocks.useProfile, + }; +}); + +vi.mock('src/queries/regions/regions', async () => { + const actual = await vi.importActual('src/queries/regions/regions'); + return { + ...actual, + useRegionQuery: queryMocks.useRegionQuery, + useRegionsQuery: queryMocks.useRegionsQuery, + }; +}); + +vi.mock('src/queries/object-storage/queries', async () => { + const actual = await vi.importActual('src/queries/object-storage/queries'); + return { + ...actual, + useObjectStorageClusters: queryMocks.useObjectStorageClusters, + }; +}); + +const mockOnClose = vi.fn(); + +describe('BucketDetailsDrawer: Legacy UI', () => { + const bucket = objectStorageBucketFactory.build(); + const region = regionFactory.build({ + id: bucket.region, + }); + + beforeEach(() => { + vi.resetAllMocks(); + queryMocks.useProfile.mockReturnValue({ + data: profileFactory.build({ timezone: 'UTC' }), + }); + queryMocks.useRegionQuery.mockReturnValue({ data: region }); + queryMocks.useRegionsQuery.mockReturnValue({ data: [region] }); + queryMocks.useObjectStorageClusters.mockReturnValue({ data: [] }); + + // These utils are used in the component + vi.mocked(formatDate).mockReturnValue('2019-12-12'); + vi.mocked(truncateMiddle).mockImplementation((str) => str); + vi.mocked(readableBytes).mockReturnValue({ + formatted: '1 MB', + unit: 'MB', + value: 1, + }); + }); + + it('renders correctly when open', () => { + renderWithThemeAndHookFormContext({ + component: ( + + ), + options: { + flags: { objMultiCluster: false }, + }, + }); + + expect(screen.getByText(bucket.label)).toBeInTheDocument(); + expect(screen.getByTestId('createdTime')).toHaveTextContent( + 'Created: 2019-12-12' + ); + expect(screen.getByTestId('cluster')).toHaveTextContent(region.id); + expect(screen.getByText(bucket.hostname)).toBeInTheDocument(); + expect(screen.getByText('1 MB')).toBeInTheDocument(); + expect(screen.getByText('103 objects')).toBeInTheDocument(); + }); + + it('does not render when closed', () => { + renderWithThemeAndHookFormContext({ + component: ( + + ), + options: { + flags: { objMultiCluster: false }, + }, + }); + + expect(screen.queryByText(bucket.label)).not.toBeInTheDocument(); + }); + + it('renders correctly with objMultiCluster disabled', () => { + renderWithThemeAndHookFormContext({ + component: ( + + ), + options: { + flags: { objMultiCluster: false }, + }, + }); + + expect(screen.getByTestId('cluster')).toHaveTextContent(region.id); + }); + + it('handles undefined selectedBucket gracefully', () => { + renderWithThemeAndHookFormContext({ + component: ( + + ), + options: { + flags: { objMultiCluster: false }, + }, + }); + + expect(screen.getByText('Bucket Detail')).toBeInTheDocument(); + expect(screen.queryByTestId('createdTime')).not.toBeInTheDocument(); + expect(screen.queryByTestId('cluster')).not.toBeInTheDocument(); + }); + + it('renders AccessSelect when cluster and bucketLabel are available', async () => { + renderWithThemeAndHookFormContext({ + component: ( + + ), + options: { + flags: { objMultiCluster: false }, + }, + }); + + await waitFor(() => { + expect( + screen.queryByLabelText('Access Control List (ACL)') + ).toBeInTheDocument(); + }); + }); + + it('does not render AccessSelect when cluster or bucketLabel is missing', async () => { + const bucketWithoutCluster = { ...bucket, cluster: '' }; + renderWithThemeAndHookFormContext({ + component: ( + + ), + options: { + flags: { objMultiCluster: false }, + }, + }); + + await waitFor(() => { + expect( + screen.queryByLabelText('Access Control List (ACL)') + ).not.toBeInTheDocument(); + }); + }); +}); diff --git a/packages/manager/src/features/ObjectStorage/BucketLanding/BucketDetailsDrawer.tsx b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketDetailsDrawer.tsx index 7139165f273..b08ee777f70 100644 --- a/packages/manager/src/features/ObjectStorage/BucketLanding/BucketDetailsDrawer.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketDetailsDrawer.tsx @@ -14,7 +14,7 @@ import { useAccountManagement } from 'src/hooks/useAccountManagement'; import { useFlags } from 'src/hooks/useFlags'; import { useObjectStorageClusters } from 'src/queries/object-storage/queries'; import { useProfile } from 'src/queries/profile/profile'; -import { useRegionsQuery } from 'src/queries/regions/regions'; +import { useRegionQuery, useRegionsQuery } from 'src/queries/regions/regions'; import { isFeatureEnabledV2 } from 'src/utilities/accountCapabilities'; import { formatDate } from 'src/utilities/formatDate'; import { pluralize } from 'src/utilities/pluralize'; @@ -23,38 +23,31 @@ import { readableBytes } from 'src/utilities/unitConversions'; import { AccessSelect } from '../BucketDetail/AccessSelect'; -import type { Region } from '@linode/api-v4'; import type { ACLType, - ObjectStorageEndpointTypes, + ObjectStorageBucket, } from '@linode/api-v4/lib/object-storage'; + export interface BucketDetailsDrawerProps { - bucketLabel?: string; - bucketRegion?: Region; - cluster?: string; - created?: string; - endpointType?: ObjectStorageEndpointTypes; - hostname?: string; - objectsNumber?: number; onClose: () => void; open: boolean; - size?: null | number; + selectedBucket: ObjectStorageBucket | undefined; } export const BucketDetailsDrawer = React.memo( (props: BucketDetailsDrawerProps) => { + const { onClose, open, selectedBucket } = props; + const { - bucketLabel, - bucketRegion, cluster, created, - endpointType, + endpoint_type, hostname, - objectsNumber, - onClose, - open, + label, + objects, + region, size, - } = props; + } = selectedBucket ?? {}; const flags = useFlags(); const { account } = useAccountManagement(); @@ -65,14 +58,20 @@ export const BucketDetailsDrawer = React.memo( account?.capabilities ?? [] ); - // @TODO OBJ Multicluster: Once the feature is rolled out to production, we can clean this up by removing the useObjectStorageClusters and useRegionsQuery, which will not be required at that time. + // @TODO OBJGen2 - We could clean this up when OBJ Gen2 is in GA. const { data: clusters } = useObjectStorageClusters( !isObjMultiClusterEnabled ); const { data: regions } = useRegionsQuery(); + const { data: currentRegion } = useRegionQuery(region ?? ''); const { data: profile } = useProfile(); - const actualCluster = clusters?.find((c) => c.id === cluster); - const region = regions?.find((r) => r.id === actualCluster?.region); + + // @TODO OBJGen2 - We could clean this up when OBJ Gen2 is in GA. + const selectedCluster = clusters?.find((c) => c.id === cluster); + const regionFromCluster = regions?.find( + (r) => r.id === selectedCluster?.region + ); + let formattedCreated; try { @@ -87,68 +86,66 @@ export const BucketDetailsDrawer = React.memo( - {formattedCreated ? ( + {formattedCreated && ( Created: {formattedCreated} - ) : null} - {Boolean(endpointType) && ( + )} + {Boolean(endpoint_type) && ( - Endpoint Type: {endpointType} + Endpoint Type: {endpoint_type} )} {isObjMultiClusterEnabled ? ( - {bucketRegion?.label} + {currentRegion?.label} ) : cluster ? ( - {region?.label ?? cluster} + {regionFromCluster?.label ?? cluster} ) : null} - {hostname ? ( + {hostname && ( {truncateMiddle(hostname, 50)} - ) : null} - {formattedCreated || cluster ? ( + )} + {(formattedCreated || cluster) && ( - ) : null} - {typeof size === 'number' ? ( + )} + {typeof size === 'number' && ( {readableBytes(size).formatted} - ) : null} + )} {/* @TODO OBJ Multicluster: use region instead of cluster if isObjMultiClusterEnabled. */} - {typeof objectsNumber === 'number' ? ( + {typeof objects === 'number' && ( - {pluralize('object', 'objects', objectsNumber)} + {pluralize('object', 'objects', objects)} - ) : null} - {typeof size === 'number' || typeof objectsNumber === 'number' ? ( + )} + {(typeof size === 'number' || typeof objects === 'number') && ( - ) : null} + )} {/* @TODO OBJ Multicluster: use region instead of cluster if isObjMultiClusterEnabled to getBucketAccess and updateBucketAccess. */} - {cluster && bucketLabel ? ( + {cluster && label && ( getBucketAccess( - isObjMultiClusterEnabled && bucketRegion - ? bucketRegion.id + isObjMultiClusterEnabled && currentRegion + ? currentRegion.id : cluster, - bucketLabel + label ) } updateAccess={(acl: ACLType, cors_enabled: boolean) => { @@ -158,18 +155,17 @@ export const BucketDetailsDrawer = React.memo( acl === 'custom' ? { cors_enabled } : { acl, cors_enabled }; return updateBucketAccess( - isObjMultiClusterEnabled && bucketRegion - ? bucketRegion.id + isObjMultiClusterEnabled && currentRegion + ? currentRegion.id : cluster, - bucketLabel, + label, payload ); }} - endpointType={endpointType} - name={bucketLabel} + name={label} variant="bucket" /> - ) : null} + )} ); } diff --git a/packages/manager/src/features/ObjectStorage/BucketLanding/BucketLanding.tsx b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketLanding.tsx index cd8df0fdfbe..0efe21d558a 100644 --- a/packages/manager/src/features/ObjectStorage/BucketLanding/BucketLanding.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketLanding.tsx @@ -60,22 +60,19 @@ export const BucketLanding = () => { const { classes } = useStyles(); const removeBucketConfirmationDialog = useOpenClose(); - const [bucketToRemove, setBucketToRemove] = React.useState< - ObjectStorageBucket | undefined - >(undefined); const [isLoading, setIsLoading] = React.useState(false); const [error, setError] = React.useState(undefined); const [ bucketDetailDrawerOpen, setBucketDetailDrawerOpen, ] = React.useState(false); - const [bucketForDetails, setBucketForDetails] = React.useState< + const [selectedBucket, setSelectedBucket] = React.useState< ObjectStorageBucket | undefined >(undefined); const handleClickDetails = (bucket: ObjectStorageBucket) => { setBucketDetailDrawerOpen(true); - setBucketForDetails(bucket); + setSelectedBucket(bucket); }; const closeBucketDetailDrawer = () => { @@ -83,21 +80,21 @@ export const BucketLanding = () => { }; const handleClickRemove = (bucket: ObjectStorageBucket) => { - setBucketToRemove(bucket); + setSelectedBucket(bucket); setError(undefined); removeBucketConfirmationDialog.open(); }; const removeBucket = () => { // This shouldn't happen, but just in case (and to get TS to quit complaining...) - if (!bucketToRemove) { + if (!selectedBucket) { return; } setError(undefined); setIsLoading(true); - const { cluster, label } = bucketToRemove; + const { cluster, label } = selectedBucket; deleteBucket({ cluster, label }) .then(() => { @@ -156,7 +153,7 @@ export const BucketLanding = () => { } const totalUsage = sumBucketUsage(objectStorageBucketsResponse.buckets); - const bucketLabel = bucketToRemove ? bucketToRemove.label : ''; + const bucketLabel = selectedBucket ? selectedBucket.label : ''; return ( @@ -236,15 +233,9 @@ export const BucketLanding = () => { )} ); diff --git a/packages/manager/src/features/ObjectStorage/BucketLanding/BucketRateLimitTable.tsx b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketRateLimitTable.tsx index 1b4fe2520df..58f39322eb8 100644 --- a/packages/manager/src/features/ObjectStorage/BucketLanding/BucketRateLimitTable.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketLanding/BucketRateLimitTable.tsx @@ -26,16 +26,16 @@ const tableData = ({ endpointType }: BucketRateLimitTableProps) => { return [ { checked: true, - values: ['2000', '500', '100', '200', '400'], + values: ['2,000', '500', '100', '200', '400'], }, { checked: false, values: [ - isE3 ? '20000' : '5000', - isE3 ? '2000' : '1000', + isE3 ? '20,000' : '5,000', + isE3 ? '2,000' : '1,000', isE3 ? '400' : '200', isE3 ? '400' : '200', - isE3 ? '1000' : '800', + isE3 ? '1,000' : '800', ], }, ]; diff --git a/packages/manager/src/features/ObjectStorage/BucketLanding/OMC_BucketLanding.tsx b/packages/manager/src/features/ObjectStorage/BucketLanding/OMC_BucketLanding.tsx index 70c924088a0..08669587f07 100644 --- a/packages/manager/src/features/ObjectStorage/BucketLanding/OMC_BucketLanding.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketLanding/OMC_BucketLanding.tsx @@ -18,12 +18,10 @@ import { } from 'src/queries/object-storage/queries'; import { isBucketError } from 'src/queries/object-storage/requests'; import { useProfile } from 'src/queries/profile/profile'; -import { useRegionsQuery } from 'src/queries/regions/regions'; import { sendDeleteBucketEvent, sendDeleteBucketFailedEvent, } from 'src/utilities/analytics/customEventAnalytics'; -import { getRegionsByRegionId } from 'src/utilities/regions'; import { readableBytes } from 'src/utilities/unitConversions'; import { CancelNotice } from '../CancelNotice'; @@ -45,14 +43,6 @@ export const OMC_BucketLanding = () => { const isRestrictedUser = profile?.restricted; - const { - data: regions, - error: regionErrors, - isLoading: areRegionsLoading, - } = useRegionsQuery(); - - const regionsLookup = regions && getRegionsByRegionId(regions); - const { data: objectStorageBucketsResponse, error: bucketsErrors, @@ -64,22 +54,21 @@ export const OMC_BucketLanding = () => { const { classes } = useStyles(); const removeBucketConfirmationDialog = useOpenClose(); - const [bucketToRemove, setBucketToRemove] = React.useState< - ObjectStorageBucket | undefined - >(undefined); + const [isLoading, setIsLoading] = React.useState(false); const [error, setError] = React.useState(undefined); const [ bucketDetailDrawerOpen, setBucketDetailDrawerOpen, ] = React.useState(false); - const [bucketForDetails, setBucketForDetails] = React.useState< + + const [selectedBucket, setSelectedBucket] = React.useState< ObjectStorageBucket | undefined >(undefined); const handleClickDetails = (bucket: ObjectStorageBucket) => { setBucketDetailDrawerOpen(true); - setBucketForDetails(bucket); + setSelectedBucket(bucket); }; const closeBucketDetailDrawer = () => { @@ -87,33 +76,30 @@ export const OMC_BucketLanding = () => { }; const handleClickRemove = (bucket: ObjectStorageBucket) => { - setBucketToRemove(bucket); + setSelectedBucket(bucket); setError(undefined); removeBucketConfirmationDialog.open(); }; const removeBucket = async () => { // This shouldn't happen, but just in case (and to get TS to quit complaining...) - if (!bucketToRemove) { + if (!selectedBucket) { return; } setError(undefined); setIsLoading(true); - const { label, region } = bucketToRemove; + const { label, region } = selectedBucket; + if (region) { try { await deleteBucket({ label, region }); removeBucketConfirmationDialog.close(); setIsLoading(false); - - // @analytics sendDeleteBucketEvent(region); } catch (e) { - // @analytics sendDeleteBucketFailedEvent(region); - setIsLoading(false); setError(e); } @@ -124,7 +110,7 @@ export const OMC_BucketLanding = () => { removeBucketConfirmationDialog.close(); }, [removeBucketConfirmationDialog]); - // @TODO OBJ Multicluster - region is defined as an optional field in BucketError. Once the feature is rolled out to production, we could clean this up and remove the filter. + // @TODO OBJGen2 - We could clean this up when OBJ Gen2 is in GA. const unavailableRegions = objectStorageBucketsResponse?.errors ?.map((error) => (isBucketError(error) ? error.region : error.endpoint)) .filter((region): region is Region => region !== undefined); @@ -133,7 +119,7 @@ export const OMC_BucketLanding = () => { return ; } - if (regionErrors || bucketsErrors) { + if (bucketsErrors) { return ( { ); } - if ( - areRegionsLoading || - areBucketsLoading || - objectStorageBucketsResponse === undefined - ) { + if (areBucketsLoading || objectStorageBucketsResponse === undefined) { return ; } @@ -161,8 +143,9 @@ export const OMC_BucketLanding = () => { ); } - const totalUsage = sumBucketUsage(objectStorageBucketsResponse.buckets); - const bucketLabel = bucketToRemove ? bucketToRemove.label : ''; + const buckets = objectStorageBucketsResponse.buckets; + const totalUsage = sumBucketUsage(buckets); + const bucketLabel = selectedBucket ? selectedBucket.label : ''; return ( @@ -171,11 +154,7 @@ export const OMC_BucketLanding = () => { )} - + {({ data: orderedData, handleOrderChange, order, orderBy }) => { const bucketTableProps = { data: orderedData, @@ -189,7 +168,7 @@ export const OMC_BucketLanding = () => { }} {/* If there's more than one Bucket, display the total usage. */} - {objectStorageBucketsResponse.buckets.length > 1 ? ( + {buckets.length > 1 ? ( { Total storage used: {readableBytes(totalUsage).formatted} ) : null} - 1 ? 8 : 18} - /> + 1 ? 8 : 18} /> { {/* If the user is attempting to delete their last Bucket, remind them that they will still be billed unless they cancel Object Storage in Account Settings. */} - {objectStorageBucketsResponse?.buckets.length === 1 && ( - - )} + {buckets.length === 1 && } ); diff --git a/packages/manager/src/queries/object-storage/queries.ts b/packages/manager/src/queries/object-storage/queries.ts index 5314f337a1e..11a882f2684 100644 --- a/packages/manager/src/queries/object-storage/queries.ts +++ b/packages/manager/src/queries/object-storage/queries.ts @@ -109,6 +109,10 @@ export const useObjectStorageEndpoints = (enabled = true) => { }); }; +/** + * + * @deprecated This will be replaced by useObjectStorageEndpoints + */ export const useObjectStorageClusters = (enabled: boolean = true) => useQuery({ ...objectStorageQueries.clusters, diff --git a/packages/manager/src/queries/object-storage/requests.ts b/packages/manager/src/queries/object-storage/requests.ts index 832bc22c7a9..4176f7393c4 100644 --- a/packages/manager/src/queries/object-storage/requests.ts +++ b/packages/manager/src/queries/object-storage/requests.ts @@ -18,6 +18,9 @@ import type { Region, } from '@linode/api-v4'; +/** + * @deprecated This will be replaced with `getAllObjectStorageEndpoints` when OBJ Gen2 is in GA. + */ export const getAllObjectStorageClusters = () => getAll(() => getClusters())().then((data) => data.data); diff --git a/packages/manager/src/queries/regions/regions.ts b/packages/manager/src/queries/regions/regions.ts index 9a72cae9831..eefda55290b 100644 --- a/packages/manager/src/queries/regions/regions.ts +++ b/packages/manager/src/queries/regions/regions.ts @@ -1,4 +1,4 @@ -import { getRegionAvailability } from '@linode/api-v4/lib/regions'; +import { getRegion, getRegionAvailability } from '@linode/api-v4/lib/regions'; import { createQueryKeys } from '@lukemorales/query-key-factory'; import { useQuery } from '@tanstack/react-query'; @@ -27,12 +27,27 @@ export const regionQueries = createQueryKeys('regions', { }, queryKey: null, }, + region: (regionId: string) => ({ + queryFn: () => getRegion(regionId), + queryKey: [regionId], + }), regions: { queryFn: getAllRegionsRequest, queryKey: null, }, }); +export const useRegionQuery = (regionId: string) => { + return useQuery({ + ...regionQueries.region(regionId), + enabled: Boolean(regionId), + select: (region) => ({ + ...region, + label: getNewRegionLabel(region), + }), + }); +}; + export const useRegionsQuery = () => useQuery({ ...regionQueries.regions, From 8b480cfbea0e094f7103e1bcd14d4cf256c8e9dd Mon Sep 17 00:00:00 2001 From: Jaalah Ramos Date: Thu, 22 Aug 2024 10:42:05 -0400 Subject: [PATCH 03/19] fix: Enable CORS for Legacy/Gen1 Endpoints --- .../src/features/ObjectStorage/BucketDetail/AccessSelect.tsx | 4 +++- .../ObjectStorage/BucketDetail/ObjectDetailsDrawer.tsx | 1 + packages/manager/src/mocks/serverHandlers.ts | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.tsx b/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.tsx index e77dd8eb178..7040509edfb 100644 --- a/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.tsx @@ -142,7 +142,9 @@ export const AccessSelect = React.memo((props: Props) => { : 'CORS Disabled'; const isCorsEnabled = - variant === 'bucket' && endpointType !== 'E2' && endpointType !== 'E3'; + (variant === 'bucket' || variant === 'object') && + endpointType !== 'E2' && + endpointType !== 'E3'; const selectedOption = _options.find((thisOption) => thisOption.value === selectedACL) ?? diff --git a/packages/manager/src/features/ObjectStorage/BucketDetail/ObjectDetailsDrawer.tsx b/packages/manager/src/features/ObjectStorage/BucketDetail/ObjectDetailsDrawer.tsx index 4ea8cb5854b..52fc380cfcc 100644 --- a/packages/manager/src/features/ObjectStorage/BucketDetail/ObjectDetailsDrawer.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketDetail/ObjectDetailsDrawer.tsx @@ -103,6 +103,7 @@ export const ObjectDetailsDrawer = React.memo( updateAccess={(acl: ACLType) => updateObjectACL(clusterId, bucketName, name, acl) } + endpointType={endpointType} name={name} variant="object" /> diff --git a/packages/manager/src/mocks/serverHandlers.ts b/packages/manager/src/mocks/serverHandlers.ts index 8a1a0572734..67c018cf572 100644 --- a/packages/manager/src/mocks/serverHandlers.ts +++ b/packages/manager/src/mocks/serverHandlers.ts @@ -102,6 +102,7 @@ import type { CreateObjectStorageKeyPayload, FirewallStatus, NotificationType, + ObjectStorageEndpointTypes, SecurityQuestionsPayload, TokenRequest, UpdateImageRegionsPayload, @@ -970,9 +971,13 @@ export const handlers = [ const pageSize = Number(url.searchParams.get('page_size') || 25); const randomBucketNumber = getRandomWholeNumber(1, 500); + const randomEndpointType = `E${Math.floor( + Math.random() * 4 + )}` as ObjectStorageEndpointTypes; const buckets = objectStorageBucketFactoryGen2.buildList(1, { cluster: `${region}-1`, + endpoint_type: randomEndpointType, hostname: `obj-bucket-${randomBucketNumber}.${region}.linodeobjects.com`, label: `obj-bucket-${randomBucketNumber}`, region, From 79b16e62946bc3ca5dc268ae75b14f06eb7c2cc9 Mon Sep 17 00:00:00 2001 From: Jaalah Ramos Date: Thu, 22 Aug 2024 10:47:15 -0400 Subject: [PATCH 04/19] Bump version and changelog --- packages/manager/CHANGELOG.md | 6 ++++++ packages/manager/package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/manager/CHANGELOG.md b/packages/manager/CHANGELOG.md index 1ffe480881c..d56c2f42db3 100644 --- a/packages/manager/CHANGELOG.md +++ b/packages/manager/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [2024-08-22] - v1.126.1 + +### Fix: + +- Re-enable CORS for Legacy/Gen1 Endpoints ([#10812](https://github.com/linode/manager/pull/10812)) + ## [2024-08-19] - v1.126.0 ### Added: diff --git a/packages/manager/package.json b/packages/manager/package.json index 61283f897a3..7bdd288d626 100644 --- a/packages/manager/package.json +++ b/packages/manager/package.json @@ -2,7 +2,7 @@ "name": "linode-manager", "author": "Linode", "description": "The Linode Manager website", - "version": "1.126.0", + "version": "1.126.1", "private": true, "type": "module", "bugs": { From 59d35a0f0798aa72e6c0894ebb5bcc2a830184f4 Mon Sep 17 00:00:00 2001 From: Jaalah Ramos Date: Thu, 22 Aug 2024 12:02:08 -0400 Subject: [PATCH 05/19] Add unit tests --- .../BucketDetail/AccessSelect.test.tsx | 51 ++++++++++++++++--- .../BucketDetail/AccessSelect.tsx | 6 +-- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.test.tsx b/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.test.tsx index ca35a26adb6..c9c21715175 100644 --- a/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.test.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.test.tsx @@ -4,7 +4,9 @@ import * as React from 'react'; import { renderWithTheme } from 'src/utilities/testHelpers'; -import { AccessSelect, Props } from './AccessSelect'; +import { AccessSelect } from './AccessSelect'; + +import type { Props } from './AccessSelect'; vi.mock('src/components/EnhancedSelect/Select'); @@ -12,14 +14,18 @@ const mockGetAccess = vi.fn(); const mockUpdateAccess = vi.fn(); const props: Props = { - getAccess: mockGetAccess.mockResolvedValue({ acl: 'private' }), + endpointType: 'E1', + getAccess: mockGetAccess.mockResolvedValue({ + acl: 'private', + cors_enabled: true, + }), name: 'my-object-name', updateAccess: mockUpdateAccess.mockResolvedValue({}), - variant: 'object', + variant: 'bucket', }; describe('AccessSelect', () => { - it('shows the access', async () => { + it('shows the access and CORS toggle for bucket variant', async () => { renderWithTheme(); const aclSelect = screen.getByRole('combobox'); @@ -39,9 +45,14 @@ describe('AccessSelect', () => { 'aria-selected', 'true' ); + + expect(screen.getByLabelText('CORS Enabled')).toBeInTheDocument(); + expect( + screen.getByRole('checkbox', { name: 'CORS Enabled' }) + ).toBeChecked(); }); - it('updates the access and submits the appropriate value', async () => { + it('updates the access and CORS settings and submits the appropriate values', async () => { renderWithTheme(); const aclSelect = screen.getByRole('combobox'); @@ -52,20 +63,48 @@ describe('AccessSelect', () => { expect(aclSelect).toHaveValue('Private'); }); + const corsToggle = screen.getByRole('checkbox', { name: 'CORS Enabled' }); + + // Verify initial state + expect(corsToggle).toBeChecked(); + act(() => { fireEvent.click(aclSelect); fireEvent.change(aclSelect, { target: { value: 'Authenticated Read' } }); }); - expect(aclSelect).toHaveValue('Authenticated Read'); userEvent.click(screen.getByText('Authenticated Read')); + userEvent.click(corsToggle); await waitFor(() => { expect(screen.getByRole('combobox')).toHaveValue('Authenticated Read'); + expect(corsToggle).not.toBeChecked(); expect(saveButton).toBeEnabled(); }); + fireEvent.click(saveButton); + expect(mockUpdateAccess).toHaveBeenCalledWith('authenticated-read', false); + + // Test toggling CORS back on + userEvent.click(corsToggle); + + await waitFor(() => { + expect(corsToggle).toBeChecked(); + }); + fireEvent.click(saveButton); expect(mockUpdateAccess).toHaveBeenCalledWith('authenticated-read', true); }); + + it('does not show CORS toggle for E2 and E3 endpoint types', async () => { + renderWithTheme(); + await waitFor(() => { + expect(screen.queryByLabelText('CORS Enabled')).not.toBeInTheDocument(); + }); + + renderWithTheme(); + await waitFor(() => { + expect(screen.queryByLabelText('CORS Enabled')).not.toBeInTheDocument(); + }); + }); }); diff --git a/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.tsx b/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.tsx index 7040509edfb..c3e5250e3c0 100644 --- a/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.tsx @@ -141,7 +141,7 @@ export const AccessSelect = React.memo((props: Props) => { ? 'CORS Enabled' : 'CORS Disabled'; - const isCorsEnabled = + const isCorsAvailable = (variant === 'bucket' || variant === 'object') && endpointType !== 'E2' && endpointType !== 'E3'; @@ -187,7 +187,7 @@ export const AccessSelect = React.memo((props: Props) => { ) : null} - {isCorsEnabled ? ( + {isCorsAvailable ? ( { /> ) : null} - {isCorsEnabled ? ( + {isCorsAvailable ? ( Whether Cross-Origin Resource Sharing is enabled for all origins. For more fine-grained control of CORS, please use another{' '} From d703bf6306c421f2b74bbadb184635f08232b516 Mon Sep 17 00:00:00 2001 From: jdamore-linode <97627410+jdamore-linode@users.noreply.github.com> Date: Thu, 22 Aug 2024 12:04:28 -0400 Subject: [PATCH 06/19] test: [M3-8458] - Fix StackScripts pagination test failure (#10811) * Filter StackScripts response data similarly to Cloud to fix content assertion failure * Rename `smoke-community-stackscrips.spec.ts` to `smoke-community-stackscripts.spec.ts` * Added changeset: Resolve StackScripts pagination test failure --- .../pr-10811-tests-1724336950451.md | 5 + ...s => smoke-community-stackscripts.spec.ts} | 112 ++++++++++++------ 2 files changed, 80 insertions(+), 37 deletions(-) create mode 100644 packages/manager/.changeset/pr-10811-tests-1724336950451.md rename packages/manager/cypress/e2e/core/stackscripts/{smoke-community-stackscrips.spec.ts => smoke-community-stackscripts.spec.ts} (80%) diff --git a/packages/manager/.changeset/pr-10811-tests-1724336950451.md b/packages/manager/.changeset/pr-10811-tests-1724336950451.md new file mode 100644 index 00000000000..6f4175005c7 --- /dev/null +++ b/packages/manager/.changeset/pr-10811-tests-1724336950451.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Tests +--- + +Resolve StackScripts pagination test failure ([#10811](https://github.com/linode/manager/pull/10811)) diff --git a/packages/manager/cypress/e2e/core/stackscripts/smoke-community-stackscrips.spec.ts b/packages/manager/cypress/e2e/core/stackscripts/smoke-community-stackscripts.spec.ts similarity index 80% rename from packages/manager/cypress/e2e/core/stackscripts/smoke-community-stackscrips.spec.ts rename to packages/manager/cypress/e2e/core/stackscripts/smoke-community-stackscripts.spec.ts index d30c17acd52..43ae5fa6dc0 100644 --- a/packages/manager/cypress/e2e/core/stackscripts/smoke-community-stackscrips.spec.ts +++ b/packages/manager/cypress/e2e/core/stackscripts/smoke-community-stackscripts.spec.ts @@ -1,21 +1,25 @@ -import { authenticate } from 'support/api/authentication'; +import type { StackScript } from '@linode/api-v4'; +import { Profile, getImages, getProfile } from '@linode/api-v4'; + import { stackScriptFactory } from 'src/factories'; +import { isLinodeKubeImageId } from 'src/store/image/image.helpers'; +import { formatDate } from 'src/utilities/formatDate'; + +import { authenticate } from 'support/api/authentication'; +import { interceptCreateLinode } from 'support/intercepts/linodes'; +import { mockGetUserPreferences } from 'support/intercepts/profile'; import { interceptGetStackScripts, - mockGetStackScripts, mockGetStackScript, + mockGetStackScripts, } from 'support/intercepts/stackscripts'; import { ui } from 'support/ui'; +import { cleanUp } from 'support/util/cleanup'; +import { depaginate } from 'support/util/paginate'; import { randomLabel, randomString } from 'support/util/random'; import { chooseRegion } from 'support/util/regions'; -import { cleanUp } from 'support/util/cleanup'; -import { interceptCreateLinode } from 'support/intercepts/linodes'; -import { getProfile } from '@linode/api-v4'; -import { Profile } from '@linode/api-v4'; -import { formatDate } from '@src/utilities/formatDate'; -import type { StackScript } from '@linode/api-v4'; -import { mockGetUserPreferences } from 'support/intercepts/profile'; +import type { Image } from '@linode/api-v4'; const mockStackScripts: StackScript[] = [ stackScriptFactory.build({ @@ -187,37 +191,71 @@ describe('Community Stackscripts integration tests', () => { */ it('pagination works with infinite scrolling', () => { interceptGetStackScripts().as('getStackScripts'); - cy.visitWithLogin('/stackscripts/community'); - cy.wait('@getStackScripts'); - // Confirm that empty state is not shown. - cy.get('[data-qa-stackscript-empty-msg="true"]').should('not.exist'); - cy.findByText('Automate deployment scripts').should('not.exist'); - - // Confirm that scrolling to the bottom of the StackScripts list causes - // pagination to occur automatically. Perform this check 3 times. - for (let i = 0; i < 3; i += 1) { - cy.findByLabelText('List of StackScripts') - .should('be.visible') - .within(() => { - // Scroll to the bottom of the StackScripts list, confirm Cloud fetches StackScripts, - // then confirm that list updates with the new StackScripts shown. - cy.get('tr').last().scrollIntoView(); - cy.wait('@getStackScripts').then((xhr) => { - const stackScripts = xhr.response?.body['data'] as - | StackScript[] - | undefined; - if (!stackScripts) { - throw new Error( - 'Unexpected response received when fetching StackScripts' + // Fetch all public Images to later use while filtering StackScripts. + cy.defer(() => + depaginate((page) => getImages({ page }, { is_public: true })) + ).then((publicImages: Image[]) => { + cy.visitWithLogin('/stackscripts/community'); + cy.wait('@getStackScripts'); + + // Confirm that empty state is not shown. + cy.get('[data-qa-stackscript-empty-msg="true"]').should('not.exist'); + cy.findByText('Automate deployment scripts').should('not.exist'); + + // Confirm that scrolling to the bottom of the StackScripts list causes + // pagination to occur automatically. Perform this check 3 times. + for (let i = 0; i < 3; i += 1) { + cy.findByLabelText('List of StackScripts') + .should('be.visible') + .within(() => { + // Scroll to the bottom of the StackScripts list, confirm Cloud fetches StackScripts, + // then confirm that list updates with the new StackScripts shown. + cy.get('tr').last().scrollIntoView(); + cy.wait('@getStackScripts').then((xhr) => { + const stackScripts = xhr.response?.body['data'] as + | StackScript[] + | undefined; + + if (!stackScripts) { + throw new Error( + 'Unexpected response received when fetching StackScripts' + ); + } + + // Cloud Manager hides certain StackScripts from the landing page (although they can + // still be found via search). It does this if either condition is met: + // + // - The StackScript is only compatible with deprecated Images + // - The StackScript is only compatible with LKE Images + // + // As a consequence, we can't use the API response directly to assert + // that content is shown in the list. We need to apply identical filters + // to the response first, then assert the content using that data. + const filteredStackScripts = stackScripts.filter( + (stackScript: StackScript) => { + const hasNonDeprecatedImages = stackScript.images.some( + (stackScriptImage) => { + return !!publicImages.find( + (publicImage) => publicImage.id === stackScriptImage + ); + } + ); + + const usesKubeImage = stackScript.images.some( + (stackScriptImage) => isLinodeKubeImageId(stackScriptImage) + ); + return hasNonDeprecatedImages && !usesKubeImage; + } ); - } - cy.contains( - `${stackScripts[0].username} / ${stackScripts[0].label}` - ).should('be.visible'); + + cy.contains( + `${filteredStackScripts[0].username} / ${filteredStackScripts[0].label}` + ).should('be.visible'); + }); }); - }); - } + } + }); }); /* From 07db98593ad0aa12a25146862d3ea01e5599ecc9 Mon Sep 17 00:00:00 2001 From: Jaalah Ramos Date: Thu, 22 Aug 2024 12:44:02 -0400 Subject: [PATCH 07/19] Re-worked tests --- .../BucketDetail/AccessSelect.test.tsx | 154 +++++++++++------- 1 file changed, 93 insertions(+), 61 deletions(-) diff --git a/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.test.tsx b/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.test.tsx index c9c21715175..bd7b58082c9 100644 --- a/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.test.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketDetail/AccessSelect.test.tsx @@ -1,5 +1,5 @@ import { act, fireEvent, screen, waitFor } from '@testing-library/react'; -import { userEvent } from '@testing-library/user-event'; +import userEvent from '@testing-library/user-event'; import * as React from 'react'; import { renderWithTheme } from 'src/utilities/testHelpers'; @@ -7,53 +7,90 @@ import { renderWithTheme } from 'src/utilities/testHelpers'; import { AccessSelect } from './AccessSelect'; import type { Props } from './AccessSelect'; +import type { ObjectStorageEndpointTypes } from '@linode/api-v4'; + +const CORS_ENABLED_TEXT = 'CORS Enabled'; +const AUTHENTICATED_READ_TEXT = 'Authenticated Read'; vi.mock('src/components/EnhancedSelect/Select'); -const mockGetAccess = vi.fn(); -const mockUpdateAccess = vi.fn(); +const mockGetAccess = vi.fn().mockResolvedValue({ + acl: 'private', + cors_enabled: true, +}); +const mockUpdateAccess = vi.fn().mockResolvedValue({}); -const props: Props = { +const defaultProps: Props = { endpointType: 'E1', - getAccess: mockGetAccess.mockResolvedValue({ - acl: 'private', - cors_enabled: true, - }), + getAccess: mockGetAccess, name: 'my-object-name', - updateAccess: mockUpdateAccess.mockResolvedValue({}), + updateAccess: mockUpdateAccess, variant: 'bucket', }; describe('AccessSelect', () => { - it('shows the access and CORS toggle for bucket variant', async () => { - renderWithTheme(); - const aclSelect = screen.getByRole('combobox'); - - // Confirm that combobox input field value is 'Private'. - await waitFor(() => { - expect(aclSelect).toBeEnabled(); - expect(aclSelect).toHaveValue('Private'); - }); + const renderComponent = (props: Partial = {}) => + renderWithTheme(); - // Confirm that 'Private' is selected upon opening the Autocomplete drop-down. - act(() => { - fireEvent.click(aclSelect); - fireEvent.change(aclSelect, { target: { value: 'P' } }); - }); - - expect(screen.getByText('Private').closest('li')!).toHaveAttribute( - 'aria-selected', - 'true' - ); - - expect(screen.getByLabelText('CORS Enabled')).toBeInTheDocument(); - expect( - screen.getByRole('checkbox', { name: 'CORS Enabled' }) - ).toBeChecked(); + beforeEach(() => { + vi.clearAllMocks(); }); + it.each([ + ['bucket', 'E0', true], + ['bucket', 'E1', true], + ['bucket', 'E2', false], + ['bucket', 'E3', false], + ['object', 'E0', true], + ['object', 'E1', true], + ['object', 'E2', false], + ['object', 'E3', false], + ])( + 'shows correct UI for %s variant and %s endpoint type', + async (variant, endpointType, shouldShowCORS) => { + renderComponent({ + endpointType: endpointType as ObjectStorageEndpointTypes, + variant: variant as 'bucket' | 'object', + }); + + const aclSelect = screen.getByRole('combobox'); + + await waitFor(() => { + expect(aclSelect).toBeEnabled(); + expect(aclSelect).toHaveValue('Private'); + }); + + act(() => { + fireEvent.click(aclSelect); + fireEvent.change(aclSelect, { target: { value: 'P' } }); + }); + + expect(screen.getByText('Private').closest('li')).toHaveAttribute( + 'aria-selected', + 'true' + ); + + if (shouldShowCORS) { + await waitFor(() => { + expect(screen.getByLabelText(CORS_ENABLED_TEXT)).toBeInTheDocument(); + }); + await waitFor(() => { + expect( + screen.getByRole('checkbox', { name: CORS_ENABLED_TEXT }) + ).toBeChecked(); + }); + } else { + await waitFor(() => { + expect( + screen.queryByLabelText(CORS_ENABLED_TEXT) + ).not.toBeInTheDocument(); + }); + } + } + ); + it('updates the access and CORS settings and submits the appropriate values', async () => { - renderWithTheme(); + renderComponent(); const aclSelect = screen.getByRole('combobox'); const saveButton = screen.getByText('Save').closest('button')!; @@ -63,48 +100,43 @@ describe('AccessSelect', () => { expect(aclSelect).toHaveValue('Private'); }); - const corsToggle = screen.getByRole('checkbox', { name: 'CORS Enabled' }); - - // Verify initial state + // Wait for CORS toggle to appear and be checked + const corsToggle = await screen.findByRole('checkbox', { + name: CORS_ENABLED_TEXT, + }); expect(corsToggle).toBeChecked(); act(() => { + // Open the dropdown fireEvent.click(aclSelect); - fireEvent.change(aclSelect, { target: { value: 'Authenticated Read' } }); + + // Type to filter options + fireEvent.change(aclSelect, { + target: { value: AUTHENTICATED_READ_TEXT }, + }); }); - userEvent.click(screen.getByText('Authenticated Read')); - userEvent.click(corsToggle); + // Wait for and select the "Authenticated Read" option + const authenticatedReadOption = await screen.findByText( + AUTHENTICATED_READ_TEXT + ); + await userEvent.click(authenticatedReadOption); + + await userEvent.click(corsToggle); await waitFor(() => { - expect(screen.getByRole('combobox')).toHaveValue('Authenticated Read'); + expect(aclSelect).toHaveValue(AUTHENTICATED_READ_TEXT); expect(corsToggle).not.toBeChecked(); expect(saveButton).toBeEnabled(); }); - fireEvent.click(saveButton); + await userEvent.click(saveButton); expect(mockUpdateAccess).toHaveBeenCalledWith('authenticated-read', false); - // Test toggling CORS back on - userEvent.click(corsToggle); - - await waitFor(() => { - expect(corsToggle).toBeChecked(); - }); + await userEvent.click(corsToggle); + await waitFor(() => expect(corsToggle).toBeChecked()); - fireEvent.click(saveButton); + await userEvent.click(saveButton); expect(mockUpdateAccess).toHaveBeenCalledWith('authenticated-read', true); }); - - it('does not show CORS toggle for E2 and E3 endpoint types', async () => { - renderWithTheme(); - await waitFor(() => { - expect(screen.queryByLabelText('CORS Enabled')).not.toBeInTheDocument(); - }); - - renderWithTheme(); - await waitFor(() => { - expect(screen.queryByLabelText('CORS Enabled')).not.toBeInTheDocument(); - }); - }); }); From a4435150f9a15ded777a4aee54d3c99fa8d92cda Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 15:23:09 -0400 Subject: [PATCH 08/19] build(deps): Bump axios from 1.6.8 to 1.7.4 (#10799) Bumps [axios](https://github.com/axios/axios) from 1.6.8 to 1.7.4. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.6.8...v1.7.4) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- packages/api-v4/package.json | 2 +- packages/manager/package.json | 2 +- yarn.lock | 123 ++++++++++++++-------------------- 3 files changed, 51 insertions(+), 76 deletions(-) diff --git a/packages/api-v4/package.json b/packages/api-v4/package.json index a0ea63982d6..af45e71a5c2 100644 --- a/packages/api-v4/package.json +++ b/packages/api-v4/package.json @@ -41,7 +41,7 @@ "unpkg": "./lib/index.global.js", "dependencies": { "@linode/validation": "*", - "axios": "~1.6.8", + "axios": "~1.7.4", "ipaddr.js": "^2.0.0", "yup": "^0.32.9" }, diff --git a/packages/manager/package.json b/packages/manager/package.json index fc80707287b..d4a170aec97 100644 --- a/packages/manager/package.json +++ b/packages/manager/package.json @@ -30,7 +30,7 @@ "@tanstack/react-query": "4.36.1", "@tanstack/react-query-devtools": "4.36.1", "algoliasearch": "^4.14.3", - "axios": "~1.6.8", + "axios": "~1.7.4", "braintree-web": "^3.92.2", "chart.js": "~2.9.4", "copy-to-clipboard": "^3.0.8", diff --git a/yarn.lock b/yarn.lock index db0eb12fd97..a98054d3224 100644 --- a/yarn.lock +++ b/yarn.lock @@ -234,12 +234,12 @@ "@jridgewell/trace-mapping" "^0.3.25" jsesc "^2.5.1" -"@babel/generator@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.7.tgz#1654d01de20ad66b4b4d99c135471bc654c55e6d" - integrity sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA== +"@babel/generator@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.0.tgz#f858ddfa984350bc3d3b7f125073c9af6988f18e" + integrity sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw== dependencies: - "@babel/types" "^7.24.7" + "@babel/types" "^7.25.0" "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" jsesc "^2.5.1" @@ -324,13 +324,6 @@ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== -"@babel/helper-environment-visitor@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz#4b31ba9551d1f90781ba83491dd59cf9b269f7d9" - integrity sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ== - dependencies: - "@babel/types" "^7.24.7" - "@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" @@ -339,14 +332,6 @@ "@babel/template" "^7.22.15" "@babel/types" "^7.23.0" -"@babel/helper-function-name@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz#75f1e1725742f39ac6584ee0b16d94513da38dd2" - integrity sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA== - dependencies: - "@babel/template" "^7.24.7" - "@babel/types" "^7.24.7" - "@babel/helper-hoist-variables@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" @@ -354,13 +339,6 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-hoist-variables@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz#b4ede1cde2fd89436397f30dc9376ee06b0f25ee" - integrity sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ== - dependencies: - "@babel/types" "^7.24.7" - "@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" @@ -490,13 +468,6 @@ dependencies: "@babel/types" "^7.24.5" -"@babel/helper-split-export-declaration@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz#83949436890e07fa3d6873c61a96e3bbf692d856" - integrity sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA== - dependencies: - "@babel/types" "^7.24.7" - "@babel/helper-string-parser@^7.23.4": version "7.23.4" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" @@ -507,10 +478,10 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e" integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ== -"@babel/helper-string-parser@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz#4d2d0f14820ede3b9807ea5fc36dfc8cd7da07f2" - integrity sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg== +"@babel/helper-string-parser@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" + integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== "@babel/helper-validator-identifier@^7.22.20": version "7.22.20" @@ -603,10 +574,12 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790" integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg== -"@babel/parser@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85" - integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw== +"@babel/parser@^7.25.0", "@babel/parser@^7.25.3": + version "7.25.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.3.tgz#91fb126768d944966263f0657ab222a642b82065" + integrity sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw== + dependencies: + "@babel/types" "^7.25.2" "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.24.5": version "7.24.5" @@ -1397,28 +1370,25 @@ "@babel/parser" "^7.24.0" "@babel/types" "^7.24.0" -"@babel/template@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.7.tgz#02efcee317d0609d2c07117cb70ef8fb17ab7315" - integrity sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig== +"@babel/template@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.0.tgz#e733dc3134b4fede528c15bc95e89cb98c52592a" + integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q== dependencies: "@babel/code-frame" "^7.24.7" - "@babel/parser" "^7.24.7" - "@babel/types" "^7.24.7" + "@babel/parser" "^7.25.0" + "@babel/types" "^7.25.0" "@babel/traverse@^7.18.9", "@babel/traverse@^7.23.3", "@babel/traverse@^7.23.9", "@babel/traverse@^7.24.1", "@babel/traverse@^7.24.5", "@babel/traverse@^7.7.0": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.7.tgz#de2b900163fa741721ba382163fe46a936c40cf5" - integrity sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA== + version "7.25.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.3.tgz#f1b901951c83eda2f3e29450ce92743783373490" + integrity sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ== dependencies: "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.24.7" - "@babel/helper-environment-visitor" "^7.24.7" - "@babel/helper-function-name" "^7.24.7" - "@babel/helper-hoist-variables" "^7.24.7" - "@babel/helper-split-export-declaration" "^7.24.7" - "@babel/parser" "^7.24.7" - "@babel/types" "^7.24.7" + "@babel/generator" "^7.25.0" + "@babel/parser" "^7.25.3" + "@babel/template" "^7.25.0" + "@babel/types" "^7.25.2" debug "^4.3.1" globals "^11.1.0" @@ -1449,12 +1419,12 @@ "@babel/helper-validator-identifier" "^7.24.5" to-fast-properties "^2.0.0" -"@babel/types@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.7.tgz#6027fe12bc1aa724cd32ab113fb7f1988f1f66f2" - integrity sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q== +"@babel/types@^7.25.0", "@babel/types@^7.25.2": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.2.tgz#55fb231f7dc958cd69ea141a4c2997e819646125" + integrity sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q== dependencies: - "@babel/helper-string-parser" "^7.24.7" + "@babel/helper-string-parser" "^7.24.8" "@babel/helper-validator-identifier" "^7.24.7" to-fast-properties "^2.0.0" @@ -5263,10 +5233,10 @@ axios-mock-adapter@^1.22.0: fast-deep-equal "^3.1.3" is-buffer "^2.0.5" -axios@~1.6.8: - version "1.6.8" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66" - integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ== +axios@~1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2" + integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw== dependencies: follow-redirects "^1.15.6" form-data "^4.0.0" @@ -11337,7 +11307,7 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== -"prettier-fallback@npm:prettier@^3", prettier@^3.1.1: +"prettier-fallback@npm:prettier@^3": version "3.2.5" resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== @@ -11349,6 +11319,11 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" +prettier@^3.1.1: + version "3.2.5" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" + integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== + prettier@~2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" @@ -12509,9 +12484,9 @@ semver-compare@^1.0.0: integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== "semver@2 || 3 || 4 || 5", semver@7.6.0, semver@^5.5.0, semver@^5.6.0, semver@^6.0.0, semver@^6.1.0, semver@^6.1.2, semver@^6.3.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.7, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4: - version "7.6.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" - integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== send@0.18.0: version "0.18.0" @@ -14411,9 +14386,9 @@ yallist@^4.0.0: integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yaml@2.3.1, yaml@^1.10.0, yaml@^1.7.2, yaml@^2.2.2, yaml@^2.3.0, yaml@^2.3.4: - version "2.4.5" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.5.tgz#60630b206dd6d84df97003d33fc1ddf6296cca5e" - integrity sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg== + version "2.5.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.0.tgz#c6165a721cf8000e91c36490a41d7be25176cf5d" + integrity sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw== yargs-parser@^11.1.1, yargs-parser@^21.1.1: version "21.1.1" From 7e9277015f19e4193c224892eee2a0394c504d20 Mon Sep 17 00:00:00 2001 From: Dajahi Wiley <114682940+dwiley-akamai@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:15:30 -0400 Subject: [PATCH 09/19] =?UTF-8?q?upcoming:=20[M3-8370]=20=E2=80=93=20Add?= =?UTF-8?q?=20"Encryption"=20column=20to=20Linode=20Volumes=20table=20(#10?= =?UTF-8?q?793)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...r-10793-upcoming-features-1723845275155.md | 5 + .../LinodeStorage/LinodeVolumes.test.tsx | 113 ++++++++++++++++++ .../LinodeStorage/LinodeVolumes.tsx | 19 ++- .../src/features/Volumes/VolumeTableRow.tsx | 2 +- 4 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 packages/manager/.changeset/pr-10793-upcoming-features-1723845275155.md create mode 100644 packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeVolumes.test.tsx diff --git a/packages/manager/.changeset/pr-10793-upcoming-features-1723845275155.md b/packages/manager/.changeset/pr-10793-upcoming-features-1723845275155.md new file mode 100644 index 00000000000..af5e1c985df --- /dev/null +++ b/packages/manager/.changeset/pr-10793-upcoming-features-1723845275155.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Upcoming Features +--- + +Add "Encryption" column to Linode Volumes table ([#10793](https://github.com/linode/manager/pull/10793)) diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeVolumes.test.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeVolumes.test.tsx new file mode 100644 index 00000000000..05cf8a05dc7 --- /dev/null +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeVolumes.test.tsx @@ -0,0 +1,113 @@ +import * as React from 'react'; + +import { accountFactory, linodeFactory, volumeFactory } from 'src/factories'; +import { makeResourcePage } from 'src/mocks/serverHandlers'; +import { HttpResponse, http, server } from 'src/mocks/testServer'; +import { renderWithTheme } from 'src/utilities/testHelpers'; + +import { LinodeVolumes } from './LinodeVolumes'; + +const accountEndpoint = '*/v4/account'; +const linodeInstanceEndpoint = '*/linode/instances/:id'; +const linodeVolumesEndpoint = '*/linode/instances/:id/volumes'; + +describe('LinodeVolumes', () => { + const volumes = volumeFactory.buildList(3); + + it('should render', async () => { + server.use( + http.get(linodeInstanceEndpoint, () => { + return HttpResponse.json(linodeFactory.build()); + }), + http.get(linodeVolumesEndpoint, () => { + return HttpResponse.json(makeResourcePage(volumes)); + }) + ); + + const { findByText } = renderWithTheme(); + + expect(await findByText('Volumes')).toBeVisible(); + }); + + /* @TODO BSE: Remove feature flagging/conditionality once BSE is fully rolled out */ + it('should display an "Encryption" column if the user has the account capability and the feature flag is on', async () => { + server.use( + http.get(accountEndpoint, () => { + return HttpResponse.json( + accountFactory.build({ + capabilities: ['Block Storage Encryption'], + }) + ); + }) + ); + + server.use( + http.get(linodeInstanceEndpoint, () => { + return HttpResponse.json(linodeFactory.build()); + }), + http.get(linodeVolumesEndpoint, () => { + return HttpResponse.json(makeResourcePage(volumes)); + }) + ); + + const { findByText } = renderWithTheme(, { + flags: { blockStorageEncryption: true }, + }); + + expect(await findByText('Encryption')).toBeVisible(); + }); + + it('should not display an "Encryption" column if the user has the account capability but the feature flag is off', async () => { + server.use( + http.get(accountEndpoint, () => { + return HttpResponse.json( + accountFactory.build({ + capabilities: ['Block Storage Encryption'], + }) + ); + }) + ); + + server.use( + http.get(linodeInstanceEndpoint, () => { + return HttpResponse.json(linodeFactory.build()); + }), + http.get(linodeVolumesEndpoint, () => { + return HttpResponse.json(makeResourcePage(volumes)); + }) + ); + + const { queryByText } = renderWithTheme(, { + flags: { blockStorageEncryption: false }, + }); + + expect(queryByText('Encryption')).toBeNull(); + }); + + it('should not display an "Encryption" column if the feature flag is on but the user does not have the account capability', async () => { + server.use( + http.get(accountEndpoint, () => { + return HttpResponse.json( + accountFactory.build({ + capabilities: [], + }) + ); + }) + ); + + server.use( + http.get(linodeInstanceEndpoint, () => { + return HttpResponse.json(linodeFactory.build()); + }), + http.get(linodeVolumesEndpoint, () => { + return HttpResponse.json(makeResourcePage(volumes)); + }) + ); + + const { queryByText } = renderWithTheme(, { + flags: { blockStorageEncryption: true }, + }); + + expect(queryByText('Encryption')).toBeNull(); + }); +}); diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeVolumes.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeVolumes.tsx index e4318991856..c8d7e1b3b81 100644 --- a/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeVolumes.tsx +++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodeStorage/LinodeVolumes.tsx @@ -3,6 +3,7 @@ import { useParams } from 'react-router-dom'; import { Box } from 'src/components/Box'; import { Button } from 'src/components/Button/Button'; +import { useIsBlockStorageEncryptionFeatureEnabled } from 'src/components/Encryption/utils'; import { Hidden } from 'src/components/Hidden'; import { PaginationFooter } from 'src/components/PaginationFooter/PaginationFooter'; import { Paper } from 'src/components/Paper'; @@ -73,6 +74,10 @@ export const LinodeVolumes = () => { filter ); + const { + isBlockStorageEncryptionFeatureEnabled, + } = useIsBlockStorageEncryptionFeatureEnabled(); + const [selectedVolumeId, setSelectedVolumeId] = React.useState(); const [isDetailsDrawerOpen, setIsDetailsDrawerOpen] = React.useState(false); const [isEditDrawerOpen, setIsEditDrawerOpen] = React.useState(false); @@ -124,6 +129,8 @@ export const LinodeVolumes = () => { return null; } + const numColumns = isBlockStorageEncryptionFeatureEnabled ? 6 : 5; // @TODO BSE: set colSpan for to 6 once BSE is fully rolled out + const renderTableContent = () => { if (isLoading) { return ( @@ -131,14 +138,16 @@ export const LinodeVolumes = () => { responsive={{ 3: { xsDown: true }, }} - columns={5} + columns={numColumns} rows={1} /> ); } else if (error) { return ; } else if (data?.results === 0) { - return ; + return ( + + ); } else if (data) { return data.data.map((volume) => { return ( @@ -153,6 +162,9 @@ export const LinodeVolumes = () => { handleResize: () => handleResize(volume), handleUpgrade: () => null, }} + isBlockStorageEncryptionFeatureEnabled={ + isBlockStorageEncryptionFeatureEnabled + } isDetailsPageRow key={volume.id} volume={volume} @@ -215,6 +227,9 @@ export const LinodeVolumes = () => { File System Path + {isBlockStorageEncryptionFeatureEnabled && ( + Encryption + )} diff --git a/packages/manager/src/features/Volumes/VolumeTableRow.tsx b/packages/manager/src/features/Volumes/VolumeTableRow.tsx index 25094ad7042..c7e680cb990 100644 --- a/packages/manager/src/features/Volumes/VolumeTableRow.tsx +++ b/packages/manager/src/features/Volumes/VolumeTableRow.tsx @@ -141,7 +141,7 @@ export const VolumeTableRow = React.memo((props: Props) => { )} {volume.size} GB {!isVolumesLanding && ( - + {volume.filesystem_path} From 3104637f4b949d42d33c8a90031b87515b044a5a Mon Sep 17 00:00:00 2001 From: Dajahi Wiley <114682940+dwiley-akamai@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:28:33 -0400 Subject: [PATCH 10/19] =?UTF-8?q?upcoming:=20[M3-8455]=20=E2=80=93=20Add?= =?UTF-8?q?=20"Encrypt=20Volume"=20checkbox=20in=20Clone=20Volume=20drawer?= =?UTF-8?q?=20(#10803)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...r-10803-upcoming-features-1724100276144.md | 5 ++ .../src/components/Encryption/constants.tsx | 3 + .../Volumes/CloneVolumeDrawer.test.tsx | 83 +++++++++++++++++++ .../features/Volumes/CloneVolumeDrawer.tsx | 26 +++++- .../Volumes/VolumeDrawer/PricePanel.tsx | 2 +- 5 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 packages/manager/.changeset/pr-10803-upcoming-features-1724100276144.md create mode 100644 packages/manager/src/features/Volumes/CloneVolumeDrawer.test.tsx diff --git a/packages/manager/.changeset/pr-10803-upcoming-features-1724100276144.md b/packages/manager/.changeset/pr-10803-upcoming-features-1724100276144.md new file mode 100644 index 00000000000..3fa7cdbabd1 --- /dev/null +++ b/packages/manager/.changeset/pr-10803-upcoming-features-1724100276144.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Upcoming Features +--- + +Add 'Encrypt Volume' checkbox to Clone Volume drawer ([#10803](https://github.com/linode/manager/pull/10803)) diff --git a/packages/manager/src/components/Encryption/constants.tsx b/packages/manager/src/components/Encryption/constants.tsx index e484b2eafc1..4d93f9f3a8d 100644 --- a/packages/manager/src/components/Encryption/constants.tsx +++ b/packages/manager/src/components/Encryption/constants.tsx @@ -98,3 +98,6 @@ export const BLOCK_STORAGE_USER_SIDE_ENCRYPTION_CAVEAT = export const BLOCK_STORAGE_ENCRYPTION_SETTING_IMMUTABLE_COPY = 'The encryption setting cannot be changed after creation.'; + +export const BLOCK_STORAGE_CLONING_INHERITANCE_CAVEAT = + 'Encryption is inherited from the source volume and cannot be changed when cloning volumes.'; diff --git a/packages/manager/src/features/Volumes/CloneVolumeDrawer.test.tsx b/packages/manager/src/features/Volumes/CloneVolumeDrawer.test.tsx new file mode 100644 index 00000000000..ad7ed3e90fe --- /dev/null +++ b/packages/manager/src/features/Volumes/CloneVolumeDrawer.test.tsx @@ -0,0 +1,83 @@ +import { waitFor } from '@testing-library/react'; +import * as React from 'react'; + +import { accountFactory, volumeFactory } from 'src/factories'; +import { HttpResponse, http, server } from 'src/mocks/testServer'; +import { renderWithTheme } from 'src/utilities/testHelpers'; + +import { CloneVolumeDrawer } from './CloneVolumeDrawer'; + +const accountEndpoint = '*/v4/account'; +const encryptionLabelText = 'Encrypt Volume'; + +describe('CloneVolumeDrawer', () => { + /* @TODO BSE: Remove feature flagging/conditionality once BSE is fully rolled out */ + + it('should display a disabled checkbox for volume encryption if the user has the account capability and the feature flag is on', async () => { + const volume = volumeFactory.build(); + + server.use( + http.get(accountEndpoint, () => { + return HttpResponse.json( + accountFactory.build({ capabilities: ['Block Storage Encryption'] }) + ); + }) + ); + + const { getByLabelText } = renderWithTheme( + , + { + flags: { blockStorageEncryption: true }, + } + ); + + await waitFor(() => { + expect(getByLabelText(encryptionLabelText)).not.toBeNull(); + expect(getByLabelText(encryptionLabelText)).toBeDisabled(); + }); + }); + + it('should not display a checkbox for volume encryption if the user has the account capability but the feature flag is off', async () => { + const volume = volumeFactory.build(); + + server.use( + http.get(accountEndpoint, () => { + return HttpResponse.json( + accountFactory.build({ capabilities: ['Block Storage Encryption'] }) + ); + }) + ); + + const { queryByRole } = renderWithTheme( + , + { + flags: { blockStorageEncryption: false }, + } + ); + + await waitFor(() => { + expect(queryByRole('checkbox')).not.toBeInTheDocument(); + }); + }); + + it('should not display a checkbox for volume encryption if the feature flag is on but the user lacks the account capability', async () => { + const volume = volumeFactory.build(); + + server.use( + http.get(accountEndpoint, () => { + return HttpResponse.json(accountFactory.build({ capabilities: [] })); + }) + ); + + const { queryByRole } = renderWithTheme( + , + { + flags: { blockStorageEncryption: true }, + } + ); + + await waitFor(() => { + expect(queryByRole('checkbox')).not.toBeInTheDocument(); + }); + }); +}); diff --git a/packages/manager/src/features/Volumes/CloneVolumeDrawer.tsx b/packages/manager/src/features/Volumes/CloneVolumeDrawer.tsx index 9304ab01c1f..4d4d6b7845d 100644 --- a/packages/manager/src/features/Volumes/CloneVolumeDrawer.tsx +++ b/packages/manager/src/features/Volumes/CloneVolumeDrawer.tsx @@ -1,10 +1,13 @@ -import { Volume } from '@linode/api-v4'; import { CloneVolumeSchema } from '@linode/validation/lib/volumes.schema'; import { useFormik } from 'formik'; import * as React from 'react'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; +import { Box } from 'src/components/Box'; +import { Checkbox } from 'src/components/Checkbox'; import { Drawer } from 'src/components/Drawer'; +import { BLOCK_STORAGE_CLONING_INHERITANCE_CAVEAT } from 'src/components/Encryption/constants'; +import { useIsBlockStorageEncryptionFeatureEnabled } from 'src/components/Encryption/utils'; import { Notice } from 'src/components/Notice/Notice'; import { TextField } from 'src/components/TextField'; import { Typography } from 'src/components/Typography'; @@ -21,6 +24,8 @@ import { import { PRICES_RELOAD_ERROR_NOTICE_TEXT } from 'src/utilities/pricing/constants'; import { PricePanel } from './VolumeDrawer/PricePanel'; + +import type { Volume } from '@linode/api-v4'; interface Props { onClose: () => void; open: boolean; @@ -39,6 +44,10 @@ export const CloneVolumeDrawer = (props: Props) => { const { data: grants } = useGrants(); const { data: types, isError, isLoading } = useVolumeTypesQuery(); + const { + isBlockStorageEncryptionFeatureEnabled, + } = useIsBlockStorageEncryptionFeatureEnabled(); + // Even if a restricted user has the ability to create Volumes, they // can't clone a Volume they only have read only permission on. const isReadOnly = @@ -108,6 +117,21 @@ export const CloneVolumeDrawer = (props: Props) => { required value={values.label} /> + {isBlockStorageEncryptionFeatureEnabled && ( + + + + )} { } return ( - + ); From 15e35060f41e6b28b4f07fdf1330c3fbc68e631a Mon Sep 17 00:00:00 2001 From: nikhagra <165884194+nikhagra@users.noreply.github.com> Date: Fri, 23 Aug 2024 21:13:01 +0530 Subject: [PATCH 11/19] upcoming: [DI-20284] - Added support for multiple services in the dashboards list (#10805) --- ...r-10805-upcoming-features-1724163902024.md | 5 ++ packages/api-v4/src/cloudpulse/dashboards.ts | 8 ++- packages/api-v4/src/cloudpulse/services.ts | 14 ++++- packages/api-v4/src/cloudpulse/types.ts | 10 +++- ...r-10805-upcoming-features-1724163948287.md | 5 ++ .../CloudPulseDashboardLanding.test.tsx | 20 +++---- .../CloudPulse/Utils/CloudPulseWidgetUtils.ts | 2 +- .../CloudPulse/Utils/UserPreference.ts | 10 +++- .../src/features/CloudPulse/Utils/utils.ts | 55 ++++++++++++++++++- .../shared/CloudPulseDashboardSelect.test.tsx | 38 +++++++++---- .../shared/CloudPulseDashboardSelect.tsx | 53 ++++++++++++------ .../shared/CloudPulseResourcesSelect.tsx | 6 ++ packages/manager/src/mocks/serverHandlers.ts | 9 ++- .../src/queries/cloudpulse/dashboards.ts | 17 ++++-- .../manager/src/queries/cloudpulse/metrics.ts | 1 + .../manager/src/queries/cloudpulse/queries.ts | 9 ++- .../src/queries/cloudpulse/services.ts | 8 +++ 17 files changed, 215 insertions(+), 55 deletions(-) create mode 100644 packages/api-v4/.changeset/pr-10805-upcoming-features-1724163902024.md create mode 100644 packages/manager/.changeset/pr-10805-upcoming-features-1724163948287.md diff --git a/packages/api-v4/.changeset/pr-10805-upcoming-features-1724163902024.md b/packages/api-v4/.changeset/pr-10805-upcoming-features-1724163902024.md new file mode 100644 index 00000000000..46b8dd2d56c --- /dev/null +++ b/packages/api-v4/.changeset/pr-10805-upcoming-features-1724163902024.md @@ -0,0 +1,5 @@ +--- +"@linode/api-v4": Upcoming Features +--- + +Change resource_id to resource_ids in CloudPulseMetricRequest interface and add two new interfaces. Add getCloudPulseServiceTypes to fetch list of service types & modify getDashboards function to accept serviceType parameter ([#10805](https://github.com/linode/manager/pull/10805)) diff --git a/packages/api-v4/src/cloudpulse/dashboards.ts b/packages/api-v4/src/cloudpulse/dashboards.ts index 90b4d4ef010..32b9bbf3c31 100644 --- a/packages/api-v4/src/cloudpulse/dashboards.ts +++ b/packages/api-v4/src/cloudpulse/dashboards.ts @@ -4,9 +4,13 @@ import { Dashboard } from './types'; import { API_ROOT } from 'src/constants'; // Returns the list of all the dashboards available -export const getDashboards = () => +export const getDashboards = (serviceType: string) => Request>( - setURL(`${API_ROOT}/monitor/services/linode/dashboards`), + setURL( + `${API_ROOT}/monitor/services/${encodeURIComponent( + serviceType + )}/dashboards` + ), setMethod('GET') ); diff --git a/packages/api-v4/src/cloudpulse/services.ts b/packages/api-v4/src/cloudpulse/services.ts index f8d884d572a..0ace1f4ceea 100644 --- a/packages/api-v4/src/cloudpulse/services.ts +++ b/packages/api-v4/src/cloudpulse/services.ts @@ -1,6 +1,11 @@ import { API_ROOT } from 'src/constants'; import Request, { setData, setMethod, setURL } from '../request'; -import { JWEToken, JWETokenPayLoad, MetricDefinitions } from './types'; +import { + JWEToken, + JWETokenPayLoad, + MetricDefinitions, + ServiceTypesList, +} from './types'; import { ResourcePage as Page } from 'src/types'; export const getMetricDefinitionsByServiceType = (serviceType: string) => { @@ -22,3 +27,10 @@ export const getJWEToken = (data: JWETokenPayLoad, serviceType: string) => setMethod('POST'), setData(data) ); + +// Returns the list of service types available +export const getCloudPulseServiceTypes = () => + Request( + setURL(`${API_ROOT}/monitor/services`), + setMethod('GET') + ); diff --git a/packages/api-v4/src/cloudpulse/types.ts b/packages/api-v4/src/cloudpulse/types.ts index edac74eec6d..2c9c7f57662 100644 --- a/packages/api-v4/src/cloudpulse/types.ts +++ b/packages/api-v4/src/cloudpulse/types.ts @@ -103,7 +103,7 @@ export interface CloudPulseMetricsRequest { group_by: string; relative_time_duration: TimeDuration; time_granularity: TimeGranularity | undefined; - resource_id: number[]; + resource_ids: number[]; } export interface CloudPulseMetricsResponse { @@ -124,3 +124,11 @@ export interface CloudPulseMetricsList { metric: { [resourceName: string]: string }; values: [number, string][]; } + +export interface ServiceTypes { + service_type: string; +} + +export interface ServiceTypesList { + data: ServiceTypes[]; +} diff --git a/packages/manager/.changeset/pr-10805-upcoming-features-1724163948287.md b/packages/manager/.changeset/pr-10805-upcoming-features-1724163948287.md new file mode 100644 index 00000000000..9c34b95554a --- /dev/null +++ b/packages/manager/.changeset/pr-10805-upcoming-features-1724163948287.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Upcoming Features +--- + +Modify CloudPulseDashboardSelect and its relevant queries to support multiple service types in the list ([#10805](https://github.com/linode/manager/pull/10805)) diff --git a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.test.tsx b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.test.tsx index a9da8e55f29..d54a52a0500 100644 --- a/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.test.tsx +++ b/packages/manager/src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding.test.tsx @@ -2,6 +2,7 @@ import { fireEvent } from '@testing-library/react'; import React from 'react'; import { dashboardFactory } from 'src/factories'; +import * as utils from 'src/features/CloudPulse/Utils/utils'; import { renderWithTheme } from 'src/utilities/testHelpers'; import { CloudPulseDashboardLanding } from './CloudPulseDashboardLanding'; @@ -30,18 +31,21 @@ vi.mock('src/queries/cloudpulse/dashboards', async () => { useCloudPulseDashboardsQuery: queryMocks.useCloudPulseDashboardsQuery, }; }); +const mockDashboard = dashboardFactory.build(); queryMocks.useCloudPulseDashboardsQuery.mockReturnValue({ data: { - data: dashboardFactory.buildList(1, { - label: dashboardLabel, - service_type: 'test', - }), + data: mockDashboard, }, error: false, isLoading: false, }); +vi.spyOn(utils, 'getAllDashboards').mockReturnValue({ + data: [mockDashboard], + error: '', + isLoading: false, +}); describe('CloudPulseDashboardFilterBuilder component tests', () => { it('should render error placeholder if dashboard not selected', () => { const screen = renderWithTheme(); @@ -66,14 +70,6 @@ describe('CloudPulseDashboardFilterBuilder component tests', () => { expect( screen.getByRole('option', { name: dashboardLabel }) ).toBeInTheDocument(); - - fireEvent.click(screen.getByRole('option', { name: dashboardLabel })); - - expect( - screen.getByText( - "No Filters Configured for selected dashboard's service type" - ) - ).toBeDefined(); }); it('should render error placeholder if some dashboard is select and filters are not selected', () => { diff --git a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts index 3ac3a87b3f0..fef6da64c10 100644 --- a/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/CloudPulseWidgetUtils.ts @@ -245,7 +245,7 @@ export const getCloudPulseMetricRequest = ( group_by: widget.group_by, metric: widget.metric, relative_time_duration: duration ?? widget.time_duration, - resource_id: resources + resource_ids: resources ? resourceIds.map((obj) => parseInt(obj, 10)) : widget.resource_id.map((obj) => parseInt(obj, 10)), time_granularity: diff --git a/packages/manager/src/features/CloudPulse/Utils/UserPreference.ts b/packages/manager/src/features/CloudPulse/Utils/UserPreference.ts index 175a0d0f2e8..326dd5aebb2 100644 --- a/packages/manager/src/features/CloudPulse/Utils/UserPreference.ts +++ b/packages/manager/src/features/CloudPulse/Utils/UserPreference.ts @@ -3,6 +3,8 @@ import { usePreferences, } from 'src/queries/profile/preferences'; +import { DASHBOARD_ID, TIME_DURATION } from './constants'; + import type { AclpConfig, AclpWidget } from '@linode/api-v4'; let userPreference: AclpConfig; @@ -42,7 +44,13 @@ export const updateGlobalFilterPreference = (data: {}) => { if (!userPreference) { userPreference = {} as AclpConfig; } - userPreference = { ...userPreference, ...data }; + const keys = Object.keys(data); + + if (keys.includes(DASHBOARD_ID)) { + userPreference = { ...data, [TIME_DURATION]: userPreference.timeDuration }; + } else { + userPreference = { ...userPreference, ...data }; + } debounce(userPreference); }; diff --git a/packages/manager/src/features/CloudPulse/Utils/utils.ts b/packages/manager/src/features/CloudPulse/Utils/utils.ts index 6f4088ac991..2004ba5af41 100644 --- a/packages/manager/src/features/CloudPulse/Utils/utils.ts +++ b/packages/manager/src/features/CloudPulse/Utils/utils.ts @@ -3,7 +3,15 @@ import { useFlags } from 'src/hooks/useFlags'; import { useAccount } from 'src/queries/account/account'; import { isFeatureEnabledV2 } from 'src/utilities/accountCapabilities'; -import type { TimeDuration } from '@linode/api-v4'; +import type { + APIError, + Dashboard, + ResourcePage, + ServiceTypes, + ServiceTypesList, + TimeDuration, +} from '@linode/api-v4'; +import type { UseQueryResult } from '@tanstack/react-query'; import type { StatWithDummyPoint, WithStartAndEnd, @@ -105,3 +113,48 @@ export const seriesDataFormatter = ( return convertData(formattedArray, startTime, endTime); }; + +/** + * + * @param rawServiceTypes list of service types returned from api response + * @returns converted service types list into string array + */ +export const formattedServiceTypes = ( + rawServiceTypes: ServiceTypesList | undefined +): string[] => { + if (rawServiceTypes === undefined || rawServiceTypes.data.length === 0) { + return []; + } + return rawServiceTypes.data.map((obj: ServiceTypes) => obj.service_type); +}; + +/** + * + * @param queryResults queryResults received from useCloudPulseDashboardsQuery + * @param serviceTypes list of service types available + * @returns list of dashboards for all the service types & respective loading and error states + */ +export const getAllDashboards = ( + queryResults: UseQueryResult, APIError[]>[], + serviceTypes: string[] +) => { + let error = ''; + let isLoading = false; + const data: Dashboard[] = queryResults + .filter((queryResult: UseQueryResult, index) => { + if (queryResult.isError) { + error += serviceTypes[index] + ' ,'; + } + if (queryResult.isLoading) { + isLoading = true; + } + return !queryResult.isLoading && !queryResult.isError; + }) + .map((queryResult) => queryResult?.data?.data ?? []) + .flat(); + return { + data, + error, + isLoading, + }; +}; diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDashboardSelect.test.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDashboardSelect.test.tsx index c3b58a27ec4..1ff706d78d5 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDashboardSelect.test.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDashboardSelect.test.tsx @@ -1,6 +1,8 @@ import { fireEvent, screen } from '@testing-library/react'; import React from 'react'; +import { dashboardFactory } from 'src/factories'; +import * as utils from 'src/features/CloudPulse/Utils/utils'; import { renderWithTheme } from 'src/utilities/testHelpers'; import { DASHBOARD_ID } from '../Utils/constants'; @@ -10,14 +12,16 @@ import { CloudPulseDashboardSelect } from './CloudPulseDashboardSelect'; import type { CloudPulseDashboardSelectProps } from './CloudPulseDashboardSelect'; import type { AclpConfig } from '@linode/api-v4'; -const dashboardLabel = 'Dashboard 1'; +const dashboardLabel = 'Factory Dashboard-1'; const props: CloudPulseDashboardSelectProps = { handleDashboardChange: vi.fn(), }; const queryMocks = vi.hoisted(() => ({ useCloudPulseDashboardsQuery: vi.fn().mockReturnValue({}), + useCloudPulseServiceTypes: vi.fn().mockReturnValue({}), })); +const mockDashboard = dashboardFactory.build(); vi.mock('src/queries/cloudpulse/dashboards', async () => { const actual = await vi.importActual('src/queries/cloudpulse/dashboards'); @@ -27,24 +31,34 @@ vi.mock('src/queries/cloudpulse/dashboards', async () => { }; }); +vi.mock('src/queries/cloudpulse/services', async () => { + const actual = await vi.importActual('src/queries/cloudpulse/services'); + return { + ...actual, + useCloudPulseServiceTypes: queryMocks.useCloudPulseServiceTypes, + }; +}); + queryMocks.useCloudPulseDashboardsQuery.mockReturnValue({ data: { - data: [ - { - created: '2024-04-29T17:09:29', - id: 1, - label: dashboardLabel, - service_type: 'linode', - type: 'standard', - updated: null, - widgets: {}, - }, - ], + data: [mockDashboard], }, error: false, isLoading: false, }); +queryMocks.useCloudPulseServiceTypes.mockReturnValue({ + data: { + data: [{ service_type: 'linode' }], + }, +}); + +vi.spyOn(utils, 'getAllDashboards').mockReturnValue({ + data: [mockDashboard], + error: '', + isLoading: false, +}); + describe('CloudPulse Dashboard select', () => { it('Should render dashboard select component', () => { const { getByPlaceholderText, getByTestId } = renderWithTheme( diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDashboardSelect.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDashboardSelect.tsx index 1559c72ca08..6b62eba2ea2 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDashboardSelect.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDashboardSelect.tsx @@ -4,12 +4,14 @@ import { Autocomplete } from 'src/components/Autocomplete/Autocomplete'; import { Box } from 'src/components/Box'; import { Typography } from 'src/components/Typography'; import { useCloudPulseDashboardsQuery } from 'src/queries/cloudpulse/dashboards'; +import { useCloudPulseServiceTypes } from 'src/queries/cloudpulse/services'; -import { DASHBOARD_ID, REGION, RESOURCES } from '../Utils/constants'; +import { DASHBOARD_ID } from '../Utils/constants'; import { getUserPreferenceObject, updateGlobalFilterPreference, } from '../Utils/UserPreference'; +import { formattedServiceTypes, getAllDashboards } from '../Utils/utils'; import type { Dashboard } from '@linode/api-v4'; @@ -23,35 +25,57 @@ export interface CloudPulseDashboardSelectProps { export const CloudPulseDashboardSelect = React.memo( (props: CloudPulseDashboardSelectProps) => { const { - data: dashboardsList, - error, - isLoading, - } = useCloudPulseDashboardsQuery(true); // Fetch the list of dashboards + data: serviceTypesList, + error: serviceTypesError, + isLoading: serviceTypesLoading, + } = useCloudPulseServiceTypes(true); + + const serviceTypes: string[] = formattedServiceTypes(serviceTypesList); + const { + data: dashboardsList, + error: dashboardsError, + isLoading: dashboardsLoading, + } = getAllDashboards( + useCloudPulseDashboardsQuery(serviceTypes), + serviceTypes + ); const [ selectedDashboard, setSelectedDashboard, ] = React.useState(); - const errorText: string = error ? 'Error loading dashboards' : ''; + const getErrorText = () => { + if (serviceTypesError) { + return 'Unable to load service types'; + } + + if (dashboardsError.length > 0) { + return `Unable to load ${dashboardsError.slice(0, -1)}`; + } + + return ''; + }; + + const errorText: string = getErrorText(); const placeHolder = 'Select a Dashboard'; // sorts dashboards by service type. Required due to unexpected autocomplete grouping behaviour - const getSortedDashboardsList = (options: Dashboard[]) => { + const getSortedDashboardsList = (options: Dashboard[]): Dashboard[] => { return options.sort( (a, b) => -b.service_type.localeCompare(a.service_type) ); }; - // Once the data is loaded, set the state variable with value stored in preferences React.useEffect(() => { - if (dashboardsList) { + // only call this code when the component is rendered initially + if (dashboardsList.length > 0 && selectedDashboard === undefined) { const dashboardId = getUserPreferenceObject()?.dashboardId; if (dashboardId) { - const dashboard = dashboardsList.data.find( - (obj) => obj.id === dashboardId + const dashboard = dashboardsList.find( + (obj: Dashboard) => obj.id === dashboardId ); setSelectedDashboard(dashboard); props.handleDashboardChange(dashboard, true); @@ -61,14 +85,11 @@ export const CloudPulseDashboardSelect = React.memo( } // eslint-disable-next-line react-hooks/exhaustive-deps }, [dashboardsList]); - return ( { updateGlobalFilterPreference({ [DASHBOARD_ID]: dashboard?.id, - [REGION]: undefined, - [RESOURCES]: undefined, }); setSelectedDashboard(dashboard); props.handleDashboardChange(dashboard); @@ -96,8 +117,8 @@ export const CloudPulseDashboardSelect = React.memo( groupBy={(option: Dashboard) => option.service_type} isOptionEqualToValue={(option, value) => option.id === value.id} label="Select a Dashboard" - loading={isLoading} - options={getSortedDashboardsList(dashboardsList?.data ?? [])} + loading={dashboardsLoading || serviceTypesLoading} + options={getSortedDashboardsList(dashboardsList ?? [])} placeholder={placeHolder} value={selectedDashboard ?? null} // Undefined is not allowed for uncontrolled component /> diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseResourcesSelect.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseResourcesSelect.tsx index e97a58909c8..3245d9c211f 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseResourcesSelect.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseResourcesSelect.tsx @@ -90,6 +90,12 @@ export const CloudPulseResourcesSelect = React.memo( handleResourcesSelection(resourceSelections); }} textFieldProps={{ + InputProps: { + sx: { + maxHeight: '55px', + overflow: 'auto', + }, + }, hideLabel: true, }} autoHighlight diff --git a/packages/manager/src/mocks/serverHandlers.ts b/packages/manager/src/mocks/serverHandlers.ts index 67c018cf572..5d66dcc0d6b 100644 --- a/packages/manager/src/mocks/serverHandlers.ts +++ b/packages/manager/src/mocks/serverHandlers.ts @@ -2272,7 +2272,14 @@ export const handlers = [ return HttpResponse.json(response); }), - http.get('*/v4/monitor/services/linode/dashboards', () => { + http.get('*/v4/monitor/services', () => { + const response = { + data: [{ service_type: 'linode' }], + }; + + return HttpResponse.json(response); + }), + http.get('*/v4/monitor/services/:serviceType/dashboards', () => { const response = { data: [ { diff --git a/packages/manager/src/queries/cloudpulse/dashboards.ts b/packages/manager/src/queries/cloudpulse/dashboards.ts index 0a12f16aa54..493c14f387b 100644 --- a/packages/manager/src/queries/cloudpulse/dashboards.ts +++ b/packages/manager/src/queries/cloudpulse/dashboards.ts @@ -1,15 +1,22 @@ -import { useQuery } from '@tanstack/react-query'; +import { useQueries, useQuery } from '@tanstack/react-query'; import { queryFactory } from './queries'; import type { Dashboard } from '@linode/api-v4'; import type { APIError, ResourcePage } from '@linode/api-v4/lib/types'; +import type { UseQueryOptions } from '@tanstack/react-query'; // Fetch the list of all the dashboard available -export const useCloudPulseDashboardsQuery = (enabled: boolean) => { - return useQuery, APIError[]>({ - ...queryFactory.lists._ctx.dashboards, - enabled, +export const useCloudPulseDashboardsQuery = (serviceTypes: string[]) => { + return useQueries({ + queries: serviceTypes.map< + UseQueryOptions, APIError[]> + >((serviceType) => ({ + ...queryFactory.lists._ctx.dashboards(serviceType), + enabled: serviceTypes.length > 0, + refetchOnWindowFocus: false, + retry: 0, + })), }); }; diff --git a/packages/manager/src/queries/cloudpulse/metrics.ts b/packages/manager/src/queries/cloudpulse/metrics.ts index 58599872e7c..de200c3c040 100644 --- a/packages/manager/src/queries/cloudpulse/metrics.ts +++ b/packages/manager/src/queries/cloudpulse/metrics.ts @@ -71,6 +71,7 @@ export const fetchCloudPulseMetrics = ( const config: AxiosRequestConfig = { data: requestData, headers: { + 'Authentication-Type': 'jwe', Authorization: `Bearer ${token}`, }, method: 'POST', diff --git a/packages/manager/src/queries/cloudpulse/queries.ts b/packages/manager/src/queries/cloudpulse/queries.ts index e21707e31e3..74bb3ec7e2b 100644 --- a/packages/manager/src/queries/cloudpulse/queries.ts +++ b/packages/manager/src/queries/cloudpulse/queries.ts @@ -1,4 +1,5 @@ import { + getCloudPulseServiceTypes, getDashboardById, getDashboards, getJWEToken, @@ -27,8 +28,12 @@ export const queryFactory = createQueryKeys(key, { }), lists: { contextQueries: { - dashboards: { - queryFn: getDashboards, + dashboards: (serviceType: string) => ({ + queryFn: () => getDashboards(serviceType), + queryKey: [serviceType], + }), + serviceTypes: { + queryFn: getCloudPulseServiceTypes, queryKey: null, }, }, diff --git a/packages/manager/src/queries/cloudpulse/services.ts b/packages/manager/src/queries/cloudpulse/services.ts index 8428613c2c1..410d9938cd6 100644 --- a/packages/manager/src/queries/cloudpulse/services.ts +++ b/packages/manager/src/queries/cloudpulse/services.ts @@ -7,6 +7,7 @@ import type { JWEToken, JWETokenPayLoad, MetricDefinitions, + ServiceTypesList, } from '@linode/api-v4'; export const useGetCloudPulseMetricDefinitionsByServiceType = ( @@ -31,3 +32,10 @@ export const useCloudPulseJWEtokenQuery = ( refetchOnWindowFocus: false, }); }; + +export const useCloudPulseServiceTypes = (enabled: boolean) => { + return useQuery({ + ...queryFactory.lists._ctx.serviceTypes, + enabled, + }); +}; From 43366acd98123008a093f63fcd407518459a8d39 Mon Sep 17 00:00:00 2001 From: Purvesh Makode Date: Fri, 23 Aug 2024 22:22:04 +0530 Subject: [PATCH 12/19] feat: [M3-8170] - Add CheckoutBar Story (#10784) --- .../pr-10784-added-1723651941893.md | 5 ++ .../CheckoutBar/CheckoutBar.stories.tsx | 70 +++++++++++++++++++ .../components/CheckoutBar/CheckoutBar.tsx | 34 +++++++++ 3 files changed, 109 insertions(+) create mode 100644 packages/manager/.changeset/pr-10784-added-1723651941893.md create mode 100644 packages/manager/src/components/CheckoutBar/CheckoutBar.stories.tsx diff --git a/packages/manager/.changeset/pr-10784-added-1723651941893.md b/packages/manager/.changeset/pr-10784-added-1723651941893.md new file mode 100644 index 00000000000..3d28dae816f --- /dev/null +++ b/packages/manager/.changeset/pr-10784-added-1723651941893.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Added +--- + +CheckoutBar Story ([#10784](https://github.com/linode/manager/pull/10784)) diff --git a/packages/manager/src/components/CheckoutBar/CheckoutBar.stories.tsx b/packages/manager/src/components/CheckoutBar/CheckoutBar.stories.tsx new file mode 100644 index 00000000000..85976149c20 --- /dev/null +++ b/packages/manager/src/components/CheckoutBar/CheckoutBar.stories.tsx @@ -0,0 +1,70 @@ +import React from 'react'; + +import { Typography } from 'src/components/Typography'; + +import { CheckoutBar } from './CheckoutBar'; + +import type { Meta, StoryFn, StoryObj } from '@storybook/react'; + +type Story = StoryObj; + +const Item = ({ children }: { children?: React.ReactNode }) => ( + {children} +); + +const defaultArgs = { + calculatedPrice: 30.0, + children: Child items can go here!, + heading: 'Checkout', + onDeploy: () => alert('Deploy clicked'), + submitText: 'Submit', +}; + +const meta: Meta = { + argTypes: { + onDeploy: { action: 'onDeploy' }, + }, + component: CheckoutBar, + decorators: [ + (Story: StoryFn) => ( +
+ +
+ ), + ], + title: 'Components/CheckoutBar', +}; + +export default meta; + +export const Default: Story = { + args: defaultArgs, +}; + +export const WithAgreement: Story = { + args: { + ...defaultArgs, + agreement: Agreement item can go here!, + }, +}; + +export const Disabled: Story = { + args: { + ...defaultArgs, + disabled: true, + }, +}; + +export const Loading: Story = { + args: { + ...defaultArgs, + isMakingRequest: true, + }, +}; + +export const WithFooter: Story = { + args: { + ...defaultArgs, + footer: Footer element can go here!, + }, +}; diff --git a/packages/manager/src/components/CheckoutBar/CheckoutBar.tsx b/packages/manager/src/components/CheckoutBar/CheckoutBar.tsx index 492bf4558c8..3d8ffdde20e 100644 --- a/packages/manager/src/components/CheckoutBar/CheckoutBar.tsx +++ b/packages/manager/src/components/CheckoutBar/CheckoutBar.tsx @@ -12,16 +12,50 @@ import { } from './styles'; interface CheckoutBarProps { + /** + * JSX element to be displayed as an agreement section. + */ agreement?: JSX.Element; + /** + * Calculated price to be displayed. + */ calculatedPrice?: number; + /** + * JSX element for additional content to be rendered within the component. + */ children?: JSX.Element; + /** + * Boolean to disable the `CheckoutBar` component, making it non-interactive. + * @default false + */ disabled?: boolean; + /** + * JSX element to be displayed as a footer. + */ footer?: JSX.Element; + /** + * The heading text to be displayed in the `CheckoutBar`. + */ heading: string; + /** + * Boolean indicating if a request is currently being processed. + */ isMakingRequest?: boolean; + /** + * Callback function to be called when the deploy action is triggered. + */ onDeploy: () => void; + /** + * Helper text to be displayed alongside the price. + */ priceHelperText?: string; + /** + * Text to describe the price selection. + */ priceSelectionText?: string; + /** + * Text for the submit button. + */ submitText?: string; } From fbf256a0a98b615eb0c0e121e1d878b0d155e8f8 Mon Sep 17 00:00:00 2001 From: Harsh Shankar Rao Date: Fri, 23 Aug 2024 22:51:14 +0530 Subject: [PATCH 13/19] upcoming: [M3-8305] - Display Endpoint Type alongside each endpoint hostname in Regions Column & Hostnames Drawers (#10796) --- ...r-10796-upcoming-features-1724152512210.md | 5 +++ .../AccessKeyTable/AccessKeyTable.styles.tsx | 21 ++++++++++ .../AccessKeyTable/AccessKeyTable.tsx | 28 ++++++------- .../AccessKeyTable/AccessKeyTableRow.tsx | 16 ++++---- .../AccessKeyTable/HostNameTableCell.tsx | 4 +- .../AccessKeyLanding/HostNamesDrawer.tsx | 40 ++++++++++++------- 6 files changed, 78 insertions(+), 36 deletions(-) create mode 100644 packages/manager/.changeset/pr-10796-upcoming-features-1724152512210.md create mode 100644 packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTable.styles.tsx diff --git a/packages/manager/.changeset/pr-10796-upcoming-features-1724152512210.md b/packages/manager/.changeset/pr-10796-upcoming-features-1724152512210.md new file mode 100644 index 00000000000..c3649a92a72 --- /dev/null +++ b/packages/manager/.changeset/pr-10796-upcoming-features-1724152512210.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Upcoming Features +--- + +Display Endpoint Type alongside each endpoint hostname in Regions Column & Hostnames Drawers ([#10796](https://github.com/linode/manager/pull/10796)) diff --git a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTable.styles.tsx b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTable.styles.tsx new file mode 100644 index 00000000000..49feb92bdd8 --- /dev/null +++ b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTable.styles.tsx @@ -0,0 +1,21 @@ +import { styled } from '@mui/material'; + +import { TableCell } from 'src/components/TableCell'; +import { omittedProps } from 'src/utilities/omittedProps'; + +import type { TableCellProps } from 'src/components/TableCell'; + +interface StyledLastColumnCellProps extends TableCellProps { + addPaddingRight?: boolean; +} +export const StyledLastColumnCell = styled(TableCell, { + shouldForwardProp: omittedProps(['isObjMultiClusterEnabled']), +})(({ addPaddingRight }) => ({ + '&&:last-child': { + 'padding-right': addPaddingRight ? '15px' : 0, + }, +})); + +export const StyledLabelCell = styled(TableCell)(() => ({ + width: '35%', +})); diff --git a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTable.tsx b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTable.tsx index 121dead1fc6..d39ecf5cb58 100644 --- a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTable.tsx +++ b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTable.tsx @@ -1,14 +1,7 @@ -import { - ObjectStorageKey, - ObjectStorageKeyRegions, -} from '@linode/api-v4/lib/object-storage'; -import { APIError } from '@linode/api-v4/lib/types'; -import { styled } from '@mui/material/styles'; import React, { useState } from 'react'; import { Table } from 'src/components/Table'; import { TableBody } from 'src/components/TableBody'; -import { TableCell } from 'src/components/TableCell'; import { TableHead } from 'src/components/TableHead'; import { TableRow } from 'src/components/TableRow'; import { useAccountManagement } from 'src/hooks/useAccountManagement'; @@ -16,9 +9,16 @@ import { useFlags } from 'src/hooks/useFlags'; import { isFeatureEnabledV2 } from 'src/utilities/accountCapabilities'; import { HostNamesDrawer } from '../HostNamesDrawer'; -import { OpenAccessDrawer } from '../types'; +import { StyledLabelCell, StyledLastColumnCell } from './AccessKeyTable.styles'; import { AccessKeyTableBody } from './AccessKeyTableBody'; +import type { OpenAccessDrawer } from '../types'; +import type { + ObjectStorageKey, + ObjectStorageKeyRegions, +} from '@linode/api-v4/lib/object-storage'; +import type { APIError } from '@linode/api-v4/lib/types'; + export interface AccessKeyTableProps { data: ObjectStorageKey[] | undefined; error: APIError[] | null | undefined; @@ -69,8 +69,12 @@ export const AccessKeyTable = (props: AccessKeyTableProps) => { Regions/S3 Hostnames )} - {/* empty cell for kebab menu */} - + + Actions + @@ -96,7 +100,3 @@ export const AccessKeyTable = (props: AccessKeyTableProps) => { ); }; - -const StyledLabelCell = styled(TableCell)(() => ({ - width: '35%', -})); diff --git a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTableRow.tsx b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTableRow.tsx index 92ea578fb46..76eb64490bb 100644 --- a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTableRow.tsx +++ b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/AccessKeyTableRow.tsx @@ -1,7 +1,3 @@ -import { - ObjectStorageKey, - ObjectStorageKeyRegions, -} from '@linode/api-v4/lib/object-storage'; import { styled } from '@mui/material/styles'; import React from 'react'; @@ -13,10 +9,16 @@ import { useAccountManagement } from 'src/hooks/useAccountManagement'; import { useFlags } from 'src/hooks/useFlags'; import { isFeatureEnabledV2 } from 'src/utilities/accountCapabilities'; -import { OpenAccessDrawer } from '../types'; import { AccessKeyActionMenu } from './AccessKeyActionMenu'; +import { StyledLastColumnCell } from './AccessKeyTable.styles'; import { HostNameTableCell } from './HostNameTableCell'; +import type { OpenAccessDrawer } from '../types'; +import type { + ObjectStorageKey, + ObjectStorageKeyRegions, +} from '@linode/api-v4/lib/object-storage'; + type Props = { openDrawer: OpenAccessDrawer; openRevokeDialog: (storageKeyData: ObjectStorageKey) => void; @@ -62,14 +64,14 @@ export const AccessKeyTableRow = ({ /> )} - + - + ); }; diff --git a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/HostNameTableCell.tsx b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/HostNameTableCell.tsx index ca4e0fbb6e5..14f0595acca 100644 --- a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/HostNameTableCell.tsx +++ b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/AccessKeyTable/HostNameTableCell.tsx @@ -34,10 +34,12 @@ export const HostNameTableCell = ({ } const label = regionsLookup[storageKeyData.regions[0].id]?.label; const s3Endpoint = storageKeyData?.regions[0]?.s3_endpoint; + const endpointType = storageKeyData?.regions[0]?.endpoint_type; return ( - {label}: {s3Endpoint} + {label} + {endpointType && ` (${endpointType})`}: {s3Endpoint}  {storageKeyData?.regions?.length === 1 && ( )} diff --git a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/HostNamesDrawer.tsx b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/HostNamesDrawer.tsx index c6f22605603..96944066b59 100644 --- a/packages/manager/src/features/ObjectStorage/AccessKeyLanding/HostNamesDrawer.tsx +++ b/packages/manager/src/features/ObjectStorage/AccessKeyLanding/HostNamesDrawer.tsx @@ -1,4 +1,3 @@ -import { ObjectStorageKeyRegions } from '@linode/api-v4'; import * as React from 'react'; import { Box } from 'src/components/Box'; @@ -9,6 +8,8 @@ import { getRegionsByRegionId } from 'src/utilities/regions'; import { CopyAllHostnames } from './CopyAllHostnames'; +import type { ObjectStorageKeyRegions } from '@linode/api-v4'; + interface Props { onClose: () => void; open: boolean; @@ -30,10 +31,13 @@ export const HostNamesDrawer = (props: Props) => { - `${regionsLookup[region.id]?.label}: ${region.s3_endpoint}` - ) + .map((region) => { + const label = regionsLookup[region.id]?.label; + const endpointType = region.endpoint_type + ? ` (${region.endpoint_type})` + : ''; + return `${label}${endpointType}: ${region.s3_endpoint}`; + }) .join('\n') ?? '' } /> @@ -45,15 +49,23 @@ export const HostNamesDrawer = (props: Props) => { padding: theme.spacing(1), })} > - {regions.map((region, index) => ( - - ))} + {regions.map((region, index) => { + const endpointTypeLabel = region?.endpoint_type + ? ` (${region.endpoint_type})` + : ''; + + return ( + + ); + })}
); From b6659648b8aab6d43f4d4cb95e15bc37ef53b04e Mon Sep 17 00:00:00 2001 From: corya-akamai <136115382+corya-akamai@users.noreply.github.com> Date: Fri, 23 Aug 2024 13:56:30 -0400 Subject: [PATCH 14/19] feat: [UIE-8054] - DBaaS enhancements 1 (#10786) * feat: [UIE-8054] - DBaaS enhancements 1 * Added changeset: Update DBaaS menu item with V1 or V2 capability, add mock data * Review comments * feature flag * review comments * review comments * review comments * review comments --- .../pr-10786-added-1723662117687.md | 5 ++ packages/api-v4/src/account/types.ts | 1 + packages/api-v4/src/databases/types.ts | 4 +- packages/api-v4/src/regions/types.ts | 1 + ...r-10786-upcoming-features-1723662207016.md | 5 ++ packages/manager/src/__data__/regionsData.ts | 5 ++ packages/manager/src/assets/icons/db-logo.svg | 23 +++++++ .../src/components/PrimaryNav/PrimaryNav.tsx | 4 +- .../manager/src/dev-tools/FeatureFlagTool.tsx | 2 + packages/manager/src/factories/account.ts | 2 +- packages/manager/src/factories/databases.ts | 66 ++++++++++++++----- packages/manager/src/featureFlags.ts | 1 + .../DatabaseCreate/DatabaseCreate.tsx | 18 +---- .../DatabaseResize/DatabaseResize.test.tsx | 4 +- ...atabaseResizeCurrentConfiguration.test.tsx | 4 +- .../DatabaseLanding/DatabaseLogo.tsx | 43 ++++++++++++ .../src/features/Databases/utilities.test.ts | 38 ++++++++++- .../src/features/Databases/utilities.ts | 14 +++- packages/manager/src/mocks/serverHandlers.ts | 2 +- 19 files changed, 197 insertions(+), 45 deletions(-) create mode 100644 packages/api-v4/.changeset/pr-10786-added-1723662117687.md create mode 100644 packages/manager/.changeset/pr-10786-upcoming-features-1723662207016.md create mode 100644 packages/manager/src/assets/icons/db-logo.svg create mode 100644 packages/manager/src/features/Databases/DatabaseLanding/DatabaseLogo.tsx diff --git a/packages/api-v4/.changeset/pr-10786-added-1723662117687.md b/packages/api-v4/.changeset/pr-10786-added-1723662117687.md new file mode 100644 index 00000000000..960ca5330b4 --- /dev/null +++ b/packages/api-v4/.changeset/pr-10786-added-1723662117687.md @@ -0,0 +1,5 @@ +--- +"@linode/api-v4": Added +--- + +Managed Databases V2` capability and types ([#10786](https://github.com/linode/manager/pull/10786)) diff --git a/packages/api-v4/src/account/types.ts b/packages/api-v4/src/account/types.ts index dad426d63d7..4e266b064e0 100644 --- a/packages/api-v4/src/account/types.ts +++ b/packages/api-v4/src/account/types.ts @@ -72,6 +72,7 @@ export type AccountCapability = | 'LKE HA Control Planes' | 'Machine Images' | 'Managed Databases' + | 'Managed Databases V2' | 'NodeBalancers' | 'Object Storage Access Key Regions' | 'Object Storage Endpoint Types' diff --git a/packages/api-v4/src/databases/types.ts b/packages/api-v4/src/databases/types.ts index 71c526be374..3221a8c61b6 100644 --- a/packages/api-v4/src/databases/types.ts +++ b/packages/api-v4/src/databases/types.ts @@ -81,9 +81,11 @@ export interface DatabaseInstance { * A key/value object where the key is an IP address and the value is a member type. */ members: Record; + platform?: string; } -export type ClusterSize = 1 | 3; +export type ClusterSize = 1 | 2 | 3; + type ReadonlyCount = 0 | 2; export type MySQLReplicationType = 'none' | 'semi_synch' | 'asynch'; diff --git a/packages/api-v4/src/regions/types.ts b/packages/api-v4/src/regions/types.ts index cb159254e95..c17934076bb 100644 --- a/packages/api-v4/src/regions/types.ts +++ b/packages/api-v4/src/regions/types.ts @@ -12,6 +12,7 @@ export type Capabilities = | 'Kubernetes' | 'Linodes' | 'Managed Databases' + | 'Managed Databases V2' | 'Metadata' | 'NodeBalancers' | 'Object Storage' diff --git a/packages/manager/.changeset/pr-10786-upcoming-features-1723662207016.md b/packages/manager/.changeset/pr-10786-upcoming-features-1723662207016.md new file mode 100644 index 00000000000..60c3e568960 --- /dev/null +++ b/packages/manager/.changeset/pr-10786-upcoming-features-1723662207016.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Upcoming Features +--- + +Update DBaaS menu item with V1 or V2 capability, add mock data ([#10786](https://github.com/linode/manager/pull/10786)) diff --git a/packages/manager/src/__data__/regionsData.ts b/packages/manager/src/__data__/regionsData.ts index 0a3ab6eaf2e..836fbcafea7 100644 --- a/packages/manager/src/__data__/regionsData.ts +++ b/packages/manager/src/__data__/regionsData.ts @@ -98,6 +98,7 @@ export const regions: Region[] = [ 'Vlans', 'VPCs', 'Managed Databases', + 'Managed Databases V2', 'Metadata', 'Premium Plans', 'Placement Group', @@ -129,6 +130,7 @@ export const regions: Region[] = [ 'Vlans', 'VPCs', 'Managed Databases', + 'Managed Databases V2', 'Metadata', 'Premium Plans', ], @@ -484,6 +486,7 @@ export const regions: Region[] = [ 'VPCs', 'Block Storage Migrations', 'Managed Databases', + 'Managed Databases V2', 'Placement Group', ], country: 'us', @@ -511,6 +514,7 @@ export const regions: Region[] = [ 'Cloud Firewall', 'Block Storage Migrations', 'Managed Databases', + 'Managed Databases V2', 'Placement Group', ], country: 'us', @@ -542,6 +546,7 @@ export const regions: Region[] = [ 'VPCs', 'Block Storage Migrations', 'Managed Databases', + 'Managed Databases V2', 'Placement Group', ], country: 'us', diff --git a/packages/manager/src/assets/icons/db-logo.svg b/packages/manager/src/assets/icons/db-logo.svg new file mode 100644 index 00000000000..5776006d284 --- /dev/null +++ b/packages/manager/src/assets/icons/db-logo.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/manager/src/components/PrimaryNav/PrimaryNav.tsx b/packages/manager/src/components/PrimaryNav/PrimaryNav.tsx index 65233b9bed3..e28aca7b644 100644 --- a/packages/manager/src/components/PrimaryNav/PrimaryNav.tsx +++ b/packages/manager/src/components/PrimaryNav/PrimaryNav.tsx @@ -187,7 +187,7 @@ export const PrimaryNav = (props: PrimaryNavProps) => { hide: !isDatabasesEnabled, href: '/databases', icon: , - isBeta: flags.databaseBeta, + isBeta: flags.dbaasV2?.beta, }, { activeLinks: ['/kubernetes/create'], @@ -249,7 +249,7 @@ export const PrimaryNav = (props: PrimaryNavProps) => { isDatabasesEnabled, isManaged, allowMarketplacePrefetch, - flags.databaseBeta, + flags.dbaasV2, isPlacementGroupsEnabled, flags.placementGroups, isACLPEnabled, diff --git a/packages/manager/src/dev-tools/FeatureFlagTool.tsx b/packages/manager/src/dev-tools/FeatureFlagTool.tsx index 3de0659ba92..67de298235c 100644 --- a/packages/manager/src/dev-tools/FeatureFlagTool.tsx +++ b/packages/manager/src/dev-tools/FeatureFlagTool.tsx @@ -32,6 +32,8 @@ const options: { flag: keyof Flags; label: string }[] = [ { flag: 'placementGroups', label: 'Placement Groups' }, { flag: 'selfServeBetas', label: 'Self Serve Betas' }, { flag: 'supportTicketSeverity', label: 'Support Ticket Severity' }, + { flag: 'dbaasV2', label: 'Databases V2 Beta' }, + { flag: 'databaseResize', label: 'Database Resize' }, ]; export const FeatureFlagTool = withFeatureFlagProvider(() => { diff --git a/packages/manager/src/factories/account.ts b/packages/manager/src/factories/account.ts index eff241f37d5..241deeea45f 100644 --- a/packages/manager/src/factories/account.ts +++ b/packages/manager/src/factories/account.ts @@ -45,7 +45,7 @@ export const accountFactory = Factory.Sync.makeFactory({ 'Linodes', 'LKE HA Control Planes', 'Machine Images', - 'Managed Databases', + 'Managed Databases V2', 'NodeBalancers', 'Object Storage Access Key Regions', 'Object Storage Endpoint Types', diff --git a/packages/manager/src/factories/databases.ts b/packages/manager/src/factories/databases.ts index b9188b54d62..87ee964126f 100644 --- a/packages/manager/src/factories/databases.ts +++ b/packages/manager/src/factories/databases.ts @@ -1,17 +1,20 @@ -import { +import { v4 } from 'uuid'; + +import Factory from 'src/factories/factoryProxy'; +import { pickRandom, randomDate } from 'src/utilities/random'; + +import type { + ClusterSize, Database, DatabaseBackup, DatabaseEngine, DatabaseInstance, DatabaseStatus, DatabaseType, + Engine, MySQLReplicationType, PostgresReplicationType, } from '@linode/api-v4/lib/databases/types'; -import Factory from 'src/factories/factoryProxy'; -import { v4 } from 'uuid'; - -import { pickRandom, randomDate } from 'src/utilities/random'; // These are not all of the possible statuses, but these are some common ones. export const possibleStatuses: DatabaseStatus[] = [ @@ -35,10 +38,35 @@ export const possiblePostgresReplicationTypes: PostgresReplicationType[] = [ 'asynch', ]; +export const possibleTypes: string[] = [ + 'g6-nanode-1', + 'g6-standard-2', + 'g6-standard-4', + 'g6-standard-6', + 'g6-standard-20', + 'g6-dedicated-32', + 'g6-dedicated-50', + 'g6-dedicated-56', + 'g6-dedicated-64', +]; + +export const possibleRegions: string[] = [ + 'ap-south', + 'ap-southeast', + 'ap-west', + 'ca-central', + 'eu-central', + 'fr-par', + 'us-east', + 'us-iad', + 'us-ord', +]; + export const IPv4List = ['192.0.2.1', '196.0.0.0', '198.0.0.2']; export const databaseTypeFactory = Factory.Sync.makeFactory({ class: 'standard', + disk: Factory.each((i) => i * 20480), engines: { mongodb: [ { @@ -134,32 +162,38 @@ export const databaseTypeFactory = Factory.Sync.makeFactory({ ], }, id: Factory.each((i) => `g6-standard-${i}`), - disk: Factory.each((i) => i * 20480), label: Factory.each((i) => `Linode ${i} GB`), memory: Factory.each((i) => i * 2048), vcpus: Factory.each((i) => i * 2), }); +const adb10 = (i: number) => i % 2 === 0; + export const databaseInstanceFactory = Factory.Sync.makeFactory( { - cluster_size: Factory.each(() => pickRandom([1, 3])), + cluster_size: Factory.each((i) => + adb10(i) + ? ([1, 3][i % 2] as ClusterSize) + : ([1, 2, 3][i % 3] as ClusterSize) + ), created: '2021-12-09T17:15:12', - engine: 'mysql', + engine: Factory.each((i) => ['mysql', 'postgresql'][i % 2] as Engine), hosts: { - primary: 'db-mysql-primary-0.b.linodeb.net', - secondary: 'db-mysql-secondary-0.b.linodeb.net', + primary: 'db-primary-0.b.linodeb.net', + secondary: 'db-secondary-0.b.linodeb.net', }, id: Factory.each((i) => i), instance_uri: '', - label: Factory.each((i) => `database-${i}`), + label: Factory.each((i) => `example.com-database-${i}`), members: { '2.2.2.2': 'primary', }, - region: 'us-east', - status: Factory.each(() => pickRandom(possibleStatuses)), - type: databaseTypeFactory.build().id, + platform: Factory.each((i) => (adb10(i) ? 'adb10' : 'adb20')), + region: Factory.each((i) => possibleRegions[i % possibleRegions.length]), + status: Factory.each((i) => possibleStatuses[i % possibleStatuses.length]), + type: Factory.each((i) => possibleTypes[i % possibleTypes.length]), updated: '2021-12-16T17:15:12', - version: '5.8.13', + version: Factory.each((i) => ['8.0.30', '15.7'][i % 2]), } ); @@ -189,7 +223,7 @@ export const databaseFactory = Factory.Sync.makeFactory({ ssl_connection: false, status: pickRandom(possibleStatuses), total_disk_size_gb: 15, - type: 'g6-standard-0', + type: 'g6-nanode-1', updated: '2021-12-16T17:15:12', updates: { day_of_week: 1, diff --git a/packages/manager/src/featureFlags.ts b/packages/manager/src/featureFlags.ts index 1e8c9db05dd..fc9989379ae 100644 --- a/packages/manager/src/featureFlags.ts +++ b/packages/manager/src/featureFlags.ts @@ -90,6 +90,7 @@ export interface Flags { databaseBeta: boolean; databaseResize: boolean; databases: boolean; + dbaasV2: BetaFeatureFlag; disableLargestGbPlans: boolean; eventMessagesV2: boolean; gecko: boolean; // @TODO gecko: delete this after next release diff --git a/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.tsx b/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.tsx index db6e037c3dd..349347ce978 100644 --- a/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.tsx +++ b/packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.tsx @@ -76,6 +76,7 @@ const useStyles = makeStyles()((theme: Theme) => ({ }, }, chip: { + marginLeft: 6, marginTop: 4, }, createBtn: { @@ -452,7 +453,7 @@ const DatabaseCreate = () => { }, ], labelOptions: { - suffixComponent: flags.databaseBeta ? ( + suffixComponent: flags.dbaasV2?.beta ? ( ) : null, }, @@ -564,21 +565,6 @@ const DatabaseCreate = () => { ))} - - {flags.databaseBeta ? ( - - - Notice: There is no charge for database clusters during beta. - {' '} - Database clusters will be subject to charges when the beta - period ends on May 2nd, 2022.{' '} - - View pricing - - . - - ) : undefined} - diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResize.test.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResize.test.tsx index 820807f5139..f9ed2e10136 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResize.test.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResize.test.tsx @@ -38,7 +38,7 @@ describe('database resize', () => { const standardTypes = [ databaseTypeFactory.build({ class: 'nanode', - id: 'g6-standard-0', + id: 'g6-nanode-1', label: `Nanode 1 GB`, memory: 1024, }), @@ -75,7 +75,7 @@ describe('database resize', () => { const standardTypes = [ databaseTypeFactory.build({ class: 'nanode', - id: 'g6-standard-0', + id: 'g6-nanode-1', label: `Nanode 1 GB`, memory: 1024, }), diff --git a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResizeCurrentConfiguration.test.tsx b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResizeCurrentConfiguration.test.tsx index e997f5786cf..5c59d59b338 100644 --- a/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResizeCurrentConfiguration.test.tsx +++ b/packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResizeCurrentConfiguration.test.tsx @@ -28,7 +28,7 @@ describe('database current configuration section', () => { const standardTypes = [ databaseTypeFactory.build({ class: 'nanode', - id: 'g6-standard-0', + id: 'g6-nanode-1', label: `Nanode 1 GB`, memory: 1024, }), @@ -63,7 +63,7 @@ describe('database current configuration section', () => { getByText('1 GB'); getByText('CPUs'); - getByText('4'); + getByText('2'); getByText('Total Disk Size'); getByText('15 GB'); diff --git a/packages/manager/src/features/Databases/DatabaseLanding/DatabaseLogo.tsx b/packages/manager/src/features/Databases/DatabaseLanding/DatabaseLogo.tsx new file mode 100644 index 00000000000..bce0caa0a2b --- /dev/null +++ b/packages/manager/src/features/Databases/DatabaseLanding/DatabaseLogo.tsx @@ -0,0 +1,43 @@ +import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; + +import Logo from 'src/assets/icons/db-logo.svg'; +import { BetaChip } from 'src/components/BetaChip/BetaChip'; +import { Box } from 'src/components/Box'; +import { Typography } from 'src/components/Typography'; + +import type { Theme } from '@mui/material/styles'; + +interface Props { + style?: React.CSSProperties; +} + +const useStyles = makeStyles()((theme: Theme) => ({ + betaChip: { + backgroundColor: '#727272', + color: theme.color.white, + }, + logo: { + color: '#32363C', + display: 'flex', + marginTop: '8px', + }, +})); + +export const DatabaseLogo = ({ style }: Props) => { + const { classes } = useStyles(); + return ( + + + + + Powered by + + + + ); +}; diff --git a/packages/manager/src/features/Databases/utilities.test.ts b/packages/manager/src/features/Databases/utilities.test.ts index c7171996fcb..dd981780f18 100644 --- a/packages/manager/src/features/Databases/utilities.test.ts +++ b/packages/manager/src/features/Databases/utilities.test.ts @@ -8,7 +8,7 @@ import { wrapWithTheme } from 'src/utilities/testHelpers'; import { useIsDatabasesEnabled } from './utilities'; describe('useIsDatabasesEnabled', () => { - it('should return true for an unrestricted user with the account capability', async () => { + it('should return true for an unrestricted user with the account capability V1', async () => { const account = accountFactory.build({ capabilities: ['Managed Databases'], }); @@ -20,10 +20,42 @@ describe('useIsDatabasesEnabled', () => { ); const { result } = renderHook(() => useIsDatabasesEnabled(), { - wrapper: wrapWithTheme, + wrapper: (ui) => + wrapWithTheme(ui, { + flags: { dbaasV2: { beta: false, enabled: false } }, + }), }); - await waitFor(() => expect(result.current.isDatabasesEnabled).toBe(true)); + await waitFor(() => { + expect(result.current.isDatabasesEnabled).toBe(true); + expect(result.current.isDatabasesV1Enabled).toBe(true); + expect(result.current.isDatabasesV2Enabled).toBe(false); + }); + }); + + it('should return true for an unrestricted user with the account capability V2', async () => { + const account = accountFactory.build({ + capabilities: ['Managed Databases V2'], + }); + + server.use( + http.get('*/v4/account', () => { + return HttpResponse.json(account); + }) + ); + + const { result } = renderHook(() => useIsDatabasesEnabled(), { + wrapper: (ui) => + wrapWithTheme(ui, { + flags: { dbaasV2: { beta: true, enabled: true } }, + }), + }); + + await waitFor(() => { + expect(result.current.isDatabasesEnabled).toBe(true); + expect(result.current.isDatabasesV1Enabled).toBe(false); + expect(result.current.isDatabasesV2Enabled).toBe(true); + }); }); it('should return false for an unrestricted user without the account capability', async () => { diff --git a/packages/manager/src/features/Databases/utilities.ts b/packages/manager/src/features/Databases/utilities.ts index 6fa5593aeaa..73e64f1f8e3 100644 --- a/packages/manager/src/features/Databases/utilities.ts +++ b/packages/manager/src/features/Databases/utilities.ts @@ -1,3 +1,4 @@ +import { useFlags } from 'src/hooks/useFlags'; import { useAccount } from 'src/queries/account/account'; import { useDatabaseEnginesQuery } from 'src/queries/databases/databases'; @@ -24,10 +25,21 @@ export const useIsDatabasesEnabled = () => { const checkRestrictedUser = !account; const { data: engines } = useDatabaseEnginesQuery(checkRestrictedUser); + const flags = useFlags(); if (account) { + const isDatabasesV1Enabled = account.capabilities.includes( + 'Managed Databases' + ); + + const isDatabasesV2Enabled = + account.capabilities.includes('Managed Databases V2') && + flags.dbaasV2?.enabled; + return { - isDatabasesEnabled: account.capabilities.includes('Managed Databases'), + isDatabasesEnabled: isDatabasesV1Enabled || isDatabasesV2Enabled, + isDatabasesV1Enabled, + isDatabasesV2Enabled, }; } diff --git a/packages/manager/src/mocks/serverHandlers.ts b/packages/manager/src/mocks/serverHandlers.ts index 5d66dcc0d6b..f7e7af06432 100644 --- a/packages/manager/src/mocks/serverHandlers.ts +++ b/packages/manager/src/mocks/serverHandlers.ts @@ -189,7 +189,7 @@ const entityTransfers = [ const databases = [ http.get('*/databases/instances', () => { - const databases = databaseInstanceFactory.buildList(5); + const databases = databaseInstanceFactory.buildList(9); return HttpResponse.json(makeResourcePage(databases)); }), From 484e6f696a77e78ac62d9b75e3ae3b5c27cb9835 Mon Sep 17 00:00:00 2001 From: Banks Nussman <115251059+bnussman-akamai@users.noreply.github.com> Date: Fri, 23 Aug 2024 15:30:30 -0400 Subject: [PATCH 15/19] fix: [M3-8477] - Event handlers making a proportional number of GET requests to the number of incoming events (#10824) * wrap invalidate queries * Added changeset: Event handlers making a proportional number of GET requests to the number of incoming events * add cypress test that would have caught bug * link PR for context --------- Co-authored-by: Banks Nussman --- .../pr-10824-fixed-1724428840947.md | 5 ++ .../events-fetching.spec.ts | 42 ++++++++++++++ .../manager/src/hooks/EventHandlerData.ts | 0 .../manager/src/hooks/useEventHandlers.ts | 18 +++++- .../manager/src/queries/account/billing.ts | 7 ++- packages/manager/src/queries/account/oauth.ts | 6 +- .../manager/src/queries/databases/events.ts | 6 +- packages/manager/src/queries/domains.ts | 8 +-- packages/manager/src/queries/firewalls.ts | 33 +++++------ packages/manager/src/queries/images.ts | 8 +-- .../manager/src/queries/linodes/events.ts | 56 ++++++++++--------- packages/manager/src/queries/nodebalancers.ts | 8 +-- .../manager/src/queries/profile/profile.ts | 6 +- .../manager/src/queries/profile/tokens.ts | 6 +- packages/manager/src/queries/stackscripts.ts | 6 +- packages/manager/src/queries/support.ts | 6 +- .../manager/src/queries/volumes/events.ts | 8 +-- 17 files changed, 145 insertions(+), 84 deletions(-) create mode 100644 packages/manager/.changeset/pr-10824-fixed-1724428840947.md create mode 100644 packages/manager/cypress/e2e/core/notificationsAndEvents/events-fetching.spec.ts create mode 100644 packages/manager/src/hooks/EventHandlerData.ts diff --git a/packages/manager/.changeset/pr-10824-fixed-1724428840947.md b/packages/manager/.changeset/pr-10824-fixed-1724428840947.md new file mode 100644 index 00000000000..94eda937dd4 --- /dev/null +++ b/packages/manager/.changeset/pr-10824-fixed-1724428840947.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Fixed +--- + +Event handlers making a proportional number of GET requests to the number of incoming events ([#10824](https://github.com/linode/manager/pull/10824)) diff --git a/packages/manager/cypress/e2e/core/notificationsAndEvents/events-fetching.spec.ts b/packages/manager/cypress/e2e/core/notificationsAndEvents/events-fetching.spec.ts new file mode 100644 index 00000000000..e1f3804b6a5 --- /dev/null +++ b/packages/manager/cypress/e2e/core/notificationsAndEvents/events-fetching.spec.ts @@ -0,0 +1,42 @@ +import { eventFactory } from 'src/factories'; +import { mockGetEvents } from 'support/intercepts/events'; +import { mockGetVolumes } from 'support/intercepts/volumes'; + +describe('Event Handlers', () => { + it('invokes event handlers when new events are polled and makes the correct number of requests', () => { + // See https://github.com/linode/manager/pull/10824 + + mockGetEvents([]).as('getEvents'); + mockGetVolumes([]).as('getInitialVolumes'); + + cy.visitWithLogin('/volumes'); + + // Wait for the initial events fetch and initial volumes fetch + cy.wait(['@getEvents', '@getInitialVolumes']); + + // Wait for the first polling interval to happen + cy.wait('@getEvents'); + + const polledEvents = [ + eventFactory.build({ action: 'volume_update', status: 'notification' }), + eventFactory.build({ action: 'volume_update', status: 'notification' }), + eventFactory.build({ action: 'volume_update', status: 'notification' }), + ]; + + // Pretend a volume was updated 3 times in a row + mockGetEvents(polledEvents).as('getEvents'); + + // Intercept GET volumes so we can later check how many times it is fetched + mockGetVolumes([]).as('getVolumes'); + + // Wait for volume update events to be polled + cy.wait('@getEvents'); + + // On the next interval, mock no new events + mockGetEvents([]).as('getEvents'); + cy.wait('@getEvents'); + + // Finally, verify the volume endpoint was only fetched once + cy.get('@getVolumes.all').should('have.length', 1); + }); +}); diff --git a/packages/manager/src/hooks/EventHandlerData.ts b/packages/manager/src/hooks/EventHandlerData.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/manager/src/hooks/useEventHandlers.ts b/packages/manager/src/hooks/useEventHandlers.ts index da32d9a3059..9f6312c36ea 100644 --- a/packages/manager/src/hooks/useEventHandlers.ts +++ b/packages/manager/src/hooks/useEventHandlers.ts @@ -16,10 +16,14 @@ import { supportTicketEventHandler } from 'src/queries/support'; import { volumeEventsHandler } from 'src/queries/volumes/events'; import type { Event } from '@linode/api-v4'; -import type { QueryClient } from '@tanstack/react-query'; +import type { + InvalidateQueryFilters, + QueryClient, +} from '@tanstack/react-query'; export interface EventHandlerData { event: Event; + invalidateQueries: (filters: InvalidateQueryFilters) => Promise; queryClient: QueryClient; } @@ -91,6 +95,16 @@ export const eventHandlers: { export const useEventHandlers = () => { const queryClient = useQueryClient(); + /* + * We wrap invalidateQueries because we need to enforce some options. + * + * We set `cancelRefetch` to `false` because it ensures no refetch will + * be made if there is already a request running. This is important for + * event handlers because they are envoked once for every event polled. + */ + const invalidateQueries = (filters: InvalidateQueryFilters) => + queryClient.invalidateQueries(filters, { cancelRefetch: false }); + /** * Given an event, this function finds the corresponding * event handler and invokes it. @@ -98,7 +112,7 @@ export const useEventHandlers = () => { const handleEvent = (event: Event) => { for (const eventHandler of eventHandlers) { if (eventHandler.filter(event)) { - eventHandler.handler({ event, queryClient }); + eventHandler.handler({ event, invalidateQueries, queryClient }); return; } } diff --git a/packages/manager/src/queries/account/billing.ts b/packages/manager/src/queries/account/billing.ts index 0b85e8c0cc2..9eddbf90160 100644 --- a/packages/manager/src/queries/account/billing.ts +++ b/packages/manager/src/queries/account/billing.ts @@ -29,9 +29,12 @@ export const useAllAccountPayments = ( }); }; -export const taxIdEventHandler = ({ event, queryClient }: EventHandlerData) => { +export const taxIdEventHandler = ({ + event, + invalidateQueries, +}: EventHandlerData) => { if (event.action === 'tax_id_invalid' || event.action === 'tax_id_valid') { - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: accountQueries.notifications.queryKey, }); } diff --git a/packages/manager/src/queries/account/oauth.ts b/packages/manager/src/queries/account/oauth.ts index 653b2aa1de0..50a0fd75b88 100644 --- a/packages/manager/src/queries/account/oauth.ts +++ b/packages/manager/src/queries/account/oauth.ts @@ -70,10 +70,12 @@ export const useUpdateOAuthClientMutation = (id: string) => { }); }; -export const oauthClientsEventHandler = ({ queryClient }: EventHandlerData) => { +export const oauthClientsEventHandler = ({ + invalidateQueries, +}: EventHandlerData) => { // We may over-fetch because on `onSuccess` also invalidates, but this will be // good for UX because Cloud will always be up to date - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: accountQueries.oauthClients._def, }); }; diff --git a/packages/manager/src/queries/databases/events.ts b/packages/manager/src/queries/databases/events.ts index c138284e787..33644af4a58 100644 --- a/packages/manager/src/queries/databases/events.ts +++ b/packages/manager/src/queries/databases/events.ts @@ -7,10 +7,10 @@ import type { EventHandlerData } from 'src/hooks/useEventHandlers'; export const databaseEventsHandler = ({ event, - queryClient, + invalidateQueries, }: EventHandlerData) => { if (['failed', 'finished', 'notification'].includes(event.status)) { - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: databaseQueries.databases.queryKey, }); @@ -35,7 +35,7 @@ export const databaseEventsHandler = ({ ); } - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: databaseQueries.database(engine as Engine, event.entity.id) .queryKey, }); diff --git a/packages/manager/src/queries/domains.ts b/packages/manager/src/queries/domains.ts index 41ab63b8be9..527ac5637c4 100644 --- a/packages/manager/src/queries/domains.ts +++ b/packages/manager/src/queries/domains.ts @@ -186,7 +186,7 @@ export const useUpdateDomainMutation = () => { export const domainEventsHandler = ({ event, - queryClient, + invalidateQueries, }: EventHandlerData) => { const domainId = event.entity?.id; @@ -196,17 +196,17 @@ export const domainEventsHandler = ({ if (event.action.startsWith('domain_record')) { // Invalidate the domain's records because they may have changed - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: domainQueries.domain(domainId)._ctx.records.queryKey, }); } else { // Invalidate paginated lists - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: domainQueries.domains.queryKey, }); // Invalidate the domain's details - queryClient.invalidateQueries({ + invalidateQueries({ exact: true, queryKey: domainQueries.domain(domainId).queryKey, }); diff --git a/packages/manager/src/queries/firewalls.ts b/packages/manager/src/queries/firewalls.ts index 6ad96e8ba59..bda609a9819 100644 --- a/packages/manager/src/queries/firewalls.ts +++ b/packages/manager/src/queries/firewalls.ts @@ -408,6 +408,7 @@ export const useUpdateFirewallRulesMutation = (firewallId: number) => { export const firewallEventsHandler = ({ event, + invalidateQueries, queryClient, }: EventHandlerData) => { if (!event.entity) { @@ -418,7 +419,7 @@ export const firewallEventsHandler = ({ switch (event.action) { case 'firewall_delete': // Invalidate firewall lists - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: firewallQueries.firewalls.queryKey, }); @@ -428,7 +429,7 @@ export const firewallEventsHandler = ({ }); case 'firewall_create': // Invalidate firewall lists - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: firewallQueries.firewalls.queryKey, }); case 'firewall_device_add': @@ -438,13 +439,9 @@ export const firewallEventsHandler = ({ // If a Linode is added or removed as a firewall device, invalidate it's firewalls if (event.secondary_entity && event.secondary_entity.type === 'linode') { - queryClient.invalidateQueries({ - queryKey: [ - 'linodes', - 'linode', - event.secondary_entity.id, - 'firewalls', - ], + invalidateQueries({ + queryKey: linodeQueries.linode(event.secondary_entity.id)._ctx + .firewalls.queryKey, }); } @@ -453,23 +450,19 @@ export const firewallEventsHandler = ({ event.secondary_entity && event.secondary_entity.type === 'nodebalancer' ) { - queryClient.invalidateQueries({ - queryKey: [ - 'nodebalancers', - 'nodebalancer', - event.secondary_entity.id, - 'firewalls', - ], + invalidateQueries({ + queryKey: nodebalancerQueries.nodebalancer(event.secondary_entity.id) + ._ctx.firewalls.queryKey, }); } // Invalidate the firewall - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: firewallQueries.firewall(event.entity.id).queryKey, }); // Invalidate firewall lists - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: firewallQueries.firewalls.queryKey, }); case 'firewall_disable': @@ -477,11 +470,11 @@ export const firewallEventsHandler = ({ case 'firewall_rules_update': case 'firewall_update': // invalidate the firewall - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: firewallQueries.firewall(event.entity.id).queryKey, }); // Invalidate firewall lists - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: firewallQueries.firewalls.queryKey, }); } diff --git a/packages/manager/src/queries/images.ts b/packages/manager/src/queries/images.ts index 5df6ed104f1..e79b1d5ed9b 100644 --- a/packages/manager/src/queries/images.ts +++ b/packages/manager/src/queries/images.ts @@ -174,13 +174,13 @@ export const useUpdateImageRegionsMutation = (imageId: string) => { export const imageEventsHandler = ({ event, - queryClient, + invalidateQueries, }: EventHandlerData) => { if (['failed', 'finished', 'notification'].includes(event.status)) { - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: imageQueries.all._def, }); - queryClient.invalidateQueries({ queryKey: imageQueries.paginated._def }); + invalidateQueries({ queryKey: imageQueries.paginated._def }); if (event.entity) { /* @@ -194,7 +194,7 @@ export const imageEventsHandler = ({ */ const imageId = `private/${event.entity.id}`; - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: imageQueries.image(imageId).queryKey, }); } diff --git a/packages/manager/src/queries/linodes/events.ts b/packages/manager/src/queries/linodes/events.ts index 7f44a64ba75..cfcf2151a77 100644 --- a/packages/manager/src/queries/linodes/events.ts +++ b/packages/manager/src/queries/linodes/events.ts @@ -14,6 +14,7 @@ import type { EventHandlerData } from 'src/hooks/useEventHandlers'; */ export const linodeEventsHandler = ({ event, + invalidateQueries, queryClient, }: EventHandlerData) => { const linodeId = event.entity?.id; @@ -29,7 +30,7 @@ export const linodeEventsHandler = ({ // Some Linode events are an indication that the reponse from /v4/account/notifications // has changed, so refetch notifications. if (shouldRequestNotifications(event)) { - queryClient.invalidateQueries(accountQueries.notifications); + invalidateQueries(accountQueries.notifications); } switch (event.action) { @@ -43,65 +44,63 @@ export const linodeEventsHandler = ({ case 'linode_resize_warm_create': case 'linode_reboot': case 'linode_update': - queryClient.invalidateQueries(linodeQueries.linodes); - queryClient.invalidateQueries({ + invalidateQueries(linodeQueries.linodes); + invalidateQueries({ exact: true, queryKey: linodeQueries.linode(linodeId).queryKey, }); return; case 'linode_boot': case 'linode_shutdown': - queryClient.invalidateQueries(linodeQueries.linodes); - queryClient.invalidateQueries({ + invalidateQueries(linodeQueries.linodes); + invalidateQueries({ exact: true, queryKey: linodeQueries.linode(linodeId).queryKey, }); // Ensure configs are fresh when Linode is booted up (see https://github.com/linode/manager/pull/9914) - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: linodeQueries.linode(linodeId)._ctx.configs.queryKey, }); return; case 'linode_snapshot': - queryClient.invalidateQueries(linodeQueries.linodes); - queryClient.invalidateQueries({ + invalidateQueries(linodeQueries.linodes); + invalidateQueries({ exact: true, queryKey: linodeQueries.linode(linodeId).queryKey, }); - queryClient.invalidateQueries( - linodeQueries.linode(linodeId)._ctx.backups - ); + invalidateQueries(linodeQueries.linode(linodeId)._ctx.backups); return; case 'linode_addip': case 'linode_deleteip': - queryClient.invalidateQueries(linodeQueries.linodes); - queryClient.invalidateQueries({ + invalidateQueries(linodeQueries.linodes); + invalidateQueries({ queryKey: linodeQueries.linode(linodeId)._ctx.ips.queryKey, }); - queryClient.invalidateQueries({ + invalidateQueries({ exact: true, queryKey: linodeQueries.linode(linodeId).queryKey, }); return; case 'linode_create': case 'linode_clone': - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: linodeQueries.linode(linodeId)._ctx.disks.queryKey, }); - queryClient.invalidateQueries(linodeQueries.linodes); - queryClient.invalidateQueries({ + invalidateQueries(linodeQueries.linodes); + invalidateQueries({ exact: true, queryKey: linodeQueries.linode(linodeId).queryKey, }); return; case 'linode_rebuild': - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: linodeQueries.linode(linodeId)._ctx.disks.queryKey, }); - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: linodeQueries.linode(linodeId)._ctx.configs.queryKey, }); - queryClient.invalidateQueries(linodeQueries.linodes); - queryClient.invalidateQueries({ + invalidateQueries(linodeQueries.linodes); + invalidateQueries({ exact: true, queryKey: linodeQueries.linode(linodeId).queryKey, }); @@ -110,20 +109,20 @@ export const linodeEventsHandler = ({ queryClient.removeQueries({ queryKey: linodeQueries.linode(linodeId).queryKey, }); - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: linodeQueries.linodes.queryKey, }); // A Linode made have been on a Firewall's device list, but now that it is deleted, // it will no longer be listed as a device on that firewall. Here, we invalidate outdated firewall data. - queryClient.invalidateQueries({ queryKey: firewallQueries._def }); + invalidateQueries({ queryKey: firewallQueries._def }); // A Linode may have been attached to a Volume, but deleted. We need to refetch volumes data so that // the Volumes table does not show a Volume attached to a non-existant Linode. - queryClient.invalidateQueries({ queryKey: volumeQueries.lists.queryKey }); + invalidateQueries({ queryKey: volumeQueries.lists.queryKey }); return; case 'linode_config_create': case 'linode_config_delete': case 'linode_config_update': - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: linodeQueries.linode(linodeId)._ctx.configs.queryKey, }); return; @@ -136,14 +135,17 @@ export const linodeEventsHandler = ({ * Disks have their own handler beacuse the actions are not prefixed with "linode_". * They are prefixed with "disk_". For example "disk_create" or "disk_delete". */ -export const diskEventHandler = ({ event, queryClient }: EventHandlerData) => { +export const diskEventHandler = ({ + event, + invalidateQueries, +}: EventHandlerData) => { const linodeId = event.entity?.id; if (!linodeId || ['scheduled', 'started'].includes(event.status)) { return; } - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: linodeQueries.linode(linodeId)._ctx.disks.queryKey, }); }; diff --git a/packages/manager/src/queries/nodebalancers.ts b/packages/manager/src/queries/nodebalancers.ts index b48c977d1c5..bbfe635ad9e 100644 --- a/packages/manager/src/queries/nodebalancers.ts +++ b/packages/manager/src/queries/nodebalancers.ts @@ -303,7 +303,7 @@ export const useNodeBalancerTypesQuery = () => export const nodebalancerEventHandler = ({ event, - queryClient, + invalidateQueries, }: EventHandlerData) => { const nodebalancerId = event.entity?.id; @@ -319,7 +319,7 @@ export const nodebalancerEventHandler = ({ if (event.action.startsWith('nodebalancer_config')) { // If the event is about a NodeBalancer's configs, just invalidate the configs - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: nodebalancerQueries.nodebalancer(nodebalancerId)._ctx .configurations.queryKey, }); @@ -327,13 +327,13 @@ export const nodebalancerEventHandler = ({ // If we've made it here, the event is about a NodeBalancer // Invalidate the specific NodeBalancer - queryClient.invalidateQueries({ + invalidateQueries({ exact: true, queryKey: nodebalancerQueries.nodebalancer(nodebalancerId).queryKey, }); // Invalidate all paginated lists - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: nodebalancerQueries.nodebalancers.queryKey, }); } diff --git a/packages/manager/src/queries/profile/profile.ts b/packages/manager/src/queries/profile/profile.ts index 13fb33f7783..726cd66b1cb 100644 --- a/packages/manager/src/queries/profile/profile.ts +++ b/packages/manager/src/queries/profile/profile.ts @@ -195,15 +195,15 @@ export const useDeleteSSHKeyMutation = (id: number) => { }); }; -export const sshKeyEventHandler = (event: EventHandlerData) => { +export const sshKeyEventHandler = ({ invalidateQueries }: EventHandlerData) => { // This event handler is a bit agressive and will over-fetch, but UX will // be great because this will ensure Cloud has up to date data all the time. - event.queryClient.invalidateQueries({ + invalidateQueries({ queryKey: profileQueries.sshKeys._def, }); // also invalidate the /account/users data because that endpoint returns some SSH key data - event.queryClient.invalidateQueries({ + invalidateQueries({ queryKey: accountQueries.users._ctx.paginated._def, }); }; diff --git a/packages/manager/src/queries/profile/tokens.ts b/packages/manager/src/queries/profile/tokens.ts index 19f9db88fa4..ef9ebd8da79 100644 --- a/packages/manager/src/queries/profile/tokens.ts +++ b/packages/manager/src/queries/profile/tokens.ts @@ -90,11 +90,11 @@ export const useRevokeAppAccessTokenMutation = (id: number) => { }); }; -export function tokenEventHandler({ queryClient }: EventHandlerData) { - queryClient.invalidateQueries({ +export function tokenEventHandler({ invalidateQueries }: EventHandlerData) { + invalidateQueries({ queryKey: profileQueries.appTokens._def, }); - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: profileQueries.personalAccessTokens._def, }); } diff --git a/packages/manager/src/queries/stackscripts.ts b/packages/manager/src/queries/stackscripts.ts index b520d1390bc..42bb6de6138 100644 --- a/packages/manager/src/queries/stackscripts.ts +++ b/packages/manager/src/queries/stackscripts.ts @@ -68,16 +68,16 @@ export const useStackScriptsInfiniteQuery = ( export const stackScriptEventHandler = ({ event, - queryClient, + invalidateQueries, }: EventHandlerData) => { // Keep the infinite store up to date - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: stackscriptQueries.infinite._def, }); // If the event has a StackScript entity attached, invalidate it if (event.entity?.id) { - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: stackscriptQueries.stackscript(event.entity.id).queryKey, }); } diff --git a/packages/manager/src/queries/support.ts b/packages/manager/src/queries/support.ts index 5c4ea96838c..94524983762 100644 --- a/packages/manager/src/queries/support.ts +++ b/packages/manager/src/queries/support.ts @@ -112,7 +112,7 @@ export const useSupportTicketCloseMutation = (id: number) => { export const supportTicketEventHandler = ({ event, - queryClient, + invalidateQueries, }: EventHandlerData) => { /** * Ticket events have entities that look like this: @@ -126,13 +126,13 @@ export const supportTicketEventHandler = ({ */ // Invalidate paginated support tickets - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: supportQueries.tickets._def, }); if (event.entity) { // If there is an entity associated with the event, invalidate that ticket - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: supportQueries.ticket(event.entity.id).queryKey, }); } diff --git a/packages/manager/src/queries/volumes/events.ts b/packages/manager/src/queries/volumes/events.ts index 84f2c7c6fba..3f2415f0891 100644 --- a/packages/manager/src/queries/volumes/events.ts +++ b/packages/manager/src/queries/volumes/events.ts @@ -10,10 +10,10 @@ import type { EventHandlerData } from 'src/hooks/useEventHandlers'; */ export const volumeEventsHandler = ({ event, - queryClient, + invalidateQueries, }: EventHandlerData) => { if (['failed', 'finished', 'notification'].includes(event.status)) { - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: volumeQueries.lists.queryKey, }); } @@ -24,7 +24,7 @@ export const volumeEventsHandler = ({ ) { // if a migration finishes, we want to re-request notifications so that the `volume_migration_imminent` // notification goes away. - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: accountQueries.notifications.queryKey, }); } @@ -33,7 +33,7 @@ export const volumeEventsHandler = ({ // The API gives us no way to know when a cloned volume transitions from // creating to active, so we will just refresh after 10 seconds setTimeout(() => { - queryClient.invalidateQueries({ + invalidateQueries({ queryKey: volumeQueries.lists.queryKey, }); }, 10000); From fa04d90a370102c81ec8a608996d39b09a574574 Mon Sep 17 00:00:00 2001 From: Hana Xu <115299789+hana-linode@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:02:37 -0400 Subject: [PATCH 16/19] change: [M3-8210] - Storybook nav organization POC (#10809) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description 📝 POC to clean up the side nav in Storybook by reorganizing the hierarchy/component stories, and making the logo smaller ## Changes 🔄 List any change relevant to the reviewer. - Smaller Akamai logo - Add `Icons` and `Foundations` section - Move `Design System` section to the top - Move relevant components to the new sections and consolidate related components into folders ## How to test 🧪 ### Verification steps (How to verify changes) - Pull this PR locally and run `yarn storybook` - Compare to https://design.linode.com/ --- .../manager/.changeset/pr-10809-changed-1724354812801.md | 5 +++++ packages/manager/.storybook/preview.tsx | 9 ++++++++- packages/manager/src/assets/logo/akamai-logo-color.svg | 2 +- packages/manager/src/components/Accordion.stories.tsx | 2 +- .../manager/src/components/BetaChip/BetaChip.stories.tsx | 2 +- packages/manager/src/components/Box.stories.tsx | 2 +- .../src/components/Breadcrumb/Breadcrumb.stories.tsx | 2 +- .../manager/src/components/Button/Button.stories.tsx | 2 +- .../src/components/Button/StyledTagButton.stories.tsx | 2 +- packages/manager/src/components/Checkbox.stories.tsx | 2 +- packages/manager/src/components/Chip.stories.tsx | 2 +- .../manager/src/components/Currency/Currency.stories.tsx | 2 +- .../DateTimeDisplay/DateTimeDisplay.stories.tsx | 2 +- packages/manager/src/components/Divider.stories.tsx | 2 +- .../manager/src/components/DocsLink/DocsLink.stories.tsx | 2 +- .../src/components/EditableText/EditableText.stories.tsx | 2 +- .../EnhancedNumberInput/EnhancedNumberInput.stories.tsx | 2 +- .../src/components/EntityIcon/EntityIcon.stories.tsx | 2 +- packages/manager/src/components/Flag.stories.tsx | 2 +- .../InlineMenuAction/InlineMenuAction.stories.tsx | 2 +- packages/manager/src/components/Link.stories.tsx | 2 +- packages/manager/src/components/OSIcon.stories.tsx | 2 +- packages/manager/src/components/Paper.stories.tsx | 2 +- .../components/PasswordInput/HideShowText.stories.tsx | 2 +- .../components/PasswordInput/PasswordInput.stories.tsx | 2 +- packages/manager/src/components/Radio/Radio.stories.tsx | 2 +- .../ShowMoreExpansion/ShowMoreExpansion.stories.tsx | 2 +- packages/manager/src/components/Stack.stories.tsx | 2 +- .../src/components/StatusIcon/StatusIcon.stories.tsx | 2 +- packages/manager/src/components/Tabs/Tabs.stories.tsx | 2 +- packages/manager/src/components/TextField.stories.tsx | 2 +- .../manager/src/components/Toggle/Toggle.stories.tsx | 2 +- packages/manager/src/components/Typography.stories.tsx | 2 +- 33 files changed, 44 insertions(+), 32 deletions(-) create mode 100644 packages/manager/.changeset/pr-10809-changed-1724354812801.md diff --git a/packages/manager/.changeset/pr-10809-changed-1724354812801.md b/packages/manager/.changeset/pr-10809-changed-1724354812801.md new file mode 100644 index 00000000000..34116e2d1f9 --- /dev/null +++ b/packages/manager/.changeset/pr-10809-changed-1724354812801.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Changed +--- + +Storybook nav organization ([#10809](https://github.com/linode/manager/pull/10809)) diff --git a/packages/manager/.storybook/preview.tsx b/packages/manager/.storybook/preview.tsx index 538c0b07cea..5ea09efff9d 100644 --- a/packages/manager/.storybook/preview.tsx +++ b/packages/manager/.storybook/preview.tsx @@ -61,7 +61,14 @@ const preview: Preview = { options: { storySort: { method: 'alphabetical', - order: ['Intro', 'Core Styles', 'Components', 'Features'], + order: [ + 'Intro', + 'Design System', + 'Icons', + 'Foundations', + 'Components', + 'Features', + ], }, }, viewport: { diff --git a/packages/manager/src/assets/logo/akamai-logo-color.svg b/packages/manager/src/assets/logo/akamai-logo-color.svg index c205d07e455..18259cdabee 100644 --- a/packages/manager/src/assets/logo/akamai-logo-color.svg +++ b/packages/manager/src/assets/logo/akamai-logo-color.svg @@ -1,4 +1,4 @@ - + diff --git a/packages/manager/src/components/Accordion.stories.tsx b/packages/manager/src/components/Accordion.stories.tsx index 40c68421544..0d34e246f31 100644 --- a/packages/manager/src/components/Accordion.stories.tsx +++ b/packages/manager/src/components/Accordion.stories.tsx @@ -5,7 +5,7 @@ import { Accordion } from './Accordion'; const meta: Meta = { component: Accordion, - title: 'Components/Accordion', + title: 'Foundations/Accordion', }; type Story = StoryObj; diff --git a/packages/manager/src/components/BetaChip/BetaChip.stories.tsx b/packages/manager/src/components/BetaChip/BetaChip.stories.tsx index 6115d28c209..3cc3a4ea934 100644 --- a/packages/manager/src/components/BetaChip/BetaChip.stories.tsx +++ b/packages/manager/src/components/BetaChip/BetaChip.stories.tsx @@ -12,6 +12,6 @@ export const Default: StoryObj = { const meta: Meta = { args: { color: 'default' }, component: BetaChip, - title: 'Components/Chip/BetaChip', + title: 'Foundations/Chip/BetaChip', }; export default meta; diff --git a/packages/manager/src/components/Box.stories.tsx b/packages/manager/src/components/Box.stories.tsx index 57f62dd2451..11b944f45cb 100644 --- a/packages/manager/src/components/Box.stories.tsx +++ b/packages/manager/src/components/Box.stories.tsx @@ -5,7 +5,7 @@ import { Box } from './Box'; const meta: Meta = { component: Box, - title: 'Components/Box', + title: 'Foundations/Box', }; type Story = StoryObj; diff --git a/packages/manager/src/components/Breadcrumb/Breadcrumb.stories.tsx b/packages/manager/src/components/Breadcrumb/Breadcrumb.stories.tsx index 9317926073b..a50d3a4206f 100644 --- a/packages/manager/src/components/Breadcrumb/Breadcrumb.stories.tsx +++ b/packages/manager/src/components/Breadcrumb/Breadcrumb.stories.tsx @@ -6,7 +6,7 @@ import { Breadcrumb } from './Breadcrumb'; const meta: Meta = { component: Breadcrumb, - title: 'Components/Breadcrumb', + title: 'Foundations/Breadcrumb', }; type Story = StoryObj; diff --git a/packages/manager/src/components/Button/Button.stories.tsx b/packages/manager/src/components/Button/Button.stories.tsx index d9ef1e18160..2d7edd9f745 100644 --- a/packages/manager/src/components/Button/Button.stories.tsx +++ b/packages/manager/src/components/Button/Button.stories.tsx @@ -35,7 +35,7 @@ const meta: Meta = { tooltipText: '', }, component: Button, - title: 'Components/Button', + title: 'Foundations/Button', }; export default meta; diff --git a/packages/manager/src/components/Button/StyledTagButton.stories.tsx b/packages/manager/src/components/Button/StyledTagButton.stories.tsx index 843fb1f4bd9..adb044a973b 100644 --- a/packages/manager/src/components/Button/StyledTagButton.stories.tsx +++ b/packages/manager/src/components/Button/StyledTagButton.stories.tsx @@ -12,7 +12,7 @@ const meta: Meta = { onClick: () => null, }, component: StyledTagButton, - title: 'Components/TagButton', + title: 'Components/Tags/TagButton', }; export default meta; diff --git a/packages/manager/src/components/Checkbox.stories.tsx b/packages/manager/src/components/Checkbox.stories.tsx index 8912f625726..4e8a4afddb8 100644 --- a/packages/manager/src/components/Checkbox.stories.tsx +++ b/packages/manager/src/components/Checkbox.stories.tsx @@ -5,7 +5,7 @@ import { Checkbox } from './Checkbox'; const meta: Meta = { component: Checkbox, - title: 'Components/Checkbox', + title: 'Foundations/Checkbox', }; type Story = StoryObj; diff --git a/packages/manager/src/components/Chip.stories.tsx b/packages/manager/src/components/Chip.stories.tsx index e040850646c..ed13e76cebd 100644 --- a/packages/manager/src/components/Chip.stories.tsx +++ b/packages/manager/src/components/Chip.stories.tsx @@ -66,6 +66,6 @@ export const WithDeleteButton: StoryObj = { const meta: Meta = { args: { label: 'Chip', onDelete: undefined }, component: Chip, - title: 'Components/Chip', + title: 'Foundations/Chip', }; export default meta; diff --git a/packages/manager/src/components/Currency/Currency.stories.tsx b/packages/manager/src/components/Currency/Currency.stories.tsx index dd58ddca5fa..dccf4e80c49 100644 --- a/packages/manager/src/components/Currency/Currency.stories.tsx +++ b/packages/manager/src/components/Currency/Currency.stories.tsx @@ -24,7 +24,7 @@ const meta: Meta = { }, }, component: Currency, - title: 'Components/Typography/Currency', + title: 'Foundations/Typography/Currency', }; export default meta; diff --git a/packages/manager/src/components/DateTimeDisplay/DateTimeDisplay.stories.tsx b/packages/manager/src/components/DateTimeDisplay/DateTimeDisplay.stories.tsx index e2770307f19..b0ff4fe89a5 100644 --- a/packages/manager/src/components/DateTimeDisplay/DateTimeDisplay.stories.tsx +++ b/packages/manager/src/components/DateTimeDisplay/DateTimeDisplay.stories.tsx @@ -24,7 +24,7 @@ const meta: Meta = { }, }, component: DateTimeDisplay, - title: 'Components/Typography/Date Time Display', + title: 'Foundations/Typography/Date Time Display', }; export default meta; diff --git a/packages/manager/src/components/Divider.stories.tsx b/packages/manager/src/components/Divider.stories.tsx index d4f2f055125..52619e8223f 100644 --- a/packages/manager/src/components/Divider.stories.tsx +++ b/packages/manager/src/components/Divider.stories.tsx @@ -5,7 +5,7 @@ import { Divider } from 'src/components/Divider'; const meta: Meta = { component: Divider, - title: 'Components/Divider', + title: 'Foundations/Divider', }; type Story = StoryObj; diff --git a/packages/manager/src/components/DocsLink/DocsLink.stories.tsx b/packages/manager/src/components/DocsLink/DocsLink.stories.tsx index 6d1b2154362..db5a9c8b664 100644 --- a/packages/manager/src/components/DocsLink/DocsLink.stories.tsx +++ b/packages/manager/src/components/DocsLink/DocsLink.stories.tsx @@ -16,7 +16,7 @@ const meta: Meta = { label: 'Custom Doc Link Label', }, component: DocsLink, - title: 'Components/Link/DocsLink', + title: 'Foundations/Link/DocsLink', }; export default meta; diff --git a/packages/manager/src/components/EditableText/EditableText.stories.tsx b/packages/manager/src/components/EditableText/EditableText.stories.tsx index 7ff5a3842a6..7ca7bd9a59c 100644 --- a/packages/manager/src/components/EditableText/EditableText.stories.tsx +++ b/packages/manager/src/components/EditableText/EditableText.stories.tsx @@ -44,7 +44,7 @@ export const WithSuffix: Story = { const meta: Meta = { component: EditableText, - title: 'Components/Editable Text', + title: 'Components/Input/Editable Text', }; export default meta; diff --git a/packages/manager/src/components/EnhancedNumberInput/EnhancedNumberInput.stories.tsx b/packages/manager/src/components/EnhancedNumberInput/EnhancedNumberInput.stories.tsx index 165966f7c15..ddb25f893b7 100644 --- a/packages/manager/src/components/EnhancedNumberInput/EnhancedNumberInput.stories.tsx +++ b/packages/manager/src/components/EnhancedNumberInput/EnhancedNumberInput.stories.tsx @@ -31,7 +31,7 @@ const meta: Meta = { }, args: {}, component: EnhancedNumberInput, - title: 'Components/EnhancedNumberInput', + title: 'Components/Input/EnhancedNumberInput', }; export default meta; diff --git a/packages/manager/src/components/EntityIcon/EntityIcon.stories.tsx b/packages/manager/src/components/EntityIcon/EntityIcon.stories.tsx index 7bd091305c6..f93191f3f4a 100644 --- a/packages/manager/src/components/EntityIcon/EntityIcon.stories.tsx +++ b/packages/manager/src/components/EntityIcon/EntityIcon.stories.tsx @@ -10,7 +10,7 @@ import type { EntityVariants } from 'src/components/EntityIcon/EntityIcon'; const meta: Meta = { args: { variant: 'linode' }, component: EntityIcon, - title: 'Components/EntityIcon', + title: 'Icons/EntityIcon', }; export default meta; diff --git a/packages/manager/src/components/Flag.stories.tsx b/packages/manager/src/components/Flag.stories.tsx index 26125989844..82676bdfb81 100644 --- a/packages/manager/src/components/Flag.stories.tsx +++ b/packages/manager/src/components/Flag.stories.tsx @@ -5,7 +5,7 @@ import { Flag } from './Flag'; const meta: Meta = { component: Flag, - title: 'Components/Flag', + title: 'Icons/Flag', }; type Story = StoryObj; diff --git a/packages/manager/src/components/InlineMenuAction/InlineMenuAction.stories.tsx b/packages/manager/src/components/InlineMenuAction/InlineMenuAction.stories.tsx index 996e6a5990c..914e76b2daf 100644 --- a/packages/manager/src/components/InlineMenuAction/InlineMenuAction.stories.tsx +++ b/packages/manager/src/components/InlineMenuAction/InlineMenuAction.stories.tsx @@ -17,7 +17,7 @@ const meta: Meta = { tooltipAnalyticsEvent: action('tooltipAnalyticsEvent'), }, component: InlineMenuAction, - title: 'Components/InlineMenuAction', + title: 'Components/Action Menu/InlineMenuAction', }; export default meta; diff --git a/packages/manager/src/components/Link.stories.tsx b/packages/manager/src/components/Link.stories.tsx index 5561e1d7a4d..2ae6e9a9f05 100644 --- a/packages/manager/src/components/Link.stories.tsx +++ b/packages/manager/src/components/Link.stories.tsx @@ -130,7 +130,7 @@ const meta: Meta = { to: '/internal-link', }, component: Link, - title: 'Components/Link', + title: 'Foundations/Link', }; export default meta; diff --git a/packages/manager/src/components/OSIcon.stories.tsx b/packages/manager/src/components/OSIcon.stories.tsx index e728841c789..dd16e698fb5 100644 --- a/packages/manager/src/components/OSIcon.stories.tsx +++ b/packages/manager/src/components/OSIcon.stories.tsx @@ -22,7 +22,7 @@ export const Alpine: StoryObj = { const meta: Meta = { component: OSIcon, - title: 'Components/OS Icon', + title: 'Icons/OS Icon', }; export default meta; diff --git a/packages/manager/src/components/Paper.stories.tsx b/packages/manager/src/components/Paper.stories.tsx index b86597fa680..99ae8f85374 100644 --- a/packages/manager/src/components/Paper.stories.tsx +++ b/packages/manager/src/components/Paper.stories.tsx @@ -5,7 +5,7 @@ import { Paper } from './Paper'; const meta: Meta = { component: Paper, - title: 'Components/Paper', + title: 'Foundations/Paper', }; type Story = StoryObj; diff --git a/packages/manager/src/components/PasswordInput/HideShowText.stories.tsx b/packages/manager/src/components/PasswordInput/HideShowText.stories.tsx index 8db3107e04b..b2561a58866 100644 --- a/packages/manager/src/components/PasswordInput/HideShowText.stories.tsx +++ b/packages/manager/src/components/PasswordInput/HideShowText.stories.tsx @@ -6,7 +6,7 @@ import { HideShowText } from './HideShowText'; const meta: Meta = { component: HideShowText, - title: 'Components/Hide Show Text', + title: 'Components/Input/Hide Show Text', }; type Story = StoryObj; diff --git a/packages/manager/src/components/PasswordInput/PasswordInput.stories.tsx b/packages/manager/src/components/PasswordInput/PasswordInput.stories.tsx index 2e6fcfe4acb..67a76b58e8e 100644 --- a/packages/manager/src/components/PasswordInput/PasswordInput.stories.tsx +++ b/packages/manager/src/components/PasswordInput/PasswordInput.stories.tsx @@ -6,7 +6,7 @@ import PasswordInput from './PasswordInput'; const meta: Meta = { component: PasswordInput, - title: 'Components/Password Input', + title: 'Components/Input/Password Input', }; type Story = StoryObj; diff --git a/packages/manager/src/components/Radio/Radio.stories.tsx b/packages/manager/src/components/Radio/Radio.stories.tsx index 5a6d5d4e0b7..5c94585af41 100644 --- a/packages/manager/src/components/Radio/Radio.stories.tsx +++ b/packages/manager/src/components/Radio/Radio.stories.tsx @@ -27,7 +27,7 @@ const meta: Meta = { ), ], - title: 'Components/Radio', + title: 'Foundations/Radio', }; type Story = StoryObj; diff --git a/packages/manager/src/components/ShowMoreExpansion/ShowMoreExpansion.stories.tsx b/packages/manager/src/components/ShowMoreExpansion/ShowMoreExpansion.stories.tsx index 2fce69d155d..a655dd4489a 100644 --- a/packages/manager/src/components/ShowMoreExpansion/ShowMoreExpansion.stories.tsx +++ b/packages/manager/src/components/ShowMoreExpansion/ShowMoreExpansion.stories.tsx @@ -26,7 +26,7 @@ const meta: Meta = { name: 'Show More', }, component: ShowMoreExpansion, - title: 'Components/Accordion/ShowMoreExpansion', + title: 'Foundations/Accordion/ShowMoreExpansion', }; export default meta; diff --git a/packages/manager/src/components/Stack.stories.tsx b/packages/manager/src/components/Stack.stories.tsx index 10332c01220..0a08390b6b0 100644 --- a/packages/manager/src/components/Stack.stories.tsx +++ b/packages/manager/src/components/Stack.stories.tsx @@ -55,7 +55,7 @@ export const WithDivider: StoryObj = { const meta: Meta = { component: Stack, - title: 'Components/Stack', + title: 'Foundations/Stack', }; export default meta; diff --git a/packages/manager/src/components/StatusIcon/StatusIcon.stories.tsx b/packages/manager/src/components/StatusIcon/StatusIcon.stories.tsx index efa2956860c..99e01d92df0 100644 --- a/packages/manager/src/components/StatusIcon/StatusIcon.stories.tsx +++ b/packages/manager/src/components/StatusIcon/StatusIcon.stories.tsx @@ -5,7 +5,7 @@ import { StatusIcon } from './StatusIcon'; const meta: Meta = { component: StatusIcon, - title: 'Components/StatusIcon', + title: 'Icons/StatusIcon', }; type Story = StoryObj; diff --git a/packages/manager/src/components/Tabs/Tabs.stories.tsx b/packages/manager/src/components/Tabs/Tabs.stories.tsx index 512b94f3669..7a279cfc407 100644 --- a/packages/manager/src/components/Tabs/Tabs.stories.tsx +++ b/packages/manager/src/components/Tabs/Tabs.stories.tsx @@ -71,6 +71,6 @@ const meta: Meta = { onChange: () => null, }, component: Tabs, - title: 'Components/Tabs', + title: 'Foundations/Tabs', }; export default meta; diff --git a/packages/manager/src/components/TextField.stories.tsx b/packages/manager/src/components/TextField.stories.tsx index 133499c6154..58ee3393e74 100644 --- a/packages/manager/src/components/TextField.stories.tsx +++ b/packages/manager/src/components/TextField.stories.tsx @@ -6,7 +6,7 @@ import { TextField } from './TextField'; const meta: Meta = { component: TextField, - title: 'Components/TextField', + title: 'Foundations/TextField', }; type Story = StoryObj; diff --git a/packages/manager/src/components/Toggle/Toggle.stories.tsx b/packages/manager/src/components/Toggle/Toggle.stories.tsx index 62c7ced65b1..95dbe76ab46 100644 --- a/packages/manager/src/components/Toggle/Toggle.stories.tsx +++ b/packages/manager/src/components/Toggle/Toggle.stories.tsx @@ -16,7 +16,7 @@ const meta: Meta = { disabled: false, }, component: Toggle, - title: 'Components/Toggle', + title: 'Foundations/Toggle', }; export default meta; diff --git a/packages/manager/src/components/Typography.stories.tsx b/packages/manager/src/components/Typography.stories.tsx index 4f6a9bcf658..82b893f269d 100644 --- a/packages/manager/src/components/Typography.stories.tsx +++ b/packages/manager/src/components/Typography.stories.tsx @@ -5,7 +5,7 @@ import { Typography } from './Typography'; const meta: Meta = { component: Typography, - title: 'Components/Typography', + title: 'Foundations/Typography', }; type Story = StoryObj; From 93346690e36d1d162c3a3d117eb2d34aa80b9027 Mon Sep 17 00:00:00 2001 From: Alban Bailly <130582365+abailly-akamai@users.noreply.github.com> Date: Fri, 23 Aug 2024 17:44:08 -0400 Subject: [PATCH 17/19] change: [M3-8384] - Update storybook to fix dependency vulnerabilities (#10827) * Update storybook * Added changeset: Update storybook to fix IP package vulnerability --- .../pr-10827-tech-stories-1724432793341.md | 5 + packages/manager/package.json | 28 +- yarn.lock | 1577 ++++------------- 3 files changed, 353 insertions(+), 1257 deletions(-) create mode 100644 packages/manager/.changeset/pr-10827-tech-stories-1724432793341.md diff --git a/packages/manager/.changeset/pr-10827-tech-stories-1724432793341.md b/packages/manager/.changeset/pr-10827-tech-stories-1724432793341.md new file mode 100644 index 00000000000..5cf22e645af --- /dev/null +++ b/packages/manager/.changeset/pr-10827-tech-stories-1724432793341.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Tech Stories +--- + +Update storybook to fix IP package vulnerability ([#10827](https://github.com/linode/manager/pull/10827)) diff --git a/packages/manager/package.json b/packages/manager/package.json index d4a170aec97..8d14b7950e3 100644 --- a/packages/manager/package.json +++ b/packages/manager/package.json @@ -113,19 +113,19 @@ }, "devDependencies": { "@linode/eslint-plugin-cloud-manager": "^0.0.3", - "@storybook/addon-actions": "^8.1.0", - "@storybook/addon-controls": "^8.1.0", - "@storybook/addon-docs": "^8.1.0", - "@storybook/addon-mdx-gfm": "^8.1.0", - "@storybook/addon-measure": "^8.1.0", - "@storybook/addon-storysource": "^8.1.0", - "@storybook/addon-viewport": "^8.1.0", - "@storybook/blocks": "^8.1.0", - "@storybook/manager-api": "^8.1.0", - "@storybook/preview-api": "^8.1.0", - "@storybook/react": "^8.1.0", - "@storybook/react-vite": "^8.1.0", - "@storybook/theming": "^8.1.0", + "@storybook/addon-actions": "^8.2.9", + "@storybook/addon-controls": "^8.2.9", + "@storybook/addon-docs": "^8.2.9", + "@storybook/addon-mdx-gfm": "^8.2.9", + "@storybook/addon-measure": "^8.2.9", + "@storybook/addon-storysource": "^8.2.9", + "@storybook/addon-viewport": "^8.2.9", + "@storybook/blocks": "^8.2.9", + "@storybook/manager-api": "^8.2.9", + "@storybook/preview-api": "^8.2.9", + "@storybook/react": "^8.2.9", + "@storybook/react-vite": "^8.2.9", + "@storybook/theming": "^8.2.9", "@swc/core": "^1.3.1", "@testing-library/cypress": "^10.0.2", "@testing-library/dom": "^10.1.0", @@ -208,7 +208,7 @@ "reselect-tools": "^0.0.7", "serve": "^14.0.1", "simple-git": "^3.19.0", - "storybook": "^8.1.0", + "storybook": "^8.2.9", "storybook-dark-mode": "^4.0.1", "ts-node": "^10.9.2", "vite": "^5.1.7", diff --git a/yarn.lock b/yarn.lock index a98054d3224..bc2c443ac67 100644 --- a/yarn.lock +++ b/yarn.lock @@ -124,13 +124,6 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@aw-web-design/x-default-browser@1.4.126": - version "1.4.126" - resolved "https://registry.yarnpkg.com/@aw-web-design/x-default-browser/-/x-default-browser-1.4.126.tgz#43e4bd8f0314ed907a8718d7e862a203af79bc16" - integrity sha512-Xk1sIhyNC/esHGGVjL/niHLowM0csl/kFO5uawBy4IrWwy0o1G8LGt3jP6nmWGz+USxeeqbihAmp/oVZju6wug== - dependencies: - default-browser-id "3.0.0" - "@babel/code-frame@7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" @@ -224,7 +217,7 @@ "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/generator@^7.24.4", "@babel/generator@^7.24.5": +"@babel/generator@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.5.tgz#e5afc068f932f05616b66713e28d0f04e99daeb3" integrity sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA== @@ -569,7 +562,7 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.0.tgz#26a3d1ff49031c53a97d03b604375f028746a9ac" integrity sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg== -"@babel/parser@^7.24.4", "@babel/parser@^7.24.5": +"@babel/parser@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790" integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg== @@ -1379,7 +1372,7 @@ "@babel/parser" "^7.25.0" "@babel/types" "^7.25.0" -"@babel/traverse@^7.18.9", "@babel/traverse@^7.23.3", "@babel/traverse@^7.23.9", "@babel/traverse@^7.24.1", "@babel/traverse@^7.24.5", "@babel/traverse@^7.7.0": +"@babel/traverse@^7.18.9", "@babel/traverse@^7.23.3", "@babel/traverse@^7.23.9", "@babel/traverse@^7.24.5", "@babel/traverse@^7.7.0": version "7.25.3" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.3.tgz#f1b901951c83eda2f3e29450ce92743783373490" integrity sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ== @@ -1584,11 +1577,6 @@ debug "^3.1.0" lodash.once "^4.1.1" -"@discoveryjs/json-ext@^0.5.3": - version "0.5.7" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" - integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== - "@emotion/babel-plugin@^11.11.0": version "11.11.0" resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" @@ -1778,230 +1766,230 @@ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA== -"@esbuild/aix-ppc64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537" - integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g== +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== "@esbuild/android-arm64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4" integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA== -"@esbuild/android-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9" - integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg== +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== "@esbuild/android-arm@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824" integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w== -"@esbuild/android-arm@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995" - integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w== +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== "@esbuild/android-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d" integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew== -"@esbuild/android-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98" - integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg== +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== "@esbuild/darwin-arm64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz#cbee41e988020d4b516e9d9e44dd29200996275e" integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g== -"@esbuild/darwin-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz#6e8517a045ddd86ae30c6608c8475ebc0c4000bb" - integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA== +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== "@esbuild/darwin-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd" integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== -"@esbuild/darwin-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0" - integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA== +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== "@esbuild/freebsd-arm64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487" integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA== -"@esbuild/freebsd-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911" - integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw== +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== "@esbuild/freebsd-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c" integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg== -"@esbuild/freebsd-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c" - integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw== +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== "@esbuild/linux-arm64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b" integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA== -"@esbuild/linux-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5" - integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A== +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== "@esbuild/linux-arm@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef" integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w== -"@esbuild/linux-arm@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c" - integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg== +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== "@esbuild/linux-ia32@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601" integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA== -"@esbuild/linux-ia32@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa" - integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig== +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== "@esbuild/linux-loong64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299" integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA== -"@esbuild/linux-loong64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5" - integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ== +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== "@esbuild/linux-mips64el@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec" integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w== -"@esbuild/linux-mips64el@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa" - integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA== +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== "@esbuild/linux-ppc64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8" integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg== -"@esbuild/linux-ppc64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20" - integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg== +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== "@esbuild/linux-riscv64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf" integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg== -"@esbuild/linux-riscv64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300" - integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg== +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== "@esbuild/linux-s390x@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8" integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg== -"@esbuild/linux-s390x@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685" - integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ== +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== "@esbuild/linux-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78" integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg== -"@esbuild/linux-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff" - integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw== +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== "@esbuild/netbsd-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b" integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA== -"@esbuild/netbsd-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6" - integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ== +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== "@esbuild/openbsd-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0" integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw== -"@esbuild/openbsd-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf" - integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ== +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== "@esbuild/sunos-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30" integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA== -"@esbuild/sunos-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f" - integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w== +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== "@esbuild/win32-arm64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae" integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A== -"@esbuild/win32-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90" - integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ== +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== "@esbuild/win32-ia32@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67" integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ== -"@esbuild/win32-ia32@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23" - integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ== +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== "@esbuild/win32-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz#c57c8afbb4054a3ab8317591a0b7320360b444ae" integrity sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA== -"@esbuild/win32-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc" - integrity sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ== +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" @@ -2055,11 +2043,6 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== -"@fal-works/esbuild-plugin-global-externals@^2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz#c05ed35ad82df8e6ac616c68b92c2282bd083ba4" - integrity sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ== - "@floating-ui/core@^1.6.0": version "1.6.0" resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.0.tgz#fa41b87812a16bf123122bf945946bae3fdf7fc1" @@ -2410,15 +2393,6 @@ prop-types "^15.8.1" react-is "^18.2.0" -"@ndelangen/get-tarball@^3.0.7": - version "3.0.9" - resolved "https://registry.yarnpkg.com/@ndelangen/get-tarball/-/get-tarball-3.0.9.tgz#727ff4454e65f34707e742a59e5e6b1f525d8964" - integrity sha512-9JKTEik4vq+yGosHYhZ1tiH/3WpUS0Nh0kej4Agndhox8pAdWhEx5knFVRcb/ya9knCRCs1rPxNrSXTDdfVqpA== - dependencies: - gunzip-maybe "^1.4.2" - pump "^3.0.0" - tar-fs "^2.1.1" - "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -2502,13 +2476,6 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== -"@radix-ui/primitive@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.1.tgz#e46f9958b35d10e9f6dc71c497305c22e3e55dbd" - integrity sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz#7ed868b66946aa6030e580b1ffca386dd4d21989" @@ -2516,97 +2483,7 @@ dependencies: "@babel/runtime" "^7.13.10" -"@radix-ui/react-context@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.1.tgz#fe46e67c96b240de59187dcb7a1a50ce3e2ec00c" - integrity sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg== - dependencies: - "@babel/runtime" "^7.13.10" - -"@radix-ui/react-dialog@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz#71657b1b116de6c7a0b03242d7d43e01062c7300" - integrity sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-dismissable-layer" "1.0.5" - "@radix-ui/react-focus-guards" "1.0.1" - "@radix-ui/react-focus-scope" "1.0.4" - "@radix-ui/react-id" "1.0.1" - "@radix-ui/react-portal" "1.0.4" - "@radix-ui/react-presence" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-slot" "1.0.2" - "@radix-ui/react-use-controllable-state" "1.0.1" - aria-hidden "^1.1.1" - react-remove-scroll "2.5.5" - -"@radix-ui/react-dismissable-layer@1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz#3f98425b82b9068dfbab5db5fff3df6ebf48b9d4" - integrity sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-use-callback-ref" "1.0.1" - "@radix-ui/react-use-escape-keydown" "1.0.3" - -"@radix-ui/react-focus-guards@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad" - integrity sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA== - dependencies: - "@babel/runtime" "^7.13.10" - -"@radix-ui/react-focus-scope@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz#2ac45fce8c5bb33eb18419cdc1905ef4f1906525" - integrity sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-use-callback-ref" "1.0.1" - -"@radix-ui/react-id@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0" - integrity sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-layout-effect" "1.0.1" - -"@radix-ui/react-portal@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15" - integrity sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-primitive" "1.0.3" - -"@radix-ui/react-presence@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba" - integrity sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-use-layout-effect" "1.0.1" - -"@radix-ui/react-primitive@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz#d49ea0f3f0b2fe3ab1cb5667eb03e8b843b914d0" - integrity sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-slot" "1.0.2" - -"@radix-ui/react-slot@1.0.2", "@radix-ui/react-slot@^1.0.2": +"@radix-ui/react-slot@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.2.tgz#a9ff4423eade67f501ffb32ec22064bc9d3099ab" integrity sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg== @@ -2614,36 +2491,6 @@ "@babel/runtime" "^7.13.10" "@radix-ui/react-compose-refs" "1.0.1" -"@radix-ui/react-use-callback-ref@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz#f4bb1f27f2023c984e6534317ebc411fc181107a" - integrity sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ== - dependencies: - "@babel/runtime" "^7.13.10" - -"@radix-ui/react-use-controllable-state@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz#ecd2ced34e6330caf89a82854aa2f77e07440286" - integrity sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-callback-ref" "1.0.1" - -"@radix-ui/react-use-escape-keydown@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755" - integrity sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-callback-ref" "1.0.1" - -"@radix-ui/react-use-layout-effect@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz#be8c7bc809b0c8934acf6657b577daf948a75399" - integrity sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ== - dependencies: - "@babel/runtime" "^7.13.10" - "@reach/auto-id@0.10.5": version "0.10.5" resolved "https://registry.yarnpkg.com/@reach/auto-id/-/auto-id-0.10.5.tgz#fa78c71ce2f565ebed1ad91a8d9a685176d23c48" @@ -2846,46 +2693,37 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz#719df7fb41766bc143369eaa0dd56d8dc87c9958" integrity sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg== -"@storybook/addon-actions@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-8.1.0.tgz#2191c05ca520890da923867c4ac6bb6f295d5115" - integrity sha512-6c/uZo8peHh7ZWBsNAPDSdj9keBp1q7Gddci3LIxq9S8gFLEgPwjAv+f6HVx0T61wG5PGnK0ilZsrCrXyoJodA== +"@storybook/addon-actions@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-8.2.9.tgz#5a27f07f276ec776fb768f5da9bfe2c43fe3e851" + integrity sha512-eh2teOqjga7aoClDVV+/b1gHJqsPwjiU1t+Hg/l4i2CkaBUNdYMEL90nR6fgReOdvvL5YhcPwJ8w38f9TrQcoQ== dependencies: - "@storybook/core-events" "8.1.0" "@storybook/global" "^5.0.0" "@types/uuid" "^9.0.1" dequal "^2.0.2" polished "^4.2.2" uuid "^9.0.0" -"@storybook/addon-controls@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-8.1.0.tgz#744b62a6f667f8222c7bd476c9d2b81b6f81b39d" - integrity sha512-2WNzoQ3Xd8o3H8qvy4h+mLSccz8Bfo0Fmwfi4f/BTaqNkJsxLut4A1NiI9xS7i7GvtzGaTUcnbrOubiY2tG2/A== +"@storybook/addon-controls@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-8.2.9.tgz#43f9ca53e2a709feee0c1fe6db3daee8953d2ddd" + integrity sha512-vaSE78KOE7SO0GrW4e+mdQphSNpvCX/FGybIRxyaKX9h8smoyUwRNHVyCS3ROHTwH324QWu7GDzsOVrnyXOv0A== dependencies: - "@storybook/blocks" "8.1.0" dequal "^2.0.2" lodash "^4.17.21" ts-dedent "^2.0.0" -"@storybook/addon-docs@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-8.1.0.tgz#672f56baf49221451eb67aaa9e79fe0a1ea053e2" - integrity sha512-s6bmAv5JxZiIgkG4Aup0RRrDW8Kt1XXm88m4wRqR5dnKoBaCSbjdxeJZBLb0FD6PMw0oBHltXCcZkSewsTitQQ== +"@storybook/addon-docs@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-8.2.9.tgz#bc6737cab5b3620b9291de7c14f92ad92b5a90db" + integrity sha512-flDOxFIGmXg+6lVdwTLMOKsGob1WrT7rG98mn1SNW0Nxhg3Wg+9pQuq1GLxEzKtAgSflmu+xcBRfYhsogyDXkw== dependencies: "@babel/core" "^7.24.4" "@mdx-js/react" "^3.0.0" - "@storybook/blocks" "8.1.0" - "@storybook/client-logger" "8.1.0" - "@storybook/components" "8.1.0" - "@storybook/csf-plugin" "8.1.0" - "@storybook/csf-tools" "8.1.0" + "@storybook/blocks" "8.2.9" + "@storybook/csf-plugin" "8.2.9" "@storybook/global" "^5.0.0" - "@storybook/node-logger" "8.1.0" - "@storybook/preview-api" "8.1.0" - "@storybook/react-dom-shim" "8.1.0" - "@storybook/theming" "8.1.0" - "@storybook/types" "8.1.0" + "@storybook/react-dom-shim" "8.2.9" "@types/react" "^16.8.0 || ^17.0.0 || ^18.0.0" fs-extra "^11.1.0" react "^16.8.0 || ^17.0.0 || ^18.0.0" @@ -2894,107 +2732,68 @@ rehype-slug "^6.0.0" ts-dedent "^2.0.0" -"@storybook/addon-mdx-gfm@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/addon-mdx-gfm/-/addon-mdx-gfm-8.1.0.tgz#38be4fa5553f574bd8bfd282a340471c2a857f09" - integrity sha512-71QMcOLEo44keheOrTQWS5fPxHceQD/XeRUZtUxVrMBul9R80jxJ7WI2fRQkYM0P8FxFjZ0kFKeRlflO+E1Upw== +"@storybook/addon-mdx-gfm@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-mdx-gfm/-/addon-mdx-gfm-8.2.9.tgz#b86826d833dd2e4fd00e5f21520fcd7a924368aa" + integrity sha512-qpv3oVBVStXKcYmhmsEDVlWvdOpG4bHGOchCe2iU/wlcT5zFQSpQj2IoCNbj5MxhwAw2VobrAvRjNQjv95fYAg== dependencies: - "@storybook/node-logger" "8.1.0" remark-gfm "^4.0.0" ts-dedent "^2.0.0" -"@storybook/addon-measure@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-8.1.0.tgz#b863fc992cff0e0aa920e7363b006258dd9f7828" - integrity sha512-E4QfmUTQIct4TuKKkf2sRui0OlR1jBSMMx8vl3lD15b2C1TWPXnhhOmSg0SDibAUO010KTul65enhSuqKnPEOA== +"@storybook/addon-measure@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-8.2.9.tgz#998995c31980d635132c42a8d621095e73adb9b6" + integrity sha512-XUfQtYRKWB2dfbPRmHuos816wt1JrLbtRld5ZC8J8ljeqZ4hFBPTQcgI5GAzZqjQuclLC0KuhlA/0bKxdxMMGA== dependencies: "@storybook/global" "^5.0.0" tiny-invariant "^1.3.1" -"@storybook/addon-storysource@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/addon-storysource/-/addon-storysource-8.1.0.tgz#8cd84b51ebbeea65b7226b54cb0e31309ec08754" - integrity sha512-IQp6/ZOD0CizN+k2BNxjFcppk6dvb6+aLsMFOXii/EIm7W/3wjtCOjA2pLJtDYzKAnE127vTqHZgbcKCsSyfyA== +"@storybook/addon-storysource@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-storysource/-/addon-storysource-8.2.9.tgz#c9e3e169d4b8ca646bdcd43cc5f6250fc21cc710" + integrity sha512-zSfw4FNjzSGdWvNhrjJgiqabQAklCXR3Xa0Hp5/5omG9Wl/JdiAKw9ysycQXovAv4VuubxS1x0pOTo6Wg40M3A== dependencies: - "@storybook/source-loader" "8.1.0" + "@storybook/source-loader" "8.2.9" estraverse "^5.2.0" tiny-invariant "^1.3.1" -"@storybook/addon-viewport@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-8.1.0.tgz#64b919b4fe4c0552ec8a4e111c3abd4d16f4835e" - integrity sha512-FN8V0L6rlDAgomHR9hWfOo+KwiNRpkyjJb2M7wV7ThT4azhAnDF1usBYO6eRUasJUjCKhnE8yB1VghbZWJuORg== +"@storybook/addon-viewport@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-8.2.9.tgz#56f7273450b72384bb79e9ddeab2f633f869be73" + integrity sha512-lyM24+DJEt8R0YZkJKee34NQWv0REACU6lYDalqJNdKS1sEwzLGWxg1hZXnw2JFdBID9NGVvyYU2w6LDozOB0g== dependencies: memoizerific "^1.11.3" -"@storybook/blocks@8.1.0", "@storybook/blocks@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/blocks/-/blocks-8.1.0.tgz#b8f24a5455984d28d9a8664e8b053adb616417a8" - integrity sha512-yQio/n6l3LN/TRADplxpWYsz1+vM0PiwSMpUjSEW8PfN0gnr5kQr1k/8gZGmwCeJllODFPRB5159mjbzfjT0WQ== - dependencies: - "@storybook/channels" "8.1.0" - "@storybook/client-logger" "8.1.0" - "@storybook/components" "8.1.0" - "@storybook/core-events" "8.1.0" - "@storybook/csf" "^0.1.7" - "@storybook/docs-tools" "8.1.0" +"@storybook/blocks@8.2.9", "@storybook/blocks@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/blocks/-/blocks-8.2.9.tgz#3c9018619704cee23c9e69ff263e3c0aaa9a7ccc" + integrity sha512-5276q/s/UL8arwftuBXovUNHqYo/HPQFMGXEmjVVAMXUyFjzEAfKj3+xU897J6AuL+7XVZG32WnqA+X6LJMrcQ== + dependencies: + "@storybook/csf" "0.1.11" "@storybook/global" "^5.0.0" "@storybook/icons" "^1.2.5" - "@storybook/manager-api" "8.1.0" - "@storybook/preview-api" "8.1.0" - "@storybook/theming" "8.1.0" - "@storybook/types" "8.1.0" "@types/lodash" "^4.14.167" color-convert "^2.0.1" dequal "^2.0.2" lodash "^4.17.21" - markdown-to-jsx "7.3.2" + markdown-to-jsx "^7.4.5" memoizerific "^1.11.3" polished "^4.2.2" react-colorful "^5.1.2" telejson "^7.2.0" - tocbot "^4.20.1" ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/builder-manager@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/builder-manager/-/builder-manager-8.1.0.tgz#e4b8b94484f596ebaa7d1921e723b1b90b9bc17c" - integrity sha512-QG6XRxk8Nm4BRAbwkLILts7YPF78cM/3mXH1y/zbMnxYE0suNtxb0Q9B9qE5cFK2dhgiWIprF6RWaP5kv8bpig== - dependencies: - "@fal-works/esbuild-plugin-global-externals" "^2.1.2" - "@storybook/core-common" "8.1.0" - "@storybook/manager" "8.1.0" - "@storybook/node-logger" "8.1.0" - "@types/ejs" "^3.1.1" - "@yarnpkg/esbuild-plugin-pnp" "^3.0.0-rc.10" - browser-assert "^1.2.1" - ejs "^3.1.10" - esbuild "^0.18.0 || ^0.19.0 || ^0.20.0" - esbuild-plugin-alias "^0.2.1" - express "^4.17.3" - fs-extra "^11.1.0" - process "^0.11.10" - util "^0.12.4" - -"@storybook/builder-vite@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/builder-vite/-/builder-vite-8.1.0.tgz#30aa11c33040ea8d234b1fb0a5981d2050adb685" - integrity sha512-KCTWA4gFMHm0u5YXYIaGiPasCeAzMo1yE9Z/vyWRL+2sifwDPTDu3QOhlBblGPdLzA18LVJuKcfcuWPqiQrIdA== - dependencies: - "@storybook/channels" "8.1.0" - "@storybook/client-logger" "8.1.0" - "@storybook/core-common" "8.1.0" - "@storybook/core-events" "8.1.0" - "@storybook/csf-plugin" "8.1.0" - "@storybook/node-logger" "8.1.0" - "@storybook/preview" "8.1.0" - "@storybook/preview-api" "8.1.0" - "@storybook/types" "8.1.0" +"@storybook/builder-vite@8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/builder-vite/-/builder-vite-8.2.9.tgz#f140a8a8c5cf745c847d2f37841e0f2f98926fcc" + integrity sha512-MHD3ezRjKkJkOl0u7CRQoQD/LKd28YMWIcaz4YrV6ygokc0c3RFTlOefICQFgboc+1RwIUowxN1CJ2kJ7p4SWw== + dependencies: + "@storybook/csf-plugin" "8.2.9" "@types/find-cache-dir" "^3.2.1" browser-assert "^1.2.1" es-module-lexer "^1.5.0" - express "^4.17.3" + express "^4.19.2" find-cache-dir "^3.0.0" fs-extra "^11.1.0" magic-string "^0.30.0" @@ -3011,59 +2810,6 @@ telejson "^7.2.0" tiny-invariant "^1.3.1" -"@storybook/channels@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-8.1.0.tgz#433902f8e3f5f6fa2c57152f3bff5a1e67c9c053" - integrity sha512-zZ6f1IC6AlQfPcVJeRH9MyzaGBXdniVREbjdM4qDHJkHKtWs92K2IXQ3W/aAIFKbpKKYadTWu+UQfULw0oAG3Q== - dependencies: - "@storybook/client-logger" "8.1.0" - "@storybook/core-events" "8.1.0" - "@storybook/global" "^5.0.0" - telejson "^7.2.0" - tiny-invariant "^1.3.1" - -"@storybook/cli@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/cli/-/cli-8.1.0.tgz#f2e60ecfdd621a1e61f8c5b2a343b478bc53e81e" - integrity sha512-+/wQ9JfoE+GVNpozwltUqINqlQaAU1kEAdA52q/KRVrlvQ6GhU3NkR64ZNg4IOWs4I3LKy9YXgQ++UnBqVwO5A== - dependencies: - "@babel/core" "^7.24.4" - "@babel/types" "^7.24.0" - "@ndelangen/get-tarball" "^3.0.7" - "@storybook/codemod" "8.1.0" - "@storybook/core-common" "8.1.0" - "@storybook/core-events" "8.1.0" - "@storybook/core-server" "8.1.0" - "@storybook/csf-tools" "8.1.0" - "@storybook/node-logger" "8.1.0" - "@storybook/telemetry" "8.1.0" - "@storybook/types" "8.1.0" - "@types/semver" "^7.3.4" - "@yarnpkg/fslib" "2.10.3" - "@yarnpkg/libzip" "2.3.0" - chalk "^4.1.0" - commander "^6.2.1" - cross-spawn "^7.0.3" - detect-indent "^6.1.0" - envinfo "^7.7.3" - execa "^5.0.0" - find-up "^5.0.0" - fs-extra "^11.1.0" - get-npm-tarball-url "^2.0.3" - giget "^1.0.0" - globby "^14.0.1" - jscodeshift "^0.15.1" - leven "^3.1.0" - ora "^5.4.1" - prettier "^3.1.1" - prompts "^2.4.0" - read-pkg-up "^7.0.1" - semver "^7.3.7" - strip-json-comments "^3.0.1" - tempy "^1.0.1" - tiny-invariant "^1.3.1" - ts-dedent "^2.0.0" - "@storybook/client-logger@8.0.5": version "8.0.5" resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-8.0.5.tgz#8cafa514e9a9af054f926bc179264bef2198c0ce" @@ -3071,25 +2817,16 @@ dependencies: "@storybook/global" "^5.0.0" -"@storybook/client-logger@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-8.1.0.tgz#525df1cce30e50752e15b5dd917c54315c865714" - integrity sha512-MPNggo4g/J/40muUsyo+LUN3BBcOb4FK5AD+yjDgbBPo2IwXCNqOdCHkz0TEALIVMMZ0KSdFW7uB/cFnfq/Xdw== - dependencies: - "@storybook/global" "^5.0.0" - -"@storybook/codemod@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/codemod/-/codemod-8.1.0.tgz#eba8b1956056a8feab196311228236d938195b19" - integrity sha512-RQr8/bbn4l3Du0L53AIcOc13qrDjaod8olD2SK4b4l0WoiG5OHbx4UAicC6diVhILj3hKkd4oF78STSwnDdV4A== +"@storybook/codemod@8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/codemod/-/codemod-8.2.9.tgz#f6c7f43a5aa326b64544ad6f10038edc32293827" + integrity sha512-3yRx1lFMm1FXWVv+CKDiYM4gOQPEfpcZAQrjfcumxSDUrB091pnU1PeI92Prj3vCdi4+0oPNuN4yDGNUYTMP/A== dependencies: "@babel/core" "^7.24.4" "@babel/preset-env" "^7.24.4" "@babel/types" "^7.24.0" - "@storybook/csf" "^0.1.7" - "@storybook/csf-tools" "8.1.0" - "@storybook/node-logger" "8.1.0" - "@storybook/types" "8.1.0" + "@storybook/core" "8.2.9" + "@storybook/csf" "0.1.11" "@types/cross-spawn" "^6.0.2" cross-spawn "^7.0.3" globby "^14.0.1" @@ -3099,22 +2836,6 @@ recast "^0.23.5" tiny-invariant "^1.3.1" -"@storybook/components@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/components/-/components-8.1.0.tgz#3930172443864635e6771ec9ed766417c9db870f" - integrity sha512-KFW2MXYzp3fF5pbhR+rKDN7TBFvoXp/EseByic4l7hM7P8QQN9Mm6xYMQ2T3uJtQmdEafJTa/LIqfD5kxrRqLA== - dependencies: - "@radix-ui/react-dialog" "^1.0.5" - "@radix-ui/react-slot" "^1.0.2" - "@storybook/client-logger" "8.1.0" - "@storybook/csf" "^0.1.7" - "@storybook/global" "^5.0.0" - "@storybook/icons" "^1.2.5" - "@storybook/theming" "8.1.0" - "@storybook/types" "8.1.0" - memoizerific "^1.11.3" - util-deprecate "^1.0.2" - "@storybook/components@^8.0.0": version "8.0.5" resolved "https://registry.yarnpkg.com/@storybook/components/-/components-8.0.5.tgz#e526b4600b4b8049108a1b63e71fee8d75ff8d3d" @@ -3130,40 +2851,10 @@ memoizerific "^1.11.3" util-deprecate "^1.0.2" -"@storybook/core-common@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-8.1.0.tgz#895f167b8b285572ee864cdc1de7a8463a4c1568" - integrity sha512-VDiJl+AyQLA0ys7an2O8fmgdFgaftJacVrO3P+5RtQob9BC057Mp3pq1lr1Si8orKPwFZhNJOfiF9jQeV5K+bw== - dependencies: - "@storybook/core-events" "8.1.0" - "@storybook/csf-tools" "8.1.0" - "@storybook/node-logger" "8.1.0" - "@storybook/types" "8.1.0" - "@yarnpkg/fslib" "2.10.3" - "@yarnpkg/libzip" "2.3.0" - chalk "^4.1.0" - cross-spawn "^7.0.3" - esbuild "^0.18.0 || ^0.19.0 || ^0.20.0" - esbuild-register "^3.5.0" - execa "^5.0.0" - file-system-cache "2.3.0" - find-cache-dir "^3.0.0" - find-up "^5.0.0" - fs-extra "^11.1.0" - glob "^10.0.0" - handlebars "^4.7.7" - lazy-universal-dotenv "^4.0.0" - node-fetch "^2.0.0" - picomatch "^2.3.0" - pkg-dir "^5.0.0" - prettier-fallback "npm:prettier@^3" - pretty-hrtime "^1.0.3" - resolve-from "^5.0.0" - semver "^7.3.7" - tempy "^1.0.1" - tiny-invariant "^1.3.1" - ts-dedent "^2.0.0" - util "^0.12.4" +"@storybook/components@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-8.2.9.tgz#a2394749d52940b7a224d1d4801d756b2750b488" + integrity sha512-OkkcZ/f/6o3GdFEEK9ZHKIGHWUHmavZUYs5xaSgU64bOrA2aqEFtfeWWitZYTv3Euhk8MVLWfyEMDfez0AlvDg== "@storybook/core-events@8.0.5", "@storybook/core-events@^8.0.0": version "8.0.5" @@ -3172,88 +2863,36 @@ dependencies: ts-dedent "^2.0.0" -"@storybook/core-events@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-8.1.0.tgz#1eec094bd0b7e2d7900a72da27bdd94254d65947" - integrity sha512-9oCACeyYqH7rZVHglzH//cJXdP0mM5d2nBM4kgFgTTLJpbb0+SrF0rD0EVpHfA1l4Kz7pgzTY6Xj2p4mEiZ0Qg== - dependencies: - "@storybook/csf" "^0.1.7" - ts-dedent "^2.0.0" - -"@storybook/core-server@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-8.1.0.tgz#116270cd7f0a00e03651dec099b439d5340719e8" - integrity sha512-12BjLHOND9mezi8/8VgyB8U80DOFcMqmgPTy6y6TkEmpI3TszbMIIderuWWXU0Yq9rFGya34+e2Srd6ffYh6hA== +"@storybook/core@8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/core/-/core-8.2.9.tgz#68f8659014e06f4f65f6dbdf1dd10850f31d23b3" + integrity sha512-wSER8FpA6Il/jPyDfKm3yohxDtuhisNPTonMVzd3ulNWR4zERLddyO3HrHJJwdqYHLNk4SBFzwMGpQZVws1y0w== dependencies: - "@aw-web-design/x-default-browser" "1.4.126" - "@babel/core" "^7.24.4" - "@babel/parser" "^7.24.4" - "@discoveryjs/json-ext" "^0.5.3" - "@storybook/builder-manager" "8.1.0" - "@storybook/channels" "8.1.0" - "@storybook/core-common" "8.1.0" - "@storybook/core-events" "8.1.0" - "@storybook/csf" "^0.1.7" - "@storybook/csf-tools" "8.1.0" - "@storybook/docs-mdx" "3.1.0-next.0" - "@storybook/global" "^5.0.0" - "@storybook/manager" "8.1.0" - "@storybook/manager-api" "8.1.0" - "@storybook/node-logger" "8.1.0" - "@storybook/preview-api" "8.1.0" - "@storybook/telemetry" "8.1.0" - "@storybook/types" "8.1.0" - "@types/detect-port" "^1.3.0" - "@types/diff" "^5.0.9" + "@storybook/csf" "0.1.11" + "@types/express" "^4.17.21" "@types/node" "^18.0.0" - "@types/pretty-hrtime" "^1.0.0" - "@types/semver" "^7.3.4" - better-opn "^3.0.2" - chalk "^4.1.0" - cli-table3 "^0.6.1" - compression "^1.7.4" - detect-port "^1.3.0" - diff "^5.2.0" - express "^4.17.3" - fs-extra "^11.1.0" - globby "^14.0.1" - ip "^2.0.1" - lodash "^4.17.21" - open "^8.4.0" - pretty-hrtime "^1.0.3" - prompts "^2.4.0" - read-pkg-up "^7.0.1" - semver "^7.3.7" - telejson "^7.2.0" - tiny-invariant "^1.3.1" - ts-dedent "^2.0.0" + browser-assert "^1.2.1" + esbuild "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0" + esbuild-register "^3.5.0" + express "^4.19.2" + process "^0.11.10" + recast "^0.23.5" util "^0.12.4" - util-deprecate "^1.0.2" - watchpack "^2.2.0" ws "^8.2.3" -"@storybook/csf-plugin@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-8.1.0.tgz#bc581eea3a6efcb547bb65526635817dd7169425" - integrity sha512-xWisKhyAqpXXsLASsYD+auWeIHlWdAB+wryP6S1vFDUdwzJ7HOS+FT4c7wF8AQjkF5jHPfzChYjbgII/ae6P3w== +"@storybook/csf-plugin@8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-8.2.9.tgz#1ef4a4f4bf6a601ffae110dc9722ded834e422fa" + integrity sha512-QQCFb3g12VQQEraDV1UfCmniGhQZKyT6oEt1Im6dzzPJj9NQk+6BjWoDep33CZhBHWoLryrMQd2fjuHxnFRNEA== dependencies: - "@storybook/csf-tools" "8.1.0" unplugin "^1.3.1" -"@storybook/csf-tools@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-8.1.0.tgz#09248934254eda66f7b0b02ffd68048db395acd1" - integrity sha512-nMdBFmEh0Ep/931Z/2OflTFmD+SMiwIQf0UAZ7pVGXSjVHY+PNSPyTo8967BPu89I0gjXQXYJxL6SgSM60i3kg== +"@storybook/csf@0.1.11": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.11.tgz#ad685a4fe564a47a6b73571c2e7c07b526f4f71b" + integrity sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg== dependencies: - "@babel/generator" "^7.24.4" - "@babel/parser" "^7.24.4" - "@babel/traverse" "^7.24.1" - "@babel/types" "^7.24.0" - "@storybook/csf" "^0.1.7" - "@storybook/types" "8.1.0" - fs-extra "^11.1.0" - recast "^0.23.5" - ts-dedent "^2.0.0" + type-fest "^2.19.0" "@storybook/csf@^0.0.1": version "0.0.1" @@ -3269,32 +2908,6 @@ dependencies: type-fest "^2.19.0" -"@storybook/csf@^0.1.7": - version "0.1.7" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.7.tgz#dcc6c16a353bc09c8c619ba1a23ba93b2aab0b9d" - integrity sha512-53JeLZBibjQxi0Ep+/AJTfxlofJlxy1jXcSKENlnKxHjWEYyHQCumMP5yTFjf7vhNnMjEpV3zx6t23ssFiGRyw== - dependencies: - type-fest "^2.19.0" - -"@storybook/docs-mdx@3.1.0-next.0": - version "3.1.0-next.0" - resolved "https://registry.yarnpkg.com/@storybook/docs-mdx/-/docs-mdx-3.1.0-next.0.tgz#9567c6eb621110dcf6554923a975238953d06305" - integrity sha512-t4syFIeSyufieNovZbLruPt2DmRKpbwL4fERCZ1MifWDRIORCKLc4NCEHy+IqvIqd71/SJV2k4B51nF7vlJfmQ== - -"@storybook/docs-tools@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/docs-tools/-/docs-tools-8.1.0.tgz#2f7d9d6d55e7f0a450c4c1629c34cf39c092446e" - integrity sha512-Da0sQxStqTSeIUptBfU/OIhca4dkPld7GgBPV29FfdxreTAcg5gfJyUQH4v3yR/3x8QYHAbxmvUw5Rjnq03OKw== - dependencies: - "@storybook/core-common" "8.1.0" - "@storybook/core-events" "8.1.0" - "@storybook/preview-api" "8.1.0" - "@storybook/types" "8.1.0" - "@types/doctrine" "^0.0.3" - assert "^2.1.0" - doctrine "^3.0.0" - lodash "^4.17.21" - "@storybook/global@^5.0.0": version "5.0.0" resolved "https://registry.yarnpkg.com/@storybook/global/-/global-5.0.0.tgz#b793d34b94f572c1d7d9e0f44fac4e0dbc9572ed" @@ -3305,27 +2918,6 @@ resolved "https://registry.yarnpkg.com/@storybook/icons/-/icons-1.2.9.tgz#bb4a51a79e186b62e2dd0e04928b8617ac573838" integrity sha512-cOmylsz25SYXaJL/gvTk/dl3pyk7yBFRfeXTsHvTA3dfhoU/LWSq0NKL9nM7WBasJyn6XPSGnLS4RtKXLw5EUg== -"@storybook/manager-api@8.1.0", "@storybook/manager-api@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/manager-api/-/manager-api-8.1.0.tgz#d5580c0283ca6911895d28b4eec02661af5476cb" - integrity sha512-QLKpN4epgFiC7PkY7wyVphZi0fdoHWSq7f4VoLZkwDgCizdI0FjCsKYoHSKpzN8jQlLjv62DkpXM8z/JiWSSzg== - dependencies: - "@storybook/channels" "8.1.0" - "@storybook/client-logger" "8.1.0" - "@storybook/core-events" "8.1.0" - "@storybook/csf" "^0.1.7" - "@storybook/global" "^5.0.0" - "@storybook/icons" "^1.2.5" - "@storybook/router" "8.1.0" - "@storybook/theming" "8.1.0" - "@storybook/types" "8.1.0" - dequal "^2.0.2" - lodash "^4.17.21" - memoizerific "^1.11.3" - store2 "^2.14.2" - telejson "^7.2.0" - ts-dedent "^2.0.0" - "@storybook/manager-api@^8.0.0": version "8.0.5" resolved "https://registry.yarnpkg.com/@storybook/manager-api/-/manager-api-8.0.5.tgz#7fdc49803f1507bea97392bfd05760071a19d838" @@ -3347,73 +2939,47 @@ telejson "^7.2.0" ts-dedent "^2.0.0" -"@storybook/manager@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/manager/-/manager-8.1.0.tgz#6d7022926ba802d8689515b449a3b9acc8e6030c" - integrity sha512-SXDEm8s2bdmopoj42eSGwENXTQIo22hOIKRG3roMD1R3ddlQkFyMbcfXr2g+wNzGcKKyiTEOg/arG22HHaj6ig== - -"@storybook/node-logger@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-8.1.0.tgz#66c4fc81f15e5b7ba65c0b79e7c7388d5001b00f" - integrity sha512-oCUp2V+selKVCNE3RrbFoP6lW0HYtX0N8NLsMbuxnVRIg6BC4Tn6OJ0azIWjJWpIf60A80wOUKmlE36Q32ANYg== - -"@storybook/preview-api@8.1.0", "@storybook/preview-api@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-8.1.0.tgz#23a95fa8ae79d9be28a8ba45e5231a5758f585d6" - integrity sha512-JYp58I/+u4YBUvdDbQ7G1B7CPjB/C/UU7Wgb7bdX3Kp9jQto1hYO9Arq/ncMB7w6ZZJOwTeaI0PLAFsnpFwf4w== - dependencies: - "@storybook/channels" "8.1.0" - "@storybook/client-logger" "8.1.0" - "@storybook/core-events" "8.1.0" - "@storybook/csf" "^0.1.7" - "@storybook/global" "^5.0.0" - "@storybook/types" "8.1.0" - "@types/qs" "^6.9.5" - dequal "^2.0.2" - lodash "^4.17.21" - memoizerific "^1.11.3" - qs "^6.10.0" - tiny-invariant "^1.3.1" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" +"@storybook/manager-api@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/manager-api/-/manager-api-8.2.9.tgz#f09a83fce286bc48783c75e7d7184dd8a5381527" + integrity sha512-mkYvUlfqDw+0WbxIynh5TcrotmoXlumEsOA4+45zuNea8XpEgj5cNBUCnmfEO6yQ85swqkS8YYbMpg1cZyu/Vw== -"@storybook/preview@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/preview/-/preview-8.1.0.tgz#3ca11b0424a95576b9a626e558fb8d063a55d5dd" - integrity sha512-YithzpOWhoWT2mfl4hyE7WQCwqTD5snBdEzGzpby0Cb+2Dnx/8hejGLsrphqoZkciaWchQS8nTjs9Rgj43ufcA== +"@storybook/preview-api@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-8.2.9.tgz#e35ca783a1d98174e73223856397a9767766a737" + integrity sha512-D8/t+a78OJqQAcT/ABa1C4YM/OaLGQ9IvCsp3Q9ruUqDCwuZBj8bG3D4477dlY4owX2ycC0rWYu3VvuK0EmJjA== -"@storybook/react-dom-shim@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-8.1.0.tgz#3c0599da472f599b64f2f180b92b50cdd6d5d11c" - integrity sha512-mKj86pcwL9BXwtYF63SGnYmGvacYNRW/BDkotHMS1DaN7ZBqvXlEU7vopPVL6ay2Yono7AnqQR2eQl7cUevsag== +"@storybook/react-dom-shim@8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-8.2.9.tgz#db31bdab3a995759a9e45b2dc2ca0888a75fc89d" + integrity sha512-uCAjSQEsNk8somVn1j/I1G9G/uUax5byHseIIV0Eq3gVXttGd7gaWcP+TDHtqIaenWHx4l+hCSuCesxiLWmx4Q== -"@storybook/react-vite@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/react-vite/-/react-vite-8.1.0.tgz#673d7ecd015e69c67a5fcc7f1085eb299f20e85d" - integrity sha512-dzXh43/DqQhxg97sDF2nD0oRww6F1cuaOq81QjNnUEjznHacgYiGAnag1Y3GGO3MhnjfwZzOFj92O0ynY/M2iQ== +"@storybook/react-vite@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/react-vite/-/react-vite-8.2.9.tgz#4b836a7140d4c17796a57bbddebfc09185317294" + integrity sha512-Lw6FzcAaL7jX8Y8EsDzg32Lp0NdeNJZpj0LVwX5sLOQQA6w4i3PqlFINXDY28qCGo6wqKT+w44zhgwUcU5V0Ow== dependencies: "@joshwooding/vite-plugin-react-docgen-typescript" "0.3.1" "@rollup/pluginutils" "^5.0.2" - "@storybook/builder-vite" "8.1.0" - "@storybook/node-logger" "8.1.0" - "@storybook/react" "8.1.0" + "@storybook/builder-vite" "8.2.9" + "@storybook/react" "8.2.9" find-up "^5.0.0" magic-string "^0.30.0" react-docgen "^7.0.0" resolve "^1.22.8" tsconfig-paths "^4.2.0" -"@storybook/react@8.1.0", "@storybook/react@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/react/-/react-8.1.0.tgz#e89aa332c351fc0ac8bb772181961dd60336d523" - integrity sha512-IEyRsNRRDqkxwZOFqWwTRgMzOj2p3YXsmNyGiV3vOrssZhPOCEp1CMCup7OIHk5JTnejY5CNkZYgJFvKNL5ccA== +"@storybook/react@8.2.9", "@storybook/react@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-8.2.9.tgz#91348ab82e699a2d2f48b9721fe781782badc9ac" + integrity sha512-F2xZcTDxxjpbqt7eP8rEHmlksiKmE/qtPusEWEY4N4jK01kN+ncxSl8gkJpUohMEmAnVC5t/1v/sU57xv1DYpg== dependencies: - "@storybook/client-logger" "8.1.0" - "@storybook/docs-tools" "8.1.0" + "@storybook/components" "^8.2.9" "@storybook/global" "^5.0.0" - "@storybook/preview-api" "8.1.0" - "@storybook/react-dom-shim" "8.1.0" - "@storybook/types" "8.1.0" + "@storybook/manager-api" "^8.2.9" + "@storybook/preview-api" "^8.2.9" + "@storybook/react-dom-shim" "8.2.9" + "@storybook/theming" "^8.2.9" "@types/escodegen" "^0.0.6" "@types/estree" "^0.0.51" "@types/node" "^18.0.0" @@ -3439,40 +3005,16 @@ memoizerific "^1.11.3" qs "^6.10.0" -"@storybook/router@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/router/-/router-8.1.0.tgz#9c9e18d8fb17658f0f74e765262befaeb6c46881" - integrity sha512-5B7Vxh17/+V83Ejc8Bqt5dzIGlXp4MpbSFkbbU5mXMcPoknr8fVRix82dQLktYaTVXkeGDbTrLLJDIi8BxS8aQ== - dependencies: - "@storybook/client-logger" "8.1.0" - memoizerific "^1.11.3" - qs "^6.10.0" - -"@storybook/source-loader@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/source-loader/-/source-loader-8.1.0.tgz#f5d37e2b02439ab430afbcc006a0a2059aad87cf" - integrity sha512-lUeKnIgQT/9Li6K+xfkZb/GuxOPx5GTm4pbjAKUzNA82Yff4+RFl34eyG+vqg8QHIbPJRzGb3lohC8d25/amug== +"@storybook/source-loader@8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/source-loader/-/source-loader-8.2.9.tgz#d67e805ed673afb9c3db6f5c4214d50d16bb8c54" + integrity sha512-M2A6oo1DmcQXaSDKAXik9watCUZFGxSGPnPI3H/7O3Zt1S+9TLpCWdDpOm9itYRijLEQY7u3IvPTZqlbgSl17A== dependencies: - "@storybook/csf" "^0.1.7" - "@storybook/types" "8.1.0" + "@storybook/csf" "0.1.11" estraverse "^5.2.0" lodash "^4.17.21" prettier "^3.1.1" -"@storybook/telemetry@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-8.1.0.tgz#c562f684898c0b287d0d357a658846ebe23d1c05" - integrity sha512-/VPzIAbjYGjMZWGWLRGavKEvz8j3kybCt+W47QgOiSKvYA5yrrTFnSEvW7coTITNTK1dJKTROeJ/oCySbHgTDA== - dependencies: - "@storybook/client-logger" "8.1.0" - "@storybook/core-common" "8.1.0" - "@storybook/csf-tools" "8.1.0" - chalk "^4.1.0" - detect-package-manager "^2.0.1" - fetch-retry "^5.0.2" - fs-extra "^11.1.0" - read-pkg-up "^7.0.1" - "@storybook/theming@8.0.5", "@storybook/theming@^8.0.0": version "8.0.5" resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-8.0.5.tgz#e98aa8b761b93c2cff21213770a1bafb971f2c07" @@ -3483,15 +3025,10 @@ "@storybook/global" "^5.0.0" memoizerific "^1.11.3" -"@storybook/theming@8.1.0", "@storybook/theming@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-8.1.0.tgz#7e2d04e789c7177205370f29c92318f6aa83fe74" - integrity sha512-DlRhtGpibeOZOmhaTrc0gcKzANZMzISAx2q3OZuNnfrt2b6bPNLINuIkGVa8Mm0/t6XQxPEN5iqi8LtJCiQY8A== - dependencies: - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" - "@storybook/client-logger" "8.1.0" - "@storybook/global" "^5.0.0" - memoizerific "^1.11.3" +"@storybook/theming@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-8.2.9.tgz#6eb066f8957272c0bcb0078a8a9bc378ca9311d3" + integrity sha512-OL0NFvowPX85N5zIYdgeKKaFm7V4Vgtci093vL3cDZT13LGH6GuEzJKkUFGuUGNPFlJc+EgTj0o6PYKrOLyQ6w== "@storybook/types@8.0.5": version "8.0.5" @@ -3502,15 +3039,6 @@ "@types/express" "^4.7.0" file-system-cache "2.3.0" -"@storybook/types@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@storybook/types/-/types-8.1.0.tgz#49f8e6f33e5bada7988e572d2eb9cb589dfbaaa1" - integrity sha512-VNF++bY5KvLS4GnrH6vFVC3vaG38NHHAmDRBsjUG17LKXCL5PD6+fe8XEfWX40ylQ9ntzNdtCXDSSdow15IZ+Q== - dependencies: - "@storybook/channels" "8.1.0" - "@types/express" "^4.7.0" - file-system-cache "2.3.0" - "@svgr/babel-plugin-add-jsx-attribute@8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz#4001f5d5dd87fa13303e36ee106e3ff3a7eb8b22" @@ -3947,21 +3475,6 @@ dependencies: "@types/ms" "*" -"@types/detect-port@^1.3.0": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/detect-port/-/detect-port-1.3.5.tgz#deecde143245989dee0e82115f3caba5ee0ea747" - integrity sha512-Rf3/lB9WkDfIL9eEKaSYKc+1L/rNVYBjThk22JTqQw0YozXarX8YljFAz+HCoC6h4B4KwCMsBPZHaFezwT4BNA== - -"@types/diff@^5.0.9": - version "5.2.1" - resolved "https://registry.yarnpkg.com/@types/diff/-/diff-5.2.1.tgz#cceae9c4b2dae5c6b8ab1ce1263601c255d87fb3" - integrity sha512-uxpcuwWJGhe2AR1g8hD9F5OYGCqjqWnBUQFD8gMZsDbv8oPHzxJF6iMO6n8Tk0AdzlxoaaoQhOYlIg/PukVU8g== - -"@types/doctrine@^0.0.3": - version "0.0.3" - resolved "https://registry.yarnpkg.com/@types/doctrine/-/doctrine-0.0.3.tgz#e892d293c92c9c1d3f9af72c15a554fbc7e0895a" - integrity sha512-w5jZ0ee+HaPOaX25X2/2oGR/7rgAQSYII7X7pp0m9KgBfMP7uKfMfTvcpl5Dj+eDBbpxKGiqE+flqDr6XTd2RA== - "@types/doctrine@^0.0.9": version "0.0.9" resolved "https://registry.yarnpkg.com/@types/doctrine/-/doctrine-0.0.9.tgz#d86a5f452a15e3e3113b99e39616a9baa0f9863f" @@ -3974,11 +3487,6 @@ dependencies: "@types/trusted-types" "*" -"@types/ejs@^3.1.1": - version "3.1.5" - resolved "https://registry.yarnpkg.com/@types/ejs/-/ejs-3.1.5.tgz#49d738257cc73bafe45c13cb8ff240683b4d5117" - integrity sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg== - "@types/emscripten@^1.39.6": version "1.39.10" resolved "https://registry.yarnpkg.com/@types/emscripten/-/emscripten-1.39.10.tgz#da6e58a6171b46a41d3694f812d845d515c77e18" @@ -4009,7 +3517,7 @@ "@types/range-parser" "*" "@types/send" "*" -"@types/express@^4.7.0": +"@types/express@^4.17.21", "@types/express@^4.7.0": version "4.17.21" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== @@ -4244,11 +3752,6 @@ resolved "https://registry.yarnpkg.com/@types/paypal-checkout-components/-/paypal-checkout-components-4.0.8.tgz#dae11a164fb77fe370b013c0be44951bdc4ebf4d" integrity sha512-Z3IWbFPGdgL3O+Bg+TyVmMT8S3uGBsBjw3a8uRNR4OlYWa9m895djENErJMYU8itoki9rtcQMzoHOSFn8NFb1A== -"@types/pretty-hrtime@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#ee1bd8c9f7a01b3445786aad0ef23aba5f511a44" - integrity sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA== - "@types/prop-types@*", "@types/prop-types@^15.7.11": version "15.7.11" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" @@ -4261,7 +3764,7 @@ dependencies: "@types/react" "*" -"@types/qs@*", "@types/qs@^6.9.5": +"@types/qs@*": version "6.9.11" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.11.tgz#208d8a30bc507bd82e03ada29e4732ea46a6bbda" integrity sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ== @@ -4764,13 +4267,6 @@ resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.5.0.tgz#275fb8f6e14afa6e8a0c05d4ebc94523ff775396" integrity sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A== -"@yarnpkg/esbuild-plugin-pnp@^3.0.0-rc.10": - version "3.0.0-rc.15" - resolved "https://registry.yarnpkg.com/@yarnpkg/esbuild-plugin-pnp/-/esbuild-plugin-pnp-3.0.0-rc.15.tgz#4e40e7d2eb28825c9a35ab9d04c363931d7c0e67" - integrity sha512-kYzDJO5CA9sy+on/s2aIW0411AklfCi8Ck/4QDivOqsMKpStZA2SsR+X27VTggGwpStWaLrjJcDcdDMowtG8MA== - dependencies: - tslib "^2.4.0" - "@yarnpkg/fslib@2.10.3": version "2.10.3" resolved "https://registry.yarnpkg.com/@yarnpkg/fslib/-/fslib-2.10.3.tgz#a8c9893df5d183cf6362680b9f1c6d7504dd5717" @@ -4840,11 +4336,6 @@ acorn@^8.11.3, acorn@^8.4.1, acorn@^8.9.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== -address@^1.0.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" - integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== - agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -4998,11 +4489,6 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" -app-root-dir@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" - integrity sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g== - arch@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" @@ -5030,13 +4516,6 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-hidden@^1.1.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.4.tgz#b78e383fdbc04d05762c78b4a25a501e736c4522" - integrity sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A== - dependencies: - tslib "^2.0.0" - aria-query@5.3.0, aria-query@^5.0.0, aria-query@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" @@ -5135,7 +4614,7 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== -assert@^2.0.0, assert@^2.1.0: +assert@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw== @@ -5173,7 +4652,7 @@ astral-regex@^2.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== -async@^3.2.0, async@^3.2.3: +async@^3.2.0: version "3.2.5" resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== @@ -5356,24 +4835,12 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -better-opn@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-3.0.2.tgz#f96f35deaaf8f34144a4102651babcf00d1d8817" - integrity sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ== - dependencies: - open "^8.0.4" - -big-integer@^1.6.44: - version "1.6.52" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" - integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== - binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bl@^4.0.3, bl@^4.1.0: +bl@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== @@ -5424,13 +4891,6 @@ boxen@7.0.0: widest-line "^4.0.1" wrap-ansi "^8.0.1" -bplist-parser@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" - integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== - dependencies: - big-integer "^1.6.44" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -5478,13 +4938,6 @@ browser-assert@^1.2.1: resolved "https://registry.yarnpkg.com/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200" integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== -browserify-zlib@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" - integrity sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ== - dependencies: - pako "~0.2.0" - browserslist@^4.22.2: version "4.22.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.3.tgz#299d11b7e947a6b843981392721169e27d60c5a6" @@ -5711,7 +5164,7 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -5794,11 +5247,6 @@ chokidar@^3.5.1, chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" @@ -5850,7 +5298,7 @@ cli-spinners@^2.5.0, cli-spinners@^2.9.2: resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== -cli-table3@^0.6.1, cli-table3@~0.6.1: +cli-table3@~0.6.1: version "0.6.3" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== @@ -6029,7 +5477,7 @@ compressible@~2.0.16: dependencies: mime-db ">= 1.43.0 < 2" -compression@1.7.4, compression@^1.7.4: +compression@1.7.4: version "1.7.4" resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== @@ -6157,11 +5605,6 @@ core-util-is@1.0.2: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - cosmiconfig@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" @@ -6251,10 +5694,12 @@ crypt@0.0.2: resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== -crypto-random-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" - integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== +crypto-random-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-4.0.0.tgz#5a3cc53d7dd86183df5da0312816ceeeb5bb1fc2" + integrity sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA== + dependencies: + type-fest "^1.0.1" css-box-model@^1.2.0: version "1.2.1" @@ -6540,14 +5985,6 @@ deepmerge@^4.3.1: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -default-browser-id@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" - integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== - dependencies: - bplist-parser "^0.2.0" - untildify "^4.0.0" - defaults@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" @@ -6574,11 +6011,6 @@ define-data-property@^1.1.4: es-errors "^1.3.0" gopd "^1.0.1" -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" @@ -6593,20 +6025,6 @@ defu@^6.1.3: resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479" integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== -del@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/del/-/del-6.1.1.tgz#3b70314f1ec0aa325c6b14eb36b95786671edb7a" - integrity sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg== - dependencies: - globby "^11.0.1" - graceful-fs "^4.2.4" - is-glob "^4.0.1" - is-path-cwd "^2.2.0" - is-path-inside "^3.0.2" - p-map "^4.0.0" - rimraf "^3.0.2" - slash "^3.0.0" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -6632,26 +6050,6 @@ detect-indent@^6.1.0: resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== -detect-node-es@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" - integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== - -detect-package-manager@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/detect-package-manager/-/detect-package-manager-2.0.1.tgz#6b182e3ae5e1826752bfef1de9a7b828cffa50d8" - integrity sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A== - dependencies: - execa "^5.1.1" - -detect-port@^1.3.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" - integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== - dependencies: - address "^1.0.1" - debug "4" - devlop@^1.0.0, devlop@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/devlop/-/devlop-1.1.0.tgz#4db7c2ca4dc6e0e834c30be70c94bbc976dc7018" @@ -6669,11 +6067,6 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== -diff@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" - integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== - dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -6738,26 +6131,11 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" -dotenv-expand@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" - integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== - -dotenv@^16.0.0, dotenv@^16.0.3: +dotenv@^16.0.3: version "16.4.1" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.1.tgz#1d9931f1d3e5d2959350d1250efab299561f7f11" integrity sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ== -duplexify@^3.5.0, duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -6776,13 +6154,6 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -ejs@^3.1.10: - version "3.1.10" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" - integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== - dependencies: - jake "^10.8.5" - electron-to-chromium@^1.4.648: version "1.4.665" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.665.tgz#681700bd590b0e5a3be66e3e2874ce62abcf5da5" @@ -6813,7 +6184,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: +end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -6957,11 +6328,6 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -esbuild-plugin-alias@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/esbuild-plugin-alias/-/esbuild-plugin-alias-0.2.1.tgz#45a86cb941e20e7c2bc68a2bea53562172494fcb" - integrity sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ== - esbuild-register@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/esbuild-register/-/esbuild-register-3.5.0.tgz#449613fb29ab94325c722f560f800dd946dc8ea8" @@ -6969,34 +6335,34 @@ esbuild-register@^3.5.0: dependencies: debug "^4.3.4" -"esbuild@^0.18.0 || ^0.19.0 || ^0.20.0": - version "0.20.2" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.2.tgz#9d6b2386561766ee6b5a55196c6d766d28c87ea1" - integrity sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g== +"esbuild@^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0": + version "0.21.5" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== optionalDependencies: - "@esbuild/aix-ppc64" "0.20.2" - "@esbuild/android-arm" "0.20.2" - "@esbuild/android-arm64" "0.20.2" - "@esbuild/android-x64" "0.20.2" - "@esbuild/darwin-arm64" "0.20.2" - "@esbuild/darwin-x64" "0.20.2" - "@esbuild/freebsd-arm64" "0.20.2" - "@esbuild/freebsd-x64" "0.20.2" - "@esbuild/linux-arm" "0.20.2" - "@esbuild/linux-arm64" "0.20.2" - "@esbuild/linux-ia32" "0.20.2" - "@esbuild/linux-loong64" "0.20.2" - "@esbuild/linux-mips64el" "0.20.2" - "@esbuild/linux-ppc64" "0.20.2" - "@esbuild/linux-riscv64" "0.20.2" - "@esbuild/linux-s390x" "0.20.2" - "@esbuild/linux-x64" "0.20.2" - "@esbuild/netbsd-x64" "0.20.2" - "@esbuild/openbsd-x64" "0.20.2" - "@esbuild/sunos-x64" "0.20.2" - "@esbuild/win32-arm64" "0.20.2" - "@esbuild/win32-ia32" "0.20.2" - "@esbuild/win32-x64" "0.20.2" + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" esbuild@^0.19.2, esbuild@^0.19.3: version "0.19.12" @@ -7570,7 +6936,7 @@ expr-eval-fork@^2.0.2: resolved "https://registry.yarnpkg.com/expr-eval-fork/-/expr-eval-fork-2.0.2.tgz#97136ac0a8178522055500f55d3d3c5ad54f400d" integrity sha512-NaAnObPVwHEYrODd7Jzp3zzT9pgTAlUUL4MZiZu9XAYPDpx89cPsfyEImFb2XY0vQNbrqg2CG7CLiI+Rs3seaQ== -express@^4.17.3: +express@^4.19.2: version "4.19.2" resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== @@ -7718,6 +7084,13 @@ fbjs@^0.8.1: setimmediate "^1.0.5" ua-parser-js "^0.7.30" +fd-package-json@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fd-package-json/-/fd-package-json-1.2.0.tgz#4f218bb8ff65c21011d1f4f17cb3d0c9e72f8da7" + integrity sha512-45LSPmWf+gC5tdCQMNH4s9Sr00bIkiD9aN7dc5hqkrEw1geRYyDQS1v1oMHAW3ysfxfndqGsrDREHHjNNbKUfA== + dependencies: + walk-up-path "^3.0.1" + fd-slicer@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" @@ -7725,11 +7098,6 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -fetch-retry@^5.0.2: - version "5.0.6" - resolved "https://registry.yarnpkg.com/fetch-retry/-/fetch-retry-5.0.6.tgz#17d0bc90423405b7a88b74355bf364acd2a7fa56" - integrity sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ== - fflate@^0.4.8: version "0.4.8" resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae" @@ -7776,13 +7144,6 @@ file-system-cache@2.3.0: fs-extra "11.1.1" ramda "0.29.0" -filelist@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" - integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== - dependencies: - minimatch "^5.0.1" - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -7833,7 +7194,7 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -find-up@^4.0.0, find-up@^4.1.0: +find-up@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -7973,11 +7334,6 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - fs-extra@11.1.1: version "11.1.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" @@ -8079,16 +7435,6 @@ get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@ has-symbols "^1.0.3" hasown "^2.0.0" -get-nonce@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" - integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== - -get-npm-tarball-url@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/get-npm-tarball-url/-/get-npm-tarball-url-2.1.0.tgz#cbd6bb25884622bc3191c761466c93ac83343213" - integrity sha512-ro+DiMu5DXgRBabqXupW38h7WPZ9+Ad8UjwhvsmmN8w1sU7ab0nzAXvVZ4kqYg57OrqomRtJvepX5/xvFKNtjA== - get-stdin@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-7.0.0.tgz#8d5de98f15171a125c5e516643c7a6d0ea8a96f6" @@ -8174,12 +7520,7 @@ glob-promise@^4.2.0: dependencies: "@types/glob" "^7.1.3" -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - -glob@>=7, glob@^10.0.0, glob@^10.3.1, glob@^10.3.10: +glob@>=7, glob@^10.3.1, glob@^10.3.10: version "10.3.10" resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== @@ -8247,7 +7588,7 @@ globalthis@^1.0.3: dependencies: define-properties "^1.1.3" -globby@^11.0.1, globby@^11.0.3, globby@^11.1.0: +globby@^11.0.3, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -8298,30 +7639,6 @@ graphql@^16.8.1: resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.1.tgz#1930a965bef1170603702acdb68aedd3f3cf6f07" integrity sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw== -gunzip-maybe@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz#b913564ae3be0eda6f3de36464837a9cd94b98ac" - integrity sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw== - dependencies: - browserify-zlib "^0.1.4" - is-deflate "^1.0.0" - is-gzip "^1.0.0" - peek-stream "^1.1.0" - pumpify "^1.3.3" - through2 "^2.0.3" - -handlebars@^4.7.7: - version "4.7.8" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" - integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.2" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" @@ -8634,7 +7951,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -8704,11 +8021,6 @@ invert-kv@^2.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== -ip@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105" - integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ== - ipaddr.js@1.9.1, ipaddr.js@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -8810,17 +8122,12 @@ is-date-object@^1.0.1, is-date-object@^1.0.5: dependencies: has-tostringtag "^1.0.0" -is-deflate@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-deflate/-/is-deflate-1.0.0.tgz#c862901c3c161fb09dac7cdc7e784f80e98f2f14" - integrity sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ== - is-directory@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" integrity sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw== -is-docker@^2.0.0, is-docker@^2.1.1: +is-docker@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== @@ -8873,11 +8180,6 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-gzip@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-gzip/-/is-gzip-1.0.0.tgz#6ca8b07b99c77998025900e555ced8ed80879a83" - integrity sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ== - is-installed-globally@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" @@ -8931,11 +8233,6 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-path-cwd@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - is-path-inside@^3.0.2, is-path-inside@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" @@ -9076,11 +8373,6 @@ isarray@^2.0.5: resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -9155,16 +8447,6 @@ jackspeak@2.1.1, jackspeak@^2.3.5, jackspeak@^3.1.2: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" -jake@^10.8.5: - version "10.8.7" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" - integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== - dependencies: - async "^3.2.3" - chalk "^4.0.2" - filelist "^1.0.4" - minimatch "^3.1.2" - joycon@^3.0.1: version "3.1.1" resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" @@ -9455,15 +8737,6 @@ lazy-ass@^1.6.0: resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" integrity sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw== -lazy-universal-dotenv@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-4.0.0.tgz#0b220c264e89a042a37181a4928cdd298af73422" - integrity sha512-aXpZJRnTkpK6gQ/z4nk+ZBLd/Qdp118cvPruLSIQzQNRhKwEcdXCOzXuF55VDqIiuAaY3UGZ10DJtvZzDcvsxg== - dependencies: - app-root-dir "^1.0.2" - dotenv "^16.0.0" - dotenv-expand "^10.0.0" - lcid@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" @@ -9841,10 +9114,10 @@ markdown-table@^3.0.0: resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.3.tgz#e6331d30e493127e031dd385488b5bd326e4a6bd" integrity sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw== -markdown-to-jsx@7.3.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.3.2.tgz#f286b4d112dad3028acc1e77dfe1f653b347e131" - integrity sha512-B+28F5ucp83aQm+OxNrPkS8z0tMKaeHiy0lHJs3LqCyDQFtWuenaIrkaVTgAm1pf1AU85LXltva86hlaT17i8Q== +markdown-to-jsx@^7.4.5: + version "7.5.0" + resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.5.0.tgz#42ece0c71e842560a7d8bd9f81e7a34515c72150" + integrity sha512-RrBNcMHiFPcz/iqIj0n3wclzHXjwS7mzjBNWecKKVhNTIxQepIix6Il/wZCn2Cg5Y1ow2Qi84+eJrryFRWBEWw== md5@^2.2.1, md5@^2.3.0: version "2.3.0" @@ -10382,13 +9655,6 @@ minimatch@9.0.3, minimatch@^9.0.1, minimatch@^9.0.3: dependencies: brace-expansion "^2.0.1" -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - minimatch@^9.0.4: version "9.0.5" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" @@ -10396,7 +9662,7 @@ minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6, minimist@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -10431,11 +9697,6 @@ minizlib@^2.1.1: minipass "^3.0.0" yallist "^4.0.0" -mkdirp-classic@^0.5.2: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - mkdirp@^0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" @@ -10566,7 +9827,7 @@ negotiator@0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -neo-async@^2.5.0, neo-async@^2.6.2: +neo-async@^2.5.0: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== @@ -10596,7 +9857,7 @@ node-fetch-native@^1.6.1: resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.2.tgz#f439000d972eb0c8a741b65dcda412322955e1c6" integrity sha512-69mtXOFZ6hSkYiXAVB5SqaRvrbITC/NPyqv7yuu/qw0nmgPyYbIMYYNIDhNtwPrzk0ptrimrLz/hhjvm4w5Z+w== -node-fetch@^1.0.1, node-fetch@^2.0.0, node-fetch@^2.6.7: +node-fetch@^1.0.1, node-fetch@^2.6.7: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -10801,15 +10062,6 @@ open@^7.4.2: is-docker "^2.0.0" is-wsl "^2.1.1" -open@^8.0.4, open@^8.4.0: - version "8.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" - integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - opencollective-postinstall@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" @@ -10964,11 +10216,6 @@ package-json-from-dist@^1.0.0: resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz#e501cd3094b278495eb4258d4c9f6d5ac3019f00" integrity sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw== -pako@~0.2.0: - version "0.2.9" - resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" - integrity sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA== - parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -11145,15 +10392,6 @@ pathval@^1.1.1: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== -peek-stream@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/peek-stream/-/peek-stream-1.1.3.tgz#3b35d84b7ccbbd262fff31dc10da56856ead6d67" - integrity sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA== - dependencies: - buffer-from "^1.0.0" - duplexify "^3.5.0" - through2 "^2.0.3" - peggy@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/peggy/-/peggy-4.0.3.tgz#7bcd47718483ab405c960350c5250e3e487dec74" @@ -11178,7 +10416,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.0, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -11227,13 +10465,6 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -pkg-dir@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" - integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== - dependencies: - find-up "^5.0.0" - pkg-types@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.3.tgz#988b42ab19254c01614d13f4f65a2cfc7880f868" @@ -11307,11 +10538,6 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== -"prettier-fallback@npm:prettier@^3": - version "3.2.5" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" - integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== - prettier-linter-helpers@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" @@ -11352,16 +10578,6 @@ pretty-format@^29.7.0: ansi-styles "^5.0.0" react-is "^18.0.0" -pretty-hrtime@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" - integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - process@^0.11.1, process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" @@ -11434,14 +10650,6 @@ psl@^1.1.33: resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -11450,15 +10658,6 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - punycode@^1.3.2, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" @@ -11732,25 +10931,6 @@ react-redux@~7.1.3: prop-types "^15.7.2" react-is "^16.9.0" -react-remove-scroll-bar@^2.3.3: - version "2.3.6" - resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz#3e585e9d163be84a010180b18721e851ac81a29c" - integrity sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g== - dependencies: - react-style-singleton "^2.2.1" - tslib "^2.0.0" - -react-remove-scroll@2.5.5: - version "2.5.5" - resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz#1e31a1260df08887a8a0e46d09271b52b3a37e77" - integrity sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw== - dependencies: - react-remove-scroll-bar "^2.3.3" - react-style-singleton "^2.2.1" - tslib "^2.1.0" - use-callback-ref "^1.3.0" - use-sidecar "^1.1.2" - react-router-dom@~5.3.4: version "5.3.4" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.4.tgz#2ed62ffd88cae6db134445f4a0c0ae8b91d2e5e6" @@ -11809,15 +10989,6 @@ react-smooth@^4.0.0: prop-types "^15.8.1" react-transition-group "^4.4.5" -react-style-singleton@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4" - integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== - dependencies: - get-nonce "^1.0.0" - invariant "^2.2.4" - tslib "^2.0.0" - react-test-renderer@16.14.0: version "16.14.0" resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.14.0.tgz#e98360087348e260c56d4fe2315e970480c228ae" @@ -11868,15 +11039,6 @@ react@^17.0.2: loose-envify "^1.1.0" object-assign "^4.1.1" -read-pkg-up@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" - integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" @@ -11905,20 +11067,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -readable-stream@^2.0.0, readable-stream@~2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.1.1, readable-stream@^3.4.0: +readable-stream@^3.4.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -12406,7 +11555,7 @@ safe-array-concat@^1.0.1: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -12778,7 +11927,7 @@ source-map@^0.5.7: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -12878,17 +12027,39 @@ storybook-dark-mode@^4.0.1: fast-deep-equal "^3.1.3" memoizerific "^1.11.3" -storybook@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/storybook/-/storybook-8.1.0.tgz#f806c0d762ac003f5ff0e6594f646f4231f4bd8a" - integrity sha512-PiOKNQHFwW4ypAdUM7CSPyt5nHamcyB1yKe/+umoLo25KhYzjJa71PR1XKyBzjM3kqz8oetauexwfRwJDbfyzg== +storybook@^8.2.9: + version "8.2.9" + resolved "https://registry.yarnpkg.com/storybook/-/storybook-8.2.9.tgz#35a670cb72367709b6ad3627dfb77c5e25a339f0" + integrity sha512-S7Q/Yt4A+nu1O23rg39lQvBqL2Vg+PKXbserDWUR4LFJtfmoZ2xGO8oFIhJmvvhjUBvolw1q7QDeswPq2i0sGw== dependencies: - "@storybook/cli" "8.1.0" - -stream-shift@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.3.tgz#85b8fab4d71010fc3ba8772e8046cc49b8a3864b" - integrity sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ== + "@babel/core" "^7.24.4" + "@babel/types" "^7.24.0" + "@storybook/codemod" "8.2.9" + "@storybook/core" "8.2.9" + "@types/semver" "^7.3.4" + "@yarnpkg/fslib" "2.10.3" + "@yarnpkg/libzip" "2.3.0" + chalk "^4.1.0" + commander "^6.2.1" + cross-spawn "^7.0.3" + detect-indent "^6.1.0" + envinfo "^7.7.3" + execa "^5.0.0" + fd-package-json "^1.2.0" + find-up "^5.0.0" + fs-extra "^11.1.0" + giget "^1.0.0" + globby "^14.0.1" + jscodeshift "^0.15.1" + leven "^3.1.0" + ora "^5.4.1" + prettier "^3.1.1" + prompts "^2.4.0" + semver "^7.3.7" + strip-json-comments "^3.0.1" + tempy "^3.1.0" + tiny-invariant "^1.3.1" + ts-dedent "^2.0.0" stream@^0.0.3: version "0.0.3" @@ -13009,13 +12180,6 @@ string_decoder@^1.1.1, string_decoder@^1.3.0: dependencies: safe-buffer "~5.2.0" -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -13219,27 +12383,6 @@ table@^6.0.9: string-width "^4.2.3" strip-ansi "^6.0.1" -tar-fs@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" - integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.1.4" - -tar-stream@^2.1.4: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - tar@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" @@ -13259,10 +12402,10 @@ telejson@^7.2.0: dependencies: memoizerific "^1.11.3" -temp-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" - integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== +temp-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-3.0.0.tgz#7f147b42ee41234cc6ba3138cd8e8aa2302acffa" + integrity sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw== temp@^0.8.4: version "0.8.4" @@ -13271,16 +12414,15 @@ temp@^0.8.4: dependencies: rimraf "~2.6.2" -tempy@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tempy/-/tempy-1.0.1.tgz#30fe901fd869cfb36ee2bd999805aa72fbb035de" - integrity sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w== +tempy@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/tempy/-/tempy-3.1.0.tgz#00958b6df85db8589cb595465e691852aac038e9" + integrity sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g== dependencies: - del "^6.0.0" - is-stream "^2.0.0" - temp-dir "^2.0.0" - type-fest "^0.16.0" - unique-string "^2.0.0" + is-stream "^3.0.0" + temp-dir "^3.0.0" + type-fest "^2.12.2" + unique-string "^3.0.0" test-exclude@^6.0.0: version "6.0.0" @@ -13332,14 +12474,6 @@ throttleit@^1.0.0: resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.1.tgz#304ec51631c3b770c65c6c6f76938b384000f4d5" integrity sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ== -through2@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - through@^2.3.6, through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -13406,11 +12540,6 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -tocbot@^4.20.1: - version "4.25.0" - resolved "https://registry.yarnpkg.com/tocbot/-/tocbot-4.25.0.tgz#bc38aea5ec8f076779bb39636f431b044129a237" - integrity sha512-kE5wyCQJ40hqUaRVkyQ4z5+4juzYsv/eK+aqD97N62YH0TxFhzJvo22RUQQZdO3YnXAk42ZOfOpjVdy+Z0YokA== - toggle-selection@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" @@ -13523,7 +12652,7 @@ tslib@^1.10.0, tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0: +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== @@ -13595,11 +12724,6 @@ type-detect@^4.0.0, type-detect@^4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-fest@^0.16.0: - version "0.16.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" - integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== - type-fest@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" @@ -13620,12 +12744,12 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -type-fest@^1.0.2: +type-fest@^1.0.1, type-fest@^1.0.2: version "1.4.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== -type-fest@^2.13.0, type-fest@^2.19.0, type-fest@~2.19: +type-fest@^2.12.2, type-fest@^2.13.0, type-fest@^2.19.0, type-fest@~2.19: version "2.19.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== @@ -13712,11 +12836,6 @@ ufo@^1.3.2: resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.4.0.tgz#39845b31be81b4f319ab1d99fd20c56cac528d32" integrity sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ== -uglify-js@^3.1.4: - version "3.17.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" - integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== - unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -13773,12 +12892,12 @@ unified@^11.0.0: trough "^2.0.0" vfile "^6.0.0" -unique-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" - integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== +unique-string@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-3.0.0.tgz#84a1c377aff5fd7a8bc6b55d8244b2bd90d75b9a" + integrity sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ== dependencies: - crypto-random-string "^2.0.0" + crypto-random-string "^4.0.0" unist-util-is@^6.0.0: version "6.0.0" @@ -13880,32 +12999,17 @@ url@^0.11.3: punycode "^1.4.1" qs "^6.11.2" -use-callback-ref@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.2.tgz#6134c7f6ff76e2be0b56c809b17a650c942b1693" - integrity sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA== - dependencies: - tslib "^2.0.0" - use-memo-one@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.3.tgz#2fd2e43a2169eabc7496960ace8c79efef975e99" integrity sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ== -use-sidecar@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2" - integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== - dependencies: - detect-node-es "^1.1.0" - tslib "^2.0.0" - use-sync-external-store@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== @@ -14088,6 +13192,11 @@ w3c-xmlserializer@^4.0.0: dependencies: xml-name-validator "^4.0.0" +walk-up-path@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-3.0.1.tgz#c8d78d5375b4966c717eb17ada73dbd41490e886" + integrity sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA== + warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" @@ -14095,14 +13204,6 @@ warning@^4.0.3: dependencies: loose-envify "^1.0.0" -watchpack@^2.2.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" @@ -14266,11 +13367,6 @@ word-wrap@^1.2.4, word-wrap@^1.2.5, word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== - wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" @@ -14360,11 +13456,6 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - "y18n@^3.2.1 || ^4.0.0": version "4.0.3" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" From 2e1fed9ee787fce5a64d5eb45881efe1b3331c6b Mon Sep 17 00:00:00 2001 From: Purvesh Makode Date: Mon, 26 Aug 2024 11:10:13 +0530 Subject: [PATCH 18/19] test: [M3-8463] - Add unit tests for CheckoutBar component (#10818) * Add test cases for CheckoutBar component * Added changeset: Add unit test cases for CheckoutBar component * Remove unnecessary closing tags from components with no children * Add test coverage for onDeploy method * Refactor: Importing type with import type --- .../pr-10818-tests-1724394944251.md | 5 ++ .../CheckoutBar/CheckoutBar.test.tsx | 79 +++++++++++++++++++ .../components/CheckoutBar/CheckoutBar.tsx | 2 +- 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 packages/manager/.changeset/pr-10818-tests-1724394944251.md create mode 100644 packages/manager/src/components/CheckoutBar/CheckoutBar.test.tsx diff --git a/packages/manager/.changeset/pr-10818-tests-1724394944251.md b/packages/manager/.changeset/pr-10818-tests-1724394944251.md new file mode 100644 index 00000000000..9ce4d41ea24 --- /dev/null +++ b/packages/manager/.changeset/pr-10818-tests-1724394944251.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Tests +--- + +Add unit test cases for CheckoutBar component ([#10818](https://github.com/linode/manager/pull/10818)) diff --git a/packages/manager/src/components/CheckoutBar/CheckoutBar.test.tsx b/packages/manager/src/components/CheckoutBar/CheckoutBar.test.tsx new file mode 100644 index 00000000000..252bf55f062 --- /dev/null +++ b/packages/manager/src/components/CheckoutBar/CheckoutBar.test.tsx @@ -0,0 +1,79 @@ +import { fireEvent } from '@testing-library/react'; +import React from 'react'; + +import { renderWithTheme } from 'src/utilities/testHelpers'; + +import { CheckoutBar } from './CheckoutBar'; + +import type { CheckoutBarProps } from './CheckoutBar'; + +const defaultArgs: CheckoutBarProps = { + calculatedPrice: 30.0, + children:
Child items can go here!
, + heading: 'Checkout', + onDeploy: vi.fn(), + submitText: 'Submit', +}; + +describe('CheckoutBar', () => { + it('should render heading, children, and submit button', () => { + const { getByTestId, getByText } = renderWithTheme( + + ); + + expect(getByText('Checkout')).toBeVisible(); + expect(getByTestId('Button')).toBeInTheDocument(); + expect(getByTestId('Button')).toHaveTextContent('Submit'); + expect(getByText('Child items can go here!')).toBeInTheDocument(); + }); + + it('should render Agreement item if provided', () => { + const { getByText } = renderWithTheme( + Agreement item can go here!} + /> + ); + + expect(getByText('Agreement item can go here!')).toBeInTheDocument(); + }); + + it('should render Footer item if provided', () => { + const { getByText } = renderWithTheme( + Footer element can go here!} + /> + ); + + expect(getByText('Footer element can go here!')).toBeInTheDocument(); + }); + + it('should disable submit button and show loading icon if isMakingRequest is true', () => { + const { getByTestId } = renderWithTheme( + + ); + + expect(getByTestId('Button')).toBeDisabled(); + expect(getByTestId('loadingIcon')).toBeInTheDocument(); + }); + + it("should disable submit button and show 'Submit' text if disabled prop is set", () => { + const { getByTestId } = renderWithTheme( + + ); + + const button = getByTestId('Button'); + expect(button).toBeDisabled(); + expect(button).toHaveTextContent('Submit'); + }); + + it('should call onDeploy when the submit button is not disabled', () => { + const { getByText } = renderWithTheme(); + + const button = getByText('Submit'); + expect(button).not.toBeDisabled(); + fireEvent.click(button); + expect(defaultArgs.onDeploy).toHaveBeenCalled(); + }); +}); diff --git a/packages/manager/src/components/CheckoutBar/CheckoutBar.tsx b/packages/manager/src/components/CheckoutBar/CheckoutBar.tsx index 3d8ffdde20e..ef5d59b64ba 100644 --- a/packages/manager/src/components/CheckoutBar/CheckoutBar.tsx +++ b/packages/manager/src/components/CheckoutBar/CheckoutBar.tsx @@ -11,7 +11,7 @@ import { SxTypography, } from './styles'; -interface CheckoutBarProps { +export interface CheckoutBarProps { /** * JSX element to be displayed as an agreement section. */ From 4f297347086f12a74573753f788d071c299330b1 Mon Sep 17 00:00:00 2001 From: Azure-akamai Date: Mon, 26 Aug 2024 09:26:30 -0400 Subject: [PATCH 19/19] test: [M3-7479] - Add test for Linode VPC config not recommended notices (#10781) * Add Linode VPC config not recommended notices * Added changeset: Add test for Linode VPC config not recommended notices --- .../pr-10781-tests-1723573598915.md | 5 + .../e2e/core/linodes/linode-config.spec.ts | 156 +++++++++++++++++- 2 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 packages/manager/.changeset/pr-10781-tests-1723573598915.md diff --git a/packages/manager/.changeset/pr-10781-tests-1723573598915.md b/packages/manager/.changeset/pr-10781-tests-1723573598915.md new file mode 100644 index 00000000000..92b25bc8c5a --- /dev/null +++ b/packages/manager/.changeset/pr-10781-tests-1723573598915.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Tests +--- + +Add test for Linode VPC config not recommended notices ([#10781](https://github.com/linode/manager/pull/10781)) diff --git a/packages/manager/cypress/e2e/core/linodes/linode-config.spec.ts b/packages/manager/cypress/e2e/core/linodes/linode-config.spec.ts index e95ca4252d7..a6ea27fbc80 100644 --- a/packages/manager/cypress/e2e/core/linodes/linode-config.spec.ts +++ b/packages/manager/cypress/e2e/core/linodes/linode-config.spec.ts @@ -2,9 +2,9 @@ import { createTestLinode } from 'support/util/linodes'; import { ui } from 'support/ui'; import { authenticate } from 'support/api/authentication'; import { cleanUp } from 'support/util/cleanup'; -import { mockGetVPC } from 'support/intercepts/vpc'; +import { mockGetVPC, mockGetVPCs } from 'support/intercepts/vpc'; import { dcPricingMockLinodeTypes } from 'support/constants/dc-specific-pricing'; -import { getRegionById } from 'support/util/regions'; +import { chooseRegion, getRegionById } from 'support/util/regions'; import { mockGetVLANs } from 'support/intercepts/vlans'; import { interceptRebootLinode, @@ -32,10 +32,15 @@ import { VLANFactory, LinodeConfigInterfaceFactory, LinodeConfigInterfaceFactoryWithVPC, + subnetFactory, } from '@src/factories'; -import { randomNumber, randomLabel } from 'support/util/random'; +import { randomNumber, randomLabel, randomIp } from 'support/util/random'; import { fetchAllKernels, findKernelById } from 'support/util/kernels'; -import { NOT_NATTED_HELPER_TEXT } from 'src/features/VPCs/constants'; +import { + LINODE_UNREACHABLE_HELPER_TEXT, + NATTED_PUBLIC_IP_HELPER_TEXT, + NOT_NATTED_HELPER_TEXT, +} from 'src/features/VPCs/constants'; import type { CreateTestLinodeOptions } from 'support/util/linodes'; import type { @@ -658,5 +663,148 @@ describe('Linode Config management', () => { cy.findByText('REBOOT NEEDED').should('be.visible'); }); + + /* + * - Tests Linode config edit and VPC interface assignment UI flows using mock API data. + * - When the user sets primary interface to eth0, sets eth0 to "Public Internet", and sets eth1 to "VPC", confirm that correct notice appears. + * - When the user sets primary interface to eth0, sets eth0 to "Public Internet", sets eth1 to "VPC", and checks "Assign a public IPv4 address for this Linode", confirm that correct notice appears. + * - Confirms that "REBOOT NEEDED" status indicator appears upon creating VPC config. + */ + it('Creates a new config using non-recommended settings and confirm the informational notices', () => { + const region = chooseRegion({ capabilities: ['VPCs'] }); + const mockLinode = linodeFactory.build({ + id: randomNumber(), + label: randomLabel(), + region: region.id, + }); + const mockSubnet = subnetFactory.build({ + id: randomNumber(), + label: randomLabel(), + linodes: [], + ipv4: `${randomIp()}/0`, + }); + const mockVPC = vpcFactory.build({ + id: randomNumber(), + label: randomLabel(), + region: region.id, + subnets: [mockSubnet], + }); + + // Mock config with public internet eth0, VPC eth1 and no other interfaces. + const mockConfigWithVpc: Config = { + ...mockConfig, + interfaces: [ + LinodeConfigInterfaceFactory.build({ + ipam_address: null, + purpose: 'public', + label: null, + }), + LinodeConfigInterfaceFactoryWithVPC.build({ + vpc_id: mockVPC.id, + active: false, + label: null, + }), + ], + }; + + // Mock a Linode with no existing configs, then visit its details page. + mockGetLinodeKernel(mockKernel.id, mockKernel); + mockGetLinodeKernels([mockKernel]); + mockGetLinodeDetails(mockLinode.id, mockLinode).as('getLinode'); + mockGetLinodeDisks(mockLinode.id, []).as('getDisks'); + mockGetLinodeVolumes(mockLinode.id, []).as('getVolumes'); + mockGetLinodeConfigs(mockLinode.id, []).as('getConfigs'); + mockGetVPC(mockVPC).as('getVPC'); + mockGetVPCs([mockVPC]).as('getVPCs'); + + cy.visitWithLogin(`/linodes/${mockLinode.id}/configurations`); + cy.wait(['@getConfigs', '@getDisks', '@getLinode', '@getVolumes']); + + // Confirm that there are no configurations displayed. + cy.findByLabelText('List of Configurations').within(() => { + cy.findByText('No data to display.').should('be.visible'); + }); + + // Mock requests to create new config and re-fetch configs. + mockCreateLinodeConfigs(mockLinode.id, mockConfigWithVpc).as( + 'createLinodeConfig' + ); + mockGetLinodeConfigs(mockLinode.id, [mockConfigWithVpc]).as( + 'getLinodeConfigs' + ); + + // Create new config. + cy.findByText('Add Configuration').click(); + ui.dialog + .findByTitle('Add Configuration') + .should('be.visible') + .within(() => { + cy.get('#label').type(`${mockConfigWithVpc.label}`); + + // Sets eth0 to "Public Internet", and sets eth1 to "VPC" + cy.get('[data-qa-textfield-label="eth0"]') + .scrollIntoView() + .click() + .type('Public Internet'); + ui.select + .findItemByText('Public Internet') + .should('be.visible') + .click(); + cy.get('[data-qa-textfield-label="eth1"]') + .scrollIntoView() + .click() + .type('VPC'); + ui.select.findItemByText('VPC').should('be.visible').click(); + // Confirm that internet access warning is displayed. + cy.findByText(LINODE_UNREACHABLE_HELPER_TEXT).should('be.visible'); + + // Sets eth0 to "Public Internet", and sets eth1 to "VPC", + // and checks "Assign a public IPv4 address for this Linode" + cy.get('[data-qa-textfield-label="VPC"]') + .scrollIntoView() + .click() + .type(`${mockVPC.label}`); + ui.select + .findItemByText(`${mockVPC.label}`) + .should('be.visible') + .click(); + cy.get('[data-qa-textfield-label="Subnet"]') + .scrollIntoView() + .click() + .type(`${mockSubnet.label}`); + ui.select + .findItemByText(`${mockSubnet.label}`) + .should('be.visible') + .click(); + cy.findByText('Assign a public IPv4 address for this Linode') + .should('be.visible') + .click(); + // Confirm that internet access warning is displayed. + cy.findByText(NATTED_PUBLIC_IP_HELPER_TEXT) + .scrollIntoView() + .should('be.visible'); + + ui.buttonGroup + .findButtonByTitle('Add Configuration') + .scrollIntoView() + .should('be.visible') + .should('be.enabled') + .click(); + }); + + cy.wait(['@createLinodeConfig', '@getLinodeConfigs', '@getVPC']); + + // Confirm that Public Internet assigned to eth0, VPC to eth1, + // and that "REBOOT NEEDED" status message is shown. + cy.findByLabelText('List of Configurations').within(() => { + cy.contains(`${mockConfig.label} – ${mockKernel.label}`).should( + 'be.visible' + ); + cy.contains('eth0 – Public Internet').should('be.visible'); + cy.contains(`eth1 – VPC: ${mockVPC.label}`).should('be.visible'); + }); + + cy.findByText('REBOOT NEEDED').should('be.visible'); + }); }); });