Merge branch 'backstage:master' into master
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-tech-insights-backend': minor
|
||||
---
|
||||
|
||||
Allow FactRetrieverRegistry to be injected into buildTechInsightsContext so that we can override default registry implementation.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-jenkins': patch
|
||||
'@backstage/plugin-jenkins-backend': patch
|
||||
---
|
||||
|
||||
feature: added support for multiple branches to the `JenkinsApi`
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
'@backstage/plugin-codescene': patch
|
||||
'@backstage/plugin-sonarqube': patch
|
||||
---
|
||||
|
||||
Updated dependency `rc-progress` to `3.4.0`.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-api-docs': patch
|
||||
'@backstage/plugin-catalog': minor
|
||||
---
|
||||
|
||||
Add hidden title column to catalog and API table to enable filtering by title.
|
||||
@@ -56,7 +56,7 @@
|
||||
"pluralize": "^8.0.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"qs": "^6.9.4",
|
||||
"rc-progress": "3.3.3",
|
||||
"rc-progress": "3.4.0",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-hook-form": "^7.12.2",
|
||||
"react-markdown": "^8.0.0",
|
||||
|
||||
@@ -40,6 +40,7 @@ import React from 'react';
|
||||
import { registerComponentRouteRef } from '../../routes';
|
||||
|
||||
const defaultColumns: TableColumn<CatalogTableRow>[] = [
|
||||
CatalogTable.columns.createTitleColumn({ hidden: true }),
|
||||
CatalogTable.columns.createNameColumn({ defaultKind: 'API' }),
|
||||
CatalogTable.columns.createSystemColumn(),
|
||||
CatalogTable.columns.createOwnerColumn(),
|
||||
|
||||
@@ -136,6 +136,13 @@ export const CatalogTable: {
|
||||
createSpecLifecycleColumn(): TableColumn<CatalogTableRow>;
|
||||
createMetadataDescriptionColumn(): TableColumn<CatalogTableRow>;
|
||||
createTagsColumn(): TableColumn<CatalogTableRow>;
|
||||
createTitleColumn(
|
||||
options?:
|
||||
| {
|
||||
hidden?: boolean | undefined;
|
||||
}
|
||||
| undefined,
|
||||
): TableColumn<CatalogTableRow>;
|
||||
}>;
|
||||
};
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ export const CatalogTable = (props: CatalogTableProps) => {
|
||||
|
||||
const defaultColumns: TableColumn<CatalogTableRow>[] = useMemo(() => {
|
||||
return [
|
||||
columnFactories.createTitleColumn({ hidden: true }),
|
||||
columnFactories.createNameColumn({ defaultKind: filters.kind?.value }),
|
||||
...createEntitySpecificColumns(),
|
||||
columnFactories.createMetadataDescriptionColumn(),
|
||||
|
||||
@@ -131,4 +131,14 @@ export const columnFactories = Object.freeze({
|
||||
),
|
||||
};
|
||||
},
|
||||
createTitleColumn(options?: {
|
||||
hidden?: boolean;
|
||||
}): TableColumn<CatalogTableRow> {
|
||||
return {
|
||||
title: 'Title',
|
||||
field: 'entity.metadata.title',
|
||||
hidden: options?.hidden,
|
||||
searchable: true,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"@material-ui/core": "^4.9.10",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "^4.0.0-alpha.57",
|
||||
"rc-progress": "3.3.3",
|
||||
"rc-progress": "3.4.0",
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
"express": "^4.17.1",
|
||||
"express-promise-router": "^4.1.0",
|
||||
"jenkins": "^0.28.1",
|
||||
"promise-any-polyfill": "^1.0.1",
|
||||
"winston": "^3.2.1",
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
|
||||
@@ -118,10 +118,9 @@ describe('JenkinsApi', () => {
|
||||
it('standard github layout', async () => {
|
||||
mockedJenkinsClient.job.get.mockResolvedValueOnce(project);
|
||||
|
||||
const result = await jenkinsApi.getProjects(
|
||||
jenkinsInfo,
|
||||
const result = await jenkinsApi.getProjects(jenkinsInfo, [
|
||||
'testBranchName',
|
||||
);
|
||||
]);
|
||||
|
||||
expect(mockedJenkins).toHaveBeenCalledWith({
|
||||
baseUrl: jenkinsInfo.baseUrl,
|
||||
@@ -134,6 +133,35 @@ describe('JenkinsApi', () => {
|
||||
});
|
||||
expect(result).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('supports multiple branches', async () => {
|
||||
mockedJenkinsClient.job.get.mockResolvedValue(project);
|
||||
|
||||
const result = await jenkinsApi.getProjects(jenkinsInfo, [
|
||||
'foo',
|
||||
'bar',
|
||||
'catpants',
|
||||
]);
|
||||
|
||||
expect(mockedJenkins).toHaveBeenCalledWith({
|
||||
baseUrl: jenkinsInfo.baseUrl,
|
||||
headers: jenkinsInfo.headers,
|
||||
promisify: true,
|
||||
});
|
||||
expect(mockedJenkinsClient.job.get).toBeCalledWith({
|
||||
name: `${jenkinsInfo.jobFullName}/foo`,
|
||||
tree: expect.anything(),
|
||||
});
|
||||
expect(mockedJenkinsClient.job.get).toBeCalledWith({
|
||||
name: `${jenkinsInfo.jobFullName}/bar`,
|
||||
tree: expect.anything(),
|
||||
});
|
||||
expect(mockedJenkinsClient.job.get).toBeCalledWith({
|
||||
name: `${jenkinsInfo.jobFullName}/catpants`,
|
||||
tree: expect.anything(),
|
||||
});
|
||||
expect(result).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
describe('augmented', () => {
|
||||
const projectWithScmActions: JenkinsProject = {
|
||||
|
||||
@@ -30,6 +30,12 @@ import {
|
||||
import { jenkinsExecutePermission } from '@backstage/plugin-jenkins-common';
|
||||
import { NotAllowedError } from '@backstage/errors';
|
||||
|
||||
if (!Promise.any) {
|
||||
(async () => {
|
||||
await import('promise-any-polyfill');
|
||||
})();
|
||||
}
|
||||
|
||||
export class JenkinsApiImpl {
|
||||
private static readonly lastBuildTreeSpec = `lastBuild[
|
||||
number,
|
||||
@@ -70,18 +76,21 @@ export class JenkinsApiImpl {
|
||||
* Get a list of projects for the given JenkinsInfo.
|
||||
* @see ../../../jenkins/src/api/JenkinsApi.ts#getProjects
|
||||
*/
|
||||
async getProjects(jenkinsInfo: JenkinsInfo, branch?: string) {
|
||||
async getProjects(jenkinsInfo: JenkinsInfo, branches?: string[]) {
|
||||
const client = await JenkinsApiImpl.getClient(jenkinsInfo);
|
||||
const projects: BackstageProject[] = [];
|
||||
|
||||
if (branch) {
|
||||
// we have been asked to filter to a single branch.
|
||||
if (branches) {
|
||||
// Assume jenkinsInfo.jobFullName is a folder which contains one job per branch.
|
||||
// TODO: extract a strategy interface for this
|
||||
const job = await client.job.get({
|
||||
name: `${jenkinsInfo.jobFullName}/${branch}`,
|
||||
tree: JenkinsApiImpl.jobTreeSpec.replace(/\s/g, ''),
|
||||
});
|
||||
const job = await Promise.any(
|
||||
branches.map(branch =>
|
||||
client.job.get({
|
||||
name: `${jenkinsInfo.jobFullName}/${branch}`,
|
||||
tree: JenkinsApiImpl.jobTreeSpec.replace(/\s/g, ''),
|
||||
}),
|
||||
),
|
||||
);
|
||||
projects.push(this.augmentProject(job));
|
||||
} else {
|
||||
// We aren't filtering
|
||||
|
||||
@@ -64,12 +64,12 @@ export async function createRouter(
|
||||
request.header('authorization'),
|
||||
);
|
||||
const branch = request.query.branch;
|
||||
let branchStr: string | undefined;
|
||||
let branches: string[] | undefined;
|
||||
|
||||
if (branch === undefined) {
|
||||
branchStr = undefined;
|
||||
branches = undefined;
|
||||
} else if (typeof branch === 'string') {
|
||||
branchStr = branch;
|
||||
branches = branch.split(/,/g);
|
||||
} else {
|
||||
// this was passed in as something weird -> 400
|
||||
// https://evanhahn.com/gotchas-with-express-query-parsing-and-how-to-avoid-them/
|
||||
@@ -88,7 +88,7 @@ export async function createRouter(
|
||||
},
|
||||
backstageToken: token,
|
||||
});
|
||||
const projects = await jenkinsApi.getProjects(jenkinsInfo, branchStr);
|
||||
const projects = await jenkinsApi.getProjects(jenkinsInfo, branches);
|
||||
|
||||
response.json({
|
||||
projects: projects,
|
||||
|
||||
@@ -19,7 +19,7 @@ yarn add --cwd packages/app @backstage/plugin-jenkins
|
||||
|
||||
3. Add the `EntityJenkinsContent` extension to the `CI/CD` page and `EntityLatestJenkinsRunCard` to the `overview` page in the app (or wherever you'd prefer):
|
||||
|
||||
Note that if you configured a custom JenkinsInfoProvider in step 2, you may need a custom isJenkinsAvailable.
|
||||
Note that if you configured a custom JenkinsInfoProvider in step 2, you may need a custom isJenkinsAvailable. Also if you're transitioning to a new default branch name, you can pass multiple branch names as a comma-separated list and it will check for each branch name.
|
||||
|
||||
```tsx
|
||||
// In packages/app/src/components/catalog/EntityPage.tsx
|
||||
@@ -38,7 +38,10 @@ const serviceEntityPage = (
|
||||
<EntitySwitch>
|
||||
<EntitySwitch.Case if={isJenkinsAvailable}>
|
||||
<Grid item sm={6}>
|
||||
<EntityLatestJenkinsRunCard branch="master" variant="gridItem" />
|
||||
<EntityLatestJenkinsRunCard
|
||||
branch="main,master"
|
||||
variant="gridItem"
|
||||
/>
|
||||
</Grid>
|
||||
</EntitySwitch.Case>
|
||||
{/* ... */}
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"@material-ui/styles": "^4.10.0",
|
||||
"cross-fetch": "^3.1.5",
|
||||
"rc-progress": "3.3.3",
|
||||
"rc-progress": "3.4.0",
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -11,6 +11,7 @@ import { FactCheckerFactory } from '@backstage/plugin-tech-insights-node';
|
||||
import { FactLifecycle } from '@backstage/plugin-tech-insights-node';
|
||||
import { FactRetriever } from '@backstage/plugin-tech-insights-node';
|
||||
import { FactRetrieverRegistration } from '@backstage/plugin-tech-insights-node';
|
||||
import { FactSchema } from '@backstage/plugin-tech-insights-node';
|
||||
import { Logger } from 'winston';
|
||||
import { PluginDatabaseManager } from '@backstage/backend-common';
|
||||
import { PluginEndpointDiscovery } from '@backstage/backend-common';
|
||||
@@ -51,6 +52,22 @@ export type FactRetrieverRegistrationOptions = {
|
||||
lifecycle?: FactLifecycle;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export interface FactRetrieverRegistry {
|
||||
// (undocumented)
|
||||
get(retrieverReference: string): FactRetrieverRegistration;
|
||||
// (undocumented)
|
||||
getSchemas(): FactSchema[];
|
||||
// (undocumented)
|
||||
listRegistrations(): FactRetrieverRegistration[];
|
||||
// (undocumented)
|
||||
listRetrievers(): FactRetriever[];
|
||||
// (undocumented)
|
||||
register(registration: FactRetrieverRegistration): void;
|
||||
// (undocumented)
|
||||
readonly retrievers: Map<string, FactRetrieverRegistration>;
|
||||
}
|
||||
|
||||
// @public
|
||||
export type PersistenceContext = {
|
||||
techInsightsStore: TechInsightsStore;
|
||||
@@ -91,7 +108,8 @@ export interface TechInsightsOptions<
|
||||
// (undocumented)
|
||||
discovery: PluginEndpointDiscovery;
|
||||
factCheckerFactory?: FactCheckerFactory<CheckType, CheckResultType>;
|
||||
factRetrievers: FactRetrieverRegistration[];
|
||||
factRetrieverRegistry?: FactRetrieverRegistry;
|
||||
factRetrievers?: FactRetrieverRegistration[];
|
||||
// (undocumented)
|
||||
logger: Logger;
|
||||
// (undocumented)
|
||||
|
||||
@@ -25,5 +25,6 @@ export type {
|
||||
|
||||
export type { PersistenceContext } from './service/persistence/persistenceContext';
|
||||
export { createFactRetrieverRegistration } from './service/fact/createFactRetriever';
|
||||
export type { FactRetrieverRegistry } from './service/fact/FactRetrieverRegistry';
|
||||
export type { FactRetrieverRegistrationOptions } from './service/fact/createFactRetriever';
|
||||
export * from './service/fact/factRetrievers';
|
||||
|
||||
@@ -21,8 +21,21 @@ import {
|
||||
} from '@backstage/plugin-tech-insights-node';
|
||||
import { ConflictError, NotFoundError } from '@backstage/errors';
|
||||
|
||||
export class FactRetrieverRegistry {
|
||||
private readonly retrievers = new Map<string, FactRetrieverRegistration>();
|
||||
/**
|
||||
* @public
|
||||
*
|
||||
*/
|
||||
export interface FactRetrieverRegistry {
|
||||
readonly retrievers: Map<string, FactRetrieverRegistration>;
|
||||
register(registration: FactRetrieverRegistration): void;
|
||||
get(retrieverReference: string): FactRetrieverRegistration;
|
||||
listRetrievers(): FactRetriever[];
|
||||
listRegistrations(): FactRetrieverRegistration[];
|
||||
getSchemas(): FactSchema[];
|
||||
}
|
||||
|
||||
export class DefaultFactRetrieverRegistry implements FactRetrieverRegistry {
|
||||
readonly retrievers = new Map<string, FactRetrieverRegistration>();
|
||||
|
||||
constructor(retrievers: FactRetrieverRegistration[]) {
|
||||
retrievers.forEach(it => {
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { buildTechInsightsContext } from './techInsightsContextBuilder';
|
||||
import {
|
||||
DatabaseManager,
|
||||
getVoidLogger,
|
||||
PluginDatabaseManager,
|
||||
ServerTokenManager,
|
||||
} from '@backstage/backend-common';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { TaskScheduler } from '@backstage/backend-tasks';
|
||||
import { DefaultFactRetrieverRegistry } from './fact/FactRetrieverRegistry';
|
||||
import { Knex } from 'knex';
|
||||
|
||||
jest.mock('./fact/FactRetrieverRegistry');
|
||||
jest.mock('./fact/FactRetrieverEngine', () => ({
|
||||
FactRetrieverEngine: {
|
||||
create: jest.fn().mockResolvedValue({
|
||||
schedule: jest.fn(),
|
||||
}),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('buildTechInsightsContext', () => {
|
||||
const pluginDatabase: PluginDatabaseManager = {
|
||||
getClient: () => {
|
||||
return Promise.resolve({
|
||||
migrate: {
|
||||
latest: () => {},
|
||||
},
|
||||
}) as unknown as Promise<Knex>;
|
||||
},
|
||||
};
|
||||
const databaseManager: Partial<DatabaseManager> = {
|
||||
forPlugin: () => pluginDatabase,
|
||||
};
|
||||
const manager = databaseManager as DatabaseManager;
|
||||
const discoveryMock = {
|
||||
getBaseUrl: (_: string) => Promise.resolve('http://mock.url'),
|
||||
getExternalBaseUrl: (_: string) => Promise.resolve('http://mock.url'),
|
||||
};
|
||||
const scheduler = new TaskScheduler(manager, getVoidLogger()).forPlugin(
|
||||
'tech-insights',
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('constructs the default FactRetrieverRegistry if factRetrievers but no factRetrieverRegistry are passed', () => {
|
||||
buildTechInsightsContext({
|
||||
database: pluginDatabase,
|
||||
logger: getVoidLogger(),
|
||||
factRetrievers: [],
|
||||
scheduler: scheduler,
|
||||
config: ConfigReader.fromConfigs([]),
|
||||
discovery: discoveryMock,
|
||||
tokenManager: ServerTokenManager.noop(),
|
||||
});
|
||||
expect(DefaultFactRetrieverRegistry).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('uses factRetrieverRegistry implementation instead of the default FactRetrieverRegistry if it is passed in', () => {
|
||||
const factRetrieverRegistryMock = {} as DefaultFactRetrieverRegistry;
|
||||
|
||||
buildTechInsightsContext({
|
||||
database: pluginDatabase,
|
||||
logger: getVoidLogger(),
|
||||
factRetrievers: [],
|
||||
factRetrieverRegistry: factRetrieverRegistryMock,
|
||||
scheduler: scheduler,
|
||||
config: ConfigReader.fromConfigs([]),
|
||||
discovery: discoveryMock,
|
||||
tokenManager: ServerTokenManager.noop(),
|
||||
});
|
||||
expect(DefaultFactRetrieverRegistry).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -16,7 +16,10 @@
|
||||
|
||||
import { FactRetrieverEngine } from './fact/FactRetrieverEngine';
|
||||
import { Logger } from 'winston';
|
||||
import { FactRetrieverRegistry } from './fact/FactRetrieverRegistry';
|
||||
import {
|
||||
DefaultFactRetrieverRegistry,
|
||||
FactRetrieverRegistry,
|
||||
} from './fact/FactRetrieverRegistry';
|
||||
import { Config } from '@backstage/config';
|
||||
import {
|
||||
PluginDatabaseManager,
|
||||
@@ -49,16 +52,25 @@ export interface TechInsightsOptions<
|
||||
CheckResultType extends CheckResult,
|
||||
> {
|
||||
/**
|
||||
* A collection of FactRetrieverRegistrations.
|
||||
* Optional collection of FactRetrieverRegistrations (required if no factRetrieverRegistry passed in).
|
||||
* Used to register FactRetrievers and their schemas and schedule an execution loop for them.
|
||||
*
|
||||
* Not needed if passing in your own FactRetrieverRegistry implementation. Required otherwise.
|
||||
*/
|
||||
factRetrievers: FactRetrieverRegistration[];
|
||||
factRetrievers?: FactRetrieverRegistration[];
|
||||
|
||||
/**
|
||||
* Optional factory exposing a `construct` method to initialize a FactChecker implementation
|
||||
*/
|
||||
factCheckerFactory?: FactCheckerFactory<CheckType, CheckResultType>;
|
||||
|
||||
/**
|
||||
* Optional FactRetrieverRegistry implementation that replaces the default one.
|
||||
*
|
||||
* If passing this in you don't need to pass in factRetrievers also.
|
||||
*/
|
||||
factRetrieverRegistry?: FactRetrieverRegistry;
|
||||
|
||||
logger: Logger;
|
||||
config: Config;
|
||||
discovery: PluginEndpointDiscovery;
|
||||
@@ -109,7 +121,19 @@ export const buildTechInsightsContext = async <
|
||||
tokenManager,
|
||||
} = options;
|
||||
|
||||
const factRetrieverRegistry = new FactRetrieverRegistry(factRetrievers);
|
||||
const buildFactRetrieverRegistry = (): FactRetrieverRegistry => {
|
||||
if (!options.factRetrieverRegistry) {
|
||||
if (!factRetrievers) {
|
||||
throw new Error(
|
||||
'Failed to build FactRetrieverRegistry because no factRetrievers found',
|
||||
);
|
||||
}
|
||||
return new DefaultFactRetrieverRegistry(factRetrievers);
|
||||
}
|
||||
return options.factRetrieverRegistry;
|
||||
};
|
||||
|
||||
const factRetrieverRegistry = buildFactRetrieverRegistry();
|
||||
|
||||
const persistenceContext = await initializePersistenceContext(
|
||||
await database.getClient(),
|
||||
|
||||
@@ -2348,10 +2348,10 @@
|
||||
teeny-request "^8.0.0"
|
||||
uuid "^8.0.0"
|
||||
|
||||
"@graphiql/react@^0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.npmjs.org/@graphiql/react/-/react-0.4.2.tgz#2a12c7cf0f3945022c2231ce4e814561f2363ef7"
|
||||
integrity sha512-Df2BaA0HGRkzETCaUw4ZSDe///sfIAGZ6H436A08hmg7SU3yoWJboWGWGc/QD2NyBKVgVBMmzmHcgWhsYh03EA==
|
||||
"@graphiql/react@^0.4.3":
|
||||
version "0.4.3"
|
||||
resolved "https://registry.npmjs.org/@graphiql/react/-/react-0.4.3.tgz#29ca3125c7a349de5e9beb2aef660137fbcbde2e"
|
||||
integrity sha512-MnH+7LqRqFnwo8YBDtgDfJOdeS5QqNTzH2gTvTbEYYWaNQW1+Vhbsyu2RKHnPSgKVQlfLzdjw6SAMtSb3q1Qog==
|
||||
dependencies:
|
||||
"@graphiql/toolkit" "^0.6.0"
|
||||
codemirror "^5.65.3"
|
||||
@@ -5263,9 +5263,9 @@
|
||||
"@react-hookz/deep-equal" "^1.0.1"
|
||||
|
||||
"@react-hookz/web@^14.0.0":
|
||||
version "14.4.0"
|
||||
resolved "https://registry.npmjs.org/@react-hookz/web/-/web-14.4.0.tgz#8c5003d2ee243e4f628ca7f69a6975a4c1a84713"
|
||||
integrity sha512-MZUeiC/xCg30yBVfV3LS4gtQUngVb/r0xhaeGKk+Bx5ZaJOhHQ8kuduXP13RmbzpehJk2e1TL0oZsTofzT7QJQ==
|
||||
version "14.6.0"
|
||||
resolved "https://registry.npmjs.org/@react-hookz/web/-/web-14.6.0.tgz#8b3824841ee679b23516aa9b316e819e55590a1c"
|
||||
integrity sha512-4ZQU4wsNd4QsMe4LkF9t1y4NS2cCp1N/JfG9TYw1dsWLOJhZ0w+4ebp7cydN5BLeceIaILcfQ7fBYUvrBJN6EA==
|
||||
dependencies:
|
||||
"@react-hookz/deep-equal" "^1.0.2"
|
||||
|
||||
@@ -6787,7 +6787,7 @@
|
||||
resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
|
||||
integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
|
||||
|
||||
"@types/react-dom@*", "@types/react-dom@<18.0.0", "@types/react-dom@^17":
|
||||
"@types/react-dom@*", "@types/react-dom@<18.0.0":
|
||||
version "17.0.17"
|
||||
resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.17.tgz#2e3743277a793a96a99f1bf87614598289da68a1"
|
||||
integrity sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg==
|
||||
@@ -7245,13 +7245,13 @@
|
||||
integrity sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^5.9.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.29.0.tgz#c67794d2b0fd0b4a47f50266088acdc52a08aab6"
|
||||
integrity sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==
|
||||
version "5.30.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.0.tgz#524a11e15c09701733033c96943ecf33f55d9ca1"
|
||||
integrity sha512-lvhRJ2pGe2V9MEU46ELTdiHgiAFZPKtLhiU5wlnaYpMc2+c1R8fh8i80ZAa665drvjHKUJyRRGg3gEm1If54ow==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "5.29.0"
|
||||
"@typescript-eslint/type-utils" "5.29.0"
|
||||
"@typescript-eslint/utils" "5.29.0"
|
||||
"@typescript-eslint/scope-manager" "5.30.0"
|
||||
"@typescript-eslint/type-utils" "5.30.0"
|
||||
"@typescript-eslint/utils" "5.30.0"
|
||||
debug "^4.3.4"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
ignore "^5.2.0"
|
||||
@@ -7272,13 +7272,13 @@
|
||||
eslint-utils "^3.0.0"
|
||||
|
||||
"@typescript-eslint/parser@^5.9.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.29.0.tgz#41314b195b34d44ff38220caa55f3f93cfca43cf"
|
||||
integrity sha512-ruKWTv+x0OOxbzIw9nW5oWlUopvP/IQDjB5ZqmTglLIoDTctLlAJpAQFpNPJP/ZI7hTT9sARBosEfaKbcFuECw==
|
||||
version "5.30.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.0.tgz#a2184fb5f8ef2bf1db0ae61a43907e2e32aa1b8f"
|
||||
integrity sha512-2oYYUws5o2liX6SrFQ5RB88+PuRymaM2EU02/9Ppoyu70vllPnHVO7ioxDdq/ypXHA277R04SVjxvwI8HmZpzA==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "5.29.0"
|
||||
"@typescript-eslint/types" "5.29.0"
|
||||
"@typescript-eslint/typescript-estree" "5.29.0"
|
||||
"@typescript-eslint/scope-manager" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/typescript-estree" "5.30.0"
|
||||
debug "^4.3.4"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.20.0":
|
||||
@@ -7289,13 +7289,13 @@
|
||||
"@typescript-eslint/types" "5.20.0"
|
||||
"@typescript-eslint/visitor-keys" "5.20.0"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.29.0.tgz#2a6a32e3416cb133e9af8dcf54bf077a916aeed3"
|
||||
integrity sha512-etbXUT0FygFi2ihcxDZjz21LtC+Eps9V2xVx09zFoN44RRHPrkMflidGMI+2dUs821zR1tDS6Oc9IXxIjOUZwA==
|
||||
"@typescript-eslint/scope-manager@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.0.tgz#bf585ee801ab4ad84db2f840174e171a6bb002c7"
|
||||
integrity sha512-3TZxvlQcK5fhTBw5solQucWSJvonXf5yua5nx8OqK94hxdrT7/6W3/CS42MLd/f1BmlmmbGEgQcTHHCktUX5bQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.29.0"
|
||||
"@typescript-eslint/visitor-keys" "5.29.0"
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/visitor-keys" "5.30.0"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.9.0":
|
||||
version "5.9.0"
|
||||
@@ -7305,12 +7305,12 @@
|
||||
"@typescript-eslint/types" "5.9.0"
|
||||
"@typescript-eslint/visitor-keys" "5.9.0"
|
||||
|
||||
"@typescript-eslint/type-utils@5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.29.0.tgz#241918001d164044020b37d26d5b9f4e37cc3d5d"
|
||||
integrity sha512-JK6bAaaiJozbox3K220VRfCzLa9n0ib/J+FHIwnaV3Enw/TO267qe0pM1b1QrrEuy6xun374XEAsRlA86JJnyg==
|
||||
"@typescript-eslint/type-utils@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.30.0.tgz#98f3af926a5099153f092d4dad87148df21fbaae"
|
||||
integrity sha512-GF8JZbZqSS+azehzlv/lmQQ3EU3VfWYzCczdZjJRxSEeXDQkqFhCBgFhallLDbPwQOEQ4MHpiPfkjKk7zlmeNg==
|
||||
dependencies:
|
||||
"@typescript-eslint/utils" "5.29.0"
|
||||
"@typescript-eslint/utils" "5.30.0"
|
||||
debug "^4.3.4"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
@@ -7319,10 +7319,10 @@
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.20.0.tgz#fa39c3c2aa786568302318f1cb51fcf64258c20c"
|
||||
integrity sha512-+d8wprF9GyvPwtoB4CxBAR/s0rpP25XKgnOvMf/gMXYDvlUC3rPFHupdTQ/ow9vn7UDe5rX02ovGYQbv/IUCbg==
|
||||
|
||||
"@typescript-eslint/types@5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.29.0.tgz#7861d3d288c031703b2d97bc113696b4d8c19aab"
|
||||
integrity sha512-X99VbqvAXOMdVyfFmksMy3u8p8yoRGITgU1joBJPzeYa0rhdf5ok9S56/itRoUSh99fiDoMtarSIJXo7H/SnOg==
|
||||
"@typescript-eslint/types@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.0.tgz#db7d81d585a3da3801432a9c1d2fafbff125e110"
|
||||
integrity sha512-vfqcBrsRNWw/LBXyncMF/KrUTYYzzygCSsVqlZ1qGu1QtGs6vMkt3US0VNSQ05grXi5Yadp3qv5XZdYLjpp8ag==
|
||||
|
||||
"@typescript-eslint/types@5.9.0":
|
||||
version "5.9.0"
|
||||
@@ -7342,13 +7342,13 @@
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.29.0.tgz#e83d19aa7fd2e74616aab2f25dfbe4de4f0b5577"
|
||||
integrity sha512-mQvSUJ/JjGBdvo+1LwC+GY2XmSYjK1nAaVw2emp/E61wEVYEyibRHCqm1I1vEKbXCpUKuW4G7u9ZCaZhJbLoNQ==
|
||||
"@typescript-eslint/typescript-estree@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.0.tgz#4565ee8a6d2ac368996e20b2344ea0eab1a8f0bb"
|
||||
integrity sha512-hDEawogreZB4n1zoqcrrtg/wPyyiCxmhPLpZ6kmWfKF5M5G0clRLaEexpuWr31fZ42F96SlD/5xCt1bT5Qm4Nw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.29.0"
|
||||
"@typescript-eslint/visitor-keys" "5.29.0"
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/visitor-keys" "5.30.0"
|
||||
debug "^4.3.4"
|
||||
globby "^11.1.0"
|
||||
is-glob "^4.0.3"
|
||||
@@ -7368,15 +7368,15 @@
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/utils@5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.29.0.tgz#775046effd5019667bd086bcf326acbe32cd0082"
|
||||
integrity sha512-3Eos6uP1nyLOBayc/VUdKZikV90HahXE5Dx9L5YlSd/7ylQPXhLk1BYb29SDgnBnTp+jmSZUU0QxUiyHgW4p7A==
|
||||
"@typescript-eslint/utils@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.30.0.tgz#1dac771fead5eab40d31860716de219356f5f754"
|
||||
integrity sha512-0bIgOgZflLKIcZsWvfklsaQTM3ZUbmtH0rJ1hKyV3raoUYyeZwcjQ8ZUJTzS7KnhNcsVT1Rxs7zeeMHEhGlltw==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.9"
|
||||
"@typescript-eslint/scope-manager" "5.29.0"
|
||||
"@typescript-eslint/types" "5.29.0"
|
||||
"@typescript-eslint/typescript-estree" "5.29.0"
|
||||
"@typescript-eslint/scope-manager" "5.30.0"
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
"@typescript-eslint/typescript-estree" "5.30.0"
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
|
||||
@@ -7400,12 +7400,12 @@
|
||||
"@typescript-eslint/types" "5.20.0"
|
||||
eslint-visitor-keys "^3.0.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.29.0.tgz#7a4749fa7ef5160c44a451bf060ac1dc6dfb77ee"
|
||||
integrity sha512-Hpb/mCWsjILvikMQoZIE3voc9wtQcS0A9FUw3h8bhr9UxBdtI/tw1ZDZUOXHXLOVMedKCH5NxyzATwnU78bWCQ==
|
||||
"@typescript-eslint/visitor-keys@5.30.0":
|
||||
version "5.30.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.0.tgz#07721d23daca2ec4c2da7f1e660d41cd78bacac3"
|
||||
integrity sha512-6WcIeRk2DQ3pHKxU1Ni0qMXJkjO/zLjBymlYBy/53qxe7yjEFSvzKLDToJjURUhSl2Fzhkl4SMXQoETauF74cw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.29.0"
|
||||
"@typescript-eslint/types" "5.30.0"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.9.0":
|
||||
@@ -13997,9 +13997,9 @@ google-auth-library@^7.14.0:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
google-auth-library@^8.0.0, google-auth-library@^8.0.1, google-auth-library@^8.0.2:
|
||||
version "8.0.3"
|
||||
resolved "https://registry.npmjs.org/google-auth-library/-/google-auth-library-8.0.3.tgz#1e780430632d03df36dc22a3f5c89dbc251f2105"
|
||||
integrity sha512-1eC6yaCrPfkv3bwtb3e0AOct7E7xR/uikDyXNo/j8Wd6a1ldRgAey5FmaDGNJnHNDPLtDiENQLYsA69eXOF5sA==
|
||||
version "8.1.0"
|
||||
resolved "https://registry.npmjs.org/google-auth-library/-/google-auth-library-8.1.0.tgz#879e8d2e90a9d47e6eab32fd1d5fd9ed52d7d441"
|
||||
integrity sha512-J/fNXEnqLgbr3kmeUshZCtHQia6ZiNbbrebVzpt/+LTeY6Ka9CtbQvloTjVGVO7nyYbs0KYeuIwgUC/t2Gp1Jw==
|
||||
dependencies:
|
||||
arrify "^2.0.0"
|
||||
base64-js "^1.3.0"
|
||||
@@ -14135,11 +14135,11 @@ grapheme-splitter@^1.0.4:
|
||||
integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
|
||||
|
||||
graphiql@^1.5.12, graphiql@^1.8.8:
|
||||
version "1.9.9"
|
||||
resolved "https://registry.npmjs.org/graphiql/-/graphiql-1.9.9.tgz#dfc1760e7552140247e591e3c66d1ccc389ea71f"
|
||||
integrity sha512-eJ5kGpXFXw69QG/1SJrQs/mzGpDIv4XeGqohGSKQCOh7NtsAsQIxs/VMVR8Lvv9tx6YiIFUvAHp997NlyOwHbQ==
|
||||
version "1.9.10"
|
||||
resolved "https://registry.npmjs.org/graphiql/-/graphiql-1.9.10.tgz#ba7113ed8b1bc988d00d8d7cc51901b51b684bde"
|
||||
integrity sha512-uYYK/zBTV9Y/IHw4uopGVRusbF2xmPnptx7OMFTnTHOTQOmzfIGRTn58WuPgevyEi+9zSLojM86lot9xvNA1/w==
|
||||
dependencies:
|
||||
"@graphiql/react" "^0.4.2"
|
||||
"@graphiql/react" "^0.4.3"
|
||||
"@graphiql/toolkit" "^0.6.0"
|
||||
entities "^2.0.0"
|
||||
graphql-language-service "^5.0.6"
|
||||
@@ -21223,6 +21223,11 @@ promise-all-reject-late@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz#f8ebf13483e5ca91ad809ccc2fcf25f26f8643c2"
|
||||
integrity sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==
|
||||
|
||||
promise-any-polyfill@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/promise-any-polyfill/-/promise-any-polyfill-1.0.1.tgz#563872dd0abd370bfa8039e63980469b4b8b0d53"
|
||||
integrity sha512-51Tj+hOoV3LOeCHItmWBklN9FYkyV53uIIjjzgIchitGneTvl6+ivOxWXhxraeUzzS3YFRpXRPPbv7+KD3NzYQ==
|
||||
|
||||
promise-call-limit@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/promise-call-limit/-/promise-call-limit-1.0.1.tgz#4bdee03aeb85674385ca934da7114e9bcd3c6e24"
|
||||
@@ -21604,6 +21609,15 @@ rc-progress@3.3.3:
|
||||
classnames "^2.2.6"
|
||||
rc-util "^5.16.1"
|
||||
|
||||
rc-progress@3.4.0:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.npmjs.org/rc-progress/-/rc-progress-3.4.0.tgz#80a33c25c9675f5836ba25a87cd8dc310aad72b1"
|
||||
integrity sha512-ZuMyOzzTkZnn+EKqGQ7YHzrvGzBtcCCVjx1McC/E/pMTvr6GWVfVRSawDlWsscxsJs7MkqSTwCO6Lu4IeoY2zQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "^2.2.6"
|
||||
rc-util "^5.16.1"
|
||||
|
||||
rc-util@^5.16.1:
|
||||
version "5.16.1"
|
||||
resolved "https://registry.npmjs.org/rc-util/-/rc-util-5.16.1.tgz#374db7cb735512f05165ddc3d6b2c61c21b8b4e3"
|
||||
@@ -24611,9 +24625,9 @@ test-exclude@^6.0.0:
|
||||
minimatch "^3.0.4"
|
||||
|
||||
testcontainers@^8.1.2:
|
||||
version "8.10.1"
|
||||
resolved "https://registry.npmjs.org/testcontainers/-/testcontainers-8.10.1.tgz#2b3d1d25932f437ba4c46a1f32380ce7987629f8"
|
||||
integrity sha512-MQFoWe6sJrbcZqXb+fM7uN2w9WnV2KZnNyI7Qc9pbxQZS6oLa/or5kgL4DADAuzYFxXJvL3f8inIGI+/1S+rvA==
|
||||
version "8.11.0"
|
||||
resolved "https://registry.npmjs.org/testcontainers/-/testcontainers-8.11.0.tgz#f19307557289b7e80c7e1d65b39ab0054a2b2549"
|
||||
integrity sha512-sc9FA40waYXKVTp/Dm9qmcc8I5/TLyZd+JxtnYjIQDp1UvLzAckQPjSlGCDTdM00J2X4KDwG0+jY+8WprZbpnQ==
|
||||
dependencies:
|
||||
"@balena/dockerignore" "^1.0.2"
|
||||
"@types/archiver" "^5.3.1"
|
||||
@@ -26165,9 +26179,9 @@ winston-transport@^4.5.0:
|
||||
triple-beam "^1.3.0"
|
||||
|
||||
winston@^3.2.1, winston@^3.7.2:
|
||||
version "3.7.2"
|
||||
resolved "https://registry.npmjs.org/winston/-/winston-3.7.2.tgz#95b4eeddbec902b3db1424932ac634f887c400b1"
|
||||
integrity sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng==
|
||||
version "3.8.0"
|
||||
resolved "https://registry.npmjs.org/winston/-/winston-3.8.0.tgz#4fc8656829dcfdab3c38f558eab785eea38a5328"
|
||||
integrity sha512-Iix1w8rIq2kBDkGvclO0db2CVOHYVamCIkVWcUbs567G9i2pdB+gvqLgDgxx4B4HXHYD6U4Zybh6ojepUOqcFQ==
|
||||
dependencies:
|
||||
"@dabh/diagnostics" "^2.0.2"
|
||||
async "^3.2.3"
|
||||
@@ -26299,7 +26313,7 @@ ws@^7.3.1, ws@^7.4.6:
|
||||
resolved "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67"
|
||||
integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==
|
||||
|
||||
ws@^8.0.0, ws@^8.3.0:
|
||||
ws@^8.3.0:
|
||||
version "8.8.0"
|
||||
resolved "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz#8e71c75e2f6348dbf8d78005107297056cb77769"
|
||||
integrity sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==
|
||||
|
||||
Reference in New Issue
Block a user