From 33dd204466841c3f5312d9f8ded0153d53084096 Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Tue, 2 Apr 2024 16:01:33 +0100 Subject: [PATCH] E2C: Generate RTK Query API slice from swagger spec (#85463) * add deps and script * add codegen rtk api clise for cloud migration * rename all the mock exports to mock * Reset changes to package.json and yarn.lock * codeowners --- .github/CODEOWNERS | 1 + package.json | 4 +- public/app/core/reducers/root.ts | 6 +- .../features/migrate-to-cloud/api/baseAPI.ts | 34 ++ .../migrate-to-cloud/api/endpoints.gen.ts | 120 +++++++ .../features/migrate-to-cloud/api/index.ts | 2 + .../MigrationTokenPane/MigrationTokenPane.tsx | 12 +- .../migrate-to-cloud/{api.ts => mockAPI.ts} | 32 +- .../onprem/DisconnectModal.tsx | 4 +- .../EmptyState/CallToAction/CallToAction.tsx | 6 +- .../EmptyState/CallToAction/ConnectModal.tsx | 8 +- .../features/migrate-to-cloud/onprem/Page.tsx | 8 +- .../onprem/ResourcesTable.tsx | 12 +- public/app/store/configureStore.ts | 6 +- scripts/generate-rtk-apis.ts | 27 ++ yarn.lock | 333 +++++++++++++++++- 16 files changed, 567 insertions(+), 48 deletions(-) create mode 100644 public/app/features/migrate-to-cloud/api/baseAPI.ts create mode 100644 public/app/features/migrate-to-cloud/api/endpoints.gen.ts create mode 100644 public/app/features/migrate-to-cloud/api/index.ts rename public/app/features/migrate-to-cloud/{api.ts => mockAPI.ts} (86%) create mode 100644 scripts/generate-rtk-apis.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b0869acd6ea..563fbbeada4 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -535,6 +535,7 @@ playwright.config.ts @grafana/plugins-platform-frontend /scripts/cleanup-husky.sh @grafana/frontend-ops /scripts/verify-repo-update/ @grafana/grafana-release-guild /scripts/generate-icon-bundle.js @grafana/plugins-platform-frontend @grafana/grafana-frontend-platform +/scripts/generate-rtk-apis.ts @grafana/grafana-frontend-platform /scripts/levitate-parse-json-report.js @grafana/plugins-platform-frontend /scripts/**/generate-transformations* @grafana/dataviz-squad diff --git a/package.json b/package.json index 2b8072821d3..0e6f8bfd618 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,8 @@ "plugin:build": "nx run-many -t build --projects='@grafana-plugins/*' --exclude \"@grafana-plugins/input-datasource\"", "plugin:build:commit": "nx run-many -t build:commit --projects='@grafana-plugins/*' --exclude \"@grafana-plugins/input-datasource\"", "plugin:build:dev": "nx run-many -t dev --projects='@grafana-plugins/*' --exclude \"@grafana-plugins/input-datasource\"", - "generate-icons": "yarn workspace @grafana/saga-icons generate" + "generate-icons": "yarn workspace @grafana/saga-icons generate", + "generate-apis": "rtk-query-codegen-openapi ./scripts/generate-rtk-apis.ts" }, "grafana": { "whatsNewUrl": "https://grafana.com/docs/grafana/next/whatsnew/whats-new-in-v11-0/", @@ -85,6 +86,7 @@ "@react-types/menu": "3.9.7", "@react-types/overlays": "3.8.5", "@react-types/shared": "3.22.1", + "@rtk-query/codegen-openapi": "^1.2.0", "@rtsao/plugin-proposal-class-properties": "7.0.1-patch.1", "@swc/core": "1.4.2", "@swc/helpers": "0.5.8", diff --git a/public/app/core/reducers/root.ts b/public/app/core/reducers/root.ts index c776ce8c49c..761d7ab8efc 100644 --- a/public/app/core/reducers/root.ts +++ b/public/app/core/reducers/root.ts @@ -16,7 +16,8 @@ import exploreReducers from 'app/features/explore/state/main'; import foldersReducers from 'app/features/folders/state/reducers'; import invitesReducers from 'app/features/invites/state/reducers'; import importDashboardReducers from 'app/features/manage-dashboards/state/reducers'; -import { migrateToCloudAPI } from 'app/features/migrate-to-cloud/api'; +import { cloudMigrationAPI } from 'app/features/migrate-to-cloud/api'; +import { migrateToCloudMockAPI } from 'app/features/migrate-to-cloud/mockAPI'; import organizationReducers from 'app/features/org/state/reducers'; import panelsReducers from 'app/features/panel/state/reducers'; import { reducer as pluginsReducer } from 'app/features/plugins/admin/state/reducer'; @@ -56,7 +57,8 @@ const rootReducers = { [alertingApi.reducerPath]: alertingApi.reducer, [publicDashboardApi.reducerPath]: publicDashboardApi.reducer, [browseDashboardsAPI.reducerPath]: browseDashboardsAPI.reducer, - [migrateToCloudAPI.reducerPath]: migrateToCloudAPI.reducer, + [migrateToCloudMockAPI.reducerPath]: migrateToCloudMockAPI.reducer, + [cloudMigrationAPI.reducerPath]: cloudMigrationAPI.reducer, }; const addedReducers = {}; diff --git a/public/app/features/migrate-to-cloud/api/baseAPI.ts b/public/app/features/migrate-to-cloud/api/baseAPI.ts new file mode 100644 index 00000000000..62d97c20b9e --- /dev/null +++ b/public/app/features/migrate-to-cloud/api/baseAPI.ts @@ -0,0 +1,34 @@ +import { BaseQueryFn, createApi } from '@reduxjs/toolkit/query/react'; +import { lastValueFrom } from 'rxjs'; + +import { BackendSrvRequest, getBackendSrv } from '@grafana/runtime'; + +interface RequestOptions extends BackendSrvRequest { + manageError?: (err: unknown) => { error: unknown }; + showErrorAlert?: boolean; +} + +function createBackendSrvBaseQuery({ baseURL }: { baseURL: string }): BaseQueryFn { + async function backendSrvBaseQuery(requestOptions: RequestOptions) { + try { + const { data: responseData, ...meta } = await lastValueFrom( + getBackendSrv().fetch({ + ...requestOptions, + url: baseURL + requestOptions.url, + showErrorAlert: requestOptions.showErrorAlert, + }) + ); + return { data: responseData, meta }; + } catch (error) { + return requestOptions.manageError ? requestOptions.manageError(error) : { error }; + } + } + + return backendSrvBaseQuery; +} + +export const baseAPI = createApi({ + reducerPath: 'migrateToCloudGeneratedAPI', + baseQuery: createBackendSrvBaseQuery({ baseURL: '/api' }), + endpoints: () => ({}), +}); diff --git a/public/app/features/migrate-to-cloud/api/endpoints.gen.ts b/public/app/features/migrate-to-cloud/api/endpoints.gen.ts new file mode 100644 index 00000000000..2ac2beb2898 --- /dev/null +++ b/public/app/features/migrate-to-cloud/api/endpoints.gen.ts @@ -0,0 +1,120 @@ +import { baseAPI as api } from './baseAPI'; +const injectedRtkApi = api.injectEndpoints({ + endpoints: (build) => ({ + getMigrationList: build.query({ + query: () => ({ url: `/cloudmigration/migration` }), + }), + createMigration: build.mutation({ + query: (queryArg) => ({ + url: `/cloudmigration/migration`, + method: 'POST', + params: { authToken: queryArg.authToken }, + }), + }), + deleteCloudMigration: build.mutation({ + query: (queryArg) => ({ url: `/cloudmigration/migration/${queryArg.id}`, method: 'DELETE' }), + }), + getCloudMigration: build.query({ + query: (queryArg) => ({ url: `/cloudmigration/migration/${queryArg.id}` }), + }), + getCloudMigrationRunList: build.query({ + query: (queryArg) => ({ url: `/cloudmigration/migration/${queryArg.id}/run` }), + }), + getCloudMigrationRun: build.query({ + query: (queryArg) => ({ url: `/cloudmigration/migration/${queryArg.id}/run/${queryArg.runId}` }), + }), + createCloudMigrationToken: build.mutation({ + query: () => ({ url: `/cloudmigration/token`, method: 'POST' }), + }), + }), + overrideExisting: false, +}); +export { injectedRtkApi as enhancedApi }; +export type GetMigrationListApiResponse = /** status 200 (empty) */ CloudMigrationListResponse; +export type GetMigrationListApiArg = void; +export type CreateMigrationApiResponse = /** status 200 (empty) */ CloudMigrationResponse; +export type CreateMigrationApiArg = { + authToken?: string; +}; +export type DeleteCloudMigrationApiResponse = unknown; +export type DeleteCloudMigrationApiArg = { + /** ID of an migration */ + id: number; +}; +export type GetCloudMigrationApiResponse = /** status 200 (empty) */ CloudMigrationResponse; +export type GetCloudMigrationApiArg = { + /** ID of an migration */ + id: number; +}; +export type GetCloudMigrationRunListApiResponse = /** status 200 (empty) */ CloudMigrationRunList; +export type GetCloudMigrationRunListApiArg = { + /** ID of an migration */ + id: number; +}; +export type GetCloudMigrationRunApiResponse = /** status 200 (empty) */ CloudMigrationRun; +export type GetCloudMigrationRunApiArg = { + /** ID of an migration */ + id: number; + /** Run ID of a migration run */ + runId: number; +}; +export type CreateCloudMigrationTokenApiResponse = /** status 200 (empty) */ CreateAccessTokenResponseDto; +export type CreateCloudMigrationTokenApiArg = void; +export type CloudMigrationResponse = { + created?: string; + id?: number; + stack?: string; + updated?: string; +}; +export type CloudMigrationListResponse = { + migrations?: CloudMigrationResponse[]; +}; +export type ErrorResponseBody = { + /** Error An optional detailed description of the actual error. Only included if running in developer mode. */ + error?: string; + /** a human readable version of the error */ + message: string; + /** Status An optional status to denote the cause of the error. + + For example, a 412 Precondition Failed error may include additional information of why that error happened. */ + status?: string; +}; +export type MigratedResourceResult = { + message?: string; + status?: string; +}; +export type MigratedResource = { + id?: string; + name?: string; + refID?: string; + result?: MigratedResourceResult; + type?: string; +}; +export type MigrationResult = { + message?: string; + status?: string; +}; +export type CloudMigrationRun = { + created?: string; + finished?: string; + id?: number; + items?: MigratedResource[]; + result?: MigrationResult; + uid?: string; + updated?: string; +}; +export type CloudMigrationRunList = { + runs?: CloudMigrationRun[]; +}; +export type CreateAccessTokenResponseDto = { + token?: string; +}; +export const { + useGetMigrationListQuery, + useCreateMigrationMutation, + useDeleteCloudMigrationMutation, + useGetCloudMigrationQuery, + useGetCloudMigrationRunListQuery, + useGetCloudMigrationRunQuery, + useCreateCloudMigrationTokenMutation, +} = injectedRtkApi; diff --git a/public/app/features/migrate-to-cloud/api/index.ts b/public/app/features/migrate-to-cloud/api/index.ts new file mode 100644 index 00000000000..3c0c7cab8d9 --- /dev/null +++ b/public/app/features/migrate-to-cloud/api/index.ts @@ -0,0 +1,2 @@ +export * from './endpoints.gen'; +export { enhancedApi as cloudMigrationAPI } from './endpoints.gen'; diff --git a/public/app/features/migrate-to-cloud/cloud/MigrationTokenPane/MigrationTokenPane.tsx b/public/app/features/migrate-to-cloud/cloud/MigrationTokenPane/MigrationTokenPane.tsx index 884eaf46bc9..3c640abfcbd 100644 --- a/public/app/features/migrate-to-cloud/cloud/MigrationTokenPane/MigrationTokenPane.tsx +++ b/public/app/features/migrate-to-cloud/cloud/MigrationTokenPane/MigrationTokenPane.tsx @@ -3,7 +3,11 @@ import React from 'react'; import { Box, Button, ModalsController, Text } from '@grafana/ui'; import { t, Trans } from 'app/core/internationalization'; -import { useCreateMigrationTokenMutation, useDeleteMigrationTokenMutation, useHasMigrationTokenQuery } from '../../api'; +import { + useCreateMigrationTokenMutationMock, + useDeleteMigrationTokenMutationMock, + useHasMigrationTokenQueryMock, +} from '../../mockAPI'; import { InfoItem } from '../../shared/InfoItem'; import { DeleteMigrationTokenModal } from './DeleteMigrationTokenModal'; @@ -11,9 +15,9 @@ import { MigrationTokenModal } from './MigrationTokenModal'; import { TokenStatus } from './TokenStatus'; export const MigrationTokenPane = () => { - const { data: hasToken, isFetching } = useHasMigrationTokenQuery(); - const [createToken, createTokenResponse] = useCreateMigrationTokenMutation(); - const [deleteToken, deleteTokenResponse] = useDeleteMigrationTokenMutation(); + const { data: hasToken, isFetching } = useHasMigrationTokenQueryMock(); + const [createToken, createTokenResponse] = useCreateMigrationTokenMutationMock(); + const [deleteToken, deleteTokenResponse] = useDeleteMigrationTokenMutationMock(); return ( diff --git a/public/app/features/migrate-to-cloud/api.ts b/public/app/features/migrate-to-cloud/mockAPI.ts similarity index 86% rename from public/app/features/migrate-to-cloud/api.ts rename to public/app/features/migrate-to-cloud/mockAPI.ts index 0b8261144ee..a4ff9d547c5 100644 --- a/public/app/features/migrate-to-cloud/api.ts +++ b/public/app/features/migrate-to-cloud/mockAPI.ts @@ -36,12 +36,12 @@ interface CreateMigrationTokenResponseDTO { token: string; } -export interface ConnectStackDTO { +export interface ConnectStackDTOMock { stackURL: string; token: string; } -export interface MigrationResourceDTO { +export interface MigrationResourceDTOMock { uid: string; status: 'not-migrated' | 'migrated' | 'migrating' | 'failed'; statusMessage?: string; @@ -85,7 +85,7 @@ const mockDataSourceMetadata: Record = { }, }; -const mockMigrationResources: MigrationResourceDTO[] = Array.from({ length: 500 }).map((_, index) => { +const mockMigrationResources: MigrationResourceDTOMock[] = Array.from({ length: 500 }).map((_, index) => { const dataSource = mockDataSources[index % mockDataSources.length]; const environment = mockEnvs[index % mockEnvs.length]; const application = mockApplications[index % mockApplications.length]; @@ -130,9 +130,9 @@ function dataWithMockDelay(data: T): Promise<{ data: T }> { }); } -export const migrateToCloudAPI = createApi({ +export const migrateToCloudMockAPI = createApi({ tagTypes: ['migrationToken', 'stackDetails', 'resource'], - reducerPath: 'migrateToCloudAPI', + reducerPath: 'migrateToCloudMockAPI', baseQuery: createBackendSrvBaseQuery({ baseURL: '/api' }), endpoints: (builder) => ({ // TODO :) @@ -147,7 +147,7 @@ export const migrateToCloudAPI = createApi({ }, }), - connectStack: builder.mutation({ + connectStack: builder.mutation({ invalidatesTags: ['stackDetails'], queryFn: async ({ stackURL }) => { HAS_STACK_DETAILS = true; @@ -193,7 +193,7 @@ export const migrateToCloudAPI = createApi({ }, }), - listResources: builder.query({ + listResources: builder.query({ providesTags: ['resource'], queryFn: async () => { return dataWithMockDelay(mockMigrationResources); @@ -203,12 +203,12 @@ export const migrateToCloudAPI = createApi({ }); export const { - useGetStatusQuery, - useConnectStackMutation, - useDisconnectStackMutation, - useCreateMigrationTokenMutation, - useDeleteMigrationTokenMutation, - useHasMigrationTokenQuery, - useListResourcesQuery, - useStartMigrationMutation, -} = migrateToCloudAPI; + useGetStatusQuery: useGetStatusQueryMock, + useConnectStackMutation: useConnectStackMutationMock, + useDisconnectStackMutation: useDisconnectStackMutationMock, + useCreateMigrationTokenMutation: useCreateMigrationTokenMutationMock, + useDeleteMigrationTokenMutation: useDeleteMigrationTokenMutationMock, + useHasMigrationTokenQuery: useHasMigrationTokenQueryMock, + useListResourcesQuery: useListResourcesQueryMock, + useStartMigrationMutation: useStartMigrationMutationMock, +} = migrateToCloudMockAPI; diff --git a/public/app/features/migrate-to-cloud/onprem/DisconnectModal.tsx b/public/app/features/migrate-to-cloud/onprem/DisconnectModal.tsx index 30cd42b507f..486e71255d9 100644 --- a/public/app/features/migrate-to-cloud/onprem/DisconnectModal.tsx +++ b/public/app/features/migrate-to-cloud/onprem/DisconnectModal.tsx @@ -3,7 +3,7 @@ import React, { useCallback } from 'react'; import { Alert, ConfirmModal, Stack } from '@grafana/ui'; import { Trans, t } from 'app/core/internationalization'; -import { useDisconnectStackMutation } from '../api'; +import { useDisconnectStackMutationMock } from '../mockAPI'; interface Props { isOpen: boolean; @@ -11,7 +11,7 @@ interface Props { } export const DisconnectModal = ({ isOpen, onDismiss }: Props) => { - const [disconnectStack, { isLoading, isError }] = useDisconnectStackMutation(); + const [disconnectStack, { isLoading, isError }] = useDisconnectStackMutationMock(); const handleConfirm = useCallback(async () => { const resp = await disconnectStack(); diff --git a/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/CallToAction.tsx b/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/CallToAction.tsx index 0d3e7e55a27..f3dee4ba4d4 100644 --- a/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/CallToAction.tsx +++ b/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/CallToAction.tsx @@ -3,13 +3,13 @@ import React from 'react'; import { Box, Button, ModalsController, Text } from '@grafana/ui'; import { Trans } from 'app/core/internationalization'; -import { useConnectStackMutation, useGetStatusQuery } from '../../../api'; +import { useConnectStackMutationMock, useGetStatusQueryMock } from '../../../mockAPI'; import { ConnectModal } from './ConnectModal'; export const CallToAction = () => { - const [connectStack, connectResponse] = useConnectStackMutation(); - const { isFetching } = useGetStatusQuery(); + const [connectStack, connectResponse] = useConnectStackMutationMock(); + const { isFetching } = useGetStatusQueryMock(); return ( diff --git a/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/ConnectModal.tsx b/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/ConnectModal.tsx index 24276f8cc7d..86b62ebdec3 100644 --- a/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/ConnectModal.tsx +++ b/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/ConnectModal.tsx @@ -6,11 +6,11 @@ import { GrafanaTheme2 } from '@grafana/data'; import { Modal, Button, Stack, TextLink, Field, Input, Text, useStyles2 } from '@grafana/ui'; import { Trans, t } from 'app/core/internationalization'; -import { ConnectStackDTO } from '../../../api'; +import { ConnectStackDTOMock } from '../../../mockAPI'; interface Props { hideModal: () => void; - onConfirm: (connectStackData: ConnectStackDTO) => Promise<{ data: void } | { error: unknown }>; + onConfirm: (connectStackData: ConnectStackDTOMock) => Promise<{ data: void } | { error: unknown }>; } export const ConnectModal = ({ hideModal, onConfirm }: Props) => { @@ -24,7 +24,7 @@ export const ConnectModal = ({ hideModal, onConfirm }: Props) => { register, formState: { errors }, watch, - } = useForm({ + } = useForm({ defaultValues: { stackURL: '', token: '', @@ -34,7 +34,7 @@ export const ConnectModal = ({ hideModal, onConfirm }: Props) => { const stackURL = watch('stackURL'); const token = watch('token'); - const onConfirmConnect: SubmitHandler = async (formData) => { + const onConfirmConnect: SubmitHandler = async (formData) => { setIsConnecting(true); await onConfirm(formData); setIsConnecting(false); diff --git a/public/app/features/migrate-to-cloud/onprem/Page.tsx b/public/app/features/migrate-to-cloud/onprem/Page.tsx index fecab6a6b02..2e0114c4c0c 100644 --- a/public/app/features/migrate-to-cloud/onprem/Page.tsx +++ b/public/app/features/migrate-to-cloud/onprem/Page.tsx @@ -4,7 +4,7 @@ import React, { useState } from 'react'; import { Alert, Box, Button, Stack } from '@grafana/ui'; import { Trans, t } from 'app/core/internationalization'; -import { useGetStatusQuery, useListResourcesQuery, useStartMigrationMutation } from '../api'; +import { useGetStatusQueryMock, useListResourcesQueryMock, useStartMigrationMutationMock } from '../mockAPI'; import { DisconnectModal } from './DisconnectModal'; import { EmptyState } from './EmptyState/EmptyState'; @@ -12,10 +12,10 @@ import { MigrationInfo } from './MigrationInfo'; import { ResourcesTable } from './ResourcesTable'; export const Page = () => { - const { data: status, isFetching } = useGetStatusQuery(); - const { data: resources } = useListResourcesQuery(status?.enabled ? undefined : skipToken); + const { data: status, isFetching } = useGetStatusQueryMock(); + const { data: resources } = useListResourcesQueryMock(status?.enabled ? undefined : skipToken); const [startMigration, { isLoading: startMigrationIsLoading, isError: startMigrationIsError }] = - useStartMigrationMutation(); + useStartMigrationMutationMock(); const [isDisconnecting, setIsDisconnecting] = useState(false); if (!status?.enabled) { diff --git a/public/app/features/migrate-to-cloud/onprem/ResourcesTable.tsx b/public/app/features/migrate-to-cloud/onprem/ResourcesTable.tsx index 8806dce5ef5..65aa992b41d 100644 --- a/public/app/features/migrate-to-cloud/onprem/ResourcesTable.tsx +++ b/public/app/features/migrate-to-cloud/onprem/ResourcesTable.tsx @@ -5,10 +5,10 @@ import { InteractiveTable, CellProps, Stack, Text, Icon, useStyles2, Button } fr import { getSvgSize } from '@grafana/ui/src/components/Icon/utils'; import { t } from 'app/core/internationalization'; -import { MigrationResourceDTO } from '../api'; +import { MigrationResourceDTOMock } from '../mockAPI'; interface ResourcesTableProps { - resources: MigrationResourceDTO[]; + resources: MigrationResourceDTOMock[]; } const columns = [ @@ -21,7 +21,7 @@ export function ResourcesTable({ resources }: ResourcesTableProps) { return r.uid} pageSize={15} />; } -function NameCell(props: CellProps) { +function NameCell(props: CellProps) { const data = props.row.original; return ( @@ -35,7 +35,7 @@ function NameCell(props: CellProps) { ); } -function TypeCell(props: CellProps) { +function TypeCell(props: CellProps) { const { type } = props.row.original; if (type === 'datasource') { @@ -49,7 +49,7 @@ function TypeCell(props: CellProps) { return t('migrate-to-cloud.resource-type.unknown', 'Unknown'); } -function StatusCell(props: CellProps) { +function StatusCell(props: CellProps) { const { status, statusMessage } = props.row.original; if (status === 'not-migrated') { @@ -76,7 +76,7 @@ function StatusCell(props: CellProps) { return {t('migrate-to-cloud.resource-status.unknown', 'Unknown')}; } -function ResourceIcon({ resource }: { resource: MigrationResourceDTO }) { +function ResourceIcon({ resource }: { resource: MigrationResourceDTOMock }) { const styles = useStyles2(getIconStyles); if (resource.type === 'dashboard') { diff --git a/public/app/store/configureStore.ts b/public/app/store/configureStore.ts index ce1a65c1f0b..a33dc4caaaa 100644 --- a/public/app/store/configureStore.ts +++ b/public/app/store/configureStore.ts @@ -3,7 +3,8 @@ import { setupListeners } from '@reduxjs/toolkit/query'; import { browseDashboardsAPI } from 'app/features/browse-dashboards/api/browseDashboardsAPI'; import { publicDashboardApi } from 'app/features/dashboard/api/publicDashboardApi'; -import { migrateToCloudAPI } from 'app/features/migrate-to-cloud/api'; +import { cloudMigrationAPI } from 'app/features/migrate-to-cloud/api'; +import { migrateToCloudMockAPI } from 'app/features/migrate-to-cloud/mockAPI'; import { StoreState } from 'app/types/store'; import { buildInitialState } from '../core/reducers/navModel'; @@ -30,7 +31,8 @@ export function configureStore(initialState?: Partial) { alertingApi.middleware, publicDashboardApi.middleware, browseDashboardsAPI.middleware, - migrateToCloudAPI.middleware + cloudMigrationAPI.middleware, + migrateToCloudMockAPI.middleware ), devTools: process.env.NODE_ENV !== 'production', preloadedState: { diff --git a/scripts/generate-rtk-apis.ts b/scripts/generate-rtk-apis.ts new file mode 100644 index 00000000000..61e80c33d28 --- /dev/null +++ b/scripts/generate-rtk-apis.ts @@ -0,0 +1,27 @@ +// Generates Redux Toolkit API slices for certain APIs from the OpenAPI spec +import type { ConfigFile } from '@rtk-query/codegen-openapi'; + +const config: ConfigFile = { + schemaFile: '../public/openapi3.json', + apiFile: '', // leave this empty, and instead populate the outputFiles object below + hooks: true, + + outputFiles: { + '../public/app/features/migrate-to-cloud/api/endpoints.gen.ts': { + apiFile: '../public/app/features/migrate-to-cloud/api/baseAPI.ts', + apiImport: 'baseAPI', + filterEndpoints: [ + 'createCloudMigrationToken', + 'getMigrationList', + 'getCloudMigration', + 'createMigration', + 'runCloudMigration', + 'getCloudMigrationRun', + 'getCloudMigrationRunList', + 'deleteCloudMigration', + ], + }, + }, +}; + +export default config; diff --git a/yarn.lock b/yarn.lock index 4aad8fe05e0..f3ae16ff8e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29,6 +29,48 @@ __metadata: languageName: node linkType: hard +"@apidevtools/json-schema-ref-parser@npm:9.0.6": + version: 9.0.6 + resolution: "@apidevtools/json-schema-ref-parser@npm:9.0.6" + dependencies: + "@jsdevtools/ono": "npm:^7.1.3" + call-me-maybe: "npm:^1.0.1" + js-yaml: "npm:^3.13.1" + checksum: 10/bfdff3d3c54fac0e864322dfa62c018cbcf90f66df6cbe33868a0134bee5bc4d013f980aac0f3e83ffabf4b9c13ffedbf5bae3578ce7db7d4cb559e874b16950 + languageName: node + linkType: hard + +"@apidevtools/openapi-schemas@npm:^2.1.0": + version: 2.1.0 + resolution: "@apidevtools/openapi-schemas@npm:2.1.0" + checksum: 10/4ca78f79ee2e5a162d16d140f939ca90d51265014ea2e500955286ad3acd11b75db4179b7b4bae245b09a981baeb8d80b81bc24c61d6c471a4a4707ed277ebf2 + languageName: node + linkType: hard + +"@apidevtools/swagger-methods@npm:^3.0.2": + version: 3.0.2 + resolution: "@apidevtools/swagger-methods@npm:3.0.2" + checksum: 10/d06b1ac5c1956613c4c6be695612ef860cd4e962b93a509ca551735a328a856cae1e33399cac1dcbf8333ba22b231746f3586074769ef0e172cf549ec9e7eaae + languageName: node + linkType: hard + +"@apidevtools/swagger-parser@npm:^10.0.2, @apidevtools/swagger-parser@npm:^10.1.0": + version: 10.1.0 + resolution: "@apidevtools/swagger-parser@npm:10.1.0" + dependencies: + "@apidevtools/json-schema-ref-parser": "npm:9.0.6" + "@apidevtools/openapi-schemas": "npm:^2.1.0" + "@apidevtools/swagger-methods": "npm:^3.0.2" + "@jsdevtools/ono": "npm:^7.1.3" + ajv: "npm:^8.6.3" + ajv-draft-04: "npm:^1.0.0" + call-me-maybe: "npm:^1.0.1" + peerDependencies: + openapi-types: ">=7" + checksum: 10/24f7f6524334887ff3ef1c8c768698963f4a03e6824719fdbe98ba5444c9f1cdca9a11789e90362c882321dedec3e66f414e05035054084921fe1d2527724adb + languageName: node + linkType: hard + "@aw-web-design/x-default-browser@npm:1.4.126": version: 1.4.126 resolution: "@aw-web-design/x-default-browser@npm:1.4.126" @@ -3095,6 +3137,13 @@ __metadata: languageName: node linkType: hard +"@exodus/schemasafe@npm:^1.0.0-rc.2": + version: 1.3.0 + resolution: "@exodus/schemasafe@npm:1.3.0" + checksum: 10/791d9e4b437fe04c6d7cf028d145ed963b8fe973ba6d5811aedf7edea40d5a055a49522241efdafbc32f964c27beaddf1c85fbcc8bf5436cf394623b08e5518b + languageName: node + linkType: hard + "@fal-works/esbuild-plugin-global-externals@npm:^2.1.2": version: 2.1.2 resolution: "@fal-works/esbuild-plugin-global-externals@npm:2.1.2" @@ -4811,6 +4860,13 @@ __metadata: languageName: node linkType: hard +"@jsdevtools/ono@npm:^7.1.3": + version: 7.1.3 + resolution: "@jsdevtools/ono@npm:7.1.3" + checksum: 10/d4a036ccb9d2b21b7e4cec077c59a5a83fad58adacbce89e7e6b77a703050481ff5b6d813aef7f5ff0a8347a85a0eedf599e2e6bb5784a971a93e53e43b10157 + languageName: node + linkType: hard + "@juggle/resize-observer@npm:^3.3.1": version: 3.4.0 resolution: "@juggle/resize-observer@npm:3.4.0" @@ -7141,6 +7197,23 @@ __metadata: languageName: node linkType: hard +"@rtk-query/codegen-openapi@npm:^1.2.0": + version: 1.2.0 + resolution: "@rtk-query/codegen-openapi@npm:1.2.0" + dependencies: + "@apidevtools/swagger-parser": "npm:^10.0.2" + commander: "npm:^6.2.0" + oazapfts: "npm:^4.8.0" + prettier: "npm:^2.2.1" + semver: "npm:^7.3.5" + swagger2openapi: "npm:^7.0.4" + typescript: "npm:^5.0.0" + bin: + rtk-query-codegen-openapi: lib/bin/cli.js + checksum: 10/74b5d68b40322e6f30fff3f0250bccf378e5408e24bb47c109ad31e3c45a53c99d67b0ea0685ab0abcfc2e598eec9bdfc94aee241b61049ac862b77bd9780518 + languageName: node + linkType: hard + "@rtsao/plugin-proposal-class-properties@npm:7.0.1-patch.1": version: 7.0.1-patch.1 resolution: "@rtsao/plugin-proposal-class-properties@npm:7.0.1-patch.1" @@ -11389,6 +11462,18 @@ __metadata: languageName: node linkType: hard +"ajv-draft-04@npm:^1.0.0": + version: 1.0.0 + resolution: "ajv-draft-04@npm:1.0.0" + peerDependencies: + ajv: ^8.5.0 + peerDependenciesMeta: + ajv: + optional: true + checksum: 10/3f11fa0e7f7359bef6608657f02ab78e9cc62b1fb7bdd860db0d00351b3863a1189c1a23b72466d2d82726cab4eb20725c76f5e7c134a89865e2bfd0e6828137 + languageName: node + linkType: hard + "ajv-formats@npm:^2.1.1": version: 2.1.1 resolution: "ajv-formats@npm:2.1.1" @@ -11435,7 +11520,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.0.1, ajv@npm:^8.9.0": +"ajv@npm:^8.0.0, ajv@npm:^8.0.1, ajv@npm:^8.6.3, ajv@npm:^8.9.0": version: 8.12.0 resolution: "ajv@npm:8.12.0" dependencies: @@ -12859,6 +12944,13 @@ __metadata: languageName: node linkType: hard +"call-me-maybe@npm:^1.0.1": + version: 1.0.2 + resolution: "call-me-maybe@npm:1.0.2" + checksum: 10/3d375b6f810a82c751157b199daba60452876186c19ac653e81bfc5fc10d1e2ba7aedb8622367c3a8aca6879f0e6a29435a1193b35edb8f7fd8267a67ea32373 + languageName: node + linkType: hard + "callsite@npm:^1.0.0": version: 1.0.0 resolution: "callsite@npm:1.0.0" @@ -13555,7 +13647,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^6.2.1": +"commander@npm:^6.2.0, commander@npm:^6.2.1": version: 6.2.1 resolution: "commander@npm:6.2.1" checksum: 10/25b88c2efd0380c84f7844b39cf18510da7bfc5013692d68cdc65f764a1c34e6c8a36ea6d72b6620e3710a930cf8fab2695bdec2bf7107a0f4fa30a3ef3b7d0e @@ -16098,6 +16190,13 @@ __metadata: languageName: node linkType: hard +"es6-promise@npm:^3.2.1": + version: 3.3.1 + resolution: "es6-promise@npm:3.3.1" + checksum: 10/14f46a0a20164d4d6f8a39133c7220688bb9ee2d89a78f2345694b8ac9b6ea7b94f73488e289a083dce732831f4040013b25222d1820580c7b10b698c50c8267 + languageName: node + linkType: hard + "esbuild-loader@npm:4.1.0": version: 4.1.0 resolution: "esbuild-loader@npm:4.1.0" @@ -17321,6 +17420,13 @@ __metadata: languageName: node linkType: hard +"fast-safe-stringify@npm:^2.0.7": + version: 2.1.1 + resolution: "fast-safe-stringify@npm:2.1.1" + checksum: 10/dc1f063c2c6ac9533aee14d406441f86783a8984b2ca09b19c2fe281f9ff59d315298bc7bc22fd1f83d26fe19ef2f20e2ddb68e96b15040292e555c5ced0c1e4 + languageName: node + linkType: hard + "fast-shallow-equal@npm:^1.0.0": version: 1.0.0 resolution: "fast-shallow-equal@npm:1.0.0" @@ -18581,6 +18687,7 @@ __metadata: "@react-types/shared": "npm:3.22.1" "@reduxjs/toolkit": "npm:1.9.5" "@remix-run/router": "npm:^1.5.0" + "@rtk-query/codegen-openapi": "npm:^1.2.0" "@rtsao/plugin-proposal-class-properties": "npm:7.0.1-patch.1" "@swc/core": "npm:1.4.2" "@swc/helpers": "npm:0.5.8" @@ -19515,6 +19622,13 @@ __metadata: languageName: node linkType: hard +"http2-client@npm:^1.2.5": + version: 1.3.5 + resolution: "http2-client@npm:1.3.5" + checksum: 10/34ef17ea2814acbf9d9b5184f9e2c0767846d62abc357bd63c67b3d1f65e7b6ba772d4950ec4f5188686d3d8bfa15e3fb73721150db5bdb47bcefdba71734729 + languageName: node + linkType: hard + "https-proxy-agent@npm:^4.0.0": version: 4.0.0 resolution: "https-proxy-agent@npm:4.0.0" @@ -23406,6 +23520,15 @@ __metadata: languageName: node linkType: hard +"node-fetch-h2@npm:^2.3.0": + version: 2.3.0 + resolution: "node-fetch-h2@npm:2.3.0" + dependencies: + http2-client: "npm:^1.2.5" + checksum: 10/9495b4e52cfb23241a1bca187640a15bcaacb7a0667a825074f9dbf2c1a9b10fedd5344d775d57dea8944eeee1049959a3f662492e2f57d6d5f34c7d296e7c65 + languageName: node + linkType: hard + "node-fetch-native@npm:^1.0.2": version: 1.0.2 resolution: "node-fetch-native@npm:1.0.2" @@ -23441,6 +23564,20 @@ __metadata: languageName: node linkType: hard +"node-fetch@npm:^2.6.1": + version: 2.7.0 + resolution: "node-fetch@npm:2.7.0" + dependencies: + whatwg-url: "npm:^5.0.0" + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + checksum: 10/b24f8a3dc937f388192e59bcf9d0857d7b6940a2496f328381641cb616efccc9866e89ec43f2ec956bbd6c3d3ee05524ce77fe7b29ccd34692b3a16f237d6676 + languageName: node + linkType: hard + "node-forge@npm:^1, node-forge@npm:^1.3.1": version: 1.3.1 resolution: "node-forge@npm:1.3.1" @@ -23516,6 +23653,15 @@ __metadata: languageName: node linkType: hard +"node-readfiles@npm:^0.2.0": + version: 0.2.0 + resolution: "node-readfiles@npm:0.2.0" + dependencies: + es6-promise: "npm:^3.2.1" + checksum: 10/1db0f009955665e63983395f38c2479ef18b4ea8db1d12e03c155238ebe567f2e83981c0e47ac7c6d29ab4a3628082d5e02683e62d26e1af79852e0d8b77e3fb + languageName: node + linkType: hard + "node-releases@npm:^2.0.14": version: 2.0.14 resolution: "node-releases@npm:2.0.14" @@ -23909,6 +24055,64 @@ __metadata: languageName: node linkType: hard +"oas-kit-common@npm:^1.0.8": + version: 1.0.8 + resolution: "oas-kit-common@npm:1.0.8" + dependencies: + fast-safe-stringify: "npm:^2.0.7" + checksum: 10/576ab5f7c7fde551a9c780fde9392cb9dec5159b62c3ad4499e334bffdb12e089e97dccf2a9d0d1ac5be208f9d6f0e72da5ac3744d878134ef0177eed135cc52 + languageName: node + linkType: hard + +"oas-linter@npm:^3.2.2": + version: 3.2.2 + resolution: "oas-linter@npm:3.2.2" + dependencies: + "@exodus/schemasafe": "npm:^1.0.0-rc.2" + should: "npm:^13.2.1" + yaml: "npm:^1.10.0" + checksum: 10/8111c6c759648215b466e0e507e21e3c125762caf925dff28628c1ac0144bc82fe7f231a3249dd0400dff051574b4d5a7bbcc64b95d2f2f7e41a3377e859c395 + languageName: node + linkType: hard + +"oas-resolver@npm:^2.5.6": + version: 2.5.6 + resolution: "oas-resolver@npm:2.5.6" + dependencies: + node-fetch-h2: "npm:^2.3.0" + oas-kit-common: "npm:^1.0.8" + reftools: "npm:^1.1.9" + yaml: "npm:^1.10.0" + yargs: "npm:^17.0.1" + bin: + resolve: resolve.js + checksum: 10/9e20118bf722cb9e9f71a7079336ce705259eb380fa9c2a776d9647b93725314c23abdb6b7b3bc3c91a3559485bbb729447f72ce0c3ca9ce48281b8214a9612d + languageName: node + linkType: hard + +"oas-schema-walker@npm:^1.1.5": + version: 1.1.5 + resolution: "oas-schema-walker@npm:1.1.5" + checksum: 10/27bdeda1ebcf557b90cfb5d2ac3ca8e851f601d96215747c19ce0ae8f8458ad8012701b615fe313eacf4665b733f46ec12870f72d453251217b8a3ceb2be9abf + languageName: node + linkType: hard + +"oas-validator@npm:^5.0.8": + version: 5.0.8 + resolution: "oas-validator@npm:5.0.8" + dependencies: + call-me-maybe: "npm:^1.0.1" + oas-kit-common: "npm:^1.0.8" + oas-linter: "npm:^3.2.2" + oas-resolver: "npm:^2.5.6" + oas-schema-walker: "npm:^1.1.5" + reftools: "npm:^1.1.9" + should: "npm:^13.2.1" + yaml: "npm:^1.10.0" + checksum: 10/3e392d6c99659e58860b78ef1a46eaf8ad782449fe9a21ccb594b74f88a2c211d39ab9d016ec08c995d8728a250229aba84cb02ca3381f0fb2cc1e6782f4e21a + languageName: node + linkType: hard + "oauth-sign@npm:~0.9.0": version: 0.9.0 resolution: "oauth-sign@npm:0.9.0" @@ -23916,6 +24120,21 @@ __metadata: languageName: node linkType: hard +"oazapfts@npm:^4.8.0": + version: 4.12.0 + resolution: "oazapfts@npm:4.12.0" + dependencies: + "@apidevtools/swagger-parser": "npm:^10.1.0" + lodash: "npm:^4.17.21" + minimist: "npm:^1.2.8" + swagger2openapi: "npm:^7.0.8" + typescript: "npm:^5.2.2" + bin: + oazapfts: lib/codegen/cli.js + checksum: 10/993d2cebfb2aab6178893e63039eda5968248684e02cf7e3df41e8fbc57d3a551c1c4a7b8bc3f1384f9a10557e9fd71717eeef8b1a38948a412ba46c5271f411 + languageName: node + linkType: hard + "object-assign@npm:4.x, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" @@ -25367,7 +25586,7 @@ __metadata: languageName: node linkType: hard -"prettier@npm:^2.3.2, prettier@npm:^2.8.0, prettier@npm:^2.8.7": +"prettier@npm:^2.2.1, prettier@npm:^2.3.2, prettier@npm:^2.8.0, prettier@npm:^2.8.7": version: 2.8.8 resolution: "prettier@npm:2.8.8" bin: @@ -27285,6 +27504,13 @@ __metadata: languageName: node linkType: hard +"reftools@npm:^1.1.9": + version: 1.1.9 + resolution: "reftools@npm:1.1.9" + checksum: 10/6a124748f1c4af84bf651c31c76b7ed0a7f766533530a80cbf2d2517b26e6bfaadc0b1b3e399675343328ab861ab04881e64c8bc3c2f40fc7be27a8aacf8775e + languageName: node + linkType: hard + "regenerate-unicode-properties@npm:^10.1.0": version: 10.1.0 resolution: "regenerate-unicode-properties@npm:10.1.0" @@ -28353,6 +28579,62 @@ __metadata: languageName: node linkType: hard +"should-equal@npm:^2.0.0": + version: 2.0.0 + resolution: "should-equal@npm:2.0.0" + dependencies: + should-type: "npm:^1.4.0" + checksum: 10/700e38f7815937f15e415b29df45ae22929c98c87979eb71e3a1085ba94cd0c601f435272eef3c9399ff74fa2d424df37ff03672f61ceda21630edcc77810744 + languageName: node + linkType: hard + +"should-format@npm:^3.0.3": + version: 3.0.3 + resolution: "should-format@npm:3.0.3" + dependencies: + should-type: "npm:^1.3.0" + should-type-adaptors: "npm:^1.0.1" + checksum: 10/099157f4f9bf458919bce8e981438e139c21789bb45f8b5cd8cf4bf01c5df498f1a1e666211bfd906b72b77d645a187563554ab38af807f8cd1aaf270e326186 + languageName: node + linkType: hard + +"should-type-adaptors@npm:^1.0.1": + version: 1.1.0 + resolution: "should-type-adaptors@npm:1.1.0" + dependencies: + should-type: "npm:^1.3.0" + should-util: "npm:^1.0.0" + checksum: 10/ca0fc7b24b916373e987b46e0c54db4aa824a80090a2fbff201679fd059240f4efabe415ffef9f5cfb99d85bf4241bdc3f212a9939724413203258a7dd73c24e + languageName: node + linkType: hard + +"should-type@npm:^1.3.0, should-type@npm:^1.4.0": + version: 1.4.0 + resolution: "should-type@npm:1.4.0" + checksum: 10/3e99a930fd43a47b0967fb5e8d0be31d9e2339c49267d3eabae014717012f4bd7cd942686fc49675114982240dcbfedba94ef49d0811b8f491c7cd74343bf97f + languageName: node + linkType: hard + +"should-util@npm:^1.0.0": + version: 1.0.1 + resolution: "should-util@npm:1.0.1" + checksum: 10/c3be15e0fdc851f8338676b3f8b590d330bbea94ec41c1343cc9983dea295915073f69a215795454b6adda6579ec8927c7c0ab178b83f9f11a0247ccdba53381 + languageName: node + linkType: hard + +"should@npm:^13.2.1": + version: 13.2.3 + resolution: "should@npm:13.2.3" + dependencies: + should-equal: "npm:^2.0.0" + should-format: "npm:^3.0.3" + should-type: "npm:^1.4.0" + should-type-adaptors: "npm:^1.0.1" + should-util: "npm:^1.0.0" + checksum: 10/4d3da94f11fee3db17be09673a73cd1939b0b75ebde102161eecef5559991deed691071ccab1d9289f4b69a45ef1a9d2362686a5f1ac530a43161d5832f6aa7d + languageName: node + linkType: hard + "side-channel@npm:^1.0.4": version: 1.0.4 resolution: "side-channel@npm:1.0.4" @@ -29600,6 +29882,29 @@ __metadata: languageName: node linkType: hard +"swagger2openapi@npm:^7.0.4, swagger2openapi@npm:^7.0.8": + version: 7.0.8 + resolution: "swagger2openapi@npm:7.0.8" + dependencies: + call-me-maybe: "npm:^1.0.1" + node-fetch: "npm:^2.6.1" + node-fetch-h2: "npm:^2.3.0" + node-readfiles: "npm:^0.2.0" + oas-kit-common: "npm:^1.0.8" + oas-resolver: "npm:^2.5.6" + oas-schema-walker: "npm:^1.1.5" + oas-validator: "npm:^5.0.8" + reftools: "npm:^1.1.9" + yaml: "npm:^1.10.0" + yargs: "npm:^17.0.1" + bin: + boast: boast.js + oas-validate: oas-validate.js + swagger2openapi: swagger2openapi.js + checksum: 10/f95fe71d306ff2b5763aaa488465c4f111810a6a19f233d3ed63495a544c040d544b914921d8362e31137290bb249585e07944bd91fbb1ecad2ad6e60e9c5a72 + languageName: node + linkType: hard + "swc-loader@npm:0.2.6, swc-loader@npm:^0.2.3": version: 0.2.6 resolution: "swc-loader@npm:0.2.6" @@ -30549,6 +30854,16 @@ __metadata: languageName: node linkType: hard +"typescript@npm:^5.0.0, typescript@npm:^5.2.2": + version: 5.4.3 + resolution: "typescript@npm:5.4.3" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10/de4c69f49a7ad4b1ea66a6dcc8b055ac34eb56af059a069d8988dd811c5e649be07e042e5bf573e8d0ac3ec2f30e6c999aa651cd09f6e9cbc6113749e8b6be20 + languageName: node + linkType: hard + "typescript@patch:typescript@npm%3A5.2.2#optional!builtin": version: 5.2.2 resolution: "typescript@patch:typescript@npm%3A5.2.2#optional!builtin::version=5.2.2&hash=f3b441" @@ -30569,6 +30884,16 @@ __metadata: languageName: node linkType: hard +"typescript@patch:typescript@npm%3A^5.0.0#optional!builtin, typescript@patch:typescript@npm%3A^5.2.2#optional!builtin": + version: 5.4.3 + resolution: "typescript@patch:typescript@npm%3A5.4.3#optional!builtin::version=5.4.3&hash=5adc0c" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10/5aedd97595582b08aadb8a70e8e3ddebaf5a9c1e5ad4d6503c2fcfc15329b5cf8d01145b09913e9555683ac16c5123a96be32b6d72614098ebd42df520eed9b1 + languageName: node + linkType: hard + "ua-parser-js@npm:^1.0.32": version: 1.0.33 resolution: "ua-parser-js@npm:1.0.33" @@ -32064,7 +32389,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:17.7.2, yargs@npm:^17.3.1, yargs@npm:^17.5.1, yargs@npm:^17.6.2, yargs@npm:^17.7.2": +"yargs@npm:17.7.2, yargs@npm:^17.0.1, yargs@npm:^17.3.1, yargs@npm:^17.5.1, yargs@npm:^17.6.2, yargs@npm:^17.7.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: