API: Add programatically generated Provisioning API slice definitions
These definitions were generated using the RTKQ code generation tool and will replace the existing definitions.
This commit is contained in:
parent
74528356fa
commit
702b667dc5
20 changed files with 2020 additions and 89 deletions
13
api/config/provisioning.ts
Normal file
13
api/config/provisioning.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import type { ConfigFile } from '@rtk-query/codegen-openapi'
|
||||
|
||||
const config: ConfigFile = {
|
||||
schemaFile: '../schema/provisioning.json',
|
||||
apiFile: '../../src/store/emptyProvisioningApi.ts',
|
||||
apiImport: 'emptyProvisioningApi',
|
||||
outputFile: '../../src/store/provisioningApi.ts',
|
||||
exportName: 'provisioningApi',
|
||||
hooks: true,
|
||||
filterEndpoints: ['getSourceList', 'getSourceUploadInfo'],
|
||||
}
|
||||
|
||||
export default config
|
||||
1870
api/schema/provisioning.json
Normal file
1870
api/schema/provisioning.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -112,7 +112,7 @@
|
|||
"test": "TZ=UTC jest --verbose --no-cache",
|
||||
"test:single": "jest --verbose -w 1",
|
||||
"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 & npx @rtk-query/codegen-openapi ./api/config/contentSources.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 & npx @rtk-query/codegen-openapi ./api/config/provisioning.ts",
|
||||
"verify": "npm-run-all build lint test"
|
||||
},
|
||||
"insights": {
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
import {useGetSourceDetailQuery} from "../../../store/apiSlice";
|
||||
|
||||
type AWSAccountIdProps = {
|
||||
sourceId: string
|
||||
}
|
||||
|
||||
export const AWSAccountId = ({ sourceId }: AWSAccountIdProps) => {
|
||||
const { data } = useGetSourceDetailQuery(sourceId);
|
||||
return <>{data?.aws?.account_id}</>;
|
||||
};
|
||||
|
|
@ -14,9 +14,9 @@ import {
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
useGetSourceDetailQuery,
|
||||
useGetSourcesQuery,
|
||||
} from '../../../store/apiSlice';
|
||||
useGetSourceListQuery,
|
||||
useGetSourceUploadInfoQuery,
|
||||
} from '../../../store/provisioningApi';
|
||||
|
||||
export const AWSSourcesSelect = ({
|
||||
label,
|
||||
|
|
@ -37,16 +37,19 @@ export const AWSSourcesSelect = ({
|
|||
isSuccess,
|
||||
isError,
|
||||
refetch,
|
||||
} = useGetSourcesQuery('aws');
|
||||
} = useGetSourceListQuery({ provider: 'aws' });
|
||||
|
||||
const {
|
||||
data: sourceDetails,
|
||||
isFetching: isFetchingDetails,
|
||||
isSuccess: isSuccessDetails,
|
||||
isError: isErrorDetails,
|
||||
} = useGetSourceDetailQuery(selectedSourceId, {
|
||||
skip: !selectedSourceId,
|
||||
});
|
||||
} = useGetSourceUploadInfoQuery(
|
||||
{ id: selectedSourceId },
|
||||
{
|
||||
skip: !selectedSourceId,
|
||||
}
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isFetchingDetails || !isSuccessDetails) return;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
import {useGetSourceUploadInfoQuery} from "../../../store/provisioningApi";
|
||||
|
||||
type AwsAccountIdProps = {
|
||||
sourceId: number
|
||||
}
|
||||
|
||||
export const AwsAccountId = ({ sourceId }: AwsAccountIdProps) => {
|
||||
const { data } = useGetSourceUploadInfoQuery({ id: sourceId });
|
||||
return <>{data?.aws?.account_id}</>;
|
||||
};
|
||||
|
|
@ -12,7 +12,7 @@ import {
|
|||
} from '@patternfly/react-core';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { useGetSourceDetailQuery } from '../../../store/apiSlice';
|
||||
import { useGetSourceUploadInfoQuery } from '../../../store/provisioningApi';
|
||||
|
||||
const AzureResourceGroups = ({ label, isRequired, className, ...props }) => {
|
||||
const { change, getState } = useFormApi();
|
||||
|
|
@ -25,8 +25,8 @@ const AzureResourceGroups = ({ label, isRequired, className, ...props }) => {
|
|||
setSourceId(values['azure-sources-select']);
|
||||
};
|
||||
|
||||
const { data: sourceDetails, isFetching } = useGetSourceDetailQuery(
|
||||
sourceId,
|
||||
const { data: sourceDetails, isFetching } = useGetSourceUploadInfoQuery(
|
||||
{ id: sourceId },
|
||||
{
|
||||
skip: !sourceId,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ import {
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
useGetSourcesQuery,
|
||||
useGetSourceDetailQuery,
|
||||
} from '../../../store/apiSlice';
|
||||
useGetSourceListQuery,
|
||||
useGetSourceUploadInfoQuery,
|
||||
} from '../../../store/provisioningApi';
|
||||
|
||||
const AzureSourcesSelect = ({ label, isRequired, className, ...props }) => {
|
||||
const { change } = useFormApi();
|
||||
|
|
@ -30,16 +30,19 @@ const AzureSourcesSelect = ({ label, isRequired, className, ...props }) => {
|
|||
isSuccess,
|
||||
isError,
|
||||
refetch,
|
||||
} = useGetSourcesQuery('azure');
|
||||
} = useGetSourceListQuery({ provider: 'azure' });
|
||||
|
||||
const {
|
||||
data: sourceDetails,
|
||||
isFetching: isFetchingDetails,
|
||||
isSuccess: isSuccessDetails,
|
||||
isError: isErrorDetails,
|
||||
} = useGetSourceDetailQuery(selectedSourceId, {
|
||||
skip: !selectedSourceId,
|
||||
});
|
||||
} = useGetSourceUploadInfoQuery(
|
||||
{ id: selectedSourceId },
|
||||
{
|
||||
skip: !selectedSourceId,
|
||||
}
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isFetchingDetails || !isSuccessDetails) return;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import { ExclamationTriangleIcon, HelpIcon } from '@patternfly/react-icons';
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import ActivationKeyInformation from './ActivationKeyInformation';
|
||||
import { AWSAccountId } from './AWSAccountId';
|
||||
import { AwsAccountId } from './AwsAccountId';
|
||||
import {
|
||||
FSReviewTable,
|
||||
PackagesTable,
|
||||
|
|
@ -26,7 +26,7 @@ import {
|
|||
} from './ReviewStepTables';
|
||||
|
||||
import { RELEASES, UNIT_GIB } from '../../../constants';
|
||||
import { useGetSourcesQuery } from '../../../store/apiSlice';
|
||||
import { useGetSourceListQuery } from '../../../store/provisioningApi';
|
||||
import { useShowActivationKeyQuery } from '../../../store/rhsmApi';
|
||||
import { useGetEnvironment } from '../../../Utilities/useGetEnvironment';
|
||||
import { googleAccType } from '../steps/googleCloud';
|
||||
|
|
@ -64,7 +64,9 @@ export const ImageOutputList = () => {
|
|||
};
|
||||
|
||||
export const TargetEnvAWSList = () => {
|
||||
const { data: awsSources, isSuccess } = useGetSourcesQuery();
|
||||
const { data: awsSources, isSuccess } = useGetSourceListQuery({
|
||||
provider: 'aws',
|
||||
});
|
||||
const { isBeta } = useGetEnvironment();
|
||||
|
||||
const { getState } = useFormApi();
|
||||
|
|
@ -92,7 +94,7 @@ export const TargetEnvAWSList = () => {
|
|||
getState()?.values?.['aws-target-type'] ===
|
||||
'aws-target-type-source' &&
|
||||
isSuccess && (
|
||||
<AWSAccountId
|
||||
<AwsAccountId
|
||||
sourceId={getState()?.values?.['aws-sources-select']}
|
||||
/>
|
||||
)}
|
||||
|
|
@ -169,7 +171,7 @@ export const TargetEnvGCPList = () => {
|
|||
export const TargetEnvAzureList = () => {
|
||||
const { getState } = useFormApi();
|
||||
const { data: azureSources, isSuccess: isSuccessAzureSources } =
|
||||
useGetSourcesQuery('azure');
|
||||
useGetSourceListQuery({ provider: 'azure' });
|
||||
return (
|
||||
<TextContent>
|
||||
<Text component={TextVariants.h3}>Microsoft Azure</Text>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import {
|
|||
import { HelpIcon } from '@patternfly/react-icons';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { usePrefetch } from '../../../store/apiSlice';
|
||||
import { provisioningApi } from '../../../store/provisioningApi';
|
||||
|
||||
const TargetEnvironment = ({ label, isRequired, ...props }) => {
|
||||
const { getState, change } = useFormApi();
|
||||
|
|
@ -29,7 +29,7 @@ const TargetEnvironment = ({ label, isRequired, ...props }) => {
|
|||
'guest-image': false,
|
||||
'image-installer': false,
|
||||
});
|
||||
const prefetchSources = usePrefetch('getSources');
|
||||
const prefetchSources = provisioningApi.usePrefetch('getSourceList');
|
||||
|
||||
useEffect(() => {
|
||||
if (getState()?.values?.[input.name]) {
|
||||
|
|
@ -76,7 +76,7 @@ const TargetEnvironment = ({ label, isRequired, ...props }) => {
|
|||
}
|
||||
onClick={() => handleSetEnvironment('aws', !environment.aws)}
|
||||
onKeyDown={(e) => handleKeyDown(e, 'aws', !environment.aws)}
|
||||
onMouseEnter={() => prefetchSources('aws')}
|
||||
onMouseEnter={() => prefetchSources({ provider: 'aws' })}
|
||||
isSelected={environment.aws}
|
||||
isStacked
|
||||
isDisplayLarge
|
||||
|
|
@ -96,6 +96,7 @@ const TargetEnvironment = ({ label, isRequired, ...props }) => {
|
|||
onClick={() => handleSetEnvironment('gcp', !environment.gcp)}
|
||||
isSelected={environment.gcp}
|
||||
onKeyDown={(e) => handleKeyDown(e, 'gcp', !environment.gcp)}
|
||||
onMouseEnter={() => prefetchSources({ provider: 'gcp' })}
|
||||
isStacked
|
||||
isDisplayLarge
|
||||
/>
|
||||
|
|
@ -113,7 +114,7 @@ const TargetEnvironment = ({ label, isRequired, ...props }) => {
|
|||
}
|
||||
onClick={() => handleSetEnvironment('azure', !environment.azure)}
|
||||
onKeyDown={(e) => handleKeyDown(e, 'azure', !environment.azure)}
|
||||
onMouseEnter={() => prefetchSources('azure')}
|
||||
onMouseEnter={() => prefetchSources({ provider: 'azure' })}
|
||||
isSelected={environment.azure}
|
||||
isStacked
|
||||
isDisplayLarge
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import { useSelector } from 'react-redux';
|
|||
|
||||
import ClonesTable from './ClonesTable';
|
||||
|
||||
import { useGetSourcesQuery } from '../../store/apiSlice';
|
||||
import { useGetSourceListQuery } from '../../store/provisioningApi';
|
||||
|
||||
const sourceNotFoundPopover = () => {
|
||||
return (
|
||||
|
|
@ -59,7 +59,9 @@ const sourceNotFoundPopover = () => {
|
|||
};
|
||||
|
||||
const getAzureSourceName = (id) => {
|
||||
const { data: sources, isSuccess } = useGetSourcesQuery('azure');
|
||||
const { data: sources, isSuccess } = useGetSourceListQuery({
|
||||
provider: 'azure',
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
const sourcename = sources.find((source) => source.id === id);
|
||||
|
|
@ -74,7 +76,9 @@ const getAzureSourceName = (id) => {
|
|||
};
|
||||
|
||||
const getAWSSourceName = (id) => {
|
||||
const { data: sources, isSuccess } = useGetSourcesQuery('aws');
|
||||
const { data: sources, isSuccess } = useGetSourceListQuery({
|
||||
provider: 'aws',
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
const sourcename = sources.find((source) => source.id === id);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
export const IMAGE_BUILDER_API = '/api/image-builder/v1';
|
||||
export const RHSM_API = '/api/rhsm/v2';
|
||||
export const CONTENT_SOURCES_API = '/api/content-sources/v1';
|
||||
export const PROVISIONING_SOURCES_ENDPOINT = '/api/provisioning/v1';
|
||||
export const PROVISIONING_API = '/api/provisioning/v1';
|
||||
export const RHEL_8 = 'rhel-88';
|
||||
export const RHEL_9 = 'rhel-92';
|
||||
export const CENTOS_8 = 'centos-8';
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
|
||||
|
||||
import { SourceResponse, SourceUploadInfoResponse } from '../../types';
|
||||
|
||||
enum Provider {
|
||||
'azure',
|
||||
'aws'
|
||||
}
|
||||
|
||||
import {
|
||||
PROVISIONING_SOURCES_ENDPOINT,
|
||||
} from '../constants';
|
||||
|
||||
export const apiSlice = createApi({
|
||||
reducerPath: 'api',
|
||||
baseQuery: fetchBaseQuery({ baseUrl: '' }),
|
||||
endpoints: (builder) => ({
|
||||
getSources: builder.query<SourceResponse[], Provider>({
|
||||
query: (provider) => `${PROVISIONING_SOURCES_ENDPOINT}/sources?provider=${provider}`,
|
||||
}),
|
||||
getSourceDetail: builder.query<SourceUploadInfoResponse, string>({
|
||||
query: (sourceId) =>
|
||||
`${PROVISIONING_SOURCES_ENDPOINT}/sources/${sourceId}/upload_info`
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export const {
|
||||
useGetSourcesQuery,
|
||||
useGetSourceDetailQuery,
|
||||
usePrefetch,
|
||||
} = apiSlice;
|
||||
9
src/store/emptyProvisioningApi.ts
Normal file
9
src/store/emptyProvisioningApi.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
|
||||
import {PROVISIONING_API} from '../constants'
|
||||
|
||||
// initialize an empty api service that we'll inject endpoints into later as needed
|
||||
export const emptyProvisioningApi = createApi({
|
||||
reducerPath: 'provisioningApi',
|
||||
baseQuery: fetchBaseQuery({ baseUrl: PROVISIONING_API }),
|
||||
endpoints: () => ({}),
|
||||
})
|
||||
|
|
@ -2,29 +2,29 @@ import { notificationsReducer } from '@redhat-cloud-services/frontend-components
|
|||
import { configureStore } from '@reduxjs/toolkit';
|
||||
import promiseMiddleware from 'redux-promise-middleware';
|
||||
|
||||
import { apiSlice } from './apiSlice';
|
||||
import clonesSlice from './clonesSlice';
|
||||
import composesSlice from './composesSlice';
|
||||
import { contentSourcesApi } from './contentSourcesApi';
|
||||
import { imageBuilderApi } from './imageBuilderApi';
|
||||
import { provisioningApi } from './provisioningApi';
|
||||
import { rhsmApi } from './rhsmApi';
|
||||
|
||||
export const reducer = {
|
||||
[apiSlice.reducerPath]: apiSlice.reducer,
|
||||
clones: clonesSlice,
|
||||
composes: composesSlice,
|
||||
[contentSourcesApi.reducerPath]: contentSourcesApi.reducer,
|
||||
[imageBuilderApi.reducerPath]: imageBuilderApi.reducer,
|
||||
[rhsmApi.reducerPath]: rhsmApi.reducer,
|
||||
[provisioningApi.reducerPath]: provisioningApi.reducer,
|
||||
notifications: notificationsReducer,
|
||||
};
|
||||
|
||||
export const middleware = (getDefaultMiddleware) =>
|
||||
getDefaultMiddleware()
|
||||
.concat(promiseMiddleware)
|
||||
.concat(apiSlice.middleware)
|
||||
.concat(contentSourcesApi.middleware)
|
||||
.concat(imageBuilderApi.middleware)
|
||||
.concat(rhsmApi.middleware);
|
||||
.concat(rhsmApi.middleware)
|
||||
.concat(provisioningApi.middleware);
|
||||
|
||||
export const store = configureStore({ reducer, middleware });
|
||||
|
|
|
|||
59
src/store/provisioningApi.ts
Normal file
59
src/store/provisioningApi.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { emptyProvisioningApi as api } from "./emptyProvisioningApi";
|
||||
const injectedRtkApi = api.injectEndpoints({
|
||||
endpoints: (build) => ({
|
||||
getSourceList: build.query<GetSourceListApiResponse, GetSourceListApiArg>({
|
||||
query: (queryArg) => ({
|
||||
url: `/sources`,
|
||||
params: { provider: queryArg.provider },
|
||||
}),
|
||||
}),
|
||||
getSourceUploadInfo: build.query<
|
||||
GetSourceUploadInfoApiResponse,
|
||||
GetSourceUploadInfoApiArg
|
||||
>({
|
||||
query: (queryArg) => ({ url: `/sources/${queryArg.id}/upload_info` }),
|
||||
}),
|
||||
}),
|
||||
overrideExisting: false,
|
||||
});
|
||||
export { injectedRtkApi as provisioningApi };
|
||||
export type GetSourceListApiResponse =
|
||||
/** status 200 Returned on success. */ V1SourceResponse[];
|
||||
export type GetSourceListApiArg = {
|
||||
provider?: "aws" | "azure" | "gcp";
|
||||
};
|
||||
export type GetSourceUploadInfoApiResponse =
|
||||
/** status 200 Return on success. */ V1SourceUploadInfoResponse;
|
||||
export type GetSourceUploadInfoApiArg = {
|
||||
/** Source ID from Sources Database */
|
||||
id: number;
|
||||
};
|
||||
export type V1SourceResponse = {
|
||||
id?: string;
|
||||
name?: string;
|
||||
source_type_id?: string;
|
||||
uid?: string;
|
||||
};
|
||||
export type V1ResponseError = {
|
||||
build_time?: string;
|
||||
edge_id?: string;
|
||||
environment?: string;
|
||||
error?: string;
|
||||
msg?: string;
|
||||
trace_id?: string;
|
||||
version?: string;
|
||||
};
|
||||
export type V1SourceUploadInfoResponse = {
|
||||
aws?: {
|
||||
account_id?: string;
|
||||
} | null;
|
||||
azure?: {
|
||||
resource_groups?: string[];
|
||||
subscription_id?: string;
|
||||
tenant_id?: string;
|
||||
} | null;
|
||||
gcp?: any | null;
|
||||
provider?: string;
|
||||
};
|
||||
export const { useGetSourceListQuery, useGetSourceUploadInfoQuery } =
|
||||
injectedRtkApi;
|
||||
|
|
@ -4,7 +4,7 @@ import { screen, waitFor } from '@testing-library/react';
|
|||
import userEvent from '@testing-library/user-event';
|
||||
import { rest } from 'msw';
|
||||
|
||||
import { PROVISIONING_SOURCES_ENDPOINT } from '../../../constants.js';
|
||||
import { PROVISIONING_API } from '../../../constants.js';
|
||||
import { server } from '../../mocks/server.js';
|
||||
import { renderWithReduxRouter } from '../../testUtils';
|
||||
|
||||
|
|
@ -161,7 +161,7 @@ describe('Step Upload to Azure', () => {
|
|||
test('component renders error state correctly', async () => {
|
||||
setUp();
|
||||
server.use(
|
||||
rest.get(`${PROVISIONING_SOURCES_ENDPOINT}/sources`, (req, res, ctx) =>
|
||||
rest.get(`${PROVISIONING_API}/sources`, (req, res, ctx) =>
|
||||
res(ctx.status(500))
|
||||
)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -11,11 +11,7 @@ import userEvent from '@testing-library/user-event';
|
|||
import { rest } from 'msw';
|
||||
|
||||
import api from '../../../api.js';
|
||||
import {
|
||||
RHEL_8,
|
||||
RHEL_9,
|
||||
PROVISIONING_SOURCES_ENDPOINT,
|
||||
} from '../../../constants.js';
|
||||
import { RHEL_8, RHEL_9, PROVISIONING_API } from '../../../constants.js';
|
||||
import { mockComposesEmpty } from '../../fixtures/composes.js';
|
||||
import { customizations, ids } from '../../fixtures/customizations.js';
|
||||
import { mockPkgResultAlphaContentSources } from '../../fixtures/packages.js';
|
||||
|
|
@ -127,7 +123,7 @@ describe('Step Upload to AWS', () => {
|
|||
test('component renders error state correctly', async () => {
|
||||
setUp();
|
||||
server.use(
|
||||
rest.get(`${PROVISIONING_SOURCES_ENDPOINT}/sources`, (req, res, ctx) =>
|
||||
rest.get(`${PROVISIONING_API}/sources`, (req, res, ctx) =>
|
||||
res(ctx.status(500))
|
||||
)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { rest } from 'msw';
|
|||
import {
|
||||
CONTENT_SOURCES_API,
|
||||
IMAGE_BUILDER_API,
|
||||
PROVISIONING_SOURCES_ENDPOINT,
|
||||
PROVISIONING_API,
|
||||
RHSM_API,
|
||||
} from '../../constants';
|
||||
import {
|
||||
|
|
@ -25,12 +25,12 @@ import { mockRepositoryResults } from '../fixtures/repositories';
|
|||
import { mockSourcesByProvider, mockUploadInfo } from '../fixtures/sources';
|
||||
|
||||
export const handlers = [
|
||||
rest.get(`${PROVISIONING_SOURCES_ENDPOINT}/sources`, (req, res, ctx) => {
|
||||
rest.get(`${PROVISIONING_API}/sources`, (req, res, ctx) => {
|
||||
const provider = req.url.searchParams.get('provider');
|
||||
return res(ctx.status(200), ctx.json(mockSourcesByProvider(provider)));
|
||||
}),
|
||||
rest.get(
|
||||
`${PROVISIONING_SOURCES_ENDPOINT}/sources/:sourceId/upload_info`,
|
||||
`${PROVISIONING_API}/sources/:sourceId/upload_info`,
|
||||
(req, res, ctx) => {
|
||||
const { sourceId } = req.params;
|
||||
if (sourceId === '666' || sourceId === '667' || sourceId === '123') {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
"jsx": "react-jsx",
|
||||
"allowJs": true,
|
||||
"moduleResolution": "node",
|
||||
"strictNullChecks": true
|
||||
"strictNullChecks": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue