Merge branch 'master' of https://github.com/backstage/backstage into feat/reference-external-docs
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-adr-backend
|
||||
title: '@backstage/plugin-adr-backend'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: kuangp
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-adr-common
|
||||
title: '@backstage/plugin-adr-common'
|
||||
description: Common functionalities for the adr plugin
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-common-library
|
||||
owner: kuangp
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-adr
|
||||
title: '@backstage/plugin-adr'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: kuangp
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-airbrake-backend
|
||||
title: '@backstage/plugin-airbrake-backend'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-airbrake
|
||||
title: '@backstage/plugin-airbrake'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-allure
|
||||
title: '@backstage/plugin-allure'
|
||||
description: A Backstage plugin that integrates with Allure
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-analytics-module-ga
|
||||
title: '@backstage/plugin-analytics-module-ga'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin-module
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-analytics-module-ga4
|
||||
title: '@backstage/plugin-analytics-module-ga4'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin-module
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-analytics-module-newrelic-browser
|
||||
title: '@backstage/plugin-analytics-module-newrelic-browser'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin-module
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-apache-airflow
|
||||
title: '@backstage/plugin-apache-airflow'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-api-docs-module-protoc-gen-doc
|
||||
title: '@backstage/plugin-api-docs-module-protoc-gen-doc'
|
||||
description: >-
|
||||
Additional functionalities for the api-docs plugin that renders the output
|
||||
of the protoc-gen-doc
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin-module
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-api-docs
|
||||
title: '@backstage/plugin-api-docs'
|
||||
description: A Backstage plugin that helps represent API entities in the frontend
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: sda-se-reviewers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-apollo-explorer
|
||||
title: '@backstage/plugin-apollo-explorer'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-app-backend
|
||||
title: '@backstage/plugin-app-backend'
|
||||
description: A Backstage backend plugin that serves the Backstage frontend app
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-app-node
|
||||
title: '@backstage/plugin-app-node'
|
||||
description: Node.js library for the app plugin
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-node-library
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-auth-backend-module-gcp-iap-provider
|
||||
title: '@backstage/plugin-auth-backend-module-gcp-iap-provider'
|
||||
description: A GCP IAP auth provider module for the Backstage auth backend
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-auth-backend-module-github-provider
|
||||
title: '@backstage/plugin-auth-backend-module-github-provider'
|
||||
description: The github-provider backend module for the auth plugin.
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-auth-backend-module-gitlab-provider
|
||||
title: '@backstage/plugin-auth-backend-module-gitlab-provider'
|
||||
description: The gitlab-provider backend module for the auth plugin.
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-auth-backend-module-google-provider
|
||||
title: '@backstage/plugin-auth-backend-module-google-provider'
|
||||
description: A Google auth provider module for the Backstage auth backend
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-auth-backend
|
||||
title: '@backstage/plugin-auth-backend'
|
||||
description: A Backstage backend plugin that handles authentication
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: maintainers
|
||||
@@ -47,6 +47,7 @@
|
||||
"@backstage/types": "workspace:^",
|
||||
"@davidzemon/passport-okta-oauth": "^0.0.5",
|
||||
"@google-cloud/firestore": "^6.0.0",
|
||||
"@node-saml/passport-saml": "^4.0.4",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/passport": "^1.0.3",
|
||||
"compression": "^1.7.4",
|
||||
@@ -77,7 +78,6 @@
|
||||
"passport-microsoft": "^1.0.0",
|
||||
"passport-oauth2": "^1.6.1",
|
||||
"passport-onelogin-oauth": "^0.0.1",
|
||||
"passport-saml": "^3.1.2",
|
||||
"uuid": "^8.0.0",
|
||||
"winston": "^3.2.1",
|
||||
"yn": "^4.0.0"
|
||||
|
||||
@@ -15,16 +15,16 @@
|
||||
*/
|
||||
|
||||
import express from 'express';
|
||||
import { SamlConfig } from 'passport-saml/lib/passport-saml/types';
|
||||
import { SamlConfig } from '@node-saml/passport-saml';
|
||||
import {
|
||||
Strategy as SamlStrategy,
|
||||
Profile as SamlProfile,
|
||||
Strategy as SamlStrategy,
|
||||
VerifiedCallback,
|
||||
VerifyWithoutRequest,
|
||||
} from 'passport-saml';
|
||||
} from '@node-saml/passport-saml';
|
||||
import {
|
||||
executeFrameHandlerStrategy,
|
||||
executeRedirectStrategy,
|
||||
PassportDoneCallback,
|
||||
} from '../../lib/passport';
|
||||
import {
|
||||
AuthProviderRouteHandlers,
|
||||
@@ -62,17 +62,18 @@ export class SamlAuthProvider implements AuthProviderRouteHandlers {
|
||||
this.signInResolver = options.signInResolver;
|
||||
this.authHandler = options.authHandler;
|
||||
this.resolverContext = options.resolverContext;
|
||||
this.strategy = new SamlStrategy({ ...options }, ((
|
||||
fullProfile: SamlProfile,
|
||||
done: PassportDoneCallback<SamlAuthResult>,
|
||||
const verifier: VerifyWithoutRequest = (
|
||||
profile: SamlProfile | null,
|
||||
done: VerifiedCallback,
|
||||
) => {
|
||||
// TODO: There's plenty more validation and profile handling to do here,
|
||||
// this provider is currently only intended to validate the provider pattern
|
||||
// for non-oauth auth flows.
|
||||
// TODO: This flow doesn't issue an identity token that can be used to validate
|
||||
// the identity of the user in other backends, which we need in some form.
|
||||
done(undefined, { fullProfile });
|
||||
}) as VerifyWithoutRequest);
|
||||
done(null, { fullProfile: profile });
|
||||
};
|
||||
this.strategy = new SamlStrategy(options, verifier, verifier);
|
||||
}
|
||||
|
||||
async start(req: express.Request, res: express.Response): Promise<void> {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-auth-node
|
||||
title: '@backstage/plugin-auth-node'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-node-library
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-azure-devops-backend
|
||||
title: '@backstage/plugin-azure-devops-backend'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: awanlin
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-azure-devops-common
|
||||
title: '@backstage/plugin-azure-devops-common'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-common-library
|
||||
owner: awanlin
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-azure-devops
|
||||
title: '@backstage/plugin-azure-devops'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: awanlin
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-azure-sites-backend
|
||||
title: '@backstage/plugin-azure-sites-backend'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-azure-sites-common
|
||||
title: '@backstage/plugin-azure-sites-common'
|
||||
description: Common functionalities for the azure plugin
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-common-library
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-azure-sites
|
||||
title: '@backstage/plugin-azure-sites'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-badges-backend
|
||||
title: '@backstage/plugin-badges-backend'
|
||||
description: A Backstage backend plugin that generates README badges for your entities
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-badges
|
||||
title: '@backstage/plugin-badges'
|
||||
description: A Backstage plugin that generates README badges for your entities
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-bazaar-backend
|
||||
title: '@backstage/plugin-bazaar-backend'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-bazaar
|
||||
title: '@backstage/plugin-bazaar'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-bitbucket-cloud-common
|
||||
title: '@backstage/plugin-bitbucket-cloud-common'
|
||||
description: Common functionalities for bitbucket-cloud plugins
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-common-library
|
||||
owner: pjungermann
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-bitrise
|
||||
title: '@backstage/plugin-bitrise'
|
||||
description: A Backstage plugin that integrates towards Bitrise
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: sda-se-reviewers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-catalog-backend-module-aws
|
||||
title: '@backstage/plugin-catalog-backend-module-aws'
|
||||
description: A Backstage catalog backend module that helps integrate towards AWS
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: pjungermann
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-catalog-backend-module-bitbucket-cloud
|
||||
title: '@backstage/plugin-catalog-backend-module-bitbucket-cloud'
|
||||
description: >-
|
||||
A Backstage catalog backend module that helps integrate towards Bitbucket
|
||||
Cloud
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: pjungermann
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-catalog-backend-module-msgraph
|
||||
title: '@backstage/plugin-catalog-backend-module-msgraph'
|
||||
description: >-
|
||||
A Backstage catalog backend module that helps integrate towards Microsoft
|
||||
Graph
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: pjungermann
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-catalog-backend-module-puppetdb
|
||||
title: '@backstage/plugin-catalog-backend-module-puppetdb'
|
||||
description: A Backstage catalog backend module that helps integrate towards PuppetDB
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: catalog-maintainers
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { startTaskPipeline } from './TaskPipeline';
|
||||
import { startTaskPipeline, createBarrier } from './TaskPipeline';
|
||||
|
||||
function createLimitedLoader(count: number, loadDelay?: number) {
|
||||
const items = new Array(count).fill(0).map((_, index) => index);
|
||||
@@ -119,3 +119,88 @@ describe('startTaskPipeline', () => {
|
||||
}).toThrow('must be lower');
|
||||
});
|
||||
});
|
||||
|
||||
describe('createBarrier', () => {
|
||||
const tick = (millis: number) =>
|
||||
new Promise(resolve => setTimeout(resolve, millis));
|
||||
|
||||
it('abandons a wait after the timeout expires', async () => {
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
const barrier = createBarrier({ waitTimeoutMillis: 100, signal });
|
||||
|
||||
const fn1 = jest.fn();
|
||||
barrier.wait().then(fn1);
|
||||
|
||||
await tick(0);
|
||||
expect(fn1).not.toHaveBeenCalled();
|
||||
|
||||
await tick(50);
|
||||
expect(fn1).not.toHaveBeenCalled();
|
||||
|
||||
// start a new wait mid-way through the timeout
|
||||
// should NOT resolve when the first one times out
|
||||
const fn2 = jest.fn();
|
||||
barrier.wait().then(fn2);
|
||||
|
||||
await tick(0);
|
||||
expect(fn2).not.toHaveBeenCalled();
|
||||
|
||||
await tick(50);
|
||||
expect(fn1).toHaveBeenCalledTimes(1);
|
||||
expect(fn2).not.toHaveBeenCalled();
|
||||
|
||||
await tick(50);
|
||||
expect(fn1).toHaveBeenCalledTimes(1);
|
||||
expect(fn2).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('abandons a wait after aborted', async () => {
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
const barrier = createBarrier({ waitTimeoutMillis: 100, signal });
|
||||
|
||||
const fn1 = jest.fn();
|
||||
barrier.wait().then(fn1);
|
||||
|
||||
// should resolve immediately, not after timeout
|
||||
await tick(0);
|
||||
expect(fn1).not.toHaveBeenCalled();
|
||||
abortController.abort();
|
||||
await tick(0);
|
||||
expect(fn1).toHaveBeenCalledTimes(1);
|
||||
|
||||
// subsequent waits should be immediate no matter what
|
||||
const fn2 = jest.fn();
|
||||
barrier.wait().then(fn2);
|
||||
await tick(0);
|
||||
expect(fn2).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('release immediately unblocks all waits', async () => {
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
const barrier = createBarrier({ waitTimeoutMillis: 100, signal });
|
||||
|
||||
const fn1 = jest.fn();
|
||||
barrier.wait().then(fn1);
|
||||
|
||||
await tick(50);
|
||||
expect(fn1).not.toHaveBeenCalled();
|
||||
|
||||
// start a new wait mid-way through the timeout
|
||||
// SHOULD resolve when releasing
|
||||
const fn2 = jest.fn();
|
||||
barrier.wait().then(fn2);
|
||||
|
||||
await tick(0);
|
||||
expect(fn1).not.toHaveBeenCalled();
|
||||
expect(fn2).not.toHaveBeenCalled();
|
||||
|
||||
barrier.release();
|
||||
|
||||
await tick(0);
|
||||
expect(fn1).toHaveBeenCalledTimes(1);
|
||||
expect(fn2).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -72,50 +72,112 @@ export function startTaskPipeline<T>(options: Options<T>) {
|
||||
throw new Error('lowWatermark must be lower than highWatermark');
|
||||
}
|
||||
|
||||
let loading = false;
|
||||
let stopped = false;
|
||||
let inFlightCount = 0;
|
||||
// State is in an object so that it can be stably referenced from within
|
||||
// callbacks below
|
||||
const state = { inFlightCount: 0 };
|
||||
const abortController = new AbortController();
|
||||
const abortSignal = abortController.signal;
|
||||
|
||||
async function maybeLoadMore() {
|
||||
if (stopped || loading || inFlightCount > lowWatermark) {
|
||||
return;
|
||||
}
|
||||
const barrier = createBarrier({
|
||||
waitTimeoutMillis: pollingIntervalMs,
|
||||
signal: abortSignal,
|
||||
});
|
||||
|
||||
// Once we hit the low watermark we load in enough items to reach the high watermark
|
||||
loading = true;
|
||||
const loadCount = highWatermark - inFlightCount;
|
||||
const loadedItems = await loadTasks(loadCount);
|
||||
loading = false;
|
||||
|
||||
// We might not reach the high watermark here, in case there weren't enough items to load
|
||||
inFlightCount += loadedItems.length;
|
||||
loadedItems.forEach(item => {
|
||||
processTask(item).finally(() => {
|
||||
if (stopped) {
|
||||
return;
|
||||
async function pipelineLoop() {
|
||||
while (!abortSignal.aborted) {
|
||||
if (state.inFlightCount <= lowWatermark) {
|
||||
const loadCount = highWatermark - state.inFlightCount;
|
||||
const loadedItems = await Promise.resolve()
|
||||
.then(() => loadTasks(loadCount))
|
||||
.catch(() => {
|
||||
// Silently swallow errors and go back to sleep to try again; we
|
||||
// delegate to the loadTasks function itself to catch errors and log
|
||||
// if it so desires
|
||||
return [];
|
||||
});
|
||||
if (loadedItems.length && !abortSignal.aborted) {
|
||||
state.inFlightCount += loadedItems.length;
|
||||
for (const item of loadedItems) {
|
||||
Promise.resolve()
|
||||
.then(() => processTask(item))
|
||||
.catch(() => {
|
||||
// Silently swallow errors and go back to sleep to try again; we
|
||||
// delegate to the processTask function itself to catch errors
|
||||
// and log if it so desires
|
||||
})
|
||||
.finally(() => {
|
||||
state.inFlightCount -= 1;
|
||||
barrier.release();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For each item we complete we check if it's time to load more
|
||||
inFlightCount -= 1;
|
||||
maybeLoadMore();
|
||||
});
|
||||
});
|
||||
|
||||
// We might have processed some tasks while we where loading, so check if we can load more
|
||||
if (loadedItems.length > 1) {
|
||||
maybeLoadMore();
|
||||
await barrier.wait();
|
||||
}
|
||||
}
|
||||
|
||||
// This interval makes sure that we load in new items if the loop runs
|
||||
// dry because of the lack of available tasks. As long as there are
|
||||
// enough items to process this will be a noop.
|
||||
const intervalId = setInterval(() => {
|
||||
maybeLoadMore();
|
||||
}, pollingIntervalMs);
|
||||
pipelineLoop().catch(error => {
|
||||
// This should be impossible, but if it did happen, it would signal a
|
||||
// programming error inside the loop (errors should definitely be caught
|
||||
// inside of it). Let's rethrow with more information, and let it be caught
|
||||
// by the process' uncaught exception handler, which will log the occurrence
|
||||
// at a high level.
|
||||
throw new Error(`Unexpected error in processing pipeline loop`, error);
|
||||
});
|
||||
|
||||
return () => {
|
||||
stopped = true;
|
||||
clearInterval(intervalId);
|
||||
abortController.abort();
|
||||
barrier.destroy();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a barrier with a timeout, that can be awaited or prematurely
|
||||
* released either manually or by an abort signal.
|
||||
*/
|
||||
export function createBarrier(options: {
|
||||
waitTimeoutMillis: number;
|
||||
signal: AbortSignal;
|
||||
}): {
|
||||
wait: () => Promise<void>;
|
||||
release: () => void;
|
||||
destroy: () => void;
|
||||
} {
|
||||
const { waitTimeoutMillis, signal } = options;
|
||||
const resolvers = new Set<() => void>();
|
||||
|
||||
function wait() {
|
||||
if (signal.aborted || !(waitTimeoutMillis > 0)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return new Promise<void>(resolve => {
|
||||
const timeoutHandle = setTimeout(done, waitTimeoutMillis);
|
||||
|
||||
function done() {
|
||||
resolvers.delete(done);
|
||||
clearTimeout(timeoutHandle);
|
||||
resolve();
|
||||
}
|
||||
|
||||
resolvers.add(done);
|
||||
});
|
||||
}
|
||||
|
||||
function release() {
|
||||
const resolversToCall = new Set(resolvers);
|
||||
resolvers.clear();
|
||||
for (const resolver of resolversToCall) {
|
||||
resolver();
|
||||
}
|
||||
}
|
||||
|
||||
signal.addEventListener('abort', release);
|
||||
|
||||
return {
|
||||
wait,
|
||||
release,
|
||||
destroy: () => signal.removeEventListener('abort', release),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ export const spec = {
|
||||
name: 'kind',
|
||||
in: 'path',
|
||||
required: true,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
},
|
||||
@@ -53,6 +54,7 @@ export const spec = {
|
||||
name: 'namespace',
|
||||
in: 'path',
|
||||
required: true,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
},
|
||||
@@ -61,6 +63,7 @@ export const spec = {
|
||||
name: 'name',
|
||||
in: 'path',
|
||||
required: true,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
},
|
||||
@@ -69,6 +72,7 @@ export const spec = {
|
||||
name: 'uid',
|
||||
in: 'path',
|
||||
required: true,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
},
|
||||
@@ -78,6 +82,7 @@ export const spec = {
|
||||
in: 'query',
|
||||
description: 'Cursor to a set page of results.',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
@@ -88,6 +93,7 @@ export const spec = {
|
||||
in: 'query',
|
||||
description: 'Pointer to the previous page of results.',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
@@ -111,6 +117,7 @@ export const spec = {
|
||||
in: 'query',
|
||||
description: 'Filter for just the entities defined by this filter.',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'array',
|
||||
items: {
|
||||
@@ -123,6 +130,7 @@ export const spec = {
|
||||
in: 'query',
|
||||
description: 'Number of records to skip in the query page.',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'integer',
|
||||
minimum: 0,
|
||||
@@ -133,6 +141,7 @@ export const spec = {
|
||||
in: 'query',
|
||||
description: 'Number of records to return in the response.',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'integer',
|
||||
minimum: 0,
|
||||
@@ -1037,6 +1046,7 @@ export const spec = {
|
||||
in: 'query',
|
||||
description: 'Text search term.',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
},
|
||||
@@ -1047,6 +1057,7 @@ export const spec = {
|
||||
description:
|
||||
'A comma separated list of fields to sort returned results by.',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'array',
|
||||
items: {
|
||||
@@ -1086,6 +1097,7 @@ export const spec = {
|
||||
in: 'query',
|
||||
name: 'facet',
|
||||
required: true,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'array',
|
||||
items: {
|
||||
@@ -1141,6 +1153,7 @@ export const spec = {
|
||||
in: 'query',
|
||||
name: 'dryRun',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
},
|
||||
@@ -1226,6 +1239,7 @@ export const spec = {
|
||||
in: 'path',
|
||||
name: 'id',
|
||||
required: true,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
},
|
||||
@@ -1251,6 +1265,7 @@ export const spec = {
|
||||
in: 'path',
|
||||
name: 'id',
|
||||
required: true,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
},
|
||||
@@ -1295,7 +1310,7 @@ export const spec = {
|
||||
$ref: '#/components/schemas/LocationInput',
|
||||
},
|
||||
},
|
||||
required: ['catalogFileName', 'location'],
|
||||
required: ['location'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -20,24 +20,28 @@ components:
|
||||
name: kind
|
||||
in: path
|
||||
required: true
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
namespace:
|
||||
name: namespace
|
||||
in: path
|
||||
required: true
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
name:
|
||||
name: name
|
||||
in: path
|
||||
required: true
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
uid:
|
||||
name: uid
|
||||
in: path
|
||||
required: true
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
cursor:
|
||||
@@ -45,6 +49,7 @@ components:
|
||||
in: query
|
||||
description: Cursor to a set page of results.
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
minLength: 1
|
||||
@@ -53,6 +58,7 @@ components:
|
||||
in: query
|
||||
description: Pointer to the previous page of results.
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
minLength: 1
|
||||
@@ -71,6 +77,7 @@ components:
|
||||
in: query
|
||||
description: Filter for just the entities defined by this filter.
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
@@ -80,6 +87,7 @@ components:
|
||||
in: query
|
||||
description: Number of records to skip in the query page.
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
@@ -88,6 +96,7 @@ components:
|
||||
in: query
|
||||
description: Number of records to return in the response.
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
@@ -788,12 +797,14 @@ paths:
|
||||
in: query
|
||||
description: Text search term.
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
- name: fullTextFilterFields
|
||||
in: query
|
||||
description: A comma separated list of fields to sort returned results by.
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
@@ -818,6 +829,7 @@ paths:
|
||||
- in: query
|
||||
name: facet
|
||||
required: true
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
@@ -853,6 +865,7 @@ paths:
|
||||
- in: query
|
||||
name: dryRun
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
@@ -908,6 +921,7 @@ paths:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
delete:
|
||||
@@ -923,6 +937,7 @@ paths:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
/analyze-location:
|
||||
@@ -952,7 +967,6 @@ paths:
|
||||
location:
|
||||
$ref: '#/components/schemas/LocationInput'
|
||||
required:
|
||||
- catalogFileName
|
||||
- location
|
||||
/validate-entity:
|
||||
post:
|
||||
|
||||
@@ -28,11 +28,11 @@ describe('parseQueryEntitiesParams', () => {
|
||||
const validRequest = {
|
||||
authorizationToken: 'to_not_be_returned',
|
||||
fields: ['kind'],
|
||||
limit: '3',
|
||||
limit: 3,
|
||||
filter: ['a=1', 'b=2'],
|
||||
orderField: ['metadata.name,desc'],
|
||||
fullTextFilterTerm: 'query',
|
||||
fullTextFilterFields: 'metadata.name,metadata.namespace',
|
||||
fullTextFilterFields: ['metadata.name', 'metadata.namespace'],
|
||||
};
|
||||
const parsedObj = parseQueryEntitiesParams(
|
||||
validRequest,
|
||||
@@ -65,9 +65,7 @@ describe('parseQueryEntitiesParams', () => {
|
||||
{ filter: 3 },
|
||||
{ orderField: ['metadata.uid,diagonal'] },
|
||||
{ fields: [4] },
|
||||
{ fullTextFilterTerm: [] },
|
||||
{ fullTextFilterFields: 3 },
|
||||
])('should throw if some parameter is not valid %p', params => {
|
||||
])('should throw if some parameter is not valid %p', (params: any) => {
|
||||
expect(() => parseQueryEntitiesParams(params)).toThrow();
|
||||
});
|
||||
});
|
||||
@@ -83,7 +81,7 @@ describe('parseQueryEntitiesParams', () => {
|
||||
const validRequest = {
|
||||
authorizationToken: 'to_not_be_returned',
|
||||
fields: ['kind'],
|
||||
limit: '3',
|
||||
limit: 3,
|
||||
cursor: encodeCursor(cursor),
|
||||
};
|
||||
const parsedObj = parseQueryEntitiesParams(
|
||||
@@ -103,10 +101,10 @@ describe('parseQueryEntitiesParams', () => {
|
||||
const validRequest = {
|
||||
authorizationToken: 'to_not_be_returned',
|
||||
fields: ['kind'],
|
||||
limit: '3',
|
||||
limit: 3,
|
||||
cursor: encodeCursor(cursor),
|
||||
filter: ['a=1', 'b=2'],
|
||||
orderField: 'orderField,desc',
|
||||
orderField: ['orderField,desc'],
|
||||
query: 'query',
|
||||
};
|
||||
const parsedObj = parseQueryEntitiesParams(
|
||||
@@ -128,7 +126,7 @@ describe('parseQueryEntitiesParams', () => {
|
||||
|
||||
it.each([{ cursor: [] }, { fields: [4] }])(
|
||||
'should throw if some parameter is not valid %p',
|
||||
params => {
|
||||
(params: any) => {
|
||||
expect(() => parseQueryEntitiesParams(params)).toThrow();
|
||||
},
|
||||
);
|
||||
|
||||
@@ -20,19 +20,19 @@ import {
|
||||
QueryEntitiesRequest,
|
||||
} from '../../catalog/types';
|
||||
import { decodeCursor } from '../util';
|
||||
import { parseStringParam } from './common';
|
||||
import { parseEntityFilterParams } from './parseEntityFilterParams';
|
||||
import { parseEntityOrderFieldParams } from './parseEntityOrderFieldParams';
|
||||
import { parseEntityTransformParams } from './parseEntityTransformParams';
|
||||
import { parseFullTextFilterFields } from './parseFullTextFilterFields';
|
||||
import { spec } from '../../schema/openapi.generated';
|
||||
import { internal } from '@backstage/backend-openapi-utils';
|
||||
|
||||
export function parseQueryEntitiesParams(
|
||||
params: Record<string, unknown>,
|
||||
params: internal.QuerySchema<typeof spec, '/entities/by-query', 'get'>,
|
||||
): Omit<QueryEntitiesRequest, 'authorizationToken' | 'limit'> {
|
||||
const fields = parseEntityTransformParams(params);
|
||||
const cursor = parseStringParam(params.cursor, 'cursor');
|
||||
if (cursor) {
|
||||
const decodedCursor = decodeCursor(cursor);
|
||||
|
||||
if (params.cursor) {
|
||||
const decodedCursor = decodeCursor(params.cursor);
|
||||
const response: Omit<QueryEntitiesCursorRequest, 'authorizationToken'> = {
|
||||
cursor: decodedCursor,
|
||||
fields,
|
||||
@@ -41,12 +41,6 @@ export function parseQueryEntitiesParams(
|
||||
}
|
||||
|
||||
const filter = parseEntityFilterParams(params);
|
||||
const fullTextFilterTerm = parseStringParam(
|
||||
params.fullTextFilterTerm,
|
||||
'fullTextFilterTerm',
|
||||
);
|
||||
const fullTextFilterFields = parseFullTextFilterFields(params);
|
||||
|
||||
const orderFields = parseEntityOrderFieldParams(params);
|
||||
|
||||
const response: Omit<QueryEntitiesInitialRequest, 'authorizationToken'> = {
|
||||
@@ -54,8 +48,8 @@ export function parseQueryEntitiesParams(
|
||||
filter,
|
||||
orderFields,
|
||||
fullTextFilter: {
|
||||
term: fullTextFilterTerm || '',
|
||||
fields: fullTextFilterFields,
|
||||
term: params.fullTextFilterTerm || '',
|
||||
fields: params.fullTextFilterFields,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-catalog-graph
|
||||
title: '@backstage/plugin-catalog-graph'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: sda-se-reviewers
|
||||
+9
@@ -48,6 +48,10 @@ describe('UnregisterEntityDialog', () => {
|
||||
},
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(alertApi, 'post').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
const entity = {
|
||||
apiVersion: 'backstage.io/v1alpha1',
|
||||
kind: 'Component',
|
||||
@@ -346,6 +350,11 @@ describe('UnregisterEntityDialog', () => {
|
||||
await waitFor(() => {
|
||||
expect(deleteEntity).toHaveBeenCalled();
|
||||
expect(onConfirm).toHaveBeenCalled();
|
||||
expect(alertApi.post).toHaveBeenCalledWith({
|
||||
message: 'Removed entity n',
|
||||
severity: 'success',
|
||||
display: 'transient',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+7
-1
@@ -85,7 +85,13 @@ const Contents = ({
|
||||
setBusy(true);
|
||||
try {
|
||||
await state.deleteEntity();
|
||||
const entityName = entity.metadata.title ?? entity.metadata.name;
|
||||
onConfirm();
|
||||
alertApi.post({
|
||||
message: `Removed entity ${entityName}`,
|
||||
severity: 'success',
|
||||
display: 'transient',
|
||||
});
|
||||
} catch (err) {
|
||||
assertError(err);
|
||||
alertApi.post({ message: err.message });
|
||||
@@ -94,7 +100,7 @@ const Contents = ({
|
||||
}
|
||||
}
|
||||
},
|
||||
[alertApi, onConfirm, state],
|
||||
[alertApi, onConfirm, state, entity],
|
||||
);
|
||||
|
||||
const DialogActionsPanel = () => (
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-cicd-statistics-module-gitlab
|
||||
title: '@backstage/plugin-cicd-statistics-module-gitlab'
|
||||
description: CI/CD Statistics plugin module; Gitlab CICD
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin-module
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-cicd-statistics
|
||||
title: '@backstage/plugin-cicd-statistics'
|
||||
description: A frontend plugin visualizing CI/CD pipeline statistics (build time)
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-circleci
|
||||
title: '@backstage/plugin-circleci'
|
||||
description: A Backstage plugin that integrates towards Circle CI
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: adamdmharvey
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-cloudbuild
|
||||
title: '@backstage/plugin-cloudbuild'
|
||||
description: A Backstage plugin that integrates towards Google Cloud Build
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-code-climate
|
||||
title: '@backstage/plugin-code-climate'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-code-coverage-backend
|
||||
title: '@backstage/plugin-code-coverage-backend'
|
||||
description: A Backstage backend plugin that helps you keep track of your code coverage
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: alde
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-code-coverage
|
||||
title: '@backstage/plugin-code-coverage'
|
||||
description: A Backstage plugin that helps you keep track of your code coverage
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: alde
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-codescene
|
||||
title: '@backstage/plugin-codescene'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-config-schema
|
||||
title: '@backstage/plugin-config-schema'
|
||||
description: A Backstage plugin that lets you browse the configuration schema of your app
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-cost-insights-common
|
||||
title: '@backstage/plugin-cost-insights-common'
|
||||
description: Common functionalities for the cost-insights plugin
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-common-library
|
||||
owner: silver-lining
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-cost-insights
|
||||
title: '@backstage/plugin-cost-insights'
|
||||
description: A Backstage plugin that helps you keep track of your cloud spend
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: silver-lining
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-devtools-backend
|
||||
title: '@backstage/plugin-devtools-backend'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: awanlin
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-devtools-common
|
||||
title: '@backstage/plugin-devtools-common'
|
||||
description: Common functionalities for the devtools plugin
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-common-library
|
||||
owner: awanlin
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-devtools
|
||||
title: '@backstage/plugin-devtools'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: awanlin
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-dynatrace
|
||||
title: '@backstage/plugin-dynatrace'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-entity-feedback-backend
|
||||
title: '@backstage/plugin-entity-feedback-backend'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: kuangp
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-entity-feedback-common
|
||||
title: '@backstage/plugin-entity-feedback-common'
|
||||
description: Common functionalities for the entity-feedback plugin
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-common-library
|
||||
owner: kuangp
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-entity-feedback
|
||||
title: '@backstage/plugin-entity-feedback'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: kuangp
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-entity-validation
|
||||
title: '@backstage/plugin-entity-validation'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-events-backend-module-aws-sqs
|
||||
title: '@backstage/plugin-events-backend-module-aws-sqs'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: pjungermann
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-events-backend-module-azure
|
||||
title: '@backstage/plugin-events-backend-module-azure'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: pjungermann
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-events-backend-module-bitbucket-cloud
|
||||
title: '@backstage/plugin-events-backend-module-bitbucket-cloud'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: pjungermann
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-events-backend-module-gerrit
|
||||
title: '@backstage/plugin-events-backend-module-gerrit'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: pjungermann
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-events-backend-module-github
|
||||
title: '@backstage/plugin-events-backend-module-github'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: pjungermann
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-events-backend-module-gitlab
|
||||
title: '@backstage/plugin-events-backend-module-gitlab'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin-module
|
||||
owner: pjungermann
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-events-backend-test-utils
|
||||
title: '@backstage/plugin-events-backend-test-utils'
|
||||
description: The plugin-events-backend-test-utils for @backstage/plugin-events-node
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-node-library
|
||||
owner: pjungermann
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-events-backend
|
||||
title: '@backstage/plugin-events-backend'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: pjungermann
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-events-node
|
||||
title: '@backstage/plugin-events-node'
|
||||
description: The plugin-events-node module for @backstage/plugin-events-backend
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-node-library
|
||||
owner: pjungermann
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: internal-plugin-todo-list-backend
|
||||
title: '@internal/plugin-todo-list-backend'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: internal-plugin-todo-list-common
|
||||
title: '@internal/plugin-todo-list-common'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-common-library
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: internal-plugin-todo-list
|
||||
title: '@internal/plugin-todo-list'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-explore-backend
|
||||
title: '@backstage/plugin-explore-backend'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-explore-common
|
||||
title: '@backstage/plugin-explore-common'
|
||||
description: Common functionalities for the explore plugin
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-common-library
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-explore-react
|
||||
title: '@backstage/plugin-explore-react'
|
||||
description: >-
|
||||
A frontend library for Backstage plugins that want to interact with the
|
||||
explore plugin
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-web-library
|
||||
owner: sda-se-reviewers
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-explore
|
||||
title: '@backstage/plugin-explore'
|
||||
description: >-
|
||||
A Backstage plugin for building an exploration page of your software
|
||||
ecosystem
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: sda-se-reviewers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-firehydrant
|
||||
title: '@backstage/plugin-firehydrant'
|
||||
description: A Backstage plugin that integrates towards FireHydrant
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-fossa
|
||||
title: '@backstage/plugin-fossa'
|
||||
description: A Backstage plugin that integrates towards FOSSA
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: sda-se-reviewers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-gcalendar
|
||||
title: '@backstage/plugin-gcalendar'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-gcp-projects
|
||||
title: '@backstage/plugin-gcp-projects'
|
||||
description: A Backstage plugin that helps you manage projects in GCP
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-git-release-manager
|
||||
title: '@backstage/plugin-git-release-manager'
|
||||
description: A Backstage plugin that helps you manage releases in git
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: erikengervall
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-github-actions
|
||||
title: '@backstage/plugin-github-actions'
|
||||
description: A Backstage plugin that integrates towards GitHub Actions
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-github-deployments
|
||||
title: '@backstage/plugin-github-deployments'
|
||||
description: A Backstage plugin that integrates towards GitHub Deployments
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-github-issues
|
||||
title: '@backstage/plugin-github-issues'
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-github-pull-requests-board
|
||||
title: '@backstage/plugin-github-pull-requests-board'
|
||||
description: >-
|
||||
A Backstage plugin that allows you to see all open Pull Requests for all the
|
||||
repositories owned by your team
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-gitops-profiles
|
||||
title: '@backstage/plugin-gitops-profiles'
|
||||
description: A Backstage plugin that helps you manage GitOps profiles
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-gocd
|
||||
title: '@backstage/plugin-gocd'
|
||||
description: A Backstage plugin that integrates towards GoCD
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-graphiql
|
||||
title: '@backstage/plugin-graphiql'
|
||||
description: Backstage plugin for browsing GraphQL APIs
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-graphql-backend
|
||||
title: '@backstage/plugin-graphql-backend'
|
||||
description: An experimental Backstage backend plugin for GraphQL
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-backend-plugin
|
||||
owner: maintainers
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: backstage-plugin-graphql-voyager
|
||||
title: '@backstage/plugin-graphql-voyager'
|
||||
description: Backstage plugin for GraphQL Voyager
|
||||
spec:
|
||||
lifecycle: experimental
|
||||
type: backstage-frontend-plugin
|
||||
owner: maintainers
|
||||
@@ -233,6 +233,9 @@ const defaultConfig = [
|
||||
y: 0,
|
||||
width: 12,
|
||||
height: 1,
|
||||
movable: true,
|
||||
resizable: false,
|
||||
deletable: false,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -148,6 +148,9 @@ export type LayoutConfiguration = {
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
movable?: boolean;
|
||||
deletable?: boolean;
|
||||
resizable?: boolean;
|
||||
};
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
"react-grid-layout": "^1.3.4",
|
||||
"react-resizable": "^3.0.4",
|
||||
"react-use": "^17.2.4",
|
||||
"zod": "~3.21.4"
|
||||
"zod": "^3.21.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user