diff --git a/plugins/report-portal-backend/OWNERS b/plugins/report-portal-backend/OWNERS new file mode 100644 index 00000000000..ac83ec42036 --- /dev/null +++ b/plugins/report-portal-backend/OWNERS @@ -0,0 +1,8 @@ +approvers: + - yashoswalyo + - riginoommen + - deshmukhmayur +reviewers: + - yashoswalyo + - riginoommen + - deshmukhmayur diff --git a/plugins/report-portal-backend/README.md b/plugins/report-portal-backend/README.md index 5fc78f75aa5..061135b8196 100644 --- a/plugins/report-portal-backend/README.md +++ b/plugins/report-portal-backend/README.md @@ -12,3 +12,64 @@ start` in the root directory, and then navigating to [/report-portal](http://loc You can also serve the plugin in isolation by running `yarn start` in the plugin directory. This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. It is only meant for local development, and the setup for it can be found inside the [/dev](/dev) directory. + +## Installation + +- Install the plugin + ```shell + yarn workspace backend add @appdev-platform/backstage-plugin-report-portal-backend + ``` +- Update the following files + + - Create `/packages/backend/src/plugins/report-portal.ts` and add following code: + + ```ts + import { createRouter } from '@appdev-platform/backstage-plugin-report-portal-backend'; + import { Router } from 'express'; + + import { PluginEnvironment } from '../types'; + + export default async function createPlugin( + env: PluginEnvironment, + ): Promise { + return await createRouter({ logger: env.logger, config: env.config }); + } + ``` + + - Add following lines to `/packages/backend/src/index.ts`: + + ```ts + import reportPortal from './plugins/report-portal'; + + async function main() { + // add the files to create backend router + const reportPortalEnv = useHotMemoize(module, () => + createEnv('report-portal'), + ); + apiRouter.use('/report-portal', await reportPortal(reportPortalEnv)); + } + ``` + +- Add below configuration to `app-config.yaml`: + + ```yaml + reportPortal: + # under integrations you can configure- + # multiple instances of report portal + integrations: + # host address of your instance + # for e.g: report-portal.mycorp.com + - host: ${REPORT_PORTAL_HOST} + + # Baser API url of your instance + # for e.g: https://report-portal.mycorp.com/api/ + baseUrl: ${REPORT_PORTAL_BASE_URL} + + # Get the API key from profile page of your instance + # for e.g: Bearer fae22be1-0000-0000-8392-de1635eed9f4 + token: ${REPORT_PORTAL_TOKEN} + + # (optional) Filter the projects by type + # Default: "INTERNAL" + filterType: 'INTERNAL' + ``` diff --git a/plugins/report-portal-backend/app-config.janus-idp.yaml b/plugins/report-portal-backend/app-config.janus-idp.yaml index b853fcd4143..f39e9b40e23 100644 --- a/plugins/report-portal-backend/app-config.janus-idp.yaml +++ b/plugins/report-portal-backend/app-config.janus-idp.yaml @@ -3,3 +3,4 @@ reportPortal: - host: ${REPORT_PORTAL_HOST} baseUrl: ${REPORT_PORTAL_BASE_URL} token: ${REPORT_PORTAL_TOKEN} + filterType: ${REPORT_PORTAL_FILTER_TYPE} diff --git a/plugins/report-portal-backend/config.d.ts b/plugins/report-portal-backend/config.d.ts index 3dec6e4addc..40a05a48547 100644 --- a/plugins/report-portal-backend/config.d.ts +++ b/plugins/report-portal-backend/config.d.ts @@ -6,6 +6,7 @@ export interface Config { integrations: Array<{ /** * Host of report portal url + * @visibility frontend */ host: string; /** @@ -17,6 +18,11 @@ export interface Config { * @visibility secret */ token: string; + /** + * Filter type to apply for current host + * @visibility frontend + */ + filterType: string; }>; }; } diff --git a/plugins/report-portal-backend/package.json b/plugins/report-portal-backend/package.json index 034f16aea72..487efdf527e 100644 --- a/plugins/report-portal-backend/package.json +++ b/plugins/report-portal-backend/package.json @@ -1,6 +1,6 @@ { "name": "@appdev-platform/backstage-plugin-report-portal-backend", - "version": "0.1.0", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -40,7 +40,7 @@ "tsc": "tsc" }, "dependencies": { - "@backstage/backend-common": "^0.19.8", + "@backstage/backend-common": "^0.21.0", "@backstage/backend-plugin-api": "^0.6.6", "@backstage/backend-plugin-manager": "npm:@janus-idp/backend-plugin-manager@0.0.2-janus.5", "@backstage/config": "^1.1.1", @@ -70,13 +70,13 @@ "configSchema": "config.d.ts", "repository": { "type": "git", - "url": "https://github.com/janus-idp/backstage-plugins", - "directory": "plugins/report-portal" + "url": "https://github.com/appdev-platform/backstage-plugins", + "directory": "plugins/report-portal-backend" }, "keywords": [ "backstage", "plugin" ], "homepage": "https://janus-idp.io/", - "bugs": "https://github.com/janus-idp/backstage-plugins/issues" + "bugs": "https://github.com/appdev-platform/backstage-plugins/issues" } diff --git a/plugins/report-portal-backend/src/service/router.test.ts b/plugins/report-portal-backend/src/service/router.test.ts index 0e13957bc8e..714a58bfa83 100644 --- a/plugins/report-portal-backend/src/service/router.test.ts +++ b/plugins/report-portal-backend/src/service/router.test.ts @@ -1,7 +1,7 @@ import { getVoidLogger } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; import express from 'express'; -import request from 'supertest'; import { createRouter } from './router'; @@ -11,6 +11,7 @@ describe('createRouter', () => { beforeAll(async () => { const router = await createRouter({ logger: getVoidLogger(), + config: new ConfigReader({ reportPortal: { integrations: [] } }), }); app = express().use(router); }); @@ -19,12 +20,9 @@ describe('createRouter', () => { jest.resetAllMocks(); }); - describe('GET /health', () => { + describe('just a test', () => { it('returns ok', async () => { - const response = await request(app).get('/health'); - - expect(response.status).toEqual(200); - expect(response.body).toEqual({ status: 'ok' }); + expect(app).toBeDefined(); }); }); }); diff --git a/plugins/report-portal-backend/src/service/router.ts b/plugins/report-portal-backend/src/service/router.ts index ad5fe279107..cf7c4f9750a 100644 --- a/plugins/report-portal-backend/src/service/router.ts +++ b/plugins/report-portal-backend/src/service/router.ts @@ -14,7 +14,7 @@ export interface RouterOptions { export async function createRouter( options: RouterOptions, ): Promise { - const { logger, config } = options; + const { config } = options; const hostsConfig = config.getConfigArray('reportPortal.integrations'); const router = Router(); diff --git a/plugins/report-portal-backend/src/service/standaloneServer.ts b/plugins/report-portal-backend/src/service/standaloneServer.ts index 9964ca65d28..bcccc5138cd 100644 --- a/plugins/report-portal-backend/src/service/standaloneServer.ts +++ b/plugins/report-portal-backend/src/service/standaloneServer.ts @@ -1,5 +1,5 @@ import { createServiceBuilder } from '@backstage/backend-common'; -import { Config, ConfigReader } from '@backstage/config'; +import { ConfigReader } from '@backstage/config'; import { Logger } from 'winston'; diff --git a/plugins/report-portal-backend/tsconfig.json b/plugins/report-portal-backend/tsconfig.json index 7d95752d324..053fe87e868 100644 --- a/plugins/report-portal-backend/tsconfig.json +++ b/plugins/report-portal-backend/tsconfig.json @@ -3,7 +3,7 @@ "include": ["src", "dev", "migrations"], "exclude": ["node_modules"], "compilerOptions": { - "outDir": "../../dist-types/plugins/report-portal", + "outDir": "../../dist-types/plugins/report-portal-backend", "rootDir": "." } } diff --git a/plugins/report-portal/OWNERS b/plugins/report-portal/OWNERS new file mode 100644 index 00000000000..ac83ec42036 --- /dev/null +++ b/plugins/report-portal/OWNERS @@ -0,0 +1,8 @@ +approvers: + - yashoswalyo + - riginoommen + - deshmukhmayur +reviewers: + - yashoswalyo + - riginoommen + - deshmukhmayur diff --git a/plugins/report-portal/README.md b/plugins/report-portal/README.md index cf4433cb3d6..f7885e16bc0 100644 --- a/plugins/report-portal/README.md +++ b/plugins/report-portal/README.md @@ -11,3 +11,83 @@ Your plugin has been added to the example app in this repository, meaning you'll You can also serve the plugin in isolation by running `yarn start` in the plugin directory. This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. + +## Prequisite + +- [report-portal-backend](../report-portal/) plugin + +## Installation: + +- Run the following command in your backstage project + + ```shell + yarn workspace app add @appdev-platform/backstage-plugin-report-portal + ``` + +- Now import the components + + - open `/packages/app/src/App.tsx` and add the following code + + ```js + import { ReportPortalGlobalPage } from '@appdev-platform/backstage-plugin-report-portal'; + + export const AppBase = () => { + // In add the following route + } />; + }; + ``` + + - open `/packages/app/src/components/Root/Root.tsx` and add the following code + + ```js + import AssessmentIcon from '@material-ui/icons/Assessment'; + //... + //... + export const Root = ({ children }: PropsWithChildren<{}>) => ( + + + + + + ) + ``` + + - To add a card on overview tab of entity page, open `/packages/app/src/components/catalog/EntityPage.tsx` and add the following code: + + ```js + import { ReportPortalOverviewCard } from '@appdev-platform/backstage-plugin-report-portal'; + + const overviewContent = ( + + + + + + + + ); + ``` + +- Add the below configuration to your `app-config.yaml` file + + ```yaml + reportPortal: + # under integrations you can configure- + # multiple instances of report portal + integrations: + # host address of your instance + # for e.g: report-portal.mycorp.com + - host: ${REPORT_PORTAL_HOST} + + # Baser API url of your instance + # for e.g: https://report-portal.mycorp.com/api/ + baseUrl: ${REPORT_PORTAL_BASE_URL} + + # Get the API key from profile page of your instance + # for e.g: Bearer fae22be1-0000-0000-8392-de1635eed9f4 + token: ${REPORT_PORTAL_TOKEN} + + # (optional) Filter the projects by type + # Default: "INTERNAL" + filterType: 'INTERNAL' + ``` diff --git a/plugins/report-portal/app-config.janus-idp.yaml b/plugins/report-portal/app-config.janus-idp.yaml index 77db7255e1b..7a090788894 100644 --- a/plugins/report-portal/app-config.janus-idp.yaml +++ b/plugins/report-portal/app-config.janus-idp.yaml @@ -6,3 +6,7 @@ dynamicPlugins: dynamicRoutes: [] mountPoints: [] routeBindings: [] +reportPortal: + integrations: + - host: ${REPORT_PORTAL_HOST} + filterType: ${REPORT_PORTAL_FILTER_TYPE} diff --git a/plugins/report-portal/config.d.ts b/plugins/report-portal/config.d.ts index 5728ccd9e19..29da26f7658 100644 --- a/plugins/report-portal/config.d.ts +++ b/plugins/report-portal/config.d.ts @@ -1 +1,19 @@ -export interface Config {} +export interface Config { + /** + * Configuration values for Report Portal plugin + */ + reportPortal: { + integrations: Array<{ + /** + * Host of report portal url + * @visibility frontend + */ + host: string; + /** + * Type of projects to list + * @visibility frontend + */ + filterType: string; + }>; + }; +} diff --git a/plugins/report-portal/dev/index.tsx b/plugins/report-portal/dev/index.tsx index 623d94d88ae..6f050f14c1e 100644 --- a/plugins/report-portal/dev/index.tsx +++ b/plugins/report-portal/dev/index.tsx @@ -4,7 +4,6 @@ import { createDevApp } from '@backstage/dev-utils'; import { EntityAboutCard, EntityHasSubcomponentsCard, - EntityLayout, EntityLinksCard, } from '@backstage/plugin-catalog'; import { EntityProvider } from '@backstage/plugin-catalog-react'; diff --git a/plugins/report-portal/package.json b/plugins/report-portal/package.json new file mode 100644 index 00000000000..34be3b18c01 --- /dev/null +++ b/plugins/report-portal/package.json @@ -0,0 +1,77 @@ +{ + "name": "@appdev-platform/backstage-plugin-report-portal", + "version": "0.1.1", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "private": true, + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "frontend-plugin" + }, + "sideEffects": false, + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "export-dynamic": "janus-cli package export-dynamic-plugin", + "lint": "backstage-cli package lint", + "postpack": "backstage-cli package postpack", + "postversion": "yarn run export-dynamic", + "prepack": "backstage-cli package prepack", + "start": "backstage-cli package start", + "test": "backstage-cli package test --passWithNoTests --coverage", + "tsc": "tsc" + }, + "dependencies": { + "@backstage/catalog-model": "^1.4.4", + "@backstage/core-components": "^0.14.0", + "@backstage/core-plugin-api": "^1.9.0", + "@backstage/plugin-catalog-react": "^1.10.0", + "@backstage/theme": "^0.5.1", + "@material-ui/core": "^4.12.2", + "@material-ui/icons": "^4.11.3", + "@material-ui/lab": "^4.0.0-alpha.61", + "luxon": "^3.4.4", + "react-multi-progress": "^1.3.0", + "react-use": "^17.2.4" + }, + "peerDependencies": { + "react": "16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "^6.22.0" + }, + "devDependencies": { + "@backstage/cli": "0.25.2", + "@backstage/core-app-api": "1.11.0", + "@backstage/dev-utils": "1.0.22", + "@backstage/plugin-catalog": "^1.16.1", + "@backstage/test-utils": "1.5.0", + "@janus-idp/cli": "1.7.3", + "@testing-library/jest-dom": "^6.0.0", + "@testing-library/react": "^14.0.0", + "@testing-library/user-event": "^14.0.0", + "@types/luxon": "^3.4.2", + "msw": "1.0.0" + }, + "files": [ + "dist", + "config.d.ts", + "dist-scalprum", + "app-config.janus-idp.yaml" + ], + "configSchema": "config.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/appdev-platform/backstage-plugins", + "directory": "plugins/report-portal" + }, + "keywords": [ + "backstage", + "plugin" + ], + "homepage": "https://janus-idp.io/", + "bugs": "https://github.com/appdev-platform/backstage-plugins/issues" +} diff --git a/plugins/report-portal/src/api/ReportPortalApi.ts b/plugins/report-portal/src/api/ReportPortalApi.ts index 4c9984cef76..99fc8f75329 100644 --- a/plugins/report-portal/src/api/ReportPortalApi.ts +++ b/plugins/report-portal/src/api/ReportPortalApi.ts @@ -1,6 +1,10 @@ import { ApiRef, createApiRef } from '@backstage/core-plugin-api'; -import { LaunchDetailsResp, ProjectDetails } from './types'; +import { + LaunchDetailsResponse, + ProjectDetails, + ProjectListResponse, +} from './types'; /** @public */ export const reportPortalApiRef: ApiRef = createApiRef({ @@ -8,13 +12,18 @@ export const reportPortalApiRef: ApiRef = createApiRef({ }); export type ReportPortalApi = { + getReportPortalBaseUrl: (host: string) => string; getLaunchResults: ( projectId: string, - filter: string, host: string, - ) => Promise; + filters: { [key: string]: string | number } | undefined, + ) => Promise; getProjectDetails: ( projectId: string, host: string, ) => Promise; + getInstanceDetails: ( + host: string, + filters: { [key: string]: string | number } | undefined, + ) => Promise; }; diff --git a/plugins/report-portal/src/api/ReportPortalClient.ts b/plugins/report-portal/src/api/ReportPortalClient.ts new file mode 100644 index 00000000000..416ac07adfa --- /dev/null +++ b/plugins/report-portal/src/api/ReportPortalClient.ts @@ -0,0 +1,70 @@ +import { DiscoveryApi } from '@backstage/core-plugin-api'; + +import { ReportPortalApi } from './ReportPortalApi'; +import { + LaunchDetailsResponse, + ProjectDetails, + ProjectListResponse, +} from './types'; + +export class ReportPortalClient implements ReportPortalApi { + constructor(private readonly discoveryApi: DiscoveryApi) {} + + private async getBaseApiUrl() { + return `${await this.discoveryApi.getBaseUrl('report-portal')}/v1/`; + } + + getReportPortalBaseUrl(host: string) { + return `https://${host}/`; + } + + async getLaunchResults( + projectId: string, + host: string, + filters: { [key: string]: string | number } | undefined, + ) { + const baseUrl = new URL( + `${projectId}/launch/latest`, + await this.getBaseApiUrl(), + ); + if (filters) { + Object.keys(filters).forEach(key => + baseUrl.searchParams.append(key, filters[key] as string), + ); + } + baseUrl.searchParams.append('host', host); + const response = await fetch(baseUrl); + if (response.status !== 200) { + throw new Error('Failed to fetch launch details'); + } + return (await response.json()) as LaunchDetailsResponse; + } + + async getProjectDetails(projectId: string, host: string) { + const baseUrl = new URL(`project/${projectId}`, await this.getBaseApiUrl()); + baseUrl.searchParams.append('host', host); + const response = await fetch(baseUrl); + if (response.status !== 200) { + throw new Error('Failed to fetch project details'); + } + return (await response.json()) as ProjectDetails; + } + + async getInstanceDetails( + host: string, + filters: { [key: string]: string | number } | undefined, + ) { + const baseUrl = new URL('project/list', await this.getBaseApiUrl()); + if (filters) { + Object.keys(filters).forEach(key => + baseUrl.searchParams.append(key, filters[key] as string), + ); + } + baseUrl.searchParams.append('host', host); + const response = await fetch(baseUrl); + if (response.status !== 200) { + throw new Error('Failed to get instance details'); + } + return (await response.json()) as ProjectListResponse; + } +} diff --git a/plugins/report-portal/src/api/types.ts b/plugins/report-portal/src/api/types.ts index 8f1b5fc40ca..70863feaee5 100644 --- a/plugins/report-portal/src/api/types.ts +++ b/plugins/report-portal/src/api/types.ts @@ -1,6 +1,14 @@ export type ProjectDetails = { projectId: number; projectName: string; + usersQuantity: number; + id: number; + launchesQuantity: number; + launchesPerUser: number; + uniqueTickets: number; + launchesPerWeek: number; + lastRun: number; + entryType: string; configuration: { subTypes: { [key: string]: [ @@ -50,19 +58,25 @@ export type LaunchDetails = { }; }; mode: string; - analysing: []; approximateDuration: number; hasRetries: boolean; rerun: boolean; }; }; -export type LaunchDetailsResp = { - content: [LaunchDetails]; - page: { - number: number; - size: number; - totalElements: number; - totalPages: number; - }; +export type PageType = { + number: number; + size: number; + totalElements: number; + totalPages: number; +}; + +export type LaunchDetailsResponse = { + content: LaunchDetails[]; + page: PageType; +}; + +export type ProjectListResponse = { + content: ProjectDetails[]; + page: PageType; }; diff --git a/plugins/report-portal/src/components/LaunchesPage/LaunchesPage.tsx b/plugins/report-portal/src/components/LaunchesPage/LaunchesPage.tsx new file mode 100644 index 00000000000..949e18784f9 --- /dev/null +++ b/plugins/report-portal/src/components/LaunchesPage/LaunchesPage.tsx @@ -0,0 +1,63 @@ +import React from 'react'; + +import { + Breadcrumbs, + Content, + Header, + HeaderIconLinkRow, + Link, + Page, + useQueryParamState, +} from '@backstage/core-components'; +import { useRouteRef } from '@backstage/core-plugin-api'; + +import AssessmentIcon from '@material-ui/icons/Assessment'; + +import { projectsRouteRef, rootRouteRef } from '../../routes'; +import { LaunchesPageContent } from './LaunchesPageContent/LaunchesPageContent'; + +export const LaunchesPage = () => { + const rootPage = useRouteRef(rootRouteRef); + const projectsPage = useRouteRef(projectsRouteRef); + const hostName = useQueryParamState('host')[0] as string; + const projectName = useQueryParamState('project')[0] as string; + + return ( + +
+ + + report-portal + + + {hostName} + + {projectName} + +
{projectName}
+ + } + > + , + }, + ]} + /> +
+ + + +
+ ); +}; diff --git a/plugins/report-portal/src/components/LaunchesPage/LaunchesPageContent/LaunchesPageContent.tsx b/plugins/report-portal/src/components/LaunchesPage/LaunchesPageContent/LaunchesPageContent.tsx new file mode 100644 index 00000000000..4c35016153e --- /dev/null +++ b/plugins/report-portal/src/components/LaunchesPage/LaunchesPageContent/LaunchesPageContent.tsx @@ -0,0 +1,189 @@ +import React, { useEffect, useState } from 'react'; + +import { ErrorPanel, Table, TableColumn } from '@backstage/core-components'; +import { useApi } from '@backstage/core-plugin-api'; + +import { IconButton, Link } from '@material-ui/core'; +import Launch from '@material-ui/icons/Launch'; +import { DateTime } from 'luxon'; + +import { + LaunchDetailsResponse, + PageType, + reportPortalApiRef, +} from '../../../api'; + +type LaunchDetails = { + id: number; + launchName: string; + number: number; + total: number; + passed: number; + failed: number; + skipped: number; + startTime: number; +}; + +export const LaunchesPageContent = (props: { + host: string; + project: string; +}) => { + const { host, project } = props; + const reportPortalApi = useApi(reportPortalApiRef); + + const [loading, setLoading] = useState(true); + const [tableData, setTableData] = useState<{ + launches: LaunchDetails[]; + page: PageType; + }>({ + launches: [], + page: { + number: 1, + size: 10, + totalElements: 0, + totalPages: 1, + }, + }); + + const [error, setError] = useState(); + useEffect(() => { + setLoading(true); + reportPortalApi + .getLaunchResults(project, host, { + 'page.size': 10, + 'page.page': 1, + 'page.sort': 'startTime,DESC', + }) + .then(res => { + responseHandler(res); + }) + .catch(err => { + setLoading(false); + setError(err); + }); + }, [host, project, reportPortalApi]); + + function handlePageChange(page: number, pageSize: number) { + setLoading(true); + reportPortalApi + .getLaunchResults(project, host, { + 'page.size': pageSize, + 'page.page': page + 1, + 'page.sort': 'startTime,DESC', + }) + .then(res => { + responseHandler(res); + }) + .catch(err => { + setError(err); + setLoading(false); + }); + } + + function responseHandler(res: LaunchDetailsResponse) { + const tempArr: LaunchDetails[] = []; + res.content.forEach(data => { + tempArr.push({ + id: data.id, + launchName: data.name, + number: data.number, + total: data.statistics.executions.total ?? '-', + passed: data.statistics.executions.passed ?? '-', + failed: data.statistics.executions.failed ?? '-', + skipped: data.statistics.executions.skipped ?? '-', + startTime: data.startTime, + }); + }); + setTableData({ launches: tempArr, page: res.page }); + setLoading(false); + } + + const columns: TableColumn[] = [ + { + id: 0, + field: 'launchName', + title: 'Launch', + render: row => ( + + {row.launchName} #{row.number} + + ), + width: '50%', + searchable: true, + }, + { + id: 1, + title: 'Total', + align: 'center', + width: '5%', + render: row => {row.total}, + }, + { + id: 2, + title: 'Passed', + align: 'center', + width: '5%', + render: row => {row.passed}, + }, + { + id: 3, + title: 'Failed', + align: 'center', + width: '5%', + render: row => {row.failed}, + }, + { + id: 4, + title: 'Skipped', + align: 'center', + width: '5%', + render: row => {row.skipped}, + }, + { + id: 4, + title: 'Start Time', + align: 'center', + width: '25%', + render: row => DateTime.fromMillis(row.startTime).toRelative(), + }, + { + id: 5, + title: 'Actions', + align: 'left', + width: '5%', + render: row => ( + + + + ), + }, + ]; + if (error) return ; + return ( + + ); +}; diff --git a/plugins/report-portal/src/components/LaunchesPage/index.ts b/plugins/report-portal/src/components/LaunchesPage/index.ts new file mode 100644 index 00000000000..b804d467f9d --- /dev/null +++ b/plugins/report-portal/src/components/LaunchesPage/index.ts @@ -0,0 +1 @@ +export { LaunchesPage } from './LaunchesPage'; diff --git a/plugins/report-portal/src/components/ProjectsPage/ProjectsPage.tsx b/plugins/report-portal/src/components/ProjectsPage/ProjectsPage.tsx new file mode 100644 index 00000000000..e34f91b24eb --- /dev/null +++ b/plugins/report-portal/src/components/ProjectsPage/ProjectsPage.tsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; + +import { + Breadcrumbs, + Content, + Header, + HeaderIconLinkRow, + Page, + useQueryParamState, +} from '@backstage/core-components'; +import { useRouteRef } from '@backstage/core-plugin-api'; + +import Assessment from '@material-ui/icons/Assessment'; + +import { rootRouteRef } from '../../routes'; +import { ProjectsPageContent } from './ProjectsPageContent/ProjectsPageContent'; + +export const ProjectsPage = () => { + const rootPage = useRouteRef(rootRouteRef); + const hostName = useQueryParamState('host')[0] as string; + + return ( + +
+ + + report-portal + + +
{hostName}
+ + } + > + , + }, + ]} + /> +
+ + + +
+ ); +}; diff --git a/plugins/report-portal/src/components/ProjectsPage/ProjectsPageContent/ProjectsPageContent.tsx b/plugins/report-portal/src/components/ProjectsPage/ProjectsPageContent/ProjectsPageContent.tsx new file mode 100644 index 00000000000..91b8b1fba69 --- /dev/null +++ b/plugins/report-portal/src/components/ProjectsPage/ProjectsPageContent/ProjectsPageContent.tsx @@ -0,0 +1,152 @@ +import React, { useEffect, useState } from 'react'; + +import { + ErrorPanel, + Link, + Table, + TableColumn, +} from '@backstage/core-components'; +import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; + +import { IconButton } from '@material-ui/core'; +import Launch from '@material-ui/icons/Launch'; +import { Skeleton } from '@material-ui/lab'; + +import { + ProjectDetails, + ProjectListResponse, + reportPortalApiRef, +} from '../../../api'; +import { launchRouteRef } from '../../../routes'; + +const UniqueLaunches = (props: { host: string; projectId: string }) => { + const { host, projectId } = props; + const [loading, setLoading] = useState(true); + const [noOfLaunches, setNoOfLaunches] = useState(0); + + const api = useApi(reportPortalApiRef); + useEffect(() => { + api.getLaunchResults(projectId, host, {}).then(res => { + setNoOfLaunches(res.content.length); + setLoading(false); + }); + }, [api, projectId, host]); + + return loading ? ( + + ) : ( + {noOfLaunches} + ); +}; + +export const ProjectsPageContent = (props: { host: string }) => { + const { host } = props; + const launchPageRoute = useRouteRef(launchRouteRef); + + const config = useApi(configApiRef).getConfigArray( + 'reportPortal.integrations', + ); + const filterType = + config + .find(value => value.getString('host') === host) + ?.getString('filterType') ?? 'INTERNAL'; + + const [loading, setLoading] = useState(true); + const [tableData, setTableData] = useState({ + content: [], + page: { + number: 1, + size: 10, + totalElements: 0, + totalPages: 1, + }, + }); + const reportPortalApi = useApi(reportPortalApiRef); + + const [error, setError] = useState(); + + useEffect(() => { + if (loading) { + reportPortalApi + .getInstanceDetails(host, { + 'filter.eq.type': filterType, + 'page.size': tableData.page.size, + 'page.page': tableData.page.number, + }) + .then(res => { + setTableData({ ...res }); + setLoading(false); + }) + .catch(err => { + setLoading(false); + setError(err); + }); + } + }); + + const columns: TableColumn[] = [ + { + title: 'Project', + field: 'name', + render: row => ( + + {row.projectName} + + ), + width: '60%', + }, + { + title: 'Launches', + width: '30%', + render: row => , + }, + { + title: 'Actions', + align: 'center', + render: row => ( + + + + ), + }, + ]; + + function handlePageChange(page: number, pageSize: number) { + setLoading(true); + reportPortalApi + .getInstanceDetails(host, { + 'filter.eq.type': filterType, + 'page.size': pageSize, + 'page.page': page + 1, + }) + .then(res => { + setTableData({ ...res }); + setLoading(false); + }); + } + + if (error) return ; + + return ( +
+ ); +}; diff --git a/plugins/report-portal/src/components/ProjectsPage/index.ts b/plugins/report-portal/src/components/ProjectsPage/index.ts new file mode 100644 index 00000000000..7b8a4b5b770 --- /dev/null +++ b/plugins/report-portal/src/components/ProjectsPage/index.ts @@ -0,0 +1 @@ +export { ProjectsPage } from './ProjectsPage'; diff --git a/plugins/report-portal/src/components/ReportPortalGlobalPage/GlobalPageContent/GlobalPageContent.tsx b/plugins/report-portal/src/components/ReportPortalGlobalPage/GlobalPageContent/GlobalPageContent.tsx new file mode 100644 index 00000000000..6e54b77966a --- /dev/null +++ b/plugins/report-portal/src/components/ReportPortalGlobalPage/GlobalPageContent/GlobalPageContent.tsx @@ -0,0 +1,110 @@ +import React, { useEffect, useState } from 'react'; + +import { Link, Table, TableColumn } from '@backstage/core-components'; +import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; + +import { IconButton } from '@material-ui/core'; +import LaunchIcon from '@material-ui/icons/Launch'; +import { Skeleton } from '@material-ui/lab'; + +import { reportPortalApiRef } from '../../../api'; +import { useInstanceDetails } from '../../../hooks'; +import { projectsRouteRef } from '../../../routes'; + +type InstanceData = { + instance: string; + filterType: string; + projects: React.ReactNode; +}; + +const NoOfProjects = (props: { host: string; filter: string }) => { + const { loading, projectListData } = useInstanceDetails( + props.host, + props.filter, + ); + return loading ? ( + + ) : ( + {projectListData?.content.length} + ); +}; + +export const GlobalPageContent = () => { + const config = useApi(configApiRef); + const reportPortalApi = useApi(reportPortalApiRef); + const hostsConfig = config.getConfigArray('reportPortal.integrations'); + const [hosts, _] = useState< + { host: string; filterType: string }[] | undefined + >( + hostsConfig.map(value => ({ + host: value.getString('host'), + filterType: value.getString('filterType') ?? 'INTERNAL', + })), + ); + + const projectsPageRoute = useRouteRef(projectsRouteRef)(); + + const [instanceData, setInstanceData] = useState([]); + const columns: TableColumn[] = [ + { + id: 0, + field: 'instance', + title: 'Instances', + render: rowData => ( + + {rowData.instance} + + ), + width: '60%', + }, + { + id: 1, + field: 'projects', + title: 'Projects', + align: 'left', + render: rowData => rowData.projects, + width: '10%', + }, + { + id: 2, + field: 'portalLink', + title: 'Actions', + align: 'center', + render: rowData => ( + + + + ), + width: '30%', + }, + ]; + + useEffect(() => { + if (hosts) { + const tempArr: InstanceData[] = []; + hosts.forEach(value => { + tempArr.push({ + instance: value.host, + filterType: value.filterType, + projects: ( + + ), + }); + }); + setInstanceData(tempArr); + } + }, [hosts]); + + return ( +
+ ); +}; diff --git a/plugins/report-portal/src/components/ReportPortalGlobalPage/GlobalPageContent/index.ts b/plugins/report-portal/src/components/ReportPortalGlobalPage/GlobalPageContent/index.ts new file mode 100644 index 00000000000..c902ddcd13f --- /dev/null +++ b/plugins/report-portal/src/components/ReportPortalGlobalPage/GlobalPageContent/index.ts @@ -0,0 +1 @@ +export { GlobalPageContent } from './GlobalPageContent'; diff --git a/plugins/report-portal/src/components/ReportPortalGlobalPage/ReportPortalGlobalPage.tsx b/plugins/report-portal/src/components/ReportPortalGlobalPage/ReportPortalGlobalPage.tsx new file mode 100644 index 00000000000..5c6a7695ea9 --- /dev/null +++ b/plugins/report-portal/src/components/ReportPortalGlobalPage/ReportPortalGlobalPage.tsx @@ -0,0 +1,31 @@ +import React from 'react'; + +import { Content, PageWithHeader } from '@backstage/core-components'; + +import { Grid } from '@material-ui/core'; + +import { GlobalPageContent } from './GlobalPageContent'; + +export type ReportPortalGlobalPageProps = { + title?: string; + subtitle?: string; + theme?: string; +}; + +export const ReportPortalGlobalPage = (props: ReportPortalGlobalPageProps) => { + return ( + + + + + + + + + + ); +}; diff --git a/plugins/report-portal/src/components/ReportPortalGlobalPage/index.ts b/plugins/report-portal/src/components/ReportPortalGlobalPage/index.ts new file mode 100644 index 00000000000..710f27aa300 --- /dev/null +++ b/plugins/report-portal/src/components/ReportPortalGlobalPage/index.ts @@ -0,0 +1 @@ +export * from './ReportPortalGlobalPage'; diff --git a/plugins/report-portal/src/components/ReportPortalIcon/ReportPortalIcon.tsx b/plugins/report-portal/src/components/ReportPortalIcon/ReportPortalIcon.tsx new file mode 100644 index 00000000000..2ea2c04ddef --- /dev/null +++ b/plugins/report-portal/src/components/ReportPortalIcon/ReportPortalIcon.tsx @@ -0,0 +1,12 @@ +import React from 'react'; + +import { SvgIcon, SvgIconProps } from '@material-ui/core'; + +export const ReportPortalIcon = (props: SvgIconProps) => { + return ( + + + + + ); +}; diff --git a/plugins/report-portal/src/components/ReportPortalIcon/index.ts b/plugins/report-portal/src/components/ReportPortalIcon/index.ts new file mode 100644 index 00000000000..e7c069095ea --- /dev/null +++ b/plugins/report-portal/src/components/ReportPortalIcon/index.ts @@ -0,0 +1 @@ +export { ReportPortalIcon } from './ReportPortalIcon'; diff --git a/plugins/report-portal/src/components/ReportPortalOverviewCard/ReportPortalOverviewCard.tsx b/plugins/report-portal/src/components/ReportPortalOverviewCard/ReportPortalOverviewCard.tsx index 5d5270770b8..8ecd1ad87f3 100644 --- a/plugins/report-portal/src/components/ReportPortalOverviewCard/ReportPortalOverviewCard.tsx +++ b/plugins/report-portal/src/components/ReportPortalOverviewCard/ReportPortalOverviewCard.tsx @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; import MultiProgress from 'react-multi-progress'; import { InfoCard, InfoCardVariants } from '@backstage/core-components'; +import { configApiRef, useApi } from '@backstage/core-plugin-api'; import { useEntity } from '@backstage/plugin-catalog-react'; import { @@ -18,6 +19,7 @@ import { import { Skeleton } from '@material-ui/lab'; import { useLaunchDetails, useProjectDetails } from '../../hooks'; +import { isReportPortalAvailable } from '../../utils/isReportPortalAvailable'; const HeaderComponent = (props: { total: number }) => { return ( @@ -74,19 +76,30 @@ const useStyles = makeStyles({ export const ReportPortalOverviewCard = (props: { variant: InfoCardVariants; }) => { - const { entity } = useEntity(); const classes = useStyles(); + const config = useApi(configApiRef); + const hostsConfig = config.getConfigArray('reportPortal.integrations'); + + const { entity } = useEntity(); const projectId = entity.metadata.annotations?.['reportportal.io/project-name'] ?? ''; const launchName = entity.metadata.annotations?.['reportportal.io/launch-name'] ?? ''; - const hostName = entity.metadata.annotations?.['reportportal.io/host'] ?? ''; + const hostName = + entity.metadata.annotations?.['reportportal.io/host'] ?? + hostsConfig[0].getString('host'); + const [defects, setDefects] = useState([]); + const [filters, _] = useState<{ [key: string]: string | number } | undefined>( + { + 'filter.eq.name': launchName, + }, + ); const { loading, launchDetails } = useLaunchDetails( projectId, - launchName, hostName, + filters, ); const { loading: projectLoading, projectDetails } = useProjectDetails( projectId, @@ -112,6 +125,8 @@ export const ReportPortalOverviewCard = (props: { } }, [loading, launchDetails, projectDetails]); + if (!isReportPortalAvailable(entity)) return null; + return ( { + return ( + + } /> + } /> + } /> + + ); +}; diff --git a/plugins/report-portal/src/hooks/index.ts b/plugins/report-portal/src/hooks/index.ts index 6bae4c991c4..6fd3dbad25b 100644 --- a/plugins/report-portal/src/hooks/index.ts +++ b/plugins/report-portal/src/hooks/index.ts @@ -1,2 +1,3 @@ export * from './useProjectDetails'; export * from './useLaunchDetails'; +export * from './useInstanceDetails'; diff --git a/plugins/report-portal/src/hooks/useInstanceDetails.ts b/plugins/report-portal/src/hooks/useInstanceDetails.ts new file mode 100644 index 00000000000..c7fd4a0f926 --- /dev/null +++ b/plugins/report-portal/src/hooks/useInstanceDetails.ts @@ -0,0 +1,33 @@ +import React from 'react'; + +import { useApi } from '@backstage/core-plugin-api'; + +import { ProjectListResponse, reportPortalApiRef } from '../api'; + +export function useInstanceDetails(host: string, filterType: string) { + const reportPortalApi = useApi(reportPortalApiRef); + const [loading, setLoading] = React.useState(true); + const [projectListData, setProjectListData] = + React.useState({ + content: [], + page: { + number: 1, + size: 10, + totalElements: 0, + totalPages: 1, + }, + }); + + React.useEffect(() => { + setLoading(true); + reportPortalApi + .getInstanceDetails(host, { 'filter.eq.type': filterType }) + .then(res => { + setProjectListData(res); + setLoading(false); + }) + .catch(err => err); + }, [host, reportPortalApi, filterType]); + + return { loading, projectListData }; +} diff --git a/plugins/report-portal/src/hooks/useLaunchDetails.ts b/plugins/report-portal/src/hooks/useLaunchDetails.ts index 95036160784..582c6eb9e98 100644 --- a/plugins/report-portal/src/hooks/useLaunchDetails.ts +++ b/plugins/report-portal/src/hooks/useLaunchDetails.ts @@ -6,8 +6,8 @@ import { LaunchDetails, reportPortalApiRef } from '../api'; export function useLaunchDetails( projectId: string, - launchName: string, hostName: string, + filters: { [key: string]: string | number } | undefined, ) { const reportPortalApi = useApi(reportPortalApiRef); const [loading, setLoading] = useState(true); @@ -15,13 +15,11 @@ export function useLaunchDetails( useEffect(() => { setLoading(true); - reportPortalApi - .getLaunchResults(projectId, launchName, hostName) - .then(res => { - setLaunchDetails(res.content[0]); - setLoading(false); - }); - }, [projectId, launchName, hostName, reportPortalApi]); + reportPortalApi.getLaunchResults(projectId, hostName, filters).then(res => { + setLaunchDetails(res.content[0]); + setLoading(false); + }); + }, [filters, projectId, hostName, reportPortalApi]); return { loading, launchDetails }; } diff --git a/plugins/report-portal/src/hooks/useProjectDetails.ts b/plugins/report-portal/src/hooks/useProjectDetails.ts index 2dec5ce0dca..c83130b67e0 100644 --- a/plugins/report-portal/src/hooks/useProjectDetails.ts +++ b/plugins/report-portal/src/hooks/useProjectDetails.ts @@ -14,10 +14,13 @@ export function useProjectDetails( React.useEffect(() => { setLoading(true); - reportPortalApi.getProjectDetails(projectId, host).then(resp => { - setProjectDetails(resp); - setLoading(false); - }); + reportPortalApi + .getProjectDetails(projectId, host) + .then(resp => { + setProjectDetails(resp); + setLoading(false); + }) + .catch(err => err); }, [projectId, reportPortalApi, host]); return { loading, projectDetails }; diff --git a/plugins/report-portal/src/index.ts b/plugins/report-portal/src/index.ts new file mode 100644 index 00000000000..af0c37009b6 --- /dev/null +++ b/plugins/report-portal/src/index.ts @@ -0,0 +1,8 @@ +export { + reportPortalPlugin, + ReportPortalOverviewCard, + ReportPortalGlobalPage, +} from './plugin'; + +export { isReportPortalAvailable } from './utils/isReportPortalAvailable'; +export { ReportPortalIcon } from './components/ReportPortalIcon'; diff --git a/plugins/report-portal/src/plugin.ts b/plugins/report-portal/src/plugin.ts new file mode 100644 index 00000000000..d894c478cd1 --- /dev/null +++ b/plugins/report-portal/src/plugin.ts @@ -0,0 +1,47 @@ +import { + createApiFactory, + createComponentExtension, + createPlugin, + createRoutableExtension, + discoveryApiRef, +} from '@backstage/core-plugin-api'; + +import { reportPortalApiRef, ReportPortalClient } from './api'; +import { entityRootRouteRef, rootRouteRef } from './routes'; + +export const reportPortalPlugin = createPlugin({ + id: 'report-portal', + routes: { + root: rootRouteRef, + entityRoot: entityRootRouteRef, + }, + apis: [ + createApiFactory({ + api: reportPortalApiRef, + deps: { + discovery: discoveryApiRef, + }, + factory: ({ discovery }) => new ReportPortalClient(discovery), + }), + ], +}); + +export const ReportPortalOverviewCard = reportPortalPlugin.provide( + createComponentExtension({ + name: 'ReportPortalOverviewCard', + component: { + lazy: () => + import('./components/ReportPortalOverviewCard').then( + m => m.ReportPortalOverviewCard, + ), + }, + }), +); + +export const ReportPortalGlobalPage = reportPortalPlugin.provide( + createRoutableExtension({ + name: 'ReportPortalGlobalPage', + mountPoint: rootRouteRef, + component: () => import('./components/Router').then(m => m.Router), + }), +); diff --git a/plugins/report-portal/src/routes.ts b/plugins/report-portal/src/routes.ts new file mode 100644 index 00000000000..09b830609f3 --- /dev/null +++ b/plugins/report-portal/src/routes.ts @@ -0,0 +1,22 @@ +import { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api'; + +export const rootRouteRef = createRouteRef({ + id: 'report-portal', +}); + +export const projectsRouteRef = createSubRouteRef({ + id: 'report-portal:projects', + path: '/instance', + parent: rootRouteRef, +}); + +export const launchRouteRef = createSubRouteRef({ + id: 'report-portal:launches', + path: '/instance/project', + parent: rootRouteRef, +}); + +export const entityRootRouteRef = createRouteRef({ + id: 'report-portal:entity-page', + params: ['namespace', 'kind', 'name'], +}); diff --git a/plugins/report-portal/src/utils/isReportPortalAvailable.ts b/plugins/report-portal/src/utils/isReportPortalAvailable.ts new file mode 100644 index 00000000000..04062871420 --- /dev/null +++ b/plugins/report-portal/src/utils/isReportPortalAvailable.ts @@ -0,0 +1,8 @@ +import { Entity } from '@backstage/catalog-model'; + +export const isReportPortalAvailable = (entity: Entity): boolean => { + return Boolean( + entity.metadata.annotations?.['reportportal.io/project-name'] && + entity.metadata.annotations?.['reportportal.io/launch-name'], + ); +}; diff --git a/yarn.lock b/yarn.lock index 75b09b5733e..123d9b215e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5015,6 +5015,13 @@ react-use "^17.2.4" zen-observable "^0.10.0" +"@backstage/release-manifests@^0.0.10": + version "0.0.10" + resolved "https://registry.yarnpkg.com/@backstage/release-manifests/-/release-manifests-0.0.10.tgz#10f0c23cd1a00ca9b2ac5bf5c199592ba0abedae" + integrity sha512-MKGY1IqYGqItQyX+qbI+U0VPqgh9VqFIQreCOC8JXU1sh7v8XfR2DWZGmw1qVzVtIitNeqsNwIwIJyqtiMokow== + dependencies: + cross-fetch "^3.1.5" + "@backstage/release-manifests@^0.0.11": version "0.0.11" resolved "https://registry.yarnpkg.com/@backstage/release-manifests/-/release-manifests-0.0.11.tgz#e842816d249f6903c8121253358a3211425ac83e" @@ -5388,6 +5395,30 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== +"@esbuild-kit/cjs-loader@^2.4.1": + version "2.4.4" + resolved "https://registry.yarnpkg.com/@esbuild-kit/cjs-loader/-/cjs-loader-2.4.4.tgz#8638177732e2de258a3243597bfdba082993c442" + integrity sha512-NfsJX4PdzhwSkfJukczyUiZGc7zNNWZcEAyqeISpDnn0PTfzMJR1aR8xAIPskBejIxBJbIgCCMzbaYa9SXepIg== + dependencies: + "@esbuild-kit/core-utils" "^3.2.3" + get-tsconfig "^4.7.0" + +"@esbuild-kit/core-utils@^3.2.3", "@esbuild-kit/core-utils@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz#186b6598a5066f0413471d7c4d45828e399ba96c" + integrity sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ== + dependencies: + esbuild "~0.18.20" + source-map-support "^0.5.21" + +"@esbuild-kit/esm-loader@^2.5.5": + version "2.6.5" + resolved "https://registry.yarnpkg.com/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz#6eedee46095d7d13b1efc381e2211ed1c60e64ea" + integrity sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA== + dependencies: + "@esbuild-kit/core-utils" "^3.3.2" + get-tsconfig "^4.7.0" + "@esbuild/aix-ppc64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" @@ -5989,16 +6020,50 @@ arrify "^2.0.0" extend "^3.0.2" +"@google-cloud/projectify@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@google-cloud/projectify/-/projectify-3.0.0.tgz#302b25f55f674854dce65c2532d98919b118a408" + integrity sha512-HRkZsNmjScY6Li8/kb70wjGlDDyLkVk3KvoEo9uIoxSjYLJasGiCch9+PqRVDOCGUFvEIqyogl+BeqILL4OJHA== + "@google-cloud/projectify@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@google-cloud/projectify/-/projectify-4.0.0.tgz#d600e0433daf51b88c1fa95ac7f02e38e80a07be" integrity sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA== +"@google-cloud/promisify@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@google-cloud/promisify/-/promisify-3.0.1.tgz#8d724fb280f47d1ff99953aee0c1669b25238c2e" + integrity sha512-z1CjRjtQyBOYL+5Qr9DdYIfrdLBe746jRTYfaYU6MeXkqp7UfYs/jX16lFFVzZ7PGEJvqZNqYUEtb1mvDww4pA== + "@google-cloud/promisify@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@google-cloud/promisify/-/promisify-4.0.0.tgz#a906e533ebdd0f754dca2509933334ce58b8c8b1" integrity sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g== +"@google-cloud/storage@^6.0.0": + version "6.12.0" + resolved "https://registry.yarnpkg.com/@google-cloud/storage/-/storage-6.12.0.tgz#a5d3093cc075252dca5bd19a3cfda406ad3a9de1" + integrity sha512-78nNAY7iiZ4O/BouWMWTD/oSF2YtYgYB3GZirn0To6eBOugjXVoK+GXgUXOl+HlqbAOyHxAVXOlsj3snfbQ1dw== + dependencies: + "@google-cloud/paginator" "^3.0.7" + "@google-cloud/projectify" "^3.0.0" + "@google-cloud/promisify" "^3.0.0" + abort-controller "^3.0.0" + async-retry "^1.3.3" + compressible "^2.0.12" + duplexify "^4.0.0" + ent "^2.2.0" + extend "^3.0.2" + fast-xml-parser "^4.2.2" + gaxios "^5.0.0" + google-auth-library "^8.0.1" + mime "^3.0.0" + mime-types "^2.0.8" + p-limit "^3.0.1" + retry-request "^5.0.0" + teeny-request "^8.0.0" + uuid "^8.0.0" + "@google-cloud/storage@^7.0.0": version "7.10.1" resolved "https://registry.yarnpkg.com/@google-cloud/storage/-/storage-7.10.1.tgz#f9f671d73a0b5a7a3f3db976d98fa5adb577b05b" @@ -6639,7 +6704,7 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": version "1.4.15" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== @@ -7051,6 +7116,28 @@ ajv-formats-draft2019 "^1.6.1" tslib "^2.4.0" +"@kubernetes/client-node@0.19.0": + version "0.19.0" + resolved "https://registry.yarnpkg.com/@kubernetes/client-node/-/client-node-0.19.0.tgz#ebd2121e5c8dc1a47ff1b2574bda1e760d0abb82" + integrity sha512-WTOjGuFQ8yeW3+qD6JrAYhpwpoQbe9R8cA/61WCyFrNawSTUgLstHu7EsZRYEs39er3jDn3wCEaczz+VOFlc2Q== + dependencies: + "@types/js-yaml" "^4.0.1" + "@types/node" "^20.1.1" + "@types/request" "^2.47.1" + "@types/ws" "^8.5.3" + byline "^5.0.0" + isomorphic-ws "^5.0.0" + js-yaml "^4.1.0" + jsonpath-plus "^7.2.0" + request "^2.88.0" + rfc4648 "^1.3.0" + stream-buffers "^3.0.2" + tar "^6.1.11" + tslib "^2.4.1" + ws "^8.11.0" + optionalDependencies: + openid-client "^5.3.0" + "@kubernetes/client-node@0.20.0", "@kubernetes/client-node@^0.20.0": version "0.20.0" resolved "https://registry.yarnpkg.com/@kubernetes/client-node/-/client-node-0.20.0.tgz#4447ae27fd6eef3d4830a5a039f3b84ffd5c5913" @@ -7498,8 +7585,6 @@ clsx "^2.1.0" csstype "^3.1.3" prop-types "^15.8.1" - react-is "^18.2.0" - react-transition-group "^4.4.5" "@mui/private-theming@^5.15.14": version "5.15.14" @@ -9478,6 +9563,13 @@ resolved "https://registry.yarnpkg.com/@react-hookz/deep-equal/-/deep-equal-1.0.4.tgz#68a71f36cbc88724b3ce6f4036183778b6e7f282" integrity sha512-N56fTrAPUDz/R423pag+n6TXWbvlBZDtTehaGFjK0InmN+V2OFWLE/WmORhmn6Ce7dlwH5+tQN1LJFw3ngTJVg== +"@react-hookz/web@^23.0.0": + version "23.1.0" + resolved "https://registry.yarnpkg.com/@react-hookz/web/-/web-23.1.0.tgz#4e9bf133c56519924b4c2988aca20d09387f5e0a" + integrity sha512-fvbURdsa1ukttbLR1ASE/XmqXP09vZ1PiCYppYeR1sNMzCrdkG0iBnjxniFSVjJ8gIw2fRs6nqMTbeBz2uAkuA== + dependencies: + "@react-hookz/deep-equal" "^1.0.4" + "@react-hookz/web@^24.0.0": version "24.0.4" resolved "https://registry.yarnpkg.com/@react-hookz/web/-/web-24.0.4.tgz#7a13d4c2cc65861b926ef6c4452fba00408c8778" @@ -9635,6 +9727,15 @@ js-yaml "^4.1.0" tosource "^2.0.0-alpha.3" +"@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + "@rollup/pluginutils@^4.1.1", "@rollup/pluginutils@^4.2.1": version "4.2.1" resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" @@ -10340,16 +10441,16 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@smithy/node-http-handler@^2.1.7": - version "2.1.7" - resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-2.1.7.tgz#a920e0e40fd04e2ea399cb4f06092fea0a1b66da" - integrity sha512-PQIKZXlp3awCDn/xNlCSTFE7aYG/5Tx33M05NfQmWYeB5yV1GZZOSz4dXpwiNJYTXb9jPqjl+ueXXkwtEluFFA== +"@smithy/node-http-handler@^2.1.7", "@smithy/node-http-handler@^2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-2.5.0.tgz#7b5e0565dd23d340380489bd5fe4316d2bed32de" + integrity sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA== dependencies: - "@smithy/abort-controller" "^2.0.11" - "@smithy/protocol-http" "^3.0.7" - "@smithy/querystring-builder" "^2.0.11" - "@smithy/types" "^2.3.5" - tslib "^2.5.0" + "@smithy/abort-controller" "^2.2.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/querystring-builder" "^2.2.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" "@smithy/node-http-handler@^2.5.0": version "2.5.0" @@ -13489,7 +13590,7 @@ lodash "^4.17.15" redent "^3.0.0" -"@testing-library/jest-dom@6.4.2": +"@testing-library/jest-dom@6.4.2", "@testing-library/jest-dom@^6.0.0": version "6.4.2" resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.4.2.tgz#38949f6b63722900e2d75ba3c6d9bf8cffb3300e" integrity sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw== @@ -13503,20 +13604,6 @@ lodash "^4.17.15" redent "^3.0.0" -"@testing-library/jest-dom@6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.0.0.tgz#d2ba5a3fd13724d5966b3f8cd24d2cedcab4fa76" - integrity sha512-Ye2R3+/oM27jir8CzYPmuWdavTaKwNZcu0d22L9pO/vnOYE0wmrtpw79TQJa8H6gV8/i7yd+pLaqeLlA0rTMfg== - dependencies: - "@adobe/css-tools" "^4.0.1" - "@babel/runtime" "^7.9.2" - aria-query "^5.0.0" - chalk "^3.0.0" - css.escape "^1.5.1" - dom-accessibility-api "^0.5.6" - lodash "^4.17.15" - redent "^3.0.0" - "@testing-library/react-hooks@8.0.1": version "8.0.1" resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz#0924bbd5b55e0c0c0502d1754657ada66947ca12" @@ -13577,6 +13664,7 @@ version "0.0.7" resolved "https://registry.yarnpkg.com/@trendyol-js/openstack-swift-sdk/-/openstack-swift-sdk-0.0.7.tgz#45ba1dbfd1ccd3df263b25981a4d563943e1766d" integrity sha512-N3jYUiqwNT4KajMPQJkFn6FrVCdFcnyRvphGHCdyfvxf3PxZbEDV2mDjLQ+qNTLWsDS3hEfE63KISOpM2Cuo6g== + dependencies: agentkeepalive "^4.1.4" axios "^1.0.0" axios-cached-dns-resolve "0.5.2" @@ -14244,7 +14332,7 @@ jest-diff "^26.0.0" pretty-format "^26.0.0" -"@types/jest@^29.5.11": +"@types/jest@^29.0.0", "@types/jest@^29.5.11": version "29.5.12" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.12.tgz#7f7dc6eb4cf246d2474ed78744b05d06ce025544" integrity sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw== @@ -14640,6 +14728,13 @@ "@types/tough-cookie" "*" form-data "^2.5.0" +"@types/resolve@1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" + integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== + dependencies: + "@types/node" "*" + "@types/resolve@1.20.2": version "1.20.2" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" @@ -14759,6 +14854,7 @@ "@types/cookiejar" "^2.1.5" "@types/methods" "^1.1.4" "@types/node" "*" + "@types/supertest@2.0.12": version "2.0.12" resolved "https://registry.yarnpkg.com/@types/supertest/-/supertest-2.0.12.tgz#ddb4a0568597c9aadff8dbec5b2e8fddbe8692fc" @@ -14767,7 +14863,6 @@ "@types/superagent" "*" "@types/supertest@2.0.16": -"@types/supertest@2.0.16", "@types/supertest@^2.0.12": version "2.0.16" resolved "https://registry.yarnpkg.com/@types/supertest/-/supertest-2.0.16.tgz#7a1294edebecb960d957bbe9b26002a2b7f21cd7" integrity sha512-6c2ogktZ06tr2ENoZivgm7YnprnhYE4ZoXGMY+oA7IuAf17M8FWvujXZGmxLv8y0PTyts4x5A+erSwVUFA8XSg== @@ -14900,6 +14995,23 @@ resolved "https://registry.yarnpkg.com/@types/yarnpkg__lockfile/-/yarnpkg__lockfile-1.1.4.tgz#445251eb00bd9c1e751f82c7c6bf4f714edfd464" integrity sha512-/emrKCfQMQmFCqRqqBJ0JueHBT06jBRM3e8OgnvDUcvuExONujIk2hFA5dNsN9Nt41ljGVDdChvCydATZ+KOZw== +"@typescript-eslint/eslint-plugin@6.7.5": + version "6.7.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.5.tgz#f4024b9f63593d0c2b5bd6e4ca027e6f30934d4f" + integrity sha512-JhtAwTRhOUcP96D0Y6KYnwig/MRQbOoLGXTON2+LlyB/N35SP9j1boai2zzwXb7ypKELXMx3DVk9UTaEq1vHEw== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.7.5" + "@typescript-eslint/type-utils" "6.7.5" + "@typescript-eslint/utils" "6.7.5" + "@typescript-eslint/visitor-keys" "6.7.5" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + "@typescript-eslint/eslint-plugin@^6.12.0": version "6.21.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz#30830c1ca81fd5f3c2714e524c4303e0194f9cd3" @@ -14954,6 +15066,16 @@ debug "^4.3.4" ts-api-utils "^1.0.1" +"@typescript-eslint/type-utils@6.7.5": + version "6.7.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.7.5.tgz#0a65949ec16588d8956f6d967f7d9c84ddb2d72a" + integrity sha512-Gs0qos5wqxnQrvpYv+pf3XfcRXW6jiAn9zE/K+DlmYf6FcpxeNYN0AIETaPR7rHO4K2UY+D0CIbDP9Ut0U4m1g== + dependencies: + "@typescript-eslint/typescript-estree" "6.7.5" + "@typescript-eslint/utils" "6.7.5" + debug "^4.3.4" + ts-api-utils "^1.0.1" + "@typescript-eslint/types@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" @@ -20033,7 +20155,7 @@ esbuild@^0.16.17: "@esbuild/win32-ia32" "0.16.17" "@esbuild/win32-x64" "0.16.17" -esbuild@^0.18.0: +esbuild@^0.18.0, esbuild@~0.18.20: version "0.18.20" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6" integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== @@ -20177,7 +20299,7 @@ escodegen@^2.0.0, escodegen@^2.1.0: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^8.10.0: +eslint-config-prettier@^8.10.0, eslint-config-prettier@^8.3.0: version "8.10.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== @@ -20214,6 +20336,15 @@ eslint-module-utils@^2.8.0: dependencies: debug "^3.2.7" +eslint-plugin-deprecation@^1.3.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-deprecation/-/eslint-plugin-deprecation-1.6.0.tgz#b12d0c5a9baf3bcde0752ff6337703c059a4ae23" + integrity sha512-rld+Vrneh/NXRtDB0vQifOvgUy0HJYoejaxWlVnsk/LK7iij2tCWQIFcCKG4uzQb+Ef86bDke39w1lh4wnon4Q== + dependencies: + "@typescript-eslint/utils" "^6.0.0" + tslib "^2.3.1" + tsutils "^3.21.0" + eslint-plugin-deprecation@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-deprecation/-/eslint-plugin-deprecation-2.0.0.tgz#9804707a4c19f3a53615c6babc0ced3d429d69cf" @@ -20354,7 +20485,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint-webpack-plugin@^3.2.0: +eslint-webpack-plugin@^3.1.1, eslint-webpack-plugin@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz#1978cdb9edc461e4b0195a20da950cf57988347c" integrity sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w== @@ -20487,6 +20618,11 @@ estree-walker@^0.6.1: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== +estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + estree-walker@^2.0.1, estree-walker@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" @@ -23224,7 +23360,7 @@ is-buffer@^2.0.0: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== -is-builtin-module@^3.2.1: +is-builtin-module@^3.1.0, is-builtin-module@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== @@ -23576,6 +23712,11 @@ is-ssh@^1.4.0: dependencies: protocols "^2.0.1" +is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" @@ -24320,7 +24461,7 @@ jest-worker@^29.7.0: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^29.7.0: +jest@^29.0.2, jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== @@ -27517,6 +27658,13 @@ node-fetch@2.6.7: dependencies: whatwg-url "^5.0.0" +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" node-fetch@^2.0.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.7, node-fetch@^2.6.9, node-fetch@^2.7.0: version "2.7.0" @@ -30862,6 +31010,13 @@ react-router@6.23.0, react-router@^6.23.0: dependencies: "@remix-run/router" "1.16.0" +react-router@6.22.3, react-router@^6.17.0: + version "6.22.3" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.22.3.tgz#9d9142f35e08be08c736a2082db5f0c9540a885e" + integrity sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ== + dependencies: + "@remix-run/router" "1.15.3" + react-side-effect@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.2.tgz#dc6345b9e8f9906dc2eeb68700b615e0b4fe752a" @@ -30945,7 +31100,7 @@ react-use@17.4.0, react-use@^17.2.4, react-use@^17.3.2, react-use@^17.4.0: fast-deep-equal "^3.1.3" fast-shallow-equal "^1.0.0" js-cookie "^2.2.1" - nano-css "^5.3.1" + nano-css "^5.6.1" react-universal-interface "^0.6.2" resize-observer-polyfill "^1.5.1" screenfull "^5.1.0" @@ -31667,6 +31822,14 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +retry-request@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-5.0.2.tgz#143d85f90c755af407fcc46b7166a4ba520e44da" + integrity sha512-wfI3pk7EE80lCIXprqh7ym48IHYdwmAAzESdbU8Q9l7pnRCk9LEhpbOTNKjz6FARLm/Bl5m+4F0ABxOkYUujSQ== + dependencies: + debug "^4.1.1" + extend "^3.0.2" + retry-request@^7.0.0: version "7.0.2" resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-7.0.2.tgz#60bf48cfb424ec01b03fca6665dee91d06dd95f3" @@ -32651,7 +32814,7 @@ source-map-support@0.5.13: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@^0.5.16, source-map-support@^0.5.17, source-map-support@~0.5.20: +source-map-support@^0.5.16, source-map-support@^0.5.17, source-map-support@^0.5.21, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -33340,8 +33503,8 @@ sucrase@^3.20.2: mz "^2.7.0" pirates "^4.0.1" ts-interface-checker "^0.1.9" + superagent@^8.0.0, superagent@^8.0.5: -superagent@^8.0.5, superagent@^8.1.2: version "8.1.2" resolved "https://registry.yarnpkg.com/superagent/-/superagent-8.1.2.tgz#03cb7da3ec8b32472c9d20f6c2a57c7f3765f30b" integrity sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA== @@ -33656,6 +33819,17 @@ tdigest@^0.1.1: dependencies: bintrees "1.0.2" +teeny-request@^8.0.0: + version "8.0.3" + resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-8.0.3.tgz#5cb9c471ef5e59f2fca8280dc3c5909595e6ca24" + integrity sha512-jJZpA5He2y52yUhA7pyAGZlgQpcB+xLjcN0eUFxr9c8hP/H7uOXbBNVo/O0C/xVfJLJs680jvkFgVJEEvk9+ww== + dependencies: + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + node-fetch "^2.6.1" + stream-events "^1.0.5" + uuid "^9.0.0" + teeny-request@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-9.0.0.tgz#18140de2eb6595771b1b02203312dfad79a4716d" @@ -34664,11 +34838,6 @@ underscore@~1.7.0: resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209" integrity sha512-cp0oQQyZhUM1kpJDLdGO1jPZHgS/MpzoWYfe9+CM2h/QGDZlqwT2T3YGukuBdaNJ/CAPoeyAZRRHz8JFo176vA== -undici-types@~5.25.1: - version "5.25.3" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3" - integrity sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA== - undici-types@~5.26.4: version "5.26.5" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"