Merge branch 'master' into feature/10453-add-custom-options-catalog-table

This commit is contained in:
Shailendra Ahir
2022-03-30 07:25:22 +05:30
committed by GitHub
489 changed files with 9129 additions and 2779 deletions
+2 -2
View File
@@ -22,7 +22,7 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/config": "^1.0.0",
"@types/express": "*",
"express": "^4.17.1",
@@ -33,7 +33,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@types/http-proxy-middleware": "^0.19.3",
"@types/supertest": "^2.0.8",
"supertest": "^6.1.6",
+5 -5
View File
@@ -27,8 +27,8 @@
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/test-utils": "^1.0.1-next.1",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -40,10 +40,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/app-defaults": "^1.0.1-next.0",
"@backstage/cli": "^0.16.1-next.0",
"@backstage/app-defaults": "^1.0.1-next.1",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+3 -3
View File
@@ -28,7 +28,7 @@
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -40,10 +40,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+2 -2
View File
@@ -38,10 +38,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
@@ -220,7 +220,7 @@ describe('GoogleAnalytics', () => {
});
// Wait for any/all promises involved to settle.
await new Promise(resolve => setImmediate(resolve));
await new Promise(resolve => setTimeout(resolve));
// A pageview should have been fired immediately.
const [command, data] = ReactGA.testModeAPI.calls[1];
@@ -251,7 +251,7 @@ describe('GoogleAnalytics', () => {
});
// Wait for any/all promises involved to settle.
await new Promise(resolve => setImmediate(resolve));
await new Promise(resolve => setTimeout(resolve));
// A pageview should have been fired immediately.
const [command, data] = ReactGA.testModeAPI.calls[1];
@@ -290,7 +290,7 @@ describe('GoogleAnalytics', () => {
});
// Wait for any/all promises involved to settle.
await new Promise(resolve => setImmediate(resolve));
await new Promise(resolve => setTimeout(resolve));
// User ID should have been set after the pageview.
const [setCommand, setData] = ReactGA.testModeAPI.calls[2];
@@ -318,7 +318,7 @@ describe('GoogleAnalytics', () => {
});
// Wait for any/all promises involved to settle.
await new Promise(resolve => setImmediate(resolve));
await new Promise(resolve => setTimeout(resolve));
// A pageview should have been fired immediately.
const [command, data] = ReactGA.testModeAPI.calls[1];
@@ -369,7 +369,7 @@ describe('GoogleAnalytics', () => {
});
// Wait for any/all promises involved to settle.
await new Promise(resolve => setImmediate(resolve));
await new Promise(resolve => setTimeout(resolve));
// User ID should have been set first.
const [setCommand, setData] = ReactGA.testModeAPI.calls[1];
+2 -2
View File
@@ -36,10 +36,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+8
View File
@@ -1,5 +1,13 @@
# @backstage/plugin-api-docs
## 0.8.4-next.1
### Patch Changes
- Updated dependencies
- @backstage/plugin-catalog-react@1.0.1-next.1
- @backstage/plugin-catalog@1.1.0-next.1
## 0.8.4-next.0
### Patch Changes
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-api-docs",
"description": "A Backstage plugin that helps represent API entities in the frontend",
"version": "0.8.4-next.0",
"version": "0.8.4-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -37,8 +37,8 @@
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/plugin-catalog": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-catalog": "^1.1.0-next.1",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -56,10 +56,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+3 -3
View File
@@ -33,7 +33,7 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/config-loader": "^1.0.1-next.0",
"@backstage/config": "^1.0.0",
"@backstage/types": "^1.0.0",
@@ -50,8 +50,8 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/backend-test-utils": "^0.1.23-next.0",
"@backstage/cli": "^0.16.1-next.0",
"@backstage/backend-test-utils": "^0.1.23-next.1",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/types": "^1.0.0",
"@types/supertest": "^2.0.8",
"mock-fs": "^5.1.0",
+8
View File
@@ -1,5 +1,13 @@
# @backstage/plugin-auth-backend
## 0.13.0-next.1
### Patch Changes
- a45bce06e3: Handle trailing slashes on GitHub `enterpriseInstanceUrl` settings
- Updated dependencies
- @backstage/backend-common@0.13.2-next.1
## 0.13.0-next.0
### Minor Changes
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-auth-backend",
"description": "A Backstage backend plugin that handles authentication",
"version": "0.13.0-next.0",
"version": "0.13.0-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,7 +34,7 @@
},
"dependencies": {
"@backstage/plugin-auth-node": "^0.2.0-next.0",
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/catalog-client": "^1.0.1-next.0",
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/config": "^1.0.0",
@@ -76,8 +76,8 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/backend-test-utils": "^0.1.23-next.0",
"@backstage/cli": "^0.16.1-next.0",
"@backstage/backend-test-utils": "^0.1.23-next.1",
"@backstage/cli": "^0.17.0-next.1",
"@types/body-parser": "^1.19.0",
"@types/cookie-parser": "^1.4.2",
"@types/express-session": "^1.17.2",
@@ -44,6 +44,8 @@ jest.mock('@google-cloud/firestore', () => ({
Firestore: jest.fn().mockImplementation(() => firestoreMock),
}));
jest.useFakeTimers('legacy');
describe('FirestoreKeyStore', () => {
const key = {
kid: '123',
@@ -69,11 +71,6 @@ describe('FirestoreKeyStore', () => {
beforeEach(() => {
jest.clearAllMocks();
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
it('can create an instance without settings', async () => {
@@ -318,9 +318,9 @@ export const createGithubProvider = (
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
const clientId = envConfig.getString('clientId');
const clientSecret = envConfig.getString('clientSecret');
const enterpriseInstanceUrl = envConfig.getOptionalString(
'enterpriseInstanceUrl',
);
const enterpriseInstanceUrl = envConfig
.getOptionalString('enterpriseInstanceUrl')
?.replace(/\/$/, '');
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
const authorizationUrl = enterpriseInstanceUrl
? `${enterpriseInstanceUrl}/login/oauth/authorize`
+2 -2
View File
@@ -23,7 +23,7 @@
"start": "backstage-cli package start"
},
"dependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/config": "^1.0.0",
"@backstage/errors": "^1.0.0",
"jose": "^1.27.1",
@@ -31,7 +31,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"msw": "^0.35.0",
"uuid": "^8.0.0"
},
+2 -2
View File
@@ -23,7 +23,7 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/config": "^1.0.0",
"@backstage/plugin-azure-devops-common": "^0.2.2",
"@types/express": "^4.17.6",
@@ -35,7 +35,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@types/supertest": "^2.0.8",
"supertest": "^6.1.6",
"msw": "^0.35.0"
+1 -1
View File
@@ -32,7 +32,7 @@
"clean": "backstage-cli package clean"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0"
"@backstage/cli": "^0.17.0-next.1"
},
"files": [
"dist"
+3 -3
View File
@@ -35,7 +35,7 @@
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/plugin-azure-devops-common": "^0.2.2",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -49,10 +49,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+8
View File
@@ -1,5 +1,13 @@
# @backstage/plugin-badges-backend
## 0.1.25-next.1
### Patch Changes
- 4c93fd36ee: allow overriding `DefaultBadgeBuilder.getMarkdownCode`
- Updated dependencies
- @backstage/backend-common@0.13.2-next.1
## 0.1.25-next.0
### Patch Changes
+2
View File
@@ -122,6 +122,8 @@ export class DefaultBadgeBuilder implements BadgeBuilder {
createBadgeSvg(options: BadgeOptions): Promise<string>;
// (undocumented)
getBadges(): Promise<BadgeInfo[]>;
// (undocumented)
protected getMarkdownCode(params: Badge, badgeUrl: string): string;
}
// Warning: (ae-missing-release-tag) "RouterOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-badges-backend",
"description": "A Backstage backend plugin that generates README badges for your entities",
"version": "0.1.25-next.0",
"version": "0.1.25-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,7 +34,7 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/catalog-client": "^1.0.1-next.0",
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/config": "^1.0.0",
@@ -48,7 +48,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@types/supertest": "^2.0.8",
"supertest": "^6.1.3"
},
@@ -70,7 +70,7 @@ export class DefaultBadgeBuilder implements BadgeBuilder {
}
}
private getMarkdownCode(params: Badge, badgeUrl: string): string {
protected getMarkdownCode(params: Badge, badgeUrl: string): string {
let altText = `${params.label}: ${params.message}`;
if (params.description && params.description !== params.label) {
altText = `${params.description}, ${altText}`;
+3 -3
View File
@@ -34,7 +34,7 @@
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -46,10 +46,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+3 -3
View File
@@ -23,8 +23,8 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-test-utils": "^0.1.23-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/backend-test-utils": "^0.1.23-next.1",
"@backstage/config": "^1.0.0",
"@types/express": "^4.17.6",
"express": "^4.17.1",
@@ -34,7 +34,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0"
"@backstage/cli": "^0.17.0-next.1"
},
"files": [
"dist",
+10
View File
@@ -1,5 +1,15 @@
# @backstage/plugin-bazaar
## 0.1.19-next.1
### Patch Changes
- 69738379c7: Pass authorization header with Backstage token to backend requests.
- Updated dependencies
- @backstage/plugin-catalog-react@1.0.1-next.1
- @backstage/cli@0.17.0-next.1
- @backstage/plugin-catalog@1.1.0-next.1
## 0.1.19-next.0
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-bazaar",
"version": "0.1.19-next.0",
"version": "0.1.19-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -26,11 +26,11 @@
"dependencies": {
"@backstage/catalog-client": "^1.0.1-next.0",
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/plugin-catalog": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-catalog": "^1.1.0-next.1",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@date-io/luxon": "1.x",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -47,7 +47,7 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/dev-utils": "^1.0.1-next.0",
"@testing-library/jest-dom": "^5.10.1",
"cross-fetch": "^3.1.5"
+36 -39
View File
@@ -17,6 +17,7 @@
import {
createApiRef,
DiscoveryApi,
FetchApi,
IdentityApi,
} from '@backstage/core-plugin-api';
@@ -47,49 +48,53 @@ export interface BazaarApi {
export class BazaarClient implements BazaarApi {
private readonly identityApi: IdentityApi;
private readonly discoveryApi: DiscoveryApi;
private readonly fetchApi: FetchApi;
constructor(options: {
identityApi: IdentityApi;
discoveryApi: DiscoveryApi;
fetchApi: FetchApi;
}) {
this.identityApi = options.identityApi;
this.discoveryApi = options.discoveryApi;
this.fetchApi = options.fetchApi;
}
async updateProject(bazaarProject: any): Promise<any> {
const baseUrl = await this.discoveryApi.getBaseUrl('bazaar');
return await fetch(`${baseUrl}/projects`, {
method: 'PUT',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(bazaarProject),
}).then(resp => resp.json());
return await this.fetchApi
.fetch(`${baseUrl}/projects`, {
method: 'PUT',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(bazaarProject),
})
.then(resp => resp.json());
}
async addProject(bazaarProject: any): Promise<any> {
const baseUrl = await this.discoveryApi.getBaseUrl('bazaar');
return await fetch(`${baseUrl}/projects`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(bazaarProject),
}).then(resp => resp.json());
return await this.fetchApi
.fetch(`${baseUrl}/projects`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(bazaarProject),
})
.then(resp => resp.json());
}
async getProjectById(id: number): Promise<any> {
const baseUrl = await this.discoveryApi.getBaseUrl('bazaar');
const response = await fetch(
const response = await this.fetchApi.fetch(
`${baseUrl}/projects/${encodeURIComponent(id)}`,
{
method: 'GET',
},
);
return response.ok ? response : null;
@@ -98,11 +103,8 @@ export class BazaarClient implements BazaarApi {
async getProjectByRef(entityRef: string): Promise<any> {
const baseUrl = await this.discoveryApi.getBaseUrl('bazaar');
const response = await fetch(
const response = await this.fetchApi.fetch(
`${baseUrl}/projects/${encodeURIComponent(entityRef)}`,
{
method: 'GET',
},
);
return response.ok ? response : null;
@@ -111,19 +113,16 @@ export class BazaarClient implements BazaarApi {
async getMembers(id: number): Promise<any> {
const baseUrl = await this.discoveryApi.getBaseUrl('bazaar');
return await fetch(
`${baseUrl}/projects/${encodeURIComponent(id)}/members`,
{
method: 'GET',
},
).then(resp => resp.json());
return await this.fetchApi
.fetch(`${baseUrl}/projects/${encodeURIComponent(id)}/members`)
.then(resp => resp.json());
}
async addMember(id: number, userId: string): Promise<void> {
const baseUrl = await this.discoveryApi.getBaseUrl('bazaar');
const { picture } = await this.identityApi.getProfileInfo();
await fetch(
await this.fetchApi.fetch(
`${baseUrl}/projects/${encodeURIComponent(
id,
)}/member/${encodeURIComponent(userId)}`,
@@ -141,28 +140,26 @@ export class BazaarClient implements BazaarApi {
async deleteMember(id: number, userId: string): Promise<void> {
const baseUrl = await this.discoveryApi.getBaseUrl('bazaar');
await fetch(
await this.fetchApi.fetch(
`${baseUrl}/projects/${encodeURIComponent(
id,
)}/member/${encodeURIComponent(userId)}`,
{
method: 'DELETE',
},
{ method: 'DELETE' },
);
}
async getProjects(): Promise<any> {
const baseUrl = await this.discoveryApi.getBaseUrl('bazaar');
return await fetch(`${baseUrl}/projects`, {
method: 'GET',
}).then(resp => resp.json());
return await this.fetchApi
.fetch(`${baseUrl}/projects`)
.then(resp => resp.json());
}
async deleteProject(id: number): Promise<void> {
const baseUrl = await this.discoveryApi.getBaseUrl('bazaar');
await fetch(`${baseUrl}/projects/${encodeURIComponent(id)}`, {
await this.fetchApi.fetch(`${baseUrl}/projects/${encodeURIComponent(id)}`, {
method: 'DELETE',
});
}
+4 -2
View File
@@ -21,6 +21,7 @@ import {
createRoutableExtension,
identityApiRef,
discoveryApiRef,
fetchApiRef,
} from '@backstage/core-plugin-api';
import { bazaarApiRef, BazaarClient } from './api';
@@ -35,9 +36,10 @@ export const bazaarPlugin = createPlugin({
deps: {
identityApi: identityApiRef,
discoveryApi: discoveryApiRef,
fetchApi: fetchApiRef,
},
factory: ({ identityApi, discoveryApi }) =>
new BazaarClient({ identityApi, discoveryApi }),
factory: ({ identityApi, discoveryApi, fetchApi }) =>
new BazaarClient({ identityApi, discoveryApi, fetchApi }),
}),
],
});
+3 -3
View File
@@ -27,7 +27,7 @@
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -43,10 +43,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
@@ -1,5 +1,13 @@
# @backstage/plugin-catalog-backend-module-aws
## 0.1.4-next.1
### Patch Changes
- Updated dependencies
- @backstage/plugin-catalog-backend@1.1.0-next.1
- @backstage/backend-common@0.13.2-next.1
## 0.1.4-next.0
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-aws",
"description": "A Backstage catalog backend module that helps integrate towards AWS",
"version": "0.1.4-next.0",
"version": "0.1.4-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,11 +33,11 @@
"start": "backstage-cli package start"
},
"dependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/config": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/plugin-catalog-backend": "^1.0.1-next.0",
"@backstage/plugin-catalog-backend": "^1.1.0-next.1",
"@backstage/types": "^1.0.0",
"aws-sdk": "^2.840.0",
"lodash": "^4.17.21",
@@ -45,7 +45,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@types/lodash": "^4.14.151",
"aws-sdk-mock": "^5.2.1",
"yaml": "^1.9.2"
@@ -1,5 +1,14 @@
# @backstage/plugin-catalog-backend-module-azure
## 0.1.2-next.1
### Patch Changes
- Updated dependencies
- @backstage/plugin-catalog-backend@1.1.0-next.1
- @backstage/integration@1.1.0-next.1
- @backstage/backend-common@0.13.2-next.1
## 0.1.2-next.0
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-azure",
"description": "A Backstage catalog backend module that helps integrate towards Azure",
"version": "0.1.2-next.0",
"version": "0.1.2-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,12 +33,12 @@
"start": "backstage-cli package start"
},
"dependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/config": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/integration": "^1.0.1-next.0",
"@backstage/plugin-catalog-backend": "^1.0.1-next.0",
"@backstage/integration": "^1.1.0-next.1",
"@backstage/plugin-catalog-backend": "^1.1.0-next.1",
"@backstage/types": "^1.0.0",
"lodash": "^4.17.21",
"msw": "^0.35.0",
@@ -46,8 +46,8 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/backend-test-utils": "^0.1.23-next.0",
"@backstage/cli": "^0.16.1-next.0",
"@backstage/backend-test-utils": "^0.1.23-next.1",
"@backstage/cli": "^0.17.0-next.1",
"@types/lodash": "^4.14.151"
},
"files": [
@@ -1,5 +1,14 @@
# @backstage/plugin-catalog-backend-module-bitbucket
## 0.1.2-next.1
### Patch Changes
- Updated dependencies
- @backstage/plugin-catalog-backend@1.1.0-next.1
- @backstage/integration@1.1.0-next.1
- @backstage/backend-common@0.13.2-next.1
## 0.1.2-next.0
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-bitbucket",
"description": "A Backstage catalog backend module that helps integrate towards Bitbucket",
"version": "0.1.2-next.0",
"version": "0.1.2-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,12 +33,12 @@
"start": "backstage-cli package start"
},
"dependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/config": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/integration": "^1.0.1-next.0",
"@backstage/plugin-catalog-backend": "^1.0.1-next.0",
"@backstage/integration": "^1.1.0-next.1",
"@backstage/plugin-catalog-backend": "^1.1.0-next.1",
"@backstage/types": "^1.0.0",
"lodash": "^4.17.21",
"msw": "^0.35.0",
@@ -46,8 +46,8 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/backend-test-utils": "^0.1.23-next.0",
"@backstage/cli": "^0.16.1-next.0",
"@backstage/backend-test-utils": "^0.1.23-next.1",
"@backstage/cli": "^0.17.0-next.1",
"@types/lodash": "^4.14.151"
},
"files": [
@@ -1,5 +1,14 @@
# @backstage/plugin-catalog-backend-module-github
## 0.1.2-next.1
### Patch Changes
- Updated dependencies
- @backstage/plugin-catalog-backend@1.1.0-next.1
- @backstage/integration@1.1.0-next.1
- @backstage/backend-common@0.13.2-next.1
## 0.1.2-next.0
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-github",
"description": "A Backstage catalog backend module that helps integrate towards GitHub",
"version": "0.1.2-next.0",
"version": "0.1.2-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,12 +33,12 @@
"start": "backstage-cli package start"
},
"dependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/config": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/integration": "^1.0.1-next.0",
"@backstage/plugin-catalog-backend": "^1.0.1-next.0",
"@backstage/integration": "^1.1.0-next.1",
"@backstage/plugin-catalog-backend": "^1.1.0-next.1",
"@backstage/types": "^1.0.0",
"@octokit/graphql": "^4.5.8",
"lodash": "^4.17.21",
@@ -47,8 +47,8 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/backend-test-utils": "^0.1.23-next.0",
"@backstage/cli": "^0.16.1-next.0",
"@backstage/backend-test-utils": "^0.1.23-next.1",
"@backstage/cli": "^0.17.0-next.1",
"@types/lodash": "^4.14.151"
},
"files": [
@@ -1,5 +1,14 @@
# @backstage/plugin-catalog-backend-module-gitlab
## 0.1.2-next.1
### Patch Changes
- Updated dependencies
- @backstage/plugin-catalog-backend@1.1.0-next.1
- @backstage/integration@1.1.0-next.1
- @backstage/backend-common@0.13.2-next.1
## 0.1.2-next.0
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-gitlab",
"description": "A Backstage catalog backend module that helps integrate towards GitLab",
"version": "0.1.2-next.0",
"version": "0.1.2-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,12 +33,12 @@
"start": "backstage-cli package start"
},
"dependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/config": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/integration": "^1.0.1-next.0",
"@backstage/plugin-catalog-backend": "^1.0.1-next.0",
"@backstage/integration": "^1.1.0-next.1",
"@backstage/plugin-catalog-backend": "^1.1.0-next.1",
"@backstage/types": "^1.0.0",
"lodash": "^4.17.21",
"msw": "^0.35.0",
@@ -46,8 +46,8 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/backend-test-utils": "^0.1.23-next.0",
"@backstage/cli": "^0.16.1-next.0",
"@backstage/backend-test-utils": "^0.1.23-next.1",
"@backstage/cli": "^0.17.0-next.1",
"@types/lodash": "^4.14.151"
},
"files": [
@@ -1,5 +1,13 @@
# @backstage/plugin-catalog-backend-module-ldap
## 0.4.2-next.1
### Patch Changes
- Updated dependencies
- @backstage/plugin-catalog-backend@1.1.0-next.1
- @backstage/backend-tasks@0.3.0-next.1
## 0.4.2-next.0
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-ldap",
"description": "A Backstage catalog backend module that helps integrate towards LDAP",
"version": "0.4.2-next.0",
"version": "0.4.2-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,11 +33,11 @@
"start": "backstage-cli package start"
},
"dependencies": {
"@backstage/backend-tasks": "^0.2.2-next.0",
"@backstage/backend-tasks": "^0.3.0-next.1",
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/config": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/plugin-catalog-backend": "^1.0.1-next.0",
"@backstage/plugin-catalog-backend": "^1.1.0-next.1",
"@backstage/types": "^1.0.0",
"@types/ldapjs": "^2.2.0",
"ldapjs": "^2.2.0",
@@ -46,7 +46,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@types/lodash": "^4.14.151"
},
"files": [
@@ -1,5 +1,14 @@
# @backstage/plugin-catalog-backend-module-msgraph
## 0.3.1-next.1
### Patch Changes
- 1691c6c5c2: Clarify that config locations that emit User and Group kinds now need to declare so in the `catalog.locations.[].rules`
- Updated dependencies
- @backstage/plugin-catalog-backend@1.1.0-next.1
- @backstage/backend-tasks@0.3.0-next.1
## 0.3.1-next.0
### Patch Changes
@@ -141,8 +141,6 @@ catalog:
locations:
- type: microsoft-graph-org
target: https://graph.microsoft.com/v1.0
# If you catalog doesn't allow to import Group and User entities by
# default, allow them here
rules:
- allow: [Group, User]
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-msgraph",
"description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph",
"version": "0.3.1-next.0",
"version": "0.3.1-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,10 +34,10 @@
},
"dependencies": {
"@azure/msal-node": "^1.1.0",
"@backstage/backend-tasks": "^0.2.2-next.0",
"@backstage/backend-tasks": "^0.3.0-next.1",
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/config": "^1.0.0",
"@backstage/plugin-catalog-backend": "^1.0.1-next.0",
"@backstage/plugin-catalog-backend": "^1.1.0-next.1",
"@microsoft/microsoft-graph-types": "^2.6.0",
"@types/node-fetch": "^2.5.12",
"lodash": "^4.17.21",
@@ -48,9 +48,9 @@
"qs": "^6.9.4"
},
"devDependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-test-utils": "^0.1.23-next.0",
"@backstage/cli": "^0.16.1-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/backend-test-utils": "^0.1.23-next.1",
"@backstage/cli": "^0.17.0-next.1",
"@types/lodash": "^4.14.151",
"msw": "^0.35.0"
},
+53
View File
@@ -1,5 +1,56 @@
# @backstage/plugin-catalog-backend
## 1.1.0-next.1
### Minor Changes
- 8012ac46a0: **BREAKING (alpha api):** Replace `createCatalogPolicyDecision` export with `createCatalogConditionalDecision`, which accepts a permission parameter of type `ResourcePermission<'catalog-entity'>` along with conditions. The permission passed is expected to be the handled permission in `PermissionPolicy#handle`, whose type must first be narrowed using methods like `isPermission` and `isResourcePermission`:
```typescript
class TestPermissionPolicy implements PermissionPolicy {
async handle(
request: PolicyQuery<Permission>,
_user?: BackstageIdentityResponse,
): Promise<PolicyDecision> {
if (
// Narrow type of `request.permission` to `ResourcePermission<'catalog-entity'>
isResourcePermission(request.permission, RESOURCE_TYPE_CATALOG_ENTITY)
) {
return createCatalogConditionalDecision(
request.permission,
catalogConditions.isEntityOwner(
_user?.identity.ownershipEntityRefs ?? [],
),
);
}
return {
result: AuthorizeResult.ALLOW,
};
```
- 8012ac46a0: **BREAKING:** Mark CatalogBuilder#addPermissionRules as @alpha.
- fb02d2d94d: export `locationSpecToLocationEntity`
### Patch Changes
- ada4446733: Specify type of `visibilityPermission` property on collators and collator factories.
- 1691c6c5c2: Clarify that config locations that emit User and Group kinds now need to declare so in the `catalog.locations.[].rules`
- 8012ac46a0: Handle changes to @alpha permission-related types.
- All exported permission rules and conditions now have a `resourceType`.
- `createCatalogConditionalDecision` now expects supplied conditions to have the appropriate `resourceType`.
- `createCatalogPermissionRule` now expects `resourceType` as part of the supplied rule object.
- Introduce new `CatalogPermissionRule` convenience type.
- Updated dependencies
- @backstage/integration@1.1.0-next.1
- @backstage/plugin-permission-common@0.6.0-next.0
- @backstage/plugin-permission-node@0.6.0-next.1
- @backstage/plugin-catalog-common@1.0.1-next.1
- @backstage/backend-common@0.13.2-next.1
- @backstage/plugin-search-common@0.3.3-next.1
## 1.0.1-next.0
### Patch Changes
@@ -1394,6 +1445,8 @@
locations:
- type: github-multi-org
target: https://github.myorg.com
rules:
- allow: [User, Group]
processors:
githubMultiOrg:
+56 -18
View File
@@ -8,7 +8,7 @@
import { CatalogApi } from '@backstage/catalog-client';
import { CatalogEntityDocument } from '@backstage/plugin-catalog-common';
import { CompoundEntityRef } from '@backstage/catalog-model';
import { ConditionalPolicyDecision } from '@backstage/plugin-permission-node';
import { ConditionalPolicyDecision } from '@backstage/plugin-permission-common';
import { Conditions } from '@backstage/plugin-permission-node';
import { Config } from '@backstage/config';
import { DocumentCollatorFactory } from '@backstage/plugin-search-common';
@@ -16,6 +16,7 @@ import { Entity } from '@backstage/catalog-model';
import { EntityPolicy } from '@backstage/catalog-model';
import { GetEntitiesRequest } from '@backstage/catalog-client';
import { JsonValue } from '@backstage/types';
import { LocationEntityV1alpha1 } from '@backstage/catalog-model';
import { Logger } from 'winston';
import { Permission } from '@backstage/plugin-permission-common';
import { PermissionAuthorizer } from '@backstage/plugin-permission-common';
@@ -25,6 +26,7 @@ import { PermissionRule } from '@backstage/plugin-permission-node';
import { PluginDatabaseManager } from '@backstage/backend-common';
import { PluginEndpointDiscovery } from '@backstage/backend-common';
import { Readable } from 'stream';
import { ResourcePermission } from '@backstage/plugin-permission-common';
import { Router } from 'express';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { TokenManager } from '@backstage/backend-common';
@@ -109,13 +111,8 @@ export class BuiltinKindsEntityProcessor implements CatalogProcessor {
export class CatalogBuilder {
addEntityPolicy(...policies: EntityPolicy[]): CatalogBuilder;
addEntityProvider(...providers: EntityProvider[]): CatalogBuilder;
addPermissionRules(
...permissionRules: PermissionRule<
Entity,
EntitiesSearchFilter,
unknown[]
>[]
): void;
// @alpha
addPermissionRules(...permissionRules: CatalogPermissionRule[]): void;
addProcessor(...processors: CatalogProcessor[]): CatalogBuilder;
build(): Promise<{
processingEngine: CatalogProcessingEngine;
@@ -143,23 +140,37 @@ export const catalogConditions: Conditions<{
hasAnnotation: PermissionRule<
Entity,
EntitiesSearchFilter,
'catalog-entity',
[annotation: string]
>;
hasLabel: PermissionRule<Entity, EntitiesSearchFilter, [label: string]>;
hasLabel: PermissionRule<
Entity,
EntitiesSearchFilter,
'catalog-entity',
[label: string]
>;
hasMetadata: PermissionRule<
Entity,
EntitiesSearchFilter,
'catalog-entity',
[key: string, value?: string | undefined]
>;
hasSpec: PermissionRule<
Entity,
EntitiesSearchFilter,
'catalog-entity',
[key: string, value?: string | undefined]
>;
isEntityKind: PermissionRule<Entity, EntitiesSearchFilter, [kinds: string[]]>;
isEntityKind: PermissionRule<
Entity,
EntitiesSearchFilter,
'catalog-entity',
[kinds: string[]]
>;
isEntityOwner: PermissionRule<
Entity,
EntitiesSearchFilter,
'catalog-entity',
[claims: string[]]
>;
}>;
@@ -173,6 +184,10 @@ export type CatalogEnvironment = {
permissions: PermissionAuthorizer;
};
// @alpha
export type CatalogPermissionRule<TParams extends unknown[] = unknown[]> =
PermissionRule<Entity, EntitiesSearchFilter, 'catalog-entity', TParams>;
// @public (undocumented)
export interface CatalogProcessingEngine {
// (undocumented)
@@ -277,14 +292,17 @@ export class CodeOwnersProcessor implements CatalogProcessor {
}
// @alpha
export const createCatalogPermissionRule: <TParams extends unknown[]>(
rule: PermissionRule<Entity, EntitiesSearchFilter, TParams>,
) => PermissionRule<Entity, EntitiesSearchFilter, TParams>;
export const createCatalogConditionalDecision: (
permission: ResourcePermission<'catalog-entity'>,
conditions: PermissionCriteria<
PermissionCondition<'catalog-entity', unknown[]>
>,
) => ConditionalPolicyDecision;
// @alpha
export const createCatalogPolicyDecision: (
conditions: PermissionCriteria<PermissionCondition<unknown[]>>,
) => ConditionalPolicyDecision;
export const createCatalogPermissionRule: <TParams extends unknown[]>(
rule: PermissionRule<Entity, EntitiesSearchFilter, 'catalog-entity', TParams>,
) => PermissionRule<Entity, EntitiesSearchFilter, 'catalog-entity', TParams>;
// @public
export function createRandomProcessingInterval(options: {
@@ -458,6 +476,12 @@ export type LocationSpec = {
presence?: 'optional' | 'required';
};
// @public (undocumented)
export function locationSpecToLocationEntity(opts: {
location: LocationSpec;
parentEntity?: Entity;
}): LocationEntityV1alpha1;
// @public (undocumented)
export function parseEntityYaml(
data: Buffer,
@@ -469,23 +493,37 @@ export const permissionRules: {
hasAnnotation: PermissionRule<
Entity,
EntitiesSearchFilter,
'catalog-entity',
[annotation: string]
>;
hasLabel: PermissionRule<Entity, EntitiesSearchFilter, [label: string]>;
hasLabel: PermissionRule<
Entity,
EntitiesSearchFilter,
'catalog-entity',
[label: string]
>;
hasMetadata: PermissionRule<
Entity,
EntitiesSearchFilter,
'catalog-entity',
[key: string, value?: string | undefined]
>;
hasSpec: PermissionRule<
Entity,
EntitiesSearchFilter,
'catalog-entity',
[key: string, value?: string | undefined]
>;
isEntityKind: PermissionRule<Entity, EntitiesSearchFilter, [kinds: string[]]>;
isEntityKind: PermissionRule<
Entity,
EntitiesSearchFilter,
'catalog-entity',
[kinds: string[]]
>;
isEntityOwner: PermissionRule<
Entity,
EntitiesSearchFilter,
'catalog-entity',
[claims: string[]]
>;
};
+10 -10
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend",
"description": "The Backstage backend plugin that provides the Backstage catalog",
"version": "1.0.1-next.0",
"version": "1.1.0-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,17 +34,17 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/catalog-client": "^1.0.1-next.0",
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/config": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/integration": "^1.0.1-next.0",
"@backstage/plugin-catalog-common": "^1.0.1-next.0",
"@backstage/plugin-permission-common": "^0.5.3",
"@backstage/plugin-permission-node": "^0.5.6-next.0",
"@backstage/integration": "^1.1.0-next.1",
"@backstage/plugin-catalog-common": "^1.0.1-next.1",
"@backstage/plugin-permission-common": "^0.6.0-next.0",
"@backstage/plugin-permission-node": "^0.6.0-next.1",
"@backstage/plugin-scaffolder-common": "^1.0.1-next.0",
"@backstage/plugin-search-common": "^0.3.3-next.0",
"@backstage/plugin-search-common": "^0.3.3-next.1",
"@backstage/types": "^1.0.0",
"@types/express": "^4.17.6",
"codeowners-utils": "^1.0.2",
@@ -68,9 +68,9 @@
"zod": "^3.11.6"
},
"devDependencies": {
"@backstage/backend-test-utils": "^0.1.23-next.0",
"@backstage/cli": "^0.16.1-next.0",
"@backstage/plugin-permission-common": "^0.5.3",
"@backstage/backend-test-utils": "^0.1.23-next.1",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/plugin-permission-common": "^0.6.0-next.0",
"@backstage/plugin-search-backend-node": "0.5.3-next.0",
"@types/core-js": "^2.5.4",
"@types/git-url-parse": "^9.0.0",
+4 -3
View File
@@ -24,7 +24,8 @@ export * from './api';
export * from './catalog';
export * from './ingestion';
export * from './modules';
export * from './search';
export * from './processing';
export * from './service';
export * from './permissions';
export * from './processing';
export * from './search';
export * from './service';
export * from './util';
@@ -60,8 +60,10 @@ export class ConfigLocationEntityProvider implements EntityProvider {
const type = location.getString('type');
const target = location.getString('target');
const entity = locationSpecToLocationEntity({
type,
target: type === 'file' ? path.resolve(target) : target,
location: {
type,
target: type === 'file' ? path.resolve(target) : target,
},
});
const locationKey = getEntityLocationRef(entity);
return { entity, locationKey };
@@ -58,7 +58,7 @@ export class DefaultLocationStore implements LocationStore, EntityProvider {
return inner;
});
const entity = locationSpecToLocationEntity(location);
const entity = locationSpecToLocationEntity({ location });
await this.connection.applyMutation({
type: 'delta',
added: [{ entity, locationKey: getEntityLocationRef(entity) }],
@@ -100,7 +100,7 @@ export class DefaultLocationStore implements LocationStore, EntityProvider {
await tx<DbLocationsRow>('locations').where({ id }).del();
return location;
});
const entity = locationSpecToLocationEntity(deleted);
const entity = locationSpecToLocationEntity({ location: deleted });
await this.connection.applyMutation({
type: 'delta',
added: [],
@@ -122,7 +122,7 @@ export class DefaultLocationStore implements LocationStore, EntityProvider {
const locations = await this.locations();
const entities = locations.map(location => {
const entity = locationSpecToLocationEntity(location);
const entity = locationSpecToLocationEntity({ location });
return { entity, locationKey: getEntityLocationRef(entity) };
});
@@ -345,7 +345,7 @@ describe('PlaceholderProcessor', () => {
},
),
).rejects.toThrow(
'Placeholder $text could not form a URL out of ./a/b/catalog-info.yaml and ../c/catalog-info.yaml, TypeError: Invalid base URL: ./a/b/catalog-info.yaml',
/^Placeholder \$text could not form a URL out of \.\/a\/b\/catalog-info\.yaml and \.\.\/c\/catalog-info\.yaml, TypeError \[ERR_INVALID_URL\]/,
);
expect(read).not.toBeCalled();
@@ -18,41 +18,49 @@ import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';
import { createConditionExports } from '@backstage/plugin-permission-node';
import { permissionRules } from './rules';
const conditionExports = createConditionExports({
const { conditions, createConditionalDecision } = createConditionExports({
pluginId: 'catalog',
resourceType: RESOURCE_TYPE_CATALOG_ENTITY,
rules: permissionRules,
});
/**
* These conditions are used when creating conditional decisions that are returned
* by authorization policies.
* These conditions are used when creating conditional decisions for catalog
* entities that are returned by authorization policies.
*
* @alpha
*/
export const catalogConditions = conditionExports.conditions;
export const catalogConditions = conditions;
/**
* `createCatalogPolicyDecision` can be used when authoring policies to create
* conditional decisions.
* `createCatalogConditionalDecision` can be used when authoring policies to
* create conditional decisions. It requires a permission of type
* `ResourcePermission<'catalog-entity'>` to be passed as the first parameter.
* It's recommended that you use the provided `isResourcePermission` and
* `isPermission` helper methods to narrow the type of the permission passed to
* the handle method as shown below.
*
* ```
* // MyAuthorizationPolicy.ts
* ...
* import { createCatalogPolicyDecision } from '@backstage/plugin-catalog-backend';
* import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';
*
* class MyAuthorizationPolicy implements PermissionPolicy {
* async handle(request, user) {
* ...
*
* return createCatalogPolicyDecision({
* anyOf: [...insert conditions here...],
* });
* }
* if (isResourcePermission(request.permission, RESOURCE_TYPE_CATALOG_ENTITY)) {
* return createCatalogConditionalDecision(
* request.permission,
* { anyOf: [...insert conditions here...] }
* );
* }
*
* ...
* }
* ```
*
* @alpha
*/
export const createCatalogPolicyDecision =
conditionExports.createPolicyDecision;
export const createCatalogConditionalDecision = createConditionalDecision;
@@ -16,6 +16,6 @@
export {
catalogConditions,
createCatalogPolicyDecision,
createCatalogConditionalDecision,
} from './conditionExports';
export * from './rules';
@@ -16,12 +16,14 @@
import { get } from 'lodash';
import { Entity } from '@backstage/catalog-model';
import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';
import { createCatalogPermissionRule } from './util';
export const createPropertyRule = (propertyType: 'metadata' | 'spec') =>
createCatalogPermissionRule({
name: `HAS_${propertyType.toUpperCase()}`,
description: `Allow entities which have the specified ${propertyType} subfield.`,
resourceType: RESOURCE_TYPE_CATALOG_ENTITY,
apply: (resource: Entity, key: string, value?: string) => {
const foundValue = get(resource[propertyType], key);
if (value !== undefined) {
@@ -15,6 +15,7 @@
*/
import { Entity } from '@backstage/catalog-model';
import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';
import { createCatalogPermissionRule } from './util';
/**
@@ -27,6 +28,7 @@ export const hasAnnotation = createCatalogPermissionRule({
name: 'HAS_ANNOTATION',
description:
'Allow entities which are annotated with the specified annotation',
resourceType: RESOURCE_TYPE_CATALOG_ENTITY,
apply: (resource: Entity, annotation: string) =>
!!resource.metadata.annotations?.hasOwnProperty(annotation),
toQuery: (annotation: string) => ({
@@ -15,6 +15,7 @@
*/
import { Entity } from '@backstage/catalog-model';
import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';
import { createCatalogPermissionRule } from './util';
/**
@@ -25,6 +26,7 @@ import { createCatalogPermissionRule } from './util';
export const hasLabel = createCatalogPermissionRule({
name: 'HAS_LABEL',
description: 'Allow entities which have the specified label metadata.',
resourceType: RESOURCE_TYPE_CATALOG_ENTITY,
apply: (resource: Entity, label: string) =>
!!resource.metadata.labels?.hasOwnProperty(label),
toQuery: (label: string) => ({
@@ -36,4 +36,5 @@ export const permissionRules = {
isEntityOwner,
};
export type { CatalogPermissionRule } from './util';
export { createCatalogPermissionRule } from './util';
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import { Entity } from '@backstage/catalog-model';
import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';
import { EntitiesSearchFilter } from '../../catalog/types';
import { createCatalogPermissionRule } from './util';
@@ -25,6 +26,7 @@ import { createCatalogPermissionRule } from './util';
export const isEntityKind = createCatalogPermissionRule({
name: 'IS_ENTITY_KIND',
description: 'Allow entities with the specified kind',
resourceType: RESOURCE_TYPE_CATALOG_ENTITY,
apply(resource: Entity, kinds: string[]) {
const resourceKind = resource.kind.toLocaleLowerCase('en-US');
return kinds.some(kind => kind.toLocaleLowerCase('en-US') === resourceKind);
@@ -15,6 +15,7 @@
*/
import { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model';
import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';
import { createCatalogPermissionRule } from './util';
/**
@@ -26,6 +27,7 @@ import { createCatalogPermissionRule } from './util';
export const isEntityOwner = createCatalogPermissionRule({
name: 'IS_ENTITY_OWNER',
description: 'Allow entities owned by the current user',
resourceType: RESOURCE_TYPE_CATALOG_ENTITY,
apply: (resource: Entity, claims: string[]) => {
if (!resource.relations) {
return false;
@@ -15,9 +15,23 @@
*/
import { Entity } from '@backstage/catalog-model';
import { makeCreatePermissionRule } from '@backstage/plugin-permission-node';
import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';
import {
makeCreatePermissionRule,
PermissionRule,
} from '@backstage/plugin-permission-node';
import { EntitiesSearchFilter } from '../../catalog/types';
/**
* Convenience type for {@link @backstage/plugin-permission-node#PermissionRule}
* instances with the correct resource type, resource, and filter to work with
* the catalog.
*
* @alpha
*/
export type CatalogPermissionRule<TParams extends unknown[] = unknown[]> =
PermissionRule<Entity, EntitiesSearchFilter, 'catalog-entity', TParams>;
/**
* Helper function for creating correctly-typed
* {@link @backstage/plugin-permission-node#PermissionRule}s for the
@@ -27,5 +41,6 @@ import { EntitiesSearchFilter } from '../../catalog/types';
*/
export const createCatalogPermissionRule = makeCreatePermissionRule<
Entity,
EntitiesSearchFilter
EntitiesSearchFilter,
typeof RESOURCE_TYPE_CATALOG_ENTITY
>();
@@ -106,10 +106,10 @@ export class ProcessorOutputCollector {
this.deferredEntities.push({ entity, locationKey: location });
} else if (i.type === 'location') {
const entity = locationSpecToLocationEntity(
i.location,
this.parentEntity,
);
const entity = locationSpecToLocationEntity({
location: i.location,
parentEntity: this.parentEntity,
});
const locationKey = getEntityLocationRef(entity);
this.deferredEntities.push({ entity, locationKey });
} else if (i.type === 'relation') {
@@ -33,6 +33,7 @@ import {
catalogEntityReadPermission,
CatalogEntityDocument,
} from '@backstage/plugin-catalog-common';
import { Permission } from '@backstage/plugin-permission-common';
/**
* @public
@@ -45,7 +46,8 @@ export class DefaultCatalogCollator {
protected filter?: GetEntitiesRequest['filter'];
protected readonly catalogClient: CatalogApi;
public readonly type: string = 'software-catalog';
public readonly visibilityPermission = catalogEntityReadPermission;
public readonly visibilityPermission: Permission =
catalogEntityReadPermission;
protected tokenManager: TokenManager;
static fromConfig(
@@ -34,6 +34,7 @@ import {
catalogEntityReadPermission,
CatalogEntityDocument,
} from '@backstage/plugin-catalog-common';
import { Permission } from '@backstage/plugin-permission-common';
import { Readable } from 'stream';
/** @public */
@@ -49,7 +50,8 @@ export type DefaultCatalogCollatorFactoryOptions = {
/** @public */
export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory {
public readonly type: string = 'software-catalog';
public readonly visibilityPermission = catalogEntityReadPermission;
public readonly visibilityPermission: Permission =
catalogEntityReadPermission;
private locationTemplate: string;
private filter?: GetEntitiesRequest['filter'];
@@ -14,15 +14,11 @@
* limitations under the License.
*/
import { Entity } from '@backstage/catalog-model';
import { NotAllowedError } from '@backstage/errors';
import { AuthorizeResult } from '@backstage/plugin-permission-common';
import {
createConditionTransformer,
PermissionRule,
} from '@backstage/plugin-permission-node';
import { EntitiesSearchFilter } from '../catalog/types';
import { createConditionTransformer } from '@backstage/plugin-permission-node';
import { isEntityKind } from '../permissions/rules/isEntityKind';
import { CatalogPermissionRule } from '../permissions/rules';
import { AuthorizedEntitiesCatalog } from './AuthorizedEntitiesCatalog';
describe('AuthorizedEntitiesCatalog', () => {
@@ -36,9 +32,7 @@ describe('AuthorizedEntitiesCatalog', () => {
authorize: jest.fn(),
};
const createCatalog = (
...rules: PermissionRule<Entity, EntitiesSearchFilter, unknown[]>[]
) =>
const createCatalog = (...rules: CatalogPermissionRule[]) =>
new AuthorizedEntitiesCatalog(
fakeCatalog,
fakePermissionApi,
@@ -17,7 +17,6 @@
import { PluginDatabaseManager, UrlReader } from '@backstage/backend-common';
import {
DefaultNamespaceEntityPolicy,
Entity,
EntityPolicies,
EntityPolicy,
FieldFormatEntityPolicy,
@@ -32,7 +31,6 @@ import { ScmIntegrations } from '@backstage/integration';
import { createHash } from 'crypto';
import { Router } from 'express';
import lodash, { keyBy } from 'lodash';
import { EntitiesSearchFilter } from '../catalog';
import {
CatalogProcessor,
@@ -77,10 +75,12 @@ import { DefaultCatalogRulesEnforcer } from '../ingestion/CatalogRules';
import { Config } from '@backstage/config';
import { Logger } from 'winston';
import { connectEntityProviders } from '../processing/connectEntityProviders';
import { permissionRules as catalogPermissionRules } from '../permissions/rules';
import {
CatalogPermissionRule,
permissionRules as catalogPermissionRules,
} from '../permissions/rules';
import { PermissionAuthorizer } from '@backstage/plugin-permission-common';
import {
PermissionRule,
createConditionTransformer,
createPermissionIntegrationRouter,
} from '@backstage/plugin-permission-node';
@@ -135,11 +135,7 @@ export class CatalogBuilder {
maxSeconds: 150,
});
private locationAnalyzer: LocationAnalyzer | undefined = undefined;
private permissionRules: PermissionRule<
Entity,
EntitiesSearchFilter,
unknown[]
>[];
private permissionRules: CatalogPermissionRule[];
/**
* Creates a catalog builder.
@@ -339,14 +335,9 @@ export class CatalogBuilder {
* {@link @backstage/plugin-permission-node#PermissionRule}.
*
* @param permissionRules - Additional permission rules
* @alpha
*/
addPermissionRules(
...permissionRules: PermissionRule<
Entity,
EntitiesSearchFilter,
unknown[]
>[]
) {
addPermissionRules(...permissionRules: CatalogPermissionRule[]) {
this.permissionRules.push(...permissionRules);
}
@@ -26,7 +26,10 @@ import { LocationInput, LocationService, RefreshService } from './types';
import { basicEntityFilter } from './request';
import { createRouter } from './createRouter';
import { AuthorizeResult } from '@backstage/plugin-permission-common';
import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';
import {
createPermissionIntegrationRouter,
createPermissionRule,
} from '@backstage/plugin-permission-node';
import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';
describe('createRouter readonly disabled', () => {
@@ -568,12 +571,13 @@ describe('NextRouter permissioning', () => {
let app: express.Express;
let refreshService: RefreshService;
const fakeRule = {
const fakeRule = createPermissionRule({
name: 'FAKE_RULE',
description: 'fake rule',
resourceType: RESOURCE_TYPE_CATALOG_ENTITY,
apply: () => true,
toQuery: () => ({ key: '', values: [] }),
};
});
beforeAll(async () => {
entitiesCatalog = {
@@ -631,7 +635,11 @@ describe('NextRouter permissioning', () => {
id: '123',
resourceType: 'catalog-entity',
resourceRef: 'component:default/spidey-sense',
conditions: { rule: 'FAKE_RULE', params: ['user:default/spiderman'] },
conditions: {
rule: 'FAKE_RULE',
resourceType: 'catalog-entity',
params: ['user:default/spiderman'],
},
},
],
};
@@ -32,10 +32,14 @@ export function locationSpecToMetadataName(location: LocationSpec) {
return `generated-${hash}`;
}
export function locationSpecToLocationEntity(
location: LocationSpec,
parentEntity?: Entity,
): LocationEntityV1alpha1 {
/** @public */
export function locationSpecToLocationEntity(opts: {
location: LocationSpec;
parentEntity?: Entity;
}): LocationEntityV1alpha1 {
const location = opts.location;
const parentEntity = opts.parentEntity;
let ownLocation: string;
let originLocation: string;
if (parentEntity) {
+17
View File
@@ -0,0 +1,17 @@
/*
* 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.
*/
export { locationSpecToLocationEntity } from './conversion';
+10
View File
@@ -1,5 +1,15 @@
# @backstage/plugin-catalog-common
## 1.0.1-next.1
### Patch Changes
- ada4446733: Use `createPermission` helper when creating permissions.
- 8c8bee47f4: Add `@alpha` `CatalogEntityPermission` convenience type, available for import from `@backstage/plugin-catalog-common/alpha`.
- Updated dependencies
- @backstage/plugin-permission-common@0.6.0-next.0
- @backstage/search-common@0.3.3-next.1
## 1.0.1-next.0
### Patch Changes
+14 -8
View File
@@ -3,14 +3,15 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { BasicPermission } from '@backstage/plugin-permission-common';
import { IndexableDocument } from '@backstage/search-common';
import { Permission } from '@backstage/plugin-permission-common';
import { ResourcePermission } from '@backstage/plugin-permission-common';
// @alpha
export const catalogEntityCreatePermission: Permission;
export const catalogEntityCreatePermission: BasicPermission;
// @alpha
export const catalogEntityDeletePermission: Permission;
export const catalogEntityDeletePermission: ResourcePermission<'catalog-entity'>;
// @public
export interface CatalogEntityDocument extends IndexableDocument {
@@ -29,19 +30,24 @@ export interface CatalogEntityDocument extends IndexableDocument {
}
// @alpha
export const catalogEntityReadPermission: Permission;
export type CatalogEntityPermission = ResourcePermission<
typeof RESOURCE_TYPE_CATALOG_ENTITY
>;
// @alpha
export const catalogEntityRefreshPermission: Permission;
export const catalogEntityReadPermission: ResourcePermission<'catalog-entity'>;
// @alpha
export const catalogLocationCreatePermission: Permission;
export const catalogEntityRefreshPermission: ResourcePermission<'catalog-entity'>;
// @alpha
export const catalogLocationDeletePermission: Permission;
export const catalogLocationCreatePermission: BasicPermission;
// @alpha
export const catalogLocationReadPermission: Permission;
export const catalogLocationDeletePermission: BasicPermission;
// @alpha
export const catalogLocationReadPermission: BasicPermission;
// @alpha
export const RESOURCE_TYPE_CATALOG_ENTITY = 'catalog-entity';
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-common",
"description": "Common functionalities for the catalog plugin",
"version": "1.0.1-next.0",
"version": "1.0.1-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,11 +34,11 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
"@backstage/plugin-permission-common": "^0.5.3",
"@backstage/search-common": "^0.3.3-next.0"
"@backstage/plugin-permission-common": "^0.6.0-next.0",
"@backstage/search-common": "^0.3.3-next.1"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0"
"@backstage/cli": "^0.17.0-next.1"
},
"files": [
"dist",
+1
View File
@@ -31,5 +31,6 @@ export {
catalogLocationCreatePermission,
catalogLocationDeletePermission,
} from './permissions';
export type { CatalogEntityPermission } from './permissions';
export * from './search';
+27 -15
View File
@@ -14,7 +14,10 @@
* limitations under the License.
*/
import { Permission } from '@backstage/plugin-permission-common';
import {
createPermission,
ResourcePermission,
} from '@backstage/plugin-permission-common';
/**
* Permission resource type which corresponds to catalog entities.
@@ -24,6 +27,15 @@ import { Permission } from '@backstage/plugin-permission-common';
*/
export const RESOURCE_TYPE_CATALOG_ENTITY = 'catalog-entity';
/**
* Convenience type for catalog entity
* {@link @backstage/plugin-permission-common#ResourcePermission}s.
* @alpha
*/
export type CatalogEntityPermission = ResourcePermission<
typeof RESOURCE_TYPE_CATALOG_ENTITY
>;
/**
* This permission is used to authorize actions that involve reading one or more
* entities from the catalog.
@@ -32,13 +44,13 @@ export const RESOURCE_TYPE_CATALOG_ENTITY = 'catalog-entity';
* exist in the catalog both in the frontend and in API responses.
* @alpha
*/
export const catalogEntityReadPermission: Permission = {
export const catalogEntityReadPermission = createPermission({
name: 'catalog.entity.read',
attributes: {
action: 'read',
},
resourceType: RESOURCE_TYPE_CATALOG_ENTITY,
};
});
/**
* This permission is used to authorize actions that involve creating a new
@@ -46,38 +58,38 @@ export const catalogEntityReadPermission: Permission = {
* catalog.
* @alpha
*/
export const catalogEntityCreatePermission: Permission = {
export const catalogEntityCreatePermission = createPermission({
name: 'catalog.entity.create',
attributes: {
action: 'create',
},
};
});
/**
* This permission is used to designate actions that involve removing one or
* more entities from the catalog.
* @alpha
*/
export const catalogEntityDeletePermission: Permission = {
export const catalogEntityDeletePermission = createPermission({
name: 'catalog.entity.delete',
attributes: {
action: 'delete',
},
resourceType: RESOURCE_TYPE_CATALOG_ENTITY,
};
});
/**
* This permission is used to designate refreshing one or more entities from the
* catalog.
* @alpha
*/
export const catalogEntityRefreshPermission: Permission = {
export const catalogEntityRefreshPermission = createPermission({
name: 'catalog.entity.refresh',
attributes: {
action: 'update',
},
resourceType: RESOURCE_TYPE_CATALOG_ENTITY,
};
});
/**
* This permission is used to designate actions that involve reading one or more
@@ -87,33 +99,33 @@ export const catalogEntityRefreshPermission: Permission = {
* not exist in the catalog both in the frontend and in API responses.
* @alpha
*/
export const catalogLocationReadPermission: Permission = {
export const catalogLocationReadPermission = createPermission({
name: 'catalog.location.read',
attributes: {
action: 'read',
},
};
});
/**
* This permission is used to designate actions that involve creating catalog
* locations.
* @alpha
*/
export const catalogLocationCreatePermission: Permission = {
export const catalogLocationCreatePermission = createPermission({
name: 'catalog.location.create',
attributes: {
action: 'create',
},
};
});
/**
* This permission is used to designate actions that involve deleting locations
* from the catalog.
* @alpha
*/
export const catalogLocationDeletePermission: Permission = {
export const catalogLocationDeletePermission = createPermission({
name: 'catalog.location.delete',
attributes: {
action: 'delete',
},
};
});
+8
View File
@@ -1,5 +1,13 @@
# @backstage/plugin-catalog-graph
## 0.2.16-next.1
### Patch Changes
- 77800a32dd: Added renderNode and renderLabel property to EntityRelationsGraph to support customization using CustomNode and CustomLabel components
- Updated dependencies
- @backstage/plugin-catalog-react@1.0.1-next.1
## 0.2.16-next.0
### Patch Changes
+6
View File
@@ -128,6 +128,8 @@ export const EntityRelationsGraph: ({
relationPairs,
className,
zoom,
renderNode,
renderLabel,
}: {
rootEntityNames: CompoundEntityRef | CompoundEntityRef[];
maxDepth?: number | undefined;
@@ -142,6 +144,10 @@ export const EntityRelationsGraph: ({
relationPairs?: RelationPairs | undefined;
className?: string | undefined;
zoom?: 'disabled' | 'enabled' | 'enable-on-click' | undefined;
renderNode?: DependencyGraphTypes.RenderNodeFunction<EntityNode> | undefined;
renderLabel?:
| DependencyGraphTypes.RenderLabelFunction<EntityEdge>
| undefined;
}) => JSX.Element;
// @public
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog-graph",
"version": "0.2.16-next.0",
"version": "0.2.16-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -28,7 +28,7 @@
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -45,11 +45,11 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/plugin-catalog": "^1.0.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/plugin-catalog": "^1.1.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/react-hooks": "^7.0.2",
@@ -21,6 +21,7 @@ import {
RELATION_OWNER_OF,
RELATION_PART_OF,
} from '@backstage/catalog-model';
import { DependencyGraphTypes } from '@backstage/core-components';
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import userEvent from '@testing-library/user-event';
@@ -30,6 +31,7 @@ import { EntityRelationsGraph } from './EntityRelationsGraph';
describe('<EntityRelationsGraph/>', () => {
let Wrapper: FunctionComponent;
let catalog: jest.Mocked<CatalogApi>;
const CUSTOM_TEST_ID = 'custom-test-id';
beforeAll(() => {
Object.defineProperty(window.SVGElement.prototype, 'getBBox', {
@@ -378,4 +380,49 @@ describe('<EntityRelationsGraph/>', () => {
userEvent.click(await findByText('k:d/a1'));
expect(onNodeClick).toBeCalledTimes(1);
});
test('render custom node', async () => {
const renderNode = (props: DependencyGraphTypes.RenderNodeProps) => (
<g>
<text>{props.node.id}</text>
<circle data-testid={CUSTOM_TEST_ID} r={100} />
</g>
);
const { findAllByTestId, container } = await renderInTestApp(
<Wrapper>
<EntityRelationsGraph
rootEntityNames={{ kind: 'b', namespace: 'd', name: 'c' }}
renderNode={renderNode}
/>
</Wrapper>,
);
const node = await findAllByTestId(CUSTOM_TEST_ID);
expect(node[0]).toBeInTheDocument();
expect(container.querySelector('circle')).toBeInTheDocument();
});
test('render custom label', async () => {
const renderLabel = (props: DependencyGraphTypes.RenderLabelProps) => (
<g>
<text>{`Test-Label${props.edge.label}`}</text>
<circle data-testid={CUSTOM_TEST_ID} r={100} />
</g>
);
const { findAllByTestId, findAllByText, container } = await renderInTestApp(
<Wrapper>
<EntityRelationsGraph
rootEntityNames={{ kind: 'b', namespace: 'd', name: 'c' }}
renderLabel={renderLabel}
/>
</Wrapper>,
);
const node = await findAllByTestId(CUSTOM_TEST_ID);
expect(node[0]).toBeInTheDocument();
expect(container.querySelector('circle')).toBeInTheDocument();
const labels = await findAllByText('Test-Labelvisible');
expect(labels[0]).toBeInTheDocument();
});
});
@@ -28,7 +28,7 @@ import React, { MouseEvent, useEffect, useMemo } from 'react';
import { CustomLabel } from './CustomLabel';
import { CustomNode } from './CustomNode';
import { ALL_RELATION_PAIRS, RelationPairs } from './relations';
import { Direction, EntityNode } from './types';
import { Direction, EntityEdge, EntityNode } from './types';
import { useEntityRelationNodesAndEdges } from './useEntityRelationNodesAndEdges';
const useStyles = makeStyles(theme => ({
@@ -79,6 +79,8 @@ export const EntityRelationsGraph = ({
relationPairs = ALL_RELATION_PAIRS,
className,
zoom = 'enabled',
renderNode,
renderLabel,
}: {
rootEntityNames: CompoundEntityRef | CompoundEntityRef[];
maxDepth?: number;
@@ -91,6 +93,8 @@ export const EntityRelationsGraph = ({
relationPairs?: RelationPairs;
className?: string;
zoom?: 'enabled' | 'disabled' | 'enable-on-click';
renderNode?: DependencyGraphTypes.RenderNodeFunction<EntityNode>;
renderLabel?: DependencyGraphTypes.RenderLabelFunction<EntityEdge>;
}) => {
const theme = useTheme();
const classes = useStyles();
@@ -127,8 +131,8 @@ export const EntityRelationsGraph = ({
<DependencyGraph
nodes={nodes}
edges={edges}
renderNode={CustomNode}
renderLabel={CustomLabel}
renderNode={renderNode || CustomNode}
renderLabel={renderLabel || CustomLabel}
direction={direction}
className={classes.graph}
paddingX={theme.spacing(4)}
+2 -2
View File
@@ -46,8 +46,8 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/test-utils": "^1.0.1-next.1",
"@graphql-codegen/cli": "^2.3.1",
"@graphql-codegen/typescript": "^2.4.2",
"@graphql-codegen/typescript-resolvers": "^2.4.3",
+9
View File
@@ -1,5 +1,14 @@
# @backstage/plugin-catalog-import
## 0.8.7-next.1
### Patch Changes
- Updated dependencies
- @backstage/integration@1.1.0-next.1
- @backstage/plugin-catalog-react@1.0.1-next.1
- @backstage/integration-react@1.0.1-next.1
## 0.8.7-next.0
### Patch Changes
+6 -6
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-import",
"description": "A Backstage plugin the helps you import entities into your catalog",
"version": "0.8.7-next.0",
"version": "0.8.7-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -40,9 +40,9 @@
"@backstage/config": "^1.0.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/integration": "^1.0.1-next.0",
"@backstage/integration-react": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/integration": "^1.1.0-next.1",
"@backstage/integration-react": "^1.0.1-next.1",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
@@ -60,10 +60,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/react-hooks": "^7.0.2",
+17
View File
@@ -1,5 +1,22 @@
# @backstage/plugin-catalog-react
## 1.0.1-next.1
### Patch Changes
- 0ffd88a90e: Prevent permissions with types other than `ResourcePermission<'catalog-entity'>` from being used with the `useEntityPermission` hook.
- 4af82967f4: Decouple tags picker from backend entities
`EntityTagPicker` fetches all the tags independently and it doesn't require all the entities to be available client side.
- 37b04b5a5e: Removed broken link from Labels section of entity inspector.
- 4431873583: Update `usePermission` usage.
- Updated dependencies
- @backstage/integration@1.1.0-next.1
- @backstage/plugin-permission-react@0.4.0-next.0
- @backstage/plugin-permission-common@0.6.0-next.0
- @backstage/plugin-catalog-common@1.0.1-next.1
## 1.0.1-next.0
### Patch Changes
+4 -2
View File
@@ -16,10 +16,10 @@ import { IconButton } from '@material-ui/core';
import { LinkProps } from '@backstage/core-components';
import { Observable } from '@backstage/types';
import { Overrides } from '@material-ui/core/styles/overrides';
import { Permission } from '@backstage/plugin-permission-common';
import { PropsWithChildren } from 'react';
import { default as React_2 } from 'react';
import { ReactNode } from 'react';
import { ResourcePermission } from '@backstage/plugin-permission-common';
import { RouteRef } from '@backstage/core-plugin-api';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { StyleRules } from '@material-ui/core/styles/withStyles';
@@ -489,7 +489,9 @@ export function useEntityOwnership(): {
};
// @alpha
export function useEntityPermission(permission: Permission): {
export function useEntityPermission(
permission: ResourcePermission<'catalog-entity'>,
): {
loading: boolean;
allowed: boolean;
error?: Error;
+8 -7
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-react",
"description": "A frontend library that helps other Backstage plugins interact with the catalog",
"version": "1.0.1-next.0",
"version": "1.0.1-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -39,9 +39,10 @@
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/integration": "^1.0.1-next.0",
"@backstage/plugin-permission-common": "^0.5.3",
"@backstage/plugin-permission-react": "^0.3.4",
"@backstage/integration": "^1.1.0-next.1",
"@backstage/plugin-catalog-common": "^1.0.1-next.1",
"@backstage/plugin-permission-common": "^0.6.0-next.0",
"@backstage/plugin-permission-react": "^0.4.0-next.0",
"@backstage/theme": "^0.2.15",
"@backstage/types": "^1.0.0",
"@backstage/version-bridge": "^1.0.0",
@@ -62,11 +63,11 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/plugin-catalog-common": "^1.0.1-next.0",
"@backstage/plugin-catalog-common": "^1.0.1-next.1",
"@backstage/plugin-scaffolder-common": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/react-hooks": "^7.0.2",
@@ -14,60 +14,49 @@
* limitations under the License.
*/
import { Entity } from '@backstage/catalog-model';
import { fireEvent, render } from '@testing-library/react';
import { fireEvent, render, waitFor } from '@testing-library/react';
import React from 'react';
import { MockEntityListContextProvider } from '../../testUtils/providers';
import { EntityTagFilter } from '../../filters';
import { EntityTagPicker } from './EntityTagPicker';
import { TestApiProvider } from '@backstage/test-utils';
import { catalogApiRef } from '../../api';
import { CatalogApi } from '@backstage/catalog-client';
const taggedEntities: Entity[] = [
{
apiVersion: '1',
kind: 'Component',
metadata: {
name: 'component-1',
tags: ['tag4', 'tag1', 'tag2'],
},
},
{
apiVersion: '1',
kind: 'Component',
metadata: {
name: 'component-2',
tags: ['tag3', 'tag4'],
},
},
];
const tags = ['tag1', 'tag2', 'tag3', 'tag4'];
describe('<EntityTagPicker/>', () => {
it('renders all tags', () => {
const mockCatalogApiRef = {
getEntityFacets: async () => ({
facets: { 'metadata.tags': tags.map(value => ({ value })) },
}),
} as unknown as CatalogApi;
it('renders all tags', async () => {
const rendered = render(
<MockEntityListContextProvider
value={{ entities: taggedEntities, backendEntities: taggedEntities }}
>
<EntityTagPicker />
</MockEntityListContextProvider>,
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<MockEntityListContextProvider value={{}}>
<EntityTagPicker />
</MockEntityListContextProvider>
</TestApiProvider>,
);
expect(rendered.getByText('Tags')).toBeInTheDocument();
await waitFor(() => expect(rendered.getByText('Tags')).toBeInTheDocument());
fireEvent.click(rendered.getByTestId('tag-picker-expand'));
taggedEntities
.flatMap(e => e.metadata.tags!)
.forEach(tag => {
expect(rendered.getByText(tag)).toBeInTheDocument();
});
tags.forEach(tag => {
expect(rendered.getByText(tag)).toBeInTheDocument();
});
});
it('renders unique tags in alphabetical order', () => {
it('renders unique tags in alphabetical order', async () => {
const rendered = render(
<MockEntityListContextProvider
value={{ entities: taggedEntities, backendEntities: taggedEntities }}
>
<EntityTagPicker />
</MockEntityListContextProvider>,
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<MockEntityListContextProvider value={{}}>
<EntityTagPicker />
</MockEntityListContextProvider>
</TestApiProvider>,
);
expect(rendered.getByText('Tags')).toBeInTheDocument();
await waitFor(() => expect(rendered.getByText('Tags')).toBeInTheDocument());
fireEvent.click(rendered.getByTestId('tag-picker-expand'));
@@ -79,43 +68,47 @@ describe('<EntityTagPicker/>', () => {
]);
});
it('respects the query parameter filter value', () => {
it('respects the query parameter filter value', async () => {
const updateFilters = jest.fn();
const queryParameters = { tags: ['tag3'] };
render(
<MockEntityListContextProvider
value={{
entities: taggedEntities,
backendEntities: taggedEntities,
updateFilters,
queryParameters,
}}
>
<EntityTagPicker />
</MockEntityListContextProvider>,
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<MockEntityListContextProvider
value={{
updateFilters,
queryParameters,
}}
>
<EntityTagPicker />
</MockEntityListContextProvider>
</TestApiProvider>,
);
expect(updateFilters).toHaveBeenLastCalledWith({
tags: new EntityTagFilter(['tag3']),
});
await waitFor(() =>
expect(updateFilters).toHaveBeenLastCalledWith({
tags: new EntityTagFilter(['tag3']),
}),
);
});
it('adds tags to filters', () => {
it('adds tags to filters', async () => {
const updateFilters = jest.fn();
const rendered = render(
<MockEntityListContextProvider
value={{
entities: taggedEntities,
backendEntities: taggedEntities,
updateFilters,
}}
>
<EntityTagPicker />
</MockEntityListContextProvider>,
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<MockEntityListContextProvider
value={{
updateFilters,
}}
>
<EntityTagPicker />
</MockEntityListContextProvider>
</TestApiProvider>,
);
await waitFor(() =>
expect(updateFilters).toHaveBeenLastCalledWith({
tags: undefined,
}),
);
expect(updateFilters).toHaveBeenLastCalledWith({
tags: undefined,
});
fireEvent.click(rendered.getByTestId('tag-picker-expand'));
fireEvent.click(rendered.getByText('tag1'));
@@ -124,23 +117,25 @@ describe('<EntityTagPicker/>', () => {
});
});
it('removes tags from filters', () => {
it('removes tags from filters', async () => {
const updateFilters = jest.fn();
const rendered = render(
<MockEntityListContextProvider
value={{
entities: taggedEntities,
backendEntities: taggedEntities,
updateFilters,
filters: { tags: new EntityTagFilter(['tag1']) },
}}
>
<EntityTagPicker />
</MockEntityListContextProvider>,
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<MockEntityListContextProvider
value={{
updateFilters,
filters: { tags: new EntityTagFilter(['tag1']) },
}}
>
<EntityTagPicker />
</MockEntityListContextProvider>
</TestApiProvider>,
);
await waitFor(() =>
expect(updateFilters).toHaveBeenLastCalledWith({
tags: new EntityTagFilter(['tag1']),
}),
);
expect(updateFilters).toHaveBeenLastCalledWith({
tags: new EntityTagFilter(['tag1']),
});
fireEvent.click(rendered.getByTestId('tag-picker-expand'));
expect(rendered.getByLabelText('tag1')).toBeChecked();
@@ -150,30 +145,36 @@ describe('<EntityTagPicker/>', () => {
});
});
it('responds to external queryParameters changes', () => {
it('responds to external queryParameters changes', async () => {
const updateFilters = jest.fn();
const rendered = render(
<MockEntityListContextProvider
value={{
updateFilters,
queryParameters: { tags: ['tag1'] },
}}
>
<EntityTagPicker />
</MockEntityListContextProvider>,
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<MockEntityListContextProvider
value={{
updateFilters,
queryParameters: { tags: ['tag1'] },
}}
>
<EntityTagPicker />
</MockEntityListContextProvider>
</TestApiProvider>,
);
await waitFor(() =>
expect(updateFilters).toHaveBeenLastCalledWith({
tags: new EntityTagFilter(['tag1']),
}),
);
expect(updateFilters).toHaveBeenLastCalledWith({
tags: new EntityTagFilter(['tag1']),
});
rendered.rerender(
<MockEntityListContextProvider
value={{
updateFilters,
queryParameters: { tags: ['tag2'] },
}}
>
<EntityTagPicker />
</MockEntityListContextProvider>,
<TestApiProvider apis={[[catalogApiRef, mockCatalogApiRef]]}>
<MockEntityListContextProvider
value={{
updateFilters,
queryParameters: { tags: ['tag2'] },
}}
>
<EntityTagPicker />
</MockEntityListContextProvider>
</TestApiProvider>,
);
expect(updateFilters).toHaveBeenLastCalledWith({
tags: new EntityTagFilter(['tag2']),
@@ -14,7 +14,6 @@
* limitations under the License.
*/
import { Entity } from '@backstage/catalog-model';
import {
Box,
Checkbox,
@@ -30,6 +29,9 @@ import { Autocomplete } from '@material-ui/lab';
import React, { useEffect, useMemo, useState } from 'react';
import { useEntityList } from '../../hooks/useEntityListProvider';
import { EntityTagFilter } from '../../filters';
import { useApi } from '@backstage/core-plugin-api';
import useAsync from 'react-use/lib/useAsync';
import { catalogApiRef } from '../../api';
/** @public */
export type CatalogReactEntityTagPickerClassKey = 'input';
@@ -49,8 +51,18 @@ const checkedIcon = <CheckBoxIcon fontSize="small" />;
/** @public */
export const EntityTagPicker = () => {
const classes = useStyles();
const { updateFilters, backendEntities, filters, queryParameters } =
useEntityList();
const { updateFilters, filters, queryParameters } = useEntityList();
const catalogApi = useApi(catalogApiRef);
const { value: availableTags } = useAsync(async () => {
const facet = 'metadata.tags';
const { facets } = await catalogApi.getEntityFacets({
facets: [facet],
filter: filters.kind?.getCatalogFilters(),
});
return facets[facet].map(({ value }) => value);
}, [filters.kind]);
const queryParamTags = useMemo(
() => [queryParameters.tags].flat().filter(Boolean) as string[],
@@ -75,19 +87,7 @@ export const EntityTagPicker = () => {
});
}, [selectedTags, updateFilters]);
const availableTags = useMemo(
() =>
[
...new Set(
backendEntities
.flatMap((e: Entity) => e.metadata.tags)
.filter(Boolean) as string[],
),
].sort(),
[backendEntities],
);
if (!availableTags.length) return null;
if (!availableTags?.length) return null;
return (
<Box pb={1} pt={1}>
@@ -107,15 +107,7 @@ export function OverviewPage(props: { entity: AlphaEntity }) {
</List>
)}
{!!Object.keys(metadata.labels || {}).length && (
<List
dense
subheader={
<ListSubheader>
Labels
<HelpIcon to="https://backstage.io/docs/features/software-catalog/well-known-labels" />
</ListSubheader>
}
>
<List dense subheader={<ListSubheader>Labels</ListSubheader>}>
{Object.entries(metadata.labels!).map(entry => (
<KeyValueListItem key={entry[0]} indent entry={entry} />
))}
@@ -15,7 +15,7 @@
*/
import { stringifyEntityRef } from '@backstage/catalog-model';
import { Permission } from '@backstage/plugin-permission-common';
import { ResourcePermission } from '@backstage/plugin-permission-common';
import { usePermission } from '@backstage/plugin-permission-react';
import { useAsyncEntity } from './useEntity';
@@ -23,14 +23,18 @@ import { useAsyncEntity } from './useEntity';
* A thin wrapper around the
* {@link @backstage/plugin-permission-react#usePermission} hook which uses the
* current entity in context to make an authorization request for the given
* permission.
* {@link @backstage/plugin-catalog-common#CatalogEntityPermission}.
*
* Note: this hook blocks the permission request until the entity has loaded in
* context. If you have the entityRef and need concurrent requests, use the
* `usePermission` hook directly.
* @alpha
*/
export function useEntityPermission(permission: Permission): {
export function useEntityPermission(
// TODO(joeporpeglia) Replace with `CatalogEntityPermission` when the issue described in
// https://github.com/backstage/backstage/pull/10128 is fixed.
permission: ResourcePermission<'catalog-entity'>,
): {
loading: boolean;
allowed: boolean;
error?: Error;
@@ -44,10 +48,10 @@ export function useEntityPermission(permission: Permission): {
allowed,
loading: loadingPermission,
error: permissionError,
} = usePermission(
} = usePermission({
permission,
entity ? stringifyEntityRef(entity) : undefined,
);
resourceRef: entity ? stringifyEntityRef(entity) : undefined,
});
if (loadingEntity || loadingPermission) {
return { loading: true, allowed: false };
+14
View File
@@ -1,5 +1,19 @@
# @backstage/plugin-catalog
## 1.1.0-next.1
### Minor Changes
- bdc61b4002: Expose 'initalFilter' through initialKind prop on Catalog Page.
### Patch Changes
- Updated dependencies
- @backstage/plugin-catalog-react@1.0.1-next.1
- @backstage/plugin-catalog-common@1.0.1-next.1
- @backstage/integration-react@1.0.1-next.1
- @backstage/plugin-search-common@0.3.3-next.1
## 1.0.1-next.0
### Patch Changes
+8 -8
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog",
"description": "The Backstage plugin for browsing the Backstage catalog",
"version": "1.0.1-next.0",
"version": "1.1.0-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -39,10 +39,10 @@
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/integration-react": "^1.0.1-next.0",
"@backstage/plugin-catalog-common": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-search-common": "^0.3.3-next.0",
"@backstage/integration-react": "^1.0.1-next.1",
"@backstage/plugin-catalog-common": "^1.0.1-next.1",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/plugin-search-common": "^0.3.3-next.1",
"@backstage/theme": "^0.2.15",
"@backstage/types": "^1.0.0",
"@material-ui/core": "^4.12.2",
@@ -60,11 +60,11 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/plugin-permission-react": "^0.3.4",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/plugin-permission-react": "^0.4.0-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+3 -3
View File
@@ -38,7 +38,7 @@
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -55,10 +55,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+3 -3
View File
@@ -37,7 +37,7 @@
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -52,10 +52,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+3 -3
View File
@@ -26,7 +26,7 @@
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -40,9 +40,9 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
@@ -1,5 +1,13 @@
# @backstage/plugin-code-coverage-backend
## 0.1.29-next.1
### Patch Changes
- Updated dependencies
- @backstage/integration@1.1.0-next.1
- @backstage/backend-common@0.13.2-next.1
## 0.1.29-next.0
### Patch Changes
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-code-coverage-backend",
"description": "A Backstage backend plugin that helps you keep track of your code coverage",
"version": "0.1.29-next.0",
"version": "0.1.29-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -23,12 +23,12 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
"@backstage/backend-common": "^0.13.2-next.0",
"@backstage/backend-common": "^0.13.2-next.1",
"@backstage/catalog-client": "^1.0.1-next.0",
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/config": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/integration": "^1.0.1-next.0",
"@backstage/integration": "^1.1.0-next.1",
"@types/express": "^4.17.6",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
@@ -39,7 +39,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@types/express-xml-bodyparser": "^0.3.2",
"@types/supertest": "^2.0.8",
"msw": "^0.35.0",
+3 -3
View File
@@ -29,7 +29,7 @@
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/errors": "^1.0.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -46,10 +46,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+2 -2
View File
@@ -41,10 +41,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+2 -2
View File
@@ -60,10 +60,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+2 -2
View File
@@ -36,9 +36,9 @@
"@backstage/core-plugin-api": "^1.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+3 -3
View File
@@ -37,7 +37,7 @@
"@backstage/catalog-model": "^1.0.1-next.0",
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/plugin-explore-react": "^0.0.15",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
@@ -53,10 +53,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
+3 -3
View File
@@ -27,7 +27,7 @@
"dependencies": {
"@backstage/core-components": "^0.9.3-next.0",
"@backstage/core-plugin-api": "^1.0.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.0",
"@backstage/plugin-catalog-react": "^1.0.1-next.1",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -39,10 +39,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"@backstage/cli": "^0.17.0-next.1",
"@backstage/core-app-api": "^1.0.1-next.0",
"@backstage/dev-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.0",
"@backstage/test-utils": "^1.0.1-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",

Some files were not shown because too many files have changed in this diff Show More