Update project with latest eslint rules
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import tar, { Parse, ParseStream, ReadEntry } from 'tar';
|
||||
import path from 'path';
|
||||
import platformPath from 'path';
|
||||
import fs from 'fs-extra';
|
||||
import { Readable, pipeline as pipelineCb } from 'stream';
|
||||
import { promisify } from 'util';
|
||||
@@ -136,7 +136,7 @@ export class TarArchiveResponse implements ReadTreeResponse {
|
||||
|
||||
const dir =
|
||||
options?.targetDir ??
|
||||
(await fs.mkdtemp(path.join(this.workDir, 'backstage-')));
|
||||
(await fs.mkdtemp(platformPath.join(this.workDir, 'backstage-')));
|
||||
|
||||
const strip = this.subPath ? this.subPath.split('/').length - 1 : 0;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import path from 'path';
|
||||
import platformPath from 'path';
|
||||
import fs from 'fs-extra';
|
||||
import unzipper, { Entry } from 'unzipper';
|
||||
import archiver from 'archiver';
|
||||
@@ -131,7 +131,7 @@ export class ZipArchiveResponse implements ReadTreeResponse {
|
||||
|
||||
const dir =
|
||||
options?.targetDir ??
|
||||
(await fs.mkdtemp(path.join(this.workDir, 'backstage-')));
|
||||
(await fs.mkdtemp(platformPath.join(this.workDir, 'backstage-')));
|
||||
|
||||
await this.stream
|
||||
.pipe(unzipper.Parse())
|
||||
@@ -140,11 +140,11 @@ export class ZipArchiveResponse implements ReadTreeResponse {
|
||||
// as a zip can have files with directories without directory entries
|
||||
if (entry.type === 'File' && this.shouldBeIncluded(entry)) {
|
||||
const entryPath = this.getPath(entry);
|
||||
const dirname = path.dirname(entryPath);
|
||||
const dirname = platformPath.dirname(entryPath);
|
||||
if (dirname) {
|
||||
await fs.mkdirp(path.join(dir, dirname));
|
||||
await fs.mkdirp(platformPath.join(dir, dirname));
|
||||
}
|
||||
entry.pipe(fs.createWriteStream(path.join(dir, entryPath)));
|
||||
entry.pipe(fs.createWriteStream(platformPath.join(dir, entryPath)));
|
||||
} else {
|
||||
entry.autodrain();
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ module.exports = {
|
||||
},
|
||||
ignorePatterns: ['.eslintrc.js', '**/dist/**', '**/dist-types/**'],
|
||||
rules: {
|
||||
'no-shadow': 'off',
|
||||
'no-redeclare': 'off',
|
||||
'@typescript-eslint/no-shadow': 'error',
|
||||
'@typescript-eslint/no-redeclare': 'error',
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ module.exports = {
|
||||
},
|
||||
ignorePatterns: ['.eslintrc.js', '**/dist/**', '**/dist-types/**'],
|
||||
rules: {
|
||||
'no-shadow': 'off',
|
||||
'no-redeclare': 'off',
|
||||
'@typescript-eslint/no-shadow': 'error',
|
||||
'@typescript-eslint/no-redeclare': 'error',
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@ function serializeConfigData(
|
||||
}
|
||||
|
||||
const sanitizedConfigs = schema.process(appConfigs, {
|
||||
valueTransform: (value, { visibility }) =>
|
||||
visibility === 'secret' ? '<secret>' : value,
|
||||
valueTransform: (value, context) =>
|
||||
context.visibility === 'secret' ? '<secret>' : value,
|
||||
});
|
||||
|
||||
return ConfigReader.fromConfigs(sanitizedConfigs).get();
|
||||
|
||||
@@ -108,7 +108,7 @@ describe('bump', () => {
|
||||
paths.targetDir = '/';
|
||||
jest
|
||||
.spyOn(paths, 'resolveTargetRoot')
|
||||
.mockImplementation((...paths) => resolvePath('/', ...paths));
|
||||
.mockImplementation((...path) => resolvePath('/', ...path));
|
||||
jest.spyOn(runObj, 'runPlain').mockImplementation(async (...[, , , name]) =>
|
||||
JSON.stringify({
|
||||
type: 'inspect',
|
||||
@@ -204,7 +204,7 @@ describe('bump', () => {
|
||||
paths.targetDir = '/';
|
||||
jest
|
||||
.spyOn(paths, 'resolveTargetRoot')
|
||||
.mockImplementation((...paths) => resolvePath('/', ...paths));
|
||||
.mockImplementation((...path) => resolvePath('/', ...path));
|
||||
jest.spyOn(runObj, 'runPlain').mockImplementation(async () => '');
|
||||
jest.spyOn(runObj, 'run').mockResolvedValue(undefined);
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ export class LinkedPackageResolvePlugin implements ResolvePlugin {
|
||||
callback: () => void,
|
||||
) => {
|
||||
const pkg = this.packages.find(
|
||||
pkg => data.path && isChildPath(pkg.location, data.path),
|
||||
pkge => data.path && isChildPath(pkge.location, data.path),
|
||||
);
|
||||
if (!pkg) {
|
||||
callback();
|
||||
|
||||
@@ -42,14 +42,14 @@ export type BundlingPathsOptions = {
|
||||
export function resolveBundlingPaths(options: BundlingPathsOptions) {
|
||||
const { entry } = options;
|
||||
|
||||
const resolveTargetModule = (path: string) => {
|
||||
const resolveTargetModule = (pathString: string) => {
|
||||
for (const ext of ['mjs', 'js', 'ts', 'tsx', 'jsx']) {
|
||||
const filePath = paths.resolveTarget(`${path}.${ext}`);
|
||||
const filePath = paths.resolveTarget(`${pathString}.${ext}`);
|
||||
if (fs.pathExistsSync(filePath)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
return paths.resolveTarget(`${path}.js`);
|
||||
return paths.resolveTarget(`${pathString}.js`);
|
||||
};
|
||||
|
||||
let targetPublic = undefined;
|
||||
|
||||
@@ -118,7 +118,9 @@ export async function collectConfigSchemas(
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
depNames.map(name => processItem({ name, parentPath: pkgPath })),
|
||||
depNames.map(depName =>
|
||||
processItem({ name: depName, parentPath: pkgPath }),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,11 +27,11 @@ type Options = {
|
||||
provider: AuthProvider & { id: string };
|
||||
};
|
||||
|
||||
export type DirectAuthResponse = {
|
||||
userId: string;
|
||||
profile: ProfileInfo;
|
||||
backstageIdentity: BackstageIdentity;
|
||||
};
|
||||
// export type DirectAuthResponse = {
|
||||
// userId: string;
|
||||
// profile: ProfileInfo;
|
||||
// backstageIdentity: BackstageIdentity;
|
||||
// };
|
||||
|
||||
export class DirectAuthConnector<DirectAuthResponse> {
|
||||
private readonly discoveryApi: DiscoveryApi;
|
||||
|
||||
@@ -25,8 +25,8 @@ type RouteObject = {
|
||||
|
||||
// Similar to the same function from react-router, this collects routes from the
|
||||
// children, but only the first level of routes
|
||||
function createRoutesFromChildren(children: ReactNode): RouteObject[] {
|
||||
return Children.toArray(children)
|
||||
function createRoutesFromChildren(childrenNode: ReactNode): RouteObject[] {
|
||||
return Children.toArray(childrenNode)
|
||||
.flatMap(child => {
|
||||
if (!isValidElement(child)) {
|
||||
return [];
|
||||
|
||||
@@ -38,13 +38,13 @@ const useStyles = makeStyles(theme => ({
|
||||
},
|
||||
}));
|
||||
|
||||
export type Tab = {
|
||||
export type objectTab = {
|
||||
id: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
type HeaderTabsProps = {
|
||||
tabs: Tab[];
|
||||
tabs: objectTab[];
|
||||
onChange?: (index: number) => void;
|
||||
selectedIndex?: number;
|
||||
};
|
||||
|
||||
@@ -104,11 +104,11 @@ async function buildDistWorkspace(workspaceName: string, rootDir: string) {
|
||||
{
|
||||
helpers: {
|
||||
version(name: string) {
|
||||
const pkg = require(`${name}/package.json`);
|
||||
if (!pkg) {
|
||||
const pkge = require(`${name}/package.json`);
|
||||
if (!pkge) {
|
||||
throw new Error(`No version available for package ${name}`);
|
||||
}
|
||||
return pkg.version;
|
||||
return pkge.version;
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -43,10 +43,10 @@ describe('ScmIntegrations', () => {
|
||||
} as GitLabIntegrationConfig);
|
||||
|
||||
const i = new ScmIntegrations({
|
||||
azure: basicIntegrations([azure], i => i.config.host),
|
||||
bitbucket: basicIntegrations([bitbucket], i => i.config.host),
|
||||
github: basicIntegrations([github], i => i.config.host),
|
||||
gitlab: basicIntegrations([gitlab], i => i.config.host),
|
||||
azure: basicIntegrations([azure], item => item.config.host),
|
||||
bitbucket: basicIntegrations([bitbucket], item => item.config.host),
|
||||
github: basicIntegrations([github], item => item.config.host),
|
||||
gitlab: basicIntegrations([gitlab], item => item.config.host),
|
||||
});
|
||||
|
||||
it('can get the specifics', () => {
|
||||
|
||||
@@ -215,21 +215,21 @@ describe('GithubCredentialsProvider tests', () => {
|
||||
});
|
||||
|
||||
it('should return the default token if no app is configured', async () => {
|
||||
const github = GithubCredentialsProvider.create({
|
||||
const githubID = GithubCredentialsProvider.create({
|
||||
host: 'github.com',
|
||||
apps: [],
|
||||
token: 'fallback_token',
|
||||
});
|
||||
|
||||
await expect(
|
||||
github.getCredentials({
|
||||
githubID.getCredentials({
|
||||
url: 'https://github.com/404/foobar',
|
||||
}),
|
||||
).resolves.toEqual(expect.objectContaining({ token: 'fallback_token' }));
|
||||
});
|
||||
|
||||
it('should return the configured token if listing installations throws', async () => {
|
||||
const github = GithubCredentialsProvider.create({
|
||||
const githubID = GithubCredentialsProvider.create({
|
||||
host: 'github.com',
|
||||
apps: [
|
||||
{
|
||||
@@ -245,19 +245,19 @@ describe('GithubCredentialsProvider tests', () => {
|
||||
octokit.apps.listInstallations.mockRejectedValue({ status: 304 });
|
||||
|
||||
await expect(
|
||||
github.getCredentials({
|
||||
githubID.getCredentials({
|
||||
url: 'https://github.com/backstage',
|
||||
}),
|
||||
).resolves.toEqual(expect.objectContaining({ token: 'hardcoded_token' }));
|
||||
});
|
||||
|
||||
it('should return undefined if no token or apps are configured', async () => {
|
||||
const github = GithubCredentialsProvider.create({
|
||||
const githubID = GithubCredentialsProvider.create({
|
||||
host: 'github.com',
|
||||
});
|
||||
|
||||
await expect(
|
||||
github.getCredentials({
|
||||
githubID.getCredentials({
|
||||
url: 'https://github.com/backstage',
|
||||
}),
|
||||
).resolves.toEqual({ headers: undefined, token: undefined });
|
||||
|
||||
@@ -177,7 +177,7 @@ export class GithubAppCredentialsMux {
|
||||
),
|
||||
);
|
||||
|
||||
const result = results.find(result => result.credentials);
|
||||
const result = results.find(resultItem => resultItem.credentials);
|
||||
if (result) {
|
||||
return result.credentials!.accessToken;
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ jest.mock('fs-extra', () => {
|
||||
const fsOriginal = jest.requireActual('fs-extra');
|
||||
return {
|
||||
...fsOriginal,
|
||||
access: jest.fn().mockImplementation((path, checkType, callback) => {
|
||||
access: jest.fn().mockImplementation((paths, checkType, callback) => {
|
||||
if (
|
||||
path.includes('http://localhost:7000/static') &&
|
||||
paths.includes('http://localhost:7000/static') &&
|
||||
checkType === fs.constants.F_OK
|
||||
) {
|
||||
callback();
|
||||
|
||||
@@ -74,8 +74,8 @@ paths:
|
||||
type: 'openapi',
|
||||
title: 'OpenAPI',
|
||||
rawLanguage: 'yaml',
|
||||
component: definition => (
|
||||
<OpenApiDefinitionWidget definition={definition} />
|
||||
component: definitionString => (
|
||||
<OpenApiDefinitionWidget definition={definitionString} />
|
||||
),
|
||||
});
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ export class DatabaseEntitiesCatalog implements EntitiesCatalog {
|
||||
// produce tens of thousands of entities, and those are too large batch
|
||||
// sizes to reasonably send to the database.
|
||||
const batches = Object.values(requestsByKindAndNamespace)
|
||||
.map(requests => chunk(requests, BATCH_SIZE))
|
||||
.map(request => chunk(request, BATCH_SIZE))
|
||||
.flat();
|
||||
|
||||
// Bound the number of concurrent batches. We want a bit of concurrency for
|
||||
|
||||
+6
-3
@@ -65,7 +65,10 @@ describe('AwsOrganizationCloudAccountProcessor', () => {
|
||||
});
|
||||
|
||||
it('filters out accounts not in specified location target', async () => {
|
||||
const location = { type: 'aws-cloud-accounts', target: 'o-1vl18kc5a3' };
|
||||
const locationTest = {
|
||||
type: 'aws-cloud-accounts',
|
||||
target: 'o-1vl18kc5a3',
|
||||
};
|
||||
listAccounts.mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
Accounts: [
|
||||
@@ -83,11 +86,11 @@ describe('AwsOrganizationCloudAccountProcessor', () => {
|
||||
NextToken: undefined,
|
||||
}),
|
||||
);
|
||||
await processor.readLocation(location, false, emit);
|
||||
await processor.readLocation(locationTest, false, emit);
|
||||
expect(emit).toBeCalledTimes(1);
|
||||
expect(emit).toBeCalledWith({
|
||||
type: 'entity',
|
||||
location,
|
||||
location: locationTest,
|
||||
entity: {
|
||||
apiVersion: 'backstage.io/v1alpha1',
|
||||
kind: 'Resource',
|
||||
|
||||
@@ -66,8 +66,8 @@ export class BuiltinKindsEntityProcessor implements CatalogProcessor {
|
||||
|
||||
async validateEntityKind(entity: Entity): Promise<boolean> {
|
||||
for (const validator of this.validators) {
|
||||
const result = await validator.check(entity);
|
||||
if (result) {
|
||||
const results = await validator.check(entity);
|
||||
if (results) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ export const RegisterComponentForm = ({
|
||||
|
||||
const onSubmit = async (formData: Record<string, string>) => {
|
||||
const { componentLocation: target } = formData;
|
||||
async function saveCatalogFileConfig(target: string) {
|
||||
const data = await catalogApi.addLocation({ target });
|
||||
async function saveCatalogFileConfig(targetString: string) {
|
||||
const data = await catalogApi.addLocation({ target: targetString });
|
||||
saveConfig({
|
||||
type: 'file',
|
||||
location: data.location.target,
|
||||
@@ -80,12 +80,12 @@ export const RegisterComponentForm = ({
|
||||
});
|
||||
}
|
||||
|
||||
async function trySaveRepositoryConfig(target: string) {
|
||||
const existingCatalog = await checkForExistingCatalogInfo(target);
|
||||
async function trySaveRepositoryConfig(targetString: string) {
|
||||
const existingCatalog = await checkForExistingCatalogInfo(targetString);
|
||||
if (existingCatalog.exists) {
|
||||
const targetUrl = target.endsWith('/')
|
||||
? `${target}${existingCatalog.url}`
|
||||
: `${target}/${existingCatalog.url}`;
|
||||
const targetUrl = targetString.endsWith('/')
|
||||
? `${targetString}${existingCatalog.url}`
|
||||
: `${targetString}/${existingCatalog.url}`;
|
||||
await saveCatalogFileConfig(targetUrl);
|
||||
} else {
|
||||
saveConfig({
|
||||
|
||||
@@ -46,20 +46,20 @@ function manifestGenerationAvailable(configApi: ConfigApi): boolean {
|
||||
|
||||
function repositories(configApi: ConfigApi): string[] {
|
||||
const integrations = configApi.getConfig('integrations');
|
||||
const repositories = [];
|
||||
const repos = [];
|
||||
if (integrations.has('github')) {
|
||||
repositories.push('GitHub');
|
||||
repos.push('GitHub');
|
||||
}
|
||||
if (integrations.has('bitbucket')) {
|
||||
repositories.push('Bitbucket');
|
||||
repos.push('Bitbucket');
|
||||
}
|
||||
if (integrations.has('gitlab')) {
|
||||
repositories.push('GitLab');
|
||||
repos.push('GitLab');
|
||||
}
|
||||
if (integrations.has('azure')) {
|
||||
repositories.push('Azure');
|
||||
repos.push('Azure');
|
||||
}
|
||||
return repositories;
|
||||
return repos;
|
||||
}
|
||||
|
||||
export const ImportComponentPage = ({
|
||||
|
||||
@@ -53,8 +53,10 @@ const Route: (props: SubRoute) => null = () => null;
|
||||
// This causes all mount points that are discovered within this route to use the path of the route itself
|
||||
attachComponentData(Route, 'core.gatherMountPoints', true);
|
||||
|
||||
export function createSubRoutesFromChildren(children: ReactNode): SubRoute[] {
|
||||
return Children.toArray(children).flatMap(child => {
|
||||
export function createSubRoutesFromChildren(
|
||||
childrenNode: ReactNode,
|
||||
): SubRoute[] {
|
||||
return Children.toArray(childrenNode).flatMap(child => {
|
||||
if (!isValidElement(child)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -52,12 +52,12 @@ export const TabbedLayout = ({ routes }: { routes: SubRoute[] }) => {
|
||||
[routes],
|
||||
);
|
||||
|
||||
const onTabChange = (index: number) =>
|
||||
const onTabChange = (tabIndex: number) =>
|
||||
// Remove trailing /*
|
||||
// And remove leading / for relative navigation
|
||||
// Note! route resolves relative to the position in the React tree,
|
||||
// not relative to current location
|
||||
navigate(routes[index].path.replace(/\/\*$/, '').replace(/^\//, ''));
|
||||
navigate(routes[tabIndex].path.replace(/\/\*$/, '').replace(/^\//, ''));
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -35,8 +35,8 @@ type SwitchCase = {
|
||||
children: JSX.Element;
|
||||
};
|
||||
|
||||
function createSwitchCasesFromChildren(children: ReactNode): SwitchCase[] {
|
||||
return Children.toArray(children).flatMap(child => {
|
||||
function createSwitchCasesFromChildren(childrenNode: ReactNode): SwitchCase[] {
|
||||
return Children.toArray(childrenNode).flatMap(child => {
|
||||
if (!isValidElement(child)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -34,13 +34,13 @@ export function isOwnerOf(owner: Entity, owned: Entity) {
|
||||
|
||||
const owners = getEntityRelations(owned, RELATION_OWNED_BY);
|
||||
|
||||
for (const owner of owners) {
|
||||
for (const ownerItem of owners) {
|
||||
if (
|
||||
possibleOwners.find(
|
||||
o =>
|
||||
owner.kind.toLowerCase() === o.kind.toLowerCase() &&
|
||||
owner.namespace.toLowerCase() === o.namespace.toLowerCase() &&
|
||||
owner.name.toLowerCase() === o.name.toLowerCase(),
|
||||
ownerItem.kind.toLowerCase() === o.kind.toLowerCase() &&
|
||||
ownerItem.namespace.toLowerCase() === o.namespace.toLowerCase() &&
|
||||
ownerItem.name.toLowerCase() === o.name.toLowerCase(),
|
||||
) !== undefined
|
||||
) {
|
||||
return true;
|
||||
|
||||
@@ -18,11 +18,11 @@ import { Paper, Divider } from '@material-ui/core';
|
||||
import { AlertActionCard } from './AlertActionCard';
|
||||
import { Alert } from '../../types';
|
||||
|
||||
type AlertActionCardList = {
|
||||
type AlertActionCardListType = {
|
||||
alerts: Array<Alert>;
|
||||
};
|
||||
|
||||
export const AlertActionCardList = ({ alerts }: AlertActionCardList) => (
|
||||
export const AlertActionCardList = ({ alerts }: AlertActionCardListType) => (
|
||||
<Paper>
|
||||
{alerts.map((alert, index) => (
|
||||
<Fragment key={`alert-${index}`}>
|
||||
|
||||
@@ -18,7 +18,7 @@ import React, { PropsWithChildren } from 'react';
|
||||
import { Box, Typography } from '@material-ui/core';
|
||||
import { useBarChartLabelStyles } from '../../utils/styles';
|
||||
|
||||
type BarChartLabel = {
|
||||
type BarChartLabelType = {
|
||||
x: number;
|
||||
y: number;
|
||||
height: number;
|
||||
@@ -33,7 +33,7 @@ export const BarChartLabel = ({
|
||||
width,
|
||||
details,
|
||||
children,
|
||||
}: PropsWithChildren<BarChartLabel>) => {
|
||||
}: PropsWithChildren<BarChartLabelType>) => {
|
||||
const classes = useBarChartLabelStyles();
|
||||
const translateX = width * -0.5;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import React from 'react';
|
||||
import { ButtonBase } from '@material-ui/core';
|
||||
import { useBarChartStepperStyles as useStyles } from '../../utils/styles';
|
||||
|
||||
export type BarChartSteps = {
|
||||
export type BarChartStepsType = {
|
||||
steps: number;
|
||||
activeStep: number;
|
||||
onClick: (index: number) => void;
|
||||
@@ -28,7 +28,7 @@ export const BarChartSteps = ({
|
||||
steps,
|
||||
activeStep,
|
||||
onClick,
|
||||
}: BarChartSteps) => {
|
||||
}: BarChartStepsType) => {
|
||||
const classes = useStyles();
|
||||
const handleOnClick = (index: number) => (
|
||||
event: React.MouseEvent<HTMLButtonElement, MouseEvent>,
|
||||
|
||||
@@ -83,28 +83,31 @@ export const ProductInsights = ({
|
||||
|
||||
useEffect(() => {
|
||||
async function getAllProductInsights(
|
||||
group: string,
|
||||
project: Maybe<string>,
|
||||
products: Product[],
|
||||
lastCompleteBillingDate: string,
|
||||
groupId: string,
|
||||
projectId: Maybe<string>,
|
||||
productsId: Product[],
|
||||
lastCompleteBillingDateId: string,
|
||||
) {
|
||||
try {
|
||||
dispatchLoadingProducts(true);
|
||||
const responses = await Promise.allSettled(
|
||||
products.map(product =>
|
||||
productsId.map(product =>
|
||||
client.getProductInsights({
|
||||
group: group,
|
||||
project: project,
|
||||
group: groupId,
|
||||
project: projectId,
|
||||
product: product.kind,
|
||||
intervals: intervalsOf(DEFAULT_DURATION, lastCompleteBillingDate),
|
||||
intervals: intervalsOf(
|
||||
DEFAULT_DURATION,
|
||||
lastCompleteBillingDateId,
|
||||
),
|
||||
}),
|
||||
),
|
||||
).then(settledResponseOf);
|
||||
|
||||
const initialStates = initialStatesOf(products, responses).sort(
|
||||
const initialStatesNow = initialStatesOf(productsId, responses).sort(
|
||||
totalAggregationSort,
|
||||
);
|
||||
setStates(initialStates);
|
||||
setStates(initialStatesNow);
|
||||
} catch (e) {
|
||||
setError(e);
|
||||
} finally {
|
||||
@@ -125,8 +128,8 @@ export const ProductInsights = ({
|
||||
useEffect(
|
||||
function handleOnLoaded() {
|
||||
if (onceRef.current) {
|
||||
const products = initialStates.map(state => state.product);
|
||||
onLoaded(products);
|
||||
const currentProducts = initialStates.map(state => state.product);
|
||||
onLoaded(currentProducts);
|
||||
} else {
|
||||
onceRef.current = true;
|
||||
}
|
||||
|
||||
@@ -26,10 +26,10 @@ import {
|
||||
DateAggregation,
|
||||
} from '../types';
|
||||
import dayjs, { OpUnitType } from 'dayjs';
|
||||
import duration from 'dayjs/plugin/duration';
|
||||
import durationPlugin from 'dayjs/plugin/duration';
|
||||
import { inclusiveStartDateOf } from './duration';
|
||||
|
||||
dayjs.extend(duration);
|
||||
dayjs.extend(durationPlugin);
|
||||
|
||||
// Used for displaying status colors
|
||||
export function growthOf(ratio: number, amount?: number) {
|
||||
|
||||
@@ -36,17 +36,17 @@ export function useBuilds(owner: string, repo: string, branch?: string) {
|
||||
|
||||
const { loading, value: builds, retry } = useAsyncRetry(async () => {
|
||||
try {
|
||||
let builds;
|
||||
let build;
|
||||
if (branch) {
|
||||
builds = await api.getLastBuild(`${owner}/${repo}/${branch}`);
|
||||
build = await api.getLastBuild(`${owner}/${repo}/${branch}`);
|
||||
} else {
|
||||
builds = await api.getFolder(`${owner}/${repo}`);
|
||||
build = await api.getFolder(`${owner}/${repo}`);
|
||||
}
|
||||
|
||||
const size = Array.isArray(builds) ? builds?.[0].build_num! : 1;
|
||||
const size = Array.isArray(build) ? build?.[0].build_num! : 1;
|
||||
setTotal(size);
|
||||
|
||||
return builds || [];
|
||||
return build || [];
|
||||
} catch (e) {
|
||||
errorApi.post(e);
|
||||
throw e;
|
||||
|
||||
@@ -85,18 +85,18 @@ export const handleGetKubernetesObjectsForService: GetKubernetesObjectsForServic
|
||||
] || `backstage.io/kubernetes-id=${requestBody.entity.metadata.name}`;
|
||||
|
||||
return Promise.all(
|
||||
clusterDetailsDecoratedForAuth.map(clusterDetails => {
|
||||
clusterDetailsDecoratedForAuth.map(clusterDetailsItem => {
|
||||
return fetcher
|
||||
.fetchObjectsForService({
|
||||
serviceId,
|
||||
clusterDetails,
|
||||
clusterDetails: clusterDetailsItem,
|
||||
objectTypesToFetch,
|
||||
labelSelector,
|
||||
} as ObjectFetchParams)
|
||||
.then(result => {
|
||||
return {
|
||||
cluster: {
|
||||
name: clusterDetails.name,
|
||||
name: clusterDetailsItem.name,
|
||||
},
|
||||
resources: result.responses,
|
||||
errors: result.errors,
|
||||
|
||||
@@ -32,8 +32,8 @@ export const DeploymentDrawer = ({
|
||||
object={deployment}
|
||||
expanded={expanded}
|
||||
kind="Deployment"
|
||||
renderObject={(deployment: V1Deployment) => {
|
||||
const conditions = (deployment.status?.conditions ?? [])
|
||||
renderObject={(deploymentObj: V1Deployment) => {
|
||||
const conditions = (deploymentObj.status?.conditions ?? [])
|
||||
.map(renderCondition)
|
||||
.reduce((accum, next) => {
|
||||
accum[next[0]] = next[1];
|
||||
@@ -41,10 +41,10 @@ export const DeploymentDrawer = ({
|
||||
}, {} as { [key: string]: React.ReactNode });
|
||||
|
||||
return {
|
||||
strategy: deployment.spec?.strategy ?? '???',
|
||||
minReadySeconds: deployment.spec?.minReadySeconds ?? '???',
|
||||
strategy: deploymentObj.spec?.strategy ?? '???',
|
||||
minReadySeconds: deploymentObj.spec?.minReadySeconds ?? '???',
|
||||
progressDeadlineSeconds:
|
||||
deployment.spec?.progressDeadlineSeconds ?? '???',
|
||||
deploymentObj.spec?.progressDeadlineSeconds ?? '???',
|
||||
...conditions,
|
||||
};
|
||||
}}
|
||||
|
||||
+7
-7
@@ -32,16 +32,16 @@ export const HorizontalPodAutoscalerDrawer = ({
|
||||
kind="HorizontalPodAutoscaler"
|
||||
object={hpa}
|
||||
expanded={expanded}
|
||||
renderObject={(hpa: V1HorizontalPodAutoscaler) => {
|
||||
renderObject={(hpaObject: V1HorizontalPodAutoscaler) => {
|
||||
return {
|
||||
targetCPUUtilizationPercentage:
|
||||
hpa.spec?.targetCPUUtilizationPercentage,
|
||||
hpaObject.spec?.targetCPUUtilizationPercentage,
|
||||
currentCPUUtilizationPercentage:
|
||||
hpa.status?.currentCPUUtilizationPercentage,
|
||||
minReplicas: hpa.spec?.minReplicas,
|
||||
maxReplicas: hpa.spec?.maxReplicas,
|
||||
currentReplicas: hpa.status?.currentReplicas,
|
||||
desiredReplicas: hpa.status?.desiredReplicas,
|
||||
hpaObject.status?.currentCPUUtilizationPercentage,
|
||||
minReplicas: hpaObject.spec?.minReplicas,
|
||||
maxReplicas: hpaObject.spec?.maxReplicas,
|
||||
currentReplicas: hpaObject.status?.currentReplicas,
|
||||
desiredReplicas: hpaObject.status?.desiredReplicas,
|
||||
};
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -31,8 +31,8 @@ export const IngressDrawer = ({
|
||||
object={ingress}
|
||||
expanded={expanded}
|
||||
kind="Ingress"
|
||||
renderObject={(ingress: ExtensionsV1beta1Ingress) => {
|
||||
return ingress.spec || {};
|
||||
renderObject={(ingressObject: ExtensionsV1beta1Ingress) => {
|
||||
return ingressObject.spec || {};
|
||||
}}
|
||||
>
|
||||
<Grid
|
||||
|
||||
+8
-8
@@ -37,17 +37,17 @@ export const PodDrawer = ({
|
||||
object={pod}
|
||||
expanded={expanded}
|
||||
kind="Pod"
|
||||
renderObject={(pod: V1Pod) => {
|
||||
const phase = pod.status?.phase ?? 'unknown';
|
||||
renderObject={(podObject: V1Pod) => {
|
||||
const phase = podObject.status?.phase ?? 'unknown';
|
||||
|
||||
const ports =
|
||||
pod.spec?.containers?.map(c => {
|
||||
podObject.spec?.containers?.map(c => {
|
||||
return {
|
||||
[c.name]: c.ports,
|
||||
};
|
||||
}) ?? 'N/A';
|
||||
|
||||
const conditions = (pod.status?.conditions ?? [])
|
||||
const conditions = (podObject.status?.conditions ?? [])
|
||||
.map(renderCondition)
|
||||
.reduce((accum, next) => {
|
||||
accum[next[0]] = next[1];
|
||||
@@ -55,11 +55,11 @@ export const PodDrawer = ({
|
||||
}, {} as { [key: string]: React.ReactNode });
|
||||
|
||||
return {
|
||||
images: imageChips(pod),
|
||||
images: imageChips(podObject),
|
||||
phase: phase,
|
||||
'Containers Ready': containersReady(pod),
|
||||
'Total Restarts': totalRestarts(pod),
|
||||
'Container Statuses': containerStatuses(pod),
|
||||
'Containers Ready': containersReady(podObject),
|
||||
'Total Restarts': totalRestarts(podObject),
|
||||
'Container Statuses': containerStatuses(podObject),
|
||||
...conditions,
|
||||
'Exposed ports': ports,
|
||||
};
|
||||
|
||||
@@ -31,8 +31,8 @@ export const ServiceDrawer = ({
|
||||
object={service}
|
||||
expanded={expanded}
|
||||
kind="Service"
|
||||
renderObject={(service: V1Service) => {
|
||||
return service.spec || {};
|
||||
renderObject={(serviceObject: V1Service) => {
|
||||
return serviceObject.spec || {};
|
||||
}}
|
||||
>
|
||||
<Grid
|
||||
|
||||
@@ -36,9 +36,9 @@ export const imageChips = (pod: V1Pod): ReactNode => {
|
||||
|
||||
export const containersReady = (pod: V1Pod): string => {
|
||||
const containerStatuses = pod.status?.containerStatuses ?? [];
|
||||
const containersReady = containerStatuses.filter(cs => cs.ready).length;
|
||||
const containersReadyItem = containerStatuses.filter(cs => cs.ready).length;
|
||||
|
||||
return `${containersReady}/${containerStatuses.length}`;
|
||||
return `${containersReadyItem}/${containerStatuses.length}`;
|
||||
};
|
||||
|
||||
export const totalRestarts = (pod: V1Pod): number => {
|
||||
@@ -47,8 +47,8 @@ export const totalRestarts = (pod: V1Pod): number => {
|
||||
};
|
||||
|
||||
export const containerStatuses = (pod: V1Pod): ReactNode => {
|
||||
const containerStatuses = pod.status?.containerStatuses ?? [];
|
||||
const errors = containerStatuses.reduce((accum, next) => {
|
||||
const containerStatusesItem = pod.status?.containerStatuses ?? [];
|
||||
const errors = containerStatusesItem.reduce((accum, next) => {
|
||||
if (next.state === undefined) {
|
||||
return accum;
|
||||
}
|
||||
|
||||
@@ -73,12 +73,12 @@ export const GroupProfileCard = ({
|
||||
} = group;
|
||||
const parent = group?.relations
|
||||
?.filter(r => r.type === RELATION_CHILD_OF)
|
||||
?.map(group => group.target.name)
|
||||
?.map(groupItem => groupItem.target.name)
|
||||
.toString();
|
||||
|
||||
const childrens = group?.relations
|
||||
?.filter(r => r.type === RELATION_PARENT_OF)
|
||||
?.map(group => group.target.name);
|
||||
?.map(groupItem => groupItem.target.name);
|
||||
|
||||
const displayName = profile?.displayName ?? name;
|
||||
|
||||
|
||||
@@ -38,13 +38,13 @@ export function isOwnerOf(owner: Entity, owned: Entity) {
|
||||
|
||||
const owners = getEntityRelations(owned, RELATION_OWNED_BY);
|
||||
|
||||
for (const owner of owners) {
|
||||
for (const ownerItem of owners) {
|
||||
if (
|
||||
possibleOwners.find(
|
||||
o =>
|
||||
owner.kind.toLowerCase() === o.kind.toLowerCase() &&
|
||||
owner.namespace.toLowerCase() === o.namespace.toLowerCase() &&
|
||||
owner.name.toLowerCase() === o.name.toLowerCase(),
|
||||
ownerItem.kind.toLowerCase() === o.kind.toLowerCase() &&
|
||||
ownerItem.namespace.toLowerCase() === o.namespace.toLowerCase() &&
|
||||
ownerItem.name.toLowerCase() === o.name.toLowerCase(),
|
||||
) !== undefined
|
||||
) {
|
||||
return true;
|
||||
|
||||
@@ -32,11 +32,11 @@ export const EscalationPolicy = ({ policyId }: Props) => {
|
||||
|
||||
const { value: users, loading, error } = useAsync(async () => {
|
||||
const oncalls = await api.getOnCallByPolicyId(policyId);
|
||||
const users = oncalls
|
||||
const usersItem = oncalls
|
||||
.sort((a, b) => a.escalation_level - b.escalation_level)
|
||||
.map(oncall => oncall.user);
|
||||
|
||||
return users;
|
||||
return usersItem;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
|
||||
@@ -52,11 +52,11 @@ export const TriggerDialog = ({
|
||||
const [description, setDescription] = useState<string>('');
|
||||
|
||||
const [{ value, loading, error }, handleTriggerAlarm] = useAsyncFn(
|
||||
async (description: string) =>
|
||||
async (descriptions: string) =>
|
||||
await api.triggerAlarm({
|
||||
integrationKey,
|
||||
source: window.location.toString(),
|
||||
description,
|
||||
description: descriptions,
|
||||
userName,
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -93,12 +93,12 @@ describe('BitbucketPreparer', () => {
|
||||
});
|
||||
|
||||
it('calls the clone command with the correct arguments if an app password is provided for a repository', async () => {
|
||||
const preparer = BitbucketPreparer.fromConfig({
|
||||
const preparerCheck = BitbucketPreparer.fromConfig({
|
||||
host: 'bitbucket.org',
|
||||
username: 'fake-user',
|
||||
appPassword: 'fake-password',
|
||||
});
|
||||
await preparer.prepare(mockEntity, { logger });
|
||||
await preparerCheck.prepare(mockEntity, { logger });
|
||||
|
||||
expect(Git.fromAuth).toHaveBeenCalledWith({
|
||||
logger,
|
||||
@@ -128,12 +128,12 @@ describe('BitbucketPreparer', () => {
|
||||
});
|
||||
|
||||
it('calls the clone command with with token for auth method', async () => {
|
||||
const preparer = BitbucketPreparer.fromConfig({
|
||||
const preparerCheck = BitbucketPreparer.fromConfig({
|
||||
host: 'bitbucket.org',
|
||||
token: 'fake-token',
|
||||
});
|
||||
|
||||
await preparer.prepare(mockEntity, { logger });
|
||||
await preparerCheck.prepare(mockEntity, { logger });
|
||||
|
||||
expect(Git.fromAuth).toHaveBeenCalledWith({
|
||||
logger,
|
||||
|
||||
@@ -104,12 +104,12 @@ describe('GitHubPreparer', () => {
|
||||
});
|
||||
|
||||
it('return the temp directory with the path to the folder if it is specified', async () => {
|
||||
const preparer = GithubPreparer.fromConfig({
|
||||
const preparerCheck = GithubPreparer.fromConfig({
|
||||
host: 'github.com',
|
||||
token: 'fake-token',
|
||||
});
|
||||
mockEntity.spec.path = './template/test/1/2/3';
|
||||
const response = await preparer.prepare(mockEntity, {
|
||||
const response = await preparerCheck.prepare(mockEntity, {
|
||||
logger: getVoidLogger(),
|
||||
});
|
||||
expect(response.split('\\').join('/')).toMatch(
|
||||
@@ -118,13 +118,13 @@ describe('GitHubPreparer', () => {
|
||||
});
|
||||
|
||||
it('return the working directory with the path to the folder if it is specified', async () => {
|
||||
const preparer = GithubPreparer.fromConfig({
|
||||
const preparerCheck = GithubPreparer.fromConfig({
|
||||
host: 'github.com',
|
||||
token: 'fake-token',
|
||||
});
|
||||
|
||||
mockEntity.spec.path = './template/test/1/2/3';
|
||||
const response = await preparer.prepare(mockEntity, {
|
||||
const response = await preparerCheck.prepare(mockEntity, {
|
||||
workingDirectory: '/workDir',
|
||||
logger: getVoidLogger(),
|
||||
});
|
||||
|
||||
@@ -30,7 +30,7 @@ import { Theme as MuiTheme } from '@rjsf/material-ui';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
const Form = withTheme(MuiTheme);
|
||||
type Step = {
|
||||
type StepType = {
|
||||
schema: JSONSchema;
|
||||
label: string;
|
||||
} & Partial<Omit<FormProps<any>, 'schema'>>;
|
||||
@@ -39,7 +39,7 @@ type Props = {
|
||||
/**
|
||||
* Steps for the form, each contains label and form schema
|
||||
*/
|
||||
steps: Step[];
|
||||
steps: StepType[];
|
||||
formData: Record<string, any>;
|
||||
onChange: (e: IChangeEvent) => void;
|
||||
onReset: () => void;
|
||||
|
||||
@@ -92,8 +92,8 @@ export const TemplatePage = () => {
|
||||
);
|
||||
|
||||
const [jobId, setJobId] = useState<string | null>(null);
|
||||
const job = useJobPolling(jobId, async job => {
|
||||
if (!job.metadata.catalogInfoUrl) {
|
||||
const job = useJobPolling(jobId, async jobItem => {
|
||||
if (!jobItem.metadata.catalogInfoUrl) {
|
||||
errorApi.post(
|
||||
new Error(`No catalogInfoUrl returned from the scaffolder`),
|
||||
);
|
||||
@@ -103,7 +103,9 @@ export const TemplatePage = () => {
|
||||
try {
|
||||
const {
|
||||
entities: [createdEntity],
|
||||
} = await catalogApi.addLocation({ target: job.metadata.catalogInfoUrl });
|
||||
} = await catalogApi.addLocation({
|
||||
target: jobItem.metadata.catalogInfoUrl,
|
||||
});
|
||||
|
||||
const resolvedPath = generatePath(
|
||||
`/catalog/${entityRoute.path}`,
|
||||
@@ -122,8 +124,8 @@ export const TemplatePage = () => {
|
||||
|
||||
const handleCreate = async () => {
|
||||
try {
|
||||
const jobId = await scaffolderApi.scaffold(templateName, formState);
|
||||
setJobId(jobId);
|
||||
const Id = await scaffolderApi.scaffold(templateName, formState);
|
||||
setJobId(Id);
|
||||
setModalOpen(true);
|
||||
} catch (e) {
|
||||
errorApi.post(e);
|
||||
|
||||
@@ -59,10 +59,10 @@ type TableHeaderProps = {
|
||||
handleToggleFilters: () => void;
|
||||
};
|
||||
|
||||
type Filters = {
|
||||
selected: string;
|
||||
checked: Array<string | null>;
|
||||
};
|
||||
// type Filters = {
|
||||
// selected: string;
|
||||
// checked: Array<string | null>;
|
||||
// };
|
||||
|
||||
// TODO: move out column to make the search result component more generic
|
||||
const columns: TableColumn[] = [
|
||||
|
||||
Reference in New Issue
Block a user