diff --git a/packages/web/app/src/components/ui/button.tsx b/packages/web/app/src/components/ui/button.tsx index e882aa222..0849ee143 100644 --- a/packages/web/app/src/components/ui/button.tsx +++ b/packages/web/app/src/components/ui/button.tsx @@ -21,7 +21,7 @@ const buttonVariants = cva( default: 'h-10 py-2 px-4', sm: 'h-9 px-3 rounded-md', lg: 'h-11 px-8 rounded-md', - icon: 'size-9', + icon: 'size-10', 'icon-sm': 'size-7', }, }, diff --git a/packages/web/app/src/pages/organization.tsx b/packages/web/app/src/pages/organization.tsx index 88ca64f92..174db1445 100644 --- a/packages/web/app/src/pages/organization.tsx +++ b/packages/web/app/src/pages/organization.tsx @@ -2,15 +2,20 @@ import { ReactElement, useMemo, useRef } from 'react'; import { endOfDay, formatISO, startOfDay } from 'date-fns'; import * as echarts from 'echarts'; import ReactECharts from 'echarts-for-react'; -import { Globe, History } from 'lucide-react'; +import { Globe, History, MoveDownIcon, MoveUpIcon, SearchIcon } from 'lucide-react'; import AutoSizer from 'react-virtualized-auto-sizer'; import { useQuery } from 'urql'; +import { z } from 'zod'; import { OrganizationLayout, Page } from '@/components/layouts/organization'; +import { Button } from '@/components/ui/button'; import { Card } from '@/components/ui/card'; import { EmptyList } from '@/components/ui/empty-list'; +import { Input } from '@/components/ui/input'; import { Meta } from '@/components/ui/meta'; import { Subtitle, Title } from '@/components/ui/page'; import { QueryError } from '@/components/ui/query-error'; +import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select'; +import { Separator } from '@/components/ui/separator'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; import { FragmentType, graphql, useFragment } from '@/gql'; import { ProjectType } from '@/gql/graphql'; @@ -18,7 +23,15 @@ import { subDays } from '@/lib/date-time'; import { useFormattedNumber } from '@/lib/hooks'; import { pluralize } from '@/lib/utils'; import { UTCDate } from '@date-fns/utc'; -import { Link } from '@tanstack/react-router'; +import { Link, useRouter } from '@tanstack/react-router'; + +export const OrganizationIndexRouteSearch = z.object({ + search: z.string().optional(), + sortBy: z.enum(['requests', 'versions', 'name']).optional(), + sortOrder: z.enum(['asc', 'desc']).optional(), +}); + +type RouteSearchProps = z.infer; const ProjectCard_ProjectFragment = graphql(` fragment ProjectCard_ProjectFragment on Project { @@ -240,13 +253,29 @@ const OrganizationProjectsPageQuery = graphql(` } `); -function OrganizationPageContent(props: { organizationId: string }) { +function OrganizationPageContent( + props: { + organizationId: string; + } & RouteSearchProps, +) { const days = 14; const period = useRef<{ from: string; to: string; }>(); + // Sort by requests by default + const sortKey = props.sortBy ?? 'requests'; + + const sortOrder = + props.sortOrder === 'asc' + ? -1 + : // if the sort order is not set, sort by name in ascending order by default + !props.sortOrder && props.sortBy === 'name' + ? -1 + : // if the sort order is not set, sort in descending order by default + 1; + if (!period.current) { const now = new UTCDate(); const from = formatISO(startOfDay(subDays(now, days))); @@ -255,6 +284,8 @@ function OrganizationPageContent(props: { organizationId: string }) { period.current = { from, to }; } + const router = useRouter(); + const [query] = useQuery({ query: OrganizationProjectsPageQuery, variables: { @@ -266,13 +297,13 @@ function OrganizationPageContent(props: { organizationId: string }) { }); const currentOrganization = query.data?.organization?.organization; - const projects = query.data?.projects; + const projectsConnection = query.data?.projects; const highestNumberOfRequests = useMemo(() => { let highest = 10; - if (projects?.nodes.length) { - for (const project of projects.nodes) { + if (projectsConnection?.nodes.length) { + for (const project of projectsConnection.nodes) { for (const dataPoint of project.requestsOverTime) { if (dataPoint.value > highest) { highest = dataPoint.value; @@ -282,7 +313,40 @@ function OrganizationPageContent(props: { organizationId: string }) { } return highest; - }, [projects]); + }, [projectsConnection]); + + const projects = useMemo(() => { + if (!projectsConnection) { + return []; + } + + const searchPhrase = props.search; + const newProjects = searchPhrase + ? projectsConnection.nodes.filter(project => + project.name.toLowerCase().includes(searchPhrase.toLowerCase()), + ) + : projectsConnection.nodes.slice(); + + return newProjects.sort((a, b) => { + const diffRequests = b.totalRequests - a.totalRequests; + const diffVersions = b.schemaVersionsCount - a.schemaVersionsCount; + + if (sortKey === 'requests' && diffRequests !== 0) { + return diffRequests * sortOrder; + } + + if (sortKey === 'versions' && diffVersions !== 0) { + return diffVersions * sortOrder; + } + + if (sortKey === 'name') { + return a.name.localeCompare(b.name) * sortOrder * -1; + } + + // falls back to sort by name in ascending order + return a.name.localeCompare(b.name); + }); + }, [projectsConnection, props.search, sortKey, sortOrder]); if (query.error) { return ; @@ -296,12 +360,98 @@ function OrganizationPageContent(props: { organizationId: string }) { > <>
-
- Projects - A list of available project in your organization. +
+
+ Projects + A list of available project in your organization. +
+
+
+
+ + { + void router.navigate({ + search(params) { + return { + ...params, + search: event.target.value, + }; + }, + }); + }} + className="bg-background w-full rounded-lg pl-8 md:w-[200px] lg:w-[336px]" + /> +
+ + + +
+
- {currentOrganization && projects ? ( - projects.total === 0 ? ( + {currentOrganization && projectsConnection ? ( + projectsConnection.total === 0 ? ( ) : (
- {projects.nodes - .sort((a, b) => { - const diffOperations = b.totalRequests - a.totalRequests; - if (diffOperations !== 0) { - return diffOperations; - } - - const diffVersions = b.schemaVersionsCount - a.schemaVersionsCount; - if (diffVersions !== 0) { - return diffVersions; - } - - return a.name.localeCompare(b.name); - }) - .map(project => ( - - ))} + {projects.map(project => ( + + ))}
) ) : ( @@ -357,11 +493,20 @@ function OrganizationPageContent(props: { organizationId: string }) { ); } -export function OrganizationPage(props: { organizationId: string }): ReactElement { +export function OrganizationPage( + props: { + organizationId: string; + } & RouteSearchProps, +) { return ( <> - + ); } diff --git a/packages/web/app/src/pages/project.tsx b/packages/web/app/src/pages/project.tsx index 6f5e67ea6..ee9d98a61 100644 --- a/packages/web/app/src/pages/project.tsx +++ b/packages/web/app/src/pages/project.tsx @@ -2,14 +2,19 @@ import { ReactElement, useMemo, useRef } from 'react'; import { endOfDay, formatISO, startOfDay } from 'date-fns'; import * as echarts from 'echarts'; import ReactECharts from 'echarts-for-react'; -import { Globe, History } from 'lucide-react'; +import { Globe, History, MoveDownIcon, MoveUpIcon, SearchIcon } from 'lucide-react'; import AutoSizer from 'react-virtualized-auto-sizer'; import { useQuery } from 'urql'; +import { z } from 'zod'; import { Page, ProjectLayout } from '@/components/layouts/project'; +import { Button } from '@/components/ui/button'; import { EmptyList } from '@/components/ui/empty-list'; +import { Input } from '@/components/ui/input'; import { Meta } from '@/components/ui/meta'; import { Subtitle, Title } from '@/components/ui/page'; import { QueryError } from '@/components/ui/query-error'; +import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select'; +import { Separator } from '@/components/ui/separator'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; import { Card } from '@/components/v2/card'; import { FragmentType, graphql, useFragment } from '@/gql'; @@ -17,7 +22,7 @@ import { subDays } from '@/lib/date-time'; import { useFormattedNumber } from '@/lib/hooks'; import { cn, pluralize } from '@/lib/utils'; import { UTCDate } from '@date-fns/utc'; -import { Link } from '@tanstack/react-router'; +import { Link, useRouter } from '@tanstack/react-router'; const TargetCard_TargetFragment = graphql(` fragment TargetCard_TargetFragment on Target { @@ -201,7 +206,17 @@ const TargetCard = (props: { ); }; -const ProjectsPageContent = (props: { organizationId: string; projectId: string }) => { +export const ProjectIndexRouteSearch = z.object({ + search: z.string().optional(), + sortBy: z.enum(['requests', 'versions', 'name']).optional(), + sortOrder: z.enum(['asc', 'desc']).optional(), +}); + +type RouteSearchProps = z.infer; + +const ProjectsPageContent = ( + props: { organizationId: string; projectId: string } & RouteSearchProps, +) => { const period = useRef<{ from: string; to: string; @@ -216,6 +231,19 @@ const ProjectsPageContent = (props: { organizationId: string; projectId: string period.current = { from, to }; } + // Sort by requests by default + const sortKey = props.sortBy ?? 'requests'; + + const sortOrder = + props.sortOrder === 'asc' + ? -1 + : // if the sort order is not set, sort by name in ascending order by default + !props.sortOrder && props.sortBy === 'name' + ? -1 + : // if the sort order is not set, sort in descending order by default + 1; + const router = useRouter(); + const [query] = useQuery({ query: ProjectOverviewPageQuery, variables: { @@ -228,11 +256,43 @@ const ProjectsPageContent = (props: { organizationId: string; projectId: string }); const targetConnection = query.data?.targets; - const targets = targetConnection?.nodes; + + const targets = useMemo(() => { + if (!targetConnection) { + return []; + } + + const searchPhrase = props.search; + const newTargets = searchPhrase + ? targetConnection.nodes.filter(target => + target.name.toLowerCase().includes(searchPhrase.toLowerCase()), + ) + : targetConnection.nodes.slice(); + + return newTargets.sort((a, b) => { + const diffRequests = b.totalRequests - a.totalRequests; + const diffVersions = b.schemaVersionsCount - a.schemaVersionsCount; + + if (sortKey === 'requests' && diffRequests !== 0) { + return diffRequests * sortOrder; + } + + if (sortKey === 'versions' && diffVersions !== 0) { + return diffVersions * sortOrder; + } + + if (sortKey === 'name') { + return a.name.localeCompare(b.name) * sortOrder * -1; + } + + // falls back to sort by name in ascending order + return a.name.localeCompare(b.name); + }); + }, [targetConnection, props.search, sortKey, sortOrder]); const highestNumberOfRequests = useMemo(() => { - if (targets?.length) { - return targets.reduce((max, target) => { + if (targetConnection?.nodes?.length) { + return targetConnection.nodes.reduce((max, target) => { return Math.max( max, target.requestsOverTime.reduce((max, { value }) => Math.max(max, value), 0), @@ -241,7 +301,7 @@ const ProjectsPageContent = (props: { organizationId: string; projectId: string } return 100; - }, [targets]); + }, [targetConnection?.nodes]); if (query.error) { return ; @@ -255,50 +315,124 @@ const ProjectsPageContent = (props: { organizationId: string; projectId: string className="flex justify-between gap-12" >
-
- Targets - A list of available targets in your project. +
+
+ Targets + A list of available targets in your project. +
+
+
+
+ + { + void router.navigate({ + search(params) { + return { + ...params, + search: event.target.value, + }; + }, + }); + }} + className="bg-background w-full rounded-lg pl-8 md:w-[200px] lg:w-[336px]" + /> +
+ + + +
+
- {targets ? ( - targets.length === 0 ? ( + {targetConnection ? ( + targetConnection?.total === 0 ? ( ) : ( - targets - .sort((a, b) => { - const diffOperations = b.totalRequests - a.totalRequests; - if (diffOperations !== 0) { - return diffOperations; - } - - const diffVersions = b.schemaVersionsCount - a.schemaVersionsCount; - if (diffVersions !== 0) { - return diffVersions; - } - - return a.name.localeCompare(b.name); - }) - .map(target => ( - - )) + targets.map(target => ( + + )) ) ) : ( <> @@ -346,11 +480,19 @@ const ProjectOverviewPageQuery = graphql(` } `); -export function ProjectPage(props: { organizationId: string; projectId: string }): ReactElement { +export function ProjectPage( + props: { organizationId: string; projectId: string } & RouteSearchProps, +): ReactElement { return ( <> - + ); } diff --git a/packages/web/app/src/router.tsx b/packages/web/app/src/router.tsx index 6ac3b31e5..3a3cbc091 100644 --- a/packages/web/app/src/router.tsx +++ b/packages/web/app/src/router.tsx @@ -37,7 +37,7 @@ import { DevPage } from './pages/dev'; import { IndexPage } from './pages/index'; import { LogoutPage } from './pages/logout'; import { ManagePage } from './pages/manage'; -import { OrganizationPage } from './pages/organization'; +import { OrganizationIndexRouteSearch, OrganizationPage } from './pages/organization'; import { JoinOrganizationPage } from './pages/organization-join'; import { OrganizationMembersPage } from './pages/organization-members'; import { NewOrgPage } from './pages/organization-new'; @@ -48,7 +48,7 @@ import { OrganizationSubscriptionManagePage } from './pages/organization-subscri import { OrganizationSupportPage } from './pages/organization-support'; import { OrganizationSupportTicketPage } from './pages/organization-support-ticket'; import { OrganizationTransferPage } from './pages/organization-transfer'; -import { ProjectPage } from './pages/project'; +import { ProjectIndexRouteSearch, ProjectPage } from './pages/project'; import { ProjectAlertsPage } from './pages/project-alerts'; import { ProjectPolicyPage } from './pages/project-policy'; import { ProjectSettingsPage } from './pages/project-settings'; @@ -345,9 +345,18 @@ const organizationRoute = createRoute({ const organizationIndexRoute = createRoute({ getParentRoute: () => organizationRoute, path: '/', + validateSearch: OrganizationIndexRouteSearch.parse, component: function OrganizationRoute() { const { organizationId } = organizationRoute.useParams(); - return ; + const { search, sortBy, sortOrder } = organizationIndexRoute.useSearch(); + return ( + + ); }, notFoundComponent: NotFound, errorComponent: ErrorComponent, @@ -457,9 +466,19 @@ const projectRoute = createRoute({ const projectIndexRoute = createRoute({ getParentRoute: () => projectRoute, path: '/', + validateSearch: ProjectIndexRouteSearch.parse, component: function ProjectRoute() { const { organizationId, projectId } = projectIndexRoute.useParams(); - return ; + const { search, sortBy, sortOrder } = projectIndexRoute.useSearch(); + return ( + + ); }, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c6ade988e..66514123e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16968,10 +16968,10 @@ snapshots: dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.596.0 - '@aws-sdk/client-sts': 3.596.0(@aws-sdk/client-sso-oidc@3.596.0) + '@aws-sdk/client-sso-oidc': 3.596.0(@aws-sdk/client-sts@3.596.0) + '@aws-sdk/client-sts': 3.596.0 '@aws-sdk/core': 3.592.0 - '@aws-sdk/credential-provider-node': 3.596.0(@aws-sdk/client-sso-oidc@3.596.0)(@aws-sdk/client-sts@3.596.0(@aws-sdk/client-sso-oidc@3.596.0)) + '@aws-sdk/credential-provider-node': 3.596.0(@aws-sdk/client-sso-oidc@3.596.0(@aws-sdk/client-sts@3.596.0))(@aws-sdk/client-sts@3.596.0) '@aws-sdk/middleware-host-header': 3.577.0 '@aws-sdk/middleware-logger': 3.577.0 '@aws-sdk/middleware-recursion-detection': 3.577.0 @@ -17076,13 +17076,13 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso-oidc@3.596.0': + '@aws-sdk/client-sso-oidc@3.596.0(@aws-sdk/client-sts@3.596.0)': dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.596.0(@aws-sdk/client-sso-oidc@3.596.0) + '@aws-sdk/client-sts': 3.596.0 '@aws-sdk/core': 3.592.0 - '@aws-sdk/credential-provider-node': 3.596.0(@aws-sdk/client-sso-oidc@3.596.0)(@aws-sdk/client-sts@3.596.0(@aws-sdk/client-sso-oidc@3.596.0)) + '@aws-sdk/credential-provider-node': 3.596.0(@aws-sdk/client-sso-oidc@3.596.0(@aws-sdk/client-sts@3.596.0))(@aws-sdk/client-sts@3.596.0) '@aws-sdk/middleware-host-header': 3.577.0 '@aws-sdk/middleware-logger': 3.577.0 '@aws-sdk/middleware-recursion-detection': 3.577.0 @@ -17119,6 +17119,7 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 transitivePeerDependencies: + - '@aws-sdk/client-sts' - aws-crt '@aws-sdk/client-sso-oidc@3.614.0(@aws-sdk/client-sts@3.614.0)': @@ -17252,13 +17253,13 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sts@3.596.0(@aws-sdk/client-sso-oidc@3.596.0)': + '@aws-sdk/client-sts@3.596.0': dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.596.0 + '@aws-sdk/client-sso-oidc': 3.596.0(@aws-sdk/client-sts@3.596.0) '@aws-sdk/core': 3.592.0 - '@aws-sdk/credential-provider-node': 3.596.0(@aws-sdk/client-sso-oidc@3.596.0)(@aws-sdk/client-sts@3.596.0(@aws-sdk/client-sso-oidc@3.596.0)) + '@aws-sdk/credential-provider-node': 3.596.0(@aws-sdk/client-sso-oidc@3.596.0(@aws-sdk/client-sts@3.596.0))(@aws-sdk/client-sts@3.596.0) '@aws-sdk/middleware-host-header': 3.577.0 '@aws-sdk/middleware-logger': 3.577.0 '@aws-sdk/middleware-recursion-detection': 3.577.0 @@ -17295,7 +17296,6 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - aws-crt '@aws-sdk/client-sts@3.614.0': @@ -17401,14 +17401,14 @@ snapshots: '@smithy/util-stream': 3.0.6 tslib: 2.6.3 - '@aws-sdk/credential-provider-ini@3.596.0(@aws-sdk/client-sso-oidc@3.596.0)(@aws-sdk/client-sts@3.596.0(@aws-sdk/client-sso-oidc@3.596.0))': + '@aws-sdk/credential-provider-ini@3.596.0(@aws-sdk/client-sso-oidc@3.596.0(@aws-sdk/client-sts@3.596.0))(@aws-sdk/client-sts@3.596.0)': dependencies: - '@aws-sdk/client-sts': 3.596.0(@aws-sdk/client-sso-oidc@3.596.0) + '@aws-sdk/client-sts': 3.596.0 '@aws-sdk/credential-provider-env': 3.587.0 '@aws-sdk/credential-provider-http': 3.596.0 '@aws-sdk/credential-provider-process': 3.587.0 - '@aws-sdk/credential-provider-sso': 3.592.0(@aws-sdk/client-sso-oidc@3.596.0) - '@aws-sdk/credential-provider-web-identity': 3.587.0(@aws-sdk/client-sts@3.596.0(@aws-sdk/client-sso-oidc@3.596.0)) + '@aws-sdk/credential-provider-sso': 3.592.0(@aws-sdk/client-sso-oidc@3.596.0(@aws-sdk/client-sts@3.596.0)) + '@aws-sdk/credential-provider-web-identity': 3.587.0(@aws-sdk/client-sts@3.596.0) '@aws-sdk/types': 3.577.0 '@smithy/credential-provider-imds': 3.1.3 '@smithy/property-provider': 3.1.3 @@ -17437,14 +17437,14 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-node@3.596.0(@aws-sdk/client-sso-oidc@3.596.0)(@aws-sdk/client-sts@3.596.0(@aws-sdk/client-sso-oidc@3.596.0))': + '@aws-sdk/credential-provider-node@3.596.0(@aws-sdk/client-sso-oidc@3.596.0(@aws-sdk/client-sts@3.596.0))(@aws-sdk/client-sts@3.596.0)': dependencies: '@aws-sdk/credential-provider-env': 3.587.0 '@aws-sdk/credential-provider-http': 3.596.0 - '@aws-sdk/credential-provider-ini': 3.596.0(@aws-sdk/client-sso-oidc@3.596.0)(@aws-sdk/client-sts@3.596.0(@aws-sdk/client-sso-oidc@3.596.0)) + '@aws-sdk/credential-provider-ini': 3.596.0(@aws-sdk/client-sso-oidc@3.596.0(@aws-sdk/client-sts@3.596.0))(@aws-sdk/client-sts@3.596.0) '@aws-sdk/credential-provider-process': 3.587.0 - '@aws-sdk/credential-provider-sso': 3.592.0(@aws-sdk/client-sso-oidc@3.596.0) - '@aws-sdk/credential-provider-web-identity': 3.587.0(@aws-sdk/client-sts@3.596.0(@aws-sdk/client-sso-oidc@3.596.0)) + '@aws-sdk/credential-provider-sso': 3.592.0(@aws-sdk/client-sso-oidc@3.596.0(@aws-sdk/client-sts@3.596.0)) + '@aws-sdk/credential-provider-web-identity': 3.587.0(@aws-sdk/client-sts@3.596.0) '@aws-sdk/types': 3.577.0 '@smithy/credential-provider-imds': 3.1.3 '@smithy/property-provider': 3.1.3 @@ -17491,10 +17491,10 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/credential-provider-sso@3.592.0(@aws-sdk/client-sso-oidc@3.596.0)': + '@aws-sdk/credential-provider-sso@3.592.0(@aws-sdk/client-sso-oidc@3.596.0(@aws-sdk/client-sts@3.596.0))': dependencies: '@aws-sdk/client-sso': 3.592.0 - '@aws-sdk/token-providers': 3.587.0(@aws-sdk/client-sso-oidc@3.596.0) + '@aws-sdk/token-providers': 3.587.0(@aws-sdk/client-sso-oidc@3.596.0(@aws-sdk/client-sts@3.596.0)) '@aws-sdk/types': 3.577.0 '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.3 @@ -17517,9 +17517,9 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-web-identity@3.587.0(@aws-sdk/client-sts@3.596.0(@aws-sdk/client-sso-oidc@3.596.0))': + '@aws-sdk/credential-provider-web-identity@3.587.0(@aws-sdk/client-sts@3.596.0)': dependencies: - '@aws-sdk/client-sts': 3.596.0(@aws-sdk/client-sso-oidc@3.596.0) + '@aws-sdk/client-sts': 3.596.0 '@aws-sdk/types': 3.577.0 '@smithy/property-provider': 3.1.3 '@smithy/types': 3.3.0 @@ -17689,9 +17689,9 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/token-providers@3.587.0(@aws-sdk/client-sso-oidc@3.596.0)': + '@aws-sdk/token-providers@3.587.0(@aws-sdk/client-sso-oidc@3.596.0(@aws-sdk/client-sts@3.596.0))': dependencies: - '@aws-sdk/client-sso-oidc': 3.596.0 + '@aws-sdk/client-sso-oidc': 3.596.0(@aws-sdk/client-sts@3.596.0) '@aws-sdk/types': 3.577.0 '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.3