API: Add programatically generated Content Sources API slice definitions

These definitions were generated using the RTKQ code generation tool and
will replace the existing definitions.
This commit is contained in:
lucasgarfield 2023-07-27 12:26:31 +02:00 committed by Lucas Garfield
parent 22df78bffa
commit 74528356fa
12 changed files with 2457 additions and 26 deletions

View file

@ -0,0 +1,13 @@
import type { ConfigFile } from '@rtk-query/codegen-openapi'
const config: ConfigFile = {
schemaFile: '../schema/contentSources.json',
apiFile: '../../src/store/emptyContentSourcesApi.ts',
apiImport: 'emptyContentSourcesApi',
outputFile: '../../src/store/contentSourcesApi.ts',
exportName: 'contentSourcesApi',
hooks: true,
filterEndpoints: ['listRepositories'],
}
export default config

File diff suppressed because it is too large Load diff

View file

@ -112,7 +112,7 @@
"test": "TZ=UTC jest --verbose --no-cache", "test": "TZ=UTC jest --verbose --no-cache",
"test:single": "jest --verbose -w 1", "test:single": "jest --verbose -w 1",
"build": "webpack --config config/prod.webpack.config.js", "build": "webpack --config config/prod.webpack.config.js",
"api": "npx @rtk-query/codegen-openapi ./api/config/image-builder.ts & npx @rtk-query/codegen-openapi ./api/config/rhsm.ts", "api": "npx @rtk-query/codegen-openapi ./api/config/image-builder.ts & npx @rtk-query/codegen-openapi ./api/config/rhsm.ts & npx @rtk-query/codegen-openapi ./api/config/contentSources.ts",
"verify": "npm-run-all build lint test" "verify": "npm-run-all build lint test"
}, },
"insights": { "insights": {

View file

@ -5,7 +5,7 @@ import WizardContext from '@data-driven-forms/react-form-renderer/wizard-context
import { Button } from '@patternfly/react-core'; import { Button } from '@patternfly/react-core';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { usePrefetch } from '../../../store/apiSlice'; import { contentSourcesApi } from '../../../store/contentSourcesApi';
import { rhsmApi } from '../../../store/rhsmApi'; import { rhsmApi } from '../../../store/rhsmApi';
import { releaseToVersion } from '../../../Utilities/releaseToVersion'; import { releaseToVersion } from '../../../Utilities/releaseToVersion';
@ -19,7 +19,8 @@ const CustomButtons = ({
const [isSaving, setIsSaving] = useState(false); const [isSaving, setIsSaving] = useState(false);
const { currentStep, formOptions } = useContext(WizardContext); const { currentStep, formOptions } = useContext(WizardContext);
const prefetchActivationKeys = rhsmApi.usePrefetch('listActivationKeys'); const prefetchActivationKeys = rhsmApi.usePrefetch('listActivationKeys');
const prefetchRepositories = usePrefetch('getRepositories'); const prefetchRepositories =
contentSourcesApi.usePrefetch('listRepositories');
const onNextOrSubmit = () => { const onNextOrSubmit = () => {
if (currentStep.id === 'wizard-review') { if (currentStep.id === 'wizard-review') {
@ -44,8 +45,8 @@ const CustomButtons = ({
const release = getState().values?.release; const release = getState().values?.release;
const version = releaseToVersion(release); const version = releaseToVersion(release);
prefetchRepositories({ prefetchRepositories({
available_for_arch: 'x86_64', availableForArch: 'x86_64',
available_for_version: version, availableForVersion: version,
}); });
} }
}; };

View file

@ -37,7 +37,7 @@ import {
} from '@patternfly/react-table'; } from '@patternfly/react-table';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useGetRepositoriesQuery } from '../../../store/apiSlice'; import { useListRepositoriesQuery } from '../../../store/contentSourcesApi';
import { releaseToVersion } from '../../../Utilities/releaseToVersion'; import { releaseToVersion } from '../../../Utilities/releaseToVersion';
import { useGetEnvironment } from '../../../Utilities/useGetEnvironment'; import { useGetEnvironment } from '../../../Utilities/useGetEnvironment';
@ -205,10 +205,10 @@ const Repositories = (props) => {
const release = getState().values?.release; const release = getState().values?.release;
const version = releaseToVersion(release); const version = releaseToVersion(release);
const firstRequest = useGetRepositoriesQuery( const firstRequest = useListRepositoriesQuery(
{ {
available_for_arch: 'x86_64', availableForArch: 'x86_64',
available_for_version: version, availableForVersion: version,
limit: 100, limit: 100,
offset: 0, offset: 0,
}, },
@ -223,10 +223,10 @@ const Repositories = (props) => {
firstRequest?.data?.meta?.count <= 100; firstRequest?.data?.meta?.count <= 100;
// Fetch *all* repositories if there are more than 100 so that typeahead filter works // Fetch *all* repositories if there are more than 100 so that typeahead filter works
const followupRequest = useGetRepositoriesQuery( const followupRequest = useListRepositoriesQuery(
{ {
available_for_arch: 'x86_64', availableForArch: 'x86_64',
available_for_version: version, availableForVersion: version,
limit: firstRequest?.data?.meta?.count, limit: firstRequest?.data?.meta?.count,
offset: 0, offset: 0,
}, },

View file

@ -1,6 +1,6 @@
import axios from 'axios'; import axios from 'axios';
import { CONTENT_SOURCES, IMAGE_BUILDER_API } from './constants'; import { CONTENT_SOURCES_API, IMAGE_BUILDER_API } from './constants';
const postHeaders = { headers: { 'Content-Type': 'application/json' } }; const postHeaders = { headers: { 'Content-Type': 'application/json' } };
@ -51,7 +51,7 @@ async function getPackagesContentSources(repoUrls, search) {
}; };
const path = '/rpms/names'; const path = '/rpms/names';
const request = await axios.post( const request = await axios.post(
CONTENT_SOURCES.concat(path), CONTENT_SOURCES_API.concat(path),
body, body,
postHeaders postHeaders
); );

View file

@ -1,6 +1,6 @@
export const IMAGE_BUILDER_API = '/api/image-builder/v1'; export const IMAGE_BUILDER_API = '/api/image-builder/v1';
export const RHSM_API = '/api/rhsm/v2'; export const RHSM_API = '/api/rhsm/v2';
export const CONTENT_SOURCES = '/api/content-sources/v1'; export const CONTENT_SOURCES_API = '/api/content-sources/v1';
export const PROVISIONING_SOURCES_ENDPOINT = '/api/provisioning/v1'; export const PROVISIONING_SOURCES_ENDPOINT = '/api/provisioning/v1';
export const RHEL_8 = 'rhel-88'; export const RHEL_8 = 'rhel-88';
export const RHEL_9 = 'rhel-92'; export const RHEL_9 = 'rhel-92';

View file

@ -1,8 +1,6 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { RepositoryCollectionResponse, SourceResponse, SourceUploadInfoResponse } from '../../types'; import { SourceResponse, SourceUploadInfoResponse } from '../../types';
type GetRepositoriesArgs = { available_for_arch: string, available_for_version: string, limit: number, offset: number }
enum Provider { enum Provider {
'azure', 'azure',
@ -10,7 +8,6 @@ enum Provider {
} }
import { import {
CONTENT_SOURCES,
PROVISIONING_SOURCES_ENDPOINT, PROVISIONING_SOURCES_ENDPOINT,
} from '../constants'; } from '../constants';
@ -25,14 +22,10 @@ export const apiSlice = createApi({
query: (sourceId) => query: (sourceId) =>
`${PROVISIONING_SOURCES_ENDPOINT}/sources/${sourceId}/upload_info` `${PROVISIONING_SOURCES_ENDPOINT}/sources/${sourceId}/upload_info`
}), }),
getRepositories: builder.query<RepositoryCollectionResponse, GetRepositoriesArgs>({
query: ({available_for_arch, available_for_version, limit, offset}) => `${CONTENT_SOURCES}/repositories/?available_for_arch=${available_for_arch}&available_for_version=${available_for_version}&limit=${limit}&offset=${offset}`,
}),
}), }),
}); });
export const { export const {
useGetRepositoriesQuery,
useGetSourcesQuery, useGetSourcesQuery,
useGetSourceDetailQuery, useGetSourceDetailQuery,
usePrefetch, usePrefetch,

View file

@ -0,0 +1,98 @@
import { emptyContentSourcesApi as api } from "./emptyContentSourcesApi";
const injectedRtkApi = api.injectEndpoints({
endpoints: (build) => ({
listRepositories: build.query<
ListRepositoriesApiResponse,
ListRepositoriesApiArg
>({
query: (queryArg) => ({
url: `/repositories/`,
params: {
offset: queryArg.offset,
limit: queryArg.limit,
version: queryArg.version,
arch: queryArg.arch,
available_for_version: queryArg.availableForVersion,
available_for_arch: queryArg.availableForArch,
search: queryArg.search,
name: queryArg.name,
url: queryArg.url,
sort_by: queryArg.sortBy,
status: queryArg.status,
},
}),
}),
}),
overrideExisting: false,
});
export { injectedRtkApi as contentSourcesApi };
export type ListRepositoriesApiResponse =
/** status 200 OK */ ApiRepositoryCollectionResponse;
export type ListRepositoriesApiArg = {
/** Offset into the list of results to return in the response */
offset?: number;
/** Limit the number of items returned */
limit?: number;
/** Comma separated list of architecture to optionally filter-on (e.g. 'x86_64,s390x' would return Repositories with x86_64 or s390x only) */
version?: string;
/** Comma separated list of versions to optionally filter-on (e.g. '7,8' would return Repositories with versions 7 or 8 only) */
arch?: string;
/** Filter by compatible arch (e.g. 'x86_64' would return Repositories with the 'x86_64' arch and Repositories where arch is not set) */
availableForVersion?: string;
/** Filter by compatible version (e.g. 7 would return Repositories with the version 7 or where version is not set) */
availableForArch?: string;
/** Search term for name and url. */
search?: string;
/** Filter repositories by name using an exact match */
name?: string;
/** Filter repositories by name using an exact match */
url?: string;
/** Sets the sort order of the results */
sortBy?: string;
/** Comma separated list of statuses to optionally filter on */
status?: string;
};
export type ApiRepositoryResponse = {
account_id?: string;
distribution_arch?: string;
distribution_versions?: string[];
failed_introspections_count?: number;
gpg_key?: string;
last_introspection_error?: string;
last_introspection_time?: string;
last_success_introspection_time?: string;
last_update_introspection_time?: string;
metadata_verification?: boolean;
name?: string;
org_id?: string;
package_count?: number;
snapshot?: boolean;
status?: string;
url?: string;
uuid?: string;
};
export type ApiLinks = {
first?: string;
last?: string;
next?: string;
prev?: string;
};
export type ApiResponseMetadata = {
count?: number;
limit?: number;
offset?: number;
};
export type ApiRepositoryCollectionResponse = {
data?: ApiRepositoryResponse[];
links?: ApiLinks;
meta?: ApiResponseMetadata;
};
export type ErrorsHandlerError = {
detail?: string;
status?: number;
title?: string;
};
export type ErrorsErrorResponse = {
errors?: ErrorsHandlerError[];
};
export const { useListRepositoriesQuery } = injectedRtkApi;

View file

@ -0,0 +1,9 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import {CONTENT_SOURCES_API} from '../constants'
// initialize an empty api service that we'll inject endpoints into later as needed
export const emptyContentSourcesApi = createApi({
reducerPath: 'contentSourcesApi',
baseQuery: fetchBaseQuery({ baseUrl: CONTENT_SOURCES_API }),
endpoints: () => ({}),
})

View file

@ -5,6 +5,7 @@ import promiseMiddleware from 'redux-promise-middleware';
import { apiSlice } from './apiSlice'; import { apiSlice } from './apiSlice';
import clonesSlice from './clonesSlice'; import clonesSlice from './clonesSlice';
import composesSlice from './composesSlice'; import composesSlice from './composesSlice';
import { contentSourcesApi } from './contentSourcesApi';
import { imageBuilderApi } from './imageBuilderApi'; import { imageBuilderApi } from './imageBuilderApi';
import { rhsmApi } from './rhsmApi'; import { rhsmApi } from './rhsmApi';
@ -12,6 +13,7 @@ export const reducer = {
[apiSlice.reducerPath]: apiSlice.reducer, [apiSlice.reducerPath]: apiSlice.reducer,
clones: clonesSlice, clones: clonesSlice,
composes: composesSlice, composes: composesSlice,
[contentSourcesApi.reducerPath]: contentSourcesApi.reducer,
[imageBuilderApi.reducerPath]: imageBuilderApi.reducer, [imageBuilderApi.reducerPath]: imageBuilderApi.reducer,
[rhsmApi.reducerPath]: rhsmApi.reducer, [rhsmApi.reducerPath]: rhsmApi.reducer,
notifications: notificationsReducer, notifications: notificationsReducer,
@ -21,6 +23,7 @@ export const middleware = (getDefaultMiddleware) =>
getDefaultMiddleware() getDefaultMiddleware()
.concat(promiseMiddleware) .concat(promiseMiddleware)
.concat(apiSlice.middleware) .concat(apiSlice.middleware)
.concat(contentSourcesApi.middleware)
.concat(imageBuilderApi.middleware) .concat(imageBuilderApi.middleware)
.concat(rhsmApi.middleware); .concat(rhsmApi.middleware);

View file

@ -1,7 +1,7 @@
import { rest } from 'msw'; import { rest } from 'msw';
import { import {
CONTENT_SOURCES, CONTENT_SOURCES_API,
IMAGE_BUILDER_API, IMAGE_BUILDER_API,
PROVISIONING_SOURCES_ENDPOINT, PROVISIONING_SOURCES_ENDPOINT,
RHSM_API, RHSM_API,
@ -40,7 +40,7 @@ export const handlers = [
} }
} }
), ),
rest.post(`${CONTENT_SOURCES}/rpms/names`, async (req, res, ctx) => { rest.post(`${CONTENT_SOURCES_API}/rpms/names`, async (req, res, ctx) => {
const { search } = await req.json(); const { search } = await req.json();
return res(ctx.status(200), ctx.json(mockSourcesPackagesResults(search))); return res(ctx.status(200), ctx.json(mockSourcesPackagesResults(search)));
}), }),
@ -59,7 +59,7 @@ export const handlers = [
const { key } = req.params; const { key } = req.params;
return res(ctx.status(200), ctx.json(mockActivationKeyInformation(key))); return res(ctx.status(200), ctx.json(mockActivationKeyInformation(key)));
}), }),
rest.get(`${CONTENT_SOURCES}/repositories/`, (req, res, ctx) => { rest.get(`${CONTENT_SOURCES_API}/repositories/`, (req, res, ctx) => {
const available_for_arch = req.url.searchParams.get('available_for_arch'); const available_for_arch = req.url.searchParams.get('available_for_arch');
const available_for_version = req.url.searchParams.get( const available_for_version = req.url.searchParams.get(
'available_for_version' 'available_for_version'