({
+ id: 'y',
+});
+
+function Verifier() {
+ const holder = useApiHolder();
+ const x = holder.get(xApiRef);
+ const y = holder.get(yApiRef);
+
+ return (
+
+ {x ? (
+
+ x={x.a},{x.b}
+
+ ) : (
+ no x
+ )}
+ {y ? y={y} : no y}
+
+ );
+}
+
+describe('TestApiProvider', () => {
+ it('should provide APIs', () => {
+ render(
+
+
+ ,
+ );
+ expect(screen.getByText('x=a,3')).toBeInTheDocument();
+ expect(screen.getByText('y=y')).toBeInTheDocument();
+ });
+
+ it('should provide partial APIs', () => {
+ render(
+
+
+ ,
+ );
+ expect(screen.getByText('x=a,')).toBeInTheDocument();
+ expect(screen.getByText('no y')).toBeInTheDocument();
+ });
+
+ it('should require partial implementations to still match types', () => {
+ render(
+ // @ts-expect-error
+
+
+ ,
+ );
+ expect(screen.getByText('x=3,')).toBeInTheDocument();
+ expect(screen.getByText('no y')).toBeInTheDocument();
+ });
+
+ it('should allow empty APIs', () => {
+ render(
+
+
+ ,
+ );
+ expect(screen.getByText('no x')).toBeInTheDocument();
+ expect(screen.getByText('no y')).toBeInTheDocument();
+ });
+});
+
+describe('TestApiRegistry', () => {
+ it('should be created with APIs', () => {
+ const x = { a: 'a', b: 3 };
+ const y = 'y';
+ const registry = TestApiRegistry.from([xApiRef, x], [yApiRef, y]);
+
+ expect(registry.get(xApiRef)).toBe(x);
+ expect(registry.get(yApiRef)).toBe(y);
+ });
+
+ it('should allow partial implementations', () => {
+ const x = { a: 'a' };
+ const registry = TestApiRegistry.from([xApiRef, x]);
+
+ expect(registry.get(xApiRef)).toBe(x);
+ expect(registry.get(yApiRef)).toBeUndefined();
+ });
+
+ it('should require partial implementations to match types', () => {
+ const x = { a: 2 };
+ // @ts-expect-error
+ const registry = TestApiRegistry.from([xApiRef, x]);
+
+ expect(registry.get(xApiRef)).toBe(x);
+ expect(registry.get(yApiRef)).toBeUndefined();
+ });
+
+ it('should prefer last duplicate API that was provided', () => {
+ const x1 = { a: 'a' };
+ const x2 = { a: 's' };
+ const x3 = { a: 'd' };
+ const registry = TestApiRegistry.from(
+ [xApiRef, x1],
+ [xApiRef, x2],
+ [xApiRef, x3],
+ );
+
+ expect(registry.get(xApiRef)).toBe(x3);
+ });
+});
diff --git a/packages/test-utils/src/testUtils/TestApiProvider.tsx b/packages/test-utils/src/testUtils/TestApiProvider.tsx
new file mode 100644
index 0000000000..b1499b0cde
--- /dev/null
+++ b/packages/test-utils/src/testUtils/TestApiProvider.tsx
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React, { ReactNode } from 'react';
+import { ApiProvider } from '@backstage/core-app-api';
+import { ApiRef, ApiHolder } from '@backstage/core-plugin-api';
+
+/** @ignore */
+type TestApiProviderPropsApiPair = TApi extends infer TImpl
+ ? readonly [ApiRef, Partial]
+ : never;
+
+/** @ignore */
+type TestApiProviderPropsApiPairs = {
+ [TIndex in keyof TApiPairs]: TestApiProviderPropsApiPair;
+};
+
+/**
+ * Properties for the {@link TestApiProvider} component.
+ *
+ * @public
+ */
+export type TestApiProviderProps = {
+ apis: readonly [...TestApiProviderPropsApiPairs];
+ children: ReactNode;
+};
+
+/**
+ * The `TestApiRegistry` is an {@link @backstage/core-plugin-api#ApiHolder} implementation
+ * that is particularly well suited for development and test environments such as
+ * unit tests, storybooks, and isolated plugin development setups.
+ *
+ * @public
+ */
+export class TestApiRegistry implements ApiHolder {
+ /**
+ * Creates a new {@link TestApiRegistry} with a list of API implementation pairs.
+ *
+ * Similar to the {@link TestApiProvider}, there is no need to provide a full
+ * implementation of each API, it's enough to implement the methods that are tested.
+ *
+ * @example
+ * ```ts
+ * const apis = TestApiRegistry.from(
+ * [configApiRef, new ConfigReader({})],
+ * [identityApiRef, { getUserId: () => 'tester' }],
+ * );
+ * ```
+ *
+ * @public
+ * @param apis - A list of pairs mapping an ApiRef to its respective implementation.
+ */
+ static from(
+ ...apis: readonly [...TestApiProviderPropsApiPairs]
+ ) {
+ return new TestApiRegistry(
+ new Map(apis.map(([api, impl]) => [api.id, impl])),
+ );
+ }
+
+ private constructor(private readonly apis: Map) {}
+
+ /**
+ * Returns an implementation of the API.
+ *
+ * @public
+ */
+ get(api: ApiRef): T | undefined {
+ return this.apis.get(api.id) as T | undefined;
+ }
+}
+
+/**
+ * The `TestApiProvider` is a Utility API context provider that is particularly
+ * well suited for development and test environments such as unit tests, storybooks,
+ * and isolated plugin development setups.
+ *
+ * It lets you provide any number of API implementations, without necessarily
+ * having to fully implement each of the APIs.
+ *
+ * A migration from `ApiRegistry` and `ApiProvider` might look like this, from:
+ *
+ * ```tsx
+ * renderInTestApp(
+ *
+ * {...}
+ *
+ * )
+ * ```
+ *
+ * To the following:
+ *
+ * ```tsx
+ * renderInTestApp(
+ *
+ * {...}
+ *
+ * )
+ * ```
+ *
+ * Note that the cast to `IdentityApi` is no longer needed as long as the mock API
+ * implements a subset of the `IdentityApi`.
+ *
+ * @public
+ **/
+export const TestApiProvider = ({
+ apis,
+ children,
+}: TestApiProviderProps) => {
+ return (
+
+ );
+};
diff --git a/packages/test-utils/src/testUtils/appWrappers.test.tsx b/packages/test-utils/src/testUtils/appWrappers.test.tsx
index 25809912ec..39e5da3df2 100644
--- a/packages/test-utils/src/testUtils/appWrappers.test.tsx
+++ b/packages/test-utils/src/testUtils/appWrappers.test.tsx
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import {
createExternalRouteRef,
createRouteRef,
@@ -29,6 +28,7 @@ import React, { useEffect } from 'react';
import { Route, Routes } from 'react-router';
import { MockErrorApi } from './apis';
import { renderInTestApp, wrapInTestApp } from './appWrappers';
+import { TestApiProvider } from './TestApiProvider';
describe('wrapInTestApp', () => {
it('should provide routing and warn about missing act()', async () => {
@@ -111,9 +111,9 @@ describe('wrapInTestApp', () => {
};
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText('foo')).toBeInTheDocument();
diff --git a/packages/test-utils/src/testUtils/index.tsx b/packages/test-utils/src/testUtils/index.tsx
index 7d93d606cc..c778c5c837 100644
--- a/packages/test-utils/src/testUtils/index.tsx
+++ b/packages/test-utils/src/testUtils/index.tsx
@@ -22,3 +22,5 @@ export * from './msw';
export * from './Keyboard';
export * from './logCollector';
export * from './testingLibrary';
+export { TestApiProvider, TestApiRegistry } from './TestApiProvider';
+export type { TestApiProviderProps } from './TestApiProvider';
diff --git a/packages/theme/package.json b/packages/theme/package.json
index d9e89c969f..28a05af98d 100644
--- a/packages/theme/package.json
+++ b/packages/theme/package.json
@@ -31,7 +31,7 @@
"@material-ui/core": "^4.12.2"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2"
+ "@backstage/cli": "^0.9.0"
},
"files": [
"dist"
diff --git a/packages/types/package.json b/packages/types/package.json
index 8632422a25..197d51b061 100644
--- a/packages/types/package.json
+++ b/packages/types/package.json
@@ -31,7 +31,7 @@
},
"dependencies": {},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
+ "@backstage/cli": "^0.9.0",
"@types/zen-observable": "^0.8.0",
"zen-observable": "^0.8.15"
},
diff --git a/packages/version-bridge/package.json b/packages/version-bridge/package.json
index 7cc0b56a34..35a6e8f71d 100644
--- a/packages/version-bridge/package.json
+++ b/packages/version-bridge/package.json
@@ -33,7 +33,7 @@
"react": "^16.12.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
+ "@backstage/cli": "^0.9.0",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2"
diff --git a/plugins/allure/CHANGELOG.md b/plugins/allure/CHANGELOG.md
index 3de49b9b74..f769b6e133 100644
--- a/plugins/allure/CHANGELOG.md
+++ b/plugins/allure/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-allure
+## 0.1.7
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.1.6
### Patch Changes
diff --git a/plugins/allure/package.json b/plugins/allure/package.json
index b157795eec..9efe6132e8 100644
--- a/plugins/allure/package.json
+++ b/plugins/allure/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-allure",
"description": "A Backstage plugin that integrates with Allure",
- "version": "0.1.6",
+ "version": "0.1.7",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -22,10 +22,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -36,10 +36,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/analytics-module-ga/CHANGELOG.md b/plugins/analytics-module-ga/CHANGELOG.md
index a59bcb6351..acc5c235f9 100644
--- a/plugins/analytics-module-ga/CHANGELOG.md
+++ b/plugins/analytics-module-ga/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-analytics-module-ga
+## 0.1.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.1.2
### Patch Changes
diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json
index 4970f50c04..e0a32960c5 100644
--- a/plugins/analytics-module-ga/package.json
+++ b/plugins/analytics-module-ga/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-analytics-module-ga",
- "version": "0.1.2",
+ "version": "0.1.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -22,8 +22,8 @@
},
"dependencies": {
"@backstage/config": "^0.1.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -34,10 +34,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md
index 78f4b08bd7..0b0bd4890c 100644
--- a/plugins/api-docs/CHANGELOG.md
+++ b/plugins/api-docs/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/plugin-api-docs
+## 0.6.14
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/plugin-catalog@0.7.3
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.6.13
### Patch Changes
diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json
index 61ae26c776..a4aa15c419 100644
--- a/plugins/api-docs/package.json
+++ b/plugins/api-docs/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-api-docs",
"description": "A Backstage plugin that helps represent API entities in the frontend",
- "version": "0.6.13",
+ "version": "0.6.14",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,11 +31,11 @@
},
"dependencies": {
"@asyncapi/react-component": "^0.23.0",
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog": "^0.7.2",
- "@backstage/plugin-catalog-react": "^0.6.3",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog": "^0.7.3",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -53,10 +53,10 @@
"swagger-ui-react": "^4.0.0-rc.3"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionCard.test.tsx b/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionCard.test.tsx
index 7b0ffac58e..32a6ec0f77 100644
--- a/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionCard.test.tsx
+++ b/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionCard.test.tsx
@@ -16,13 +16,12 @@
import { ApiEntity } from '@backstage/catalog-model';
import { EntityProvider } from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { ApiDocsConfig, apiDocsConfigRef } from '../../config';
import { OpenApiDefinitionWidget } from '../OpenApiDefinitionWidget';
import { ApiDefinitionCard } from './ApiDefinitionCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
const apiDocsConfig: jest.Mocked = {
@@ -31,10 +30,10 @@ describe('', () => {
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(apiDocsConfigRef, apiDocsConfig);
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
diff --git a/plugins/api-docs/src/components/ApiDefinitionCard/ApiTypeTitle.test.tsx b/plugins/api-docs/src/components/ApiDefinitionCard/ApiTypeTitle.test.tsx
index 450e9e57ac..5476857a06 100644
--- a/plugins/api-docs/src/components/ApiDefinitionCard/ApiTypeTitle.test.tsx
+++ b/plugins/api-docs/src/components/ApiDefinitionCard/ApiTypeTitle.test.tsx
@@ -15,11 +15,10 @@
*/
import { ApiEntity } from '@backstage/catalog-model';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import React from 'react';
import { ApiDocsConfig, apiDocsConfigRef } from '../../config';
import { ApiTypeTitle } from './ApiTypeTitle';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
const apiDocsConfig: jest.Mocked = {
@@ -28,10 +27,10 @@ describe('', () => {
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(apiDocsConfigRef, apiDocsConfig);
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
diff --git a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx
index cf40e5160c..3629110d47 100644
--- a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx
+++ b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx
@@ -15,11 +15,7 @@
*/
import { Entity, RELATION_MEMBER_OF } from '@backstage/catalog-model';
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ConfigReader } from '@backstage/core-app-api';
import { TableColumn, TableProps } from '@backstage/core-components';
import {
ConfigApi,
@@ -34,7 +30,11 @@ import {
entityRouteRef,
starredEntitiesApiRef,
} from '@backstage/plugin-catalog-react';
-import { MockStorageApi, wrapInTestApp } from '@backstage/test-utils';
+import {
+ MockStorageApi,
+ TestApiProvider,
+ wrapInTestApp,
+} from '@backstage/test-utils';
import DashboardIcon from '@material-ui/icons/Dashboard';
import { render } from '@testing-library/react';
import React from 'react';
@@ -88,8 +88,8 @@ describe('ApiCatalogPage', () => {
const renderWrapped = (children: React.ReactNode) =>
render(
wrapInTestApp(
- {
new DefaultStarredEntitiesApi({ storageApi }),
],
[apiDocsConfigRef, apiDocsConfig],
- ])}
+ ]}
>
{children}
- ,
+ ,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': entityRouteRef,
diff --git a/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx b/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx
index ac09b717f7..5e7b22524a 100644
--- a/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx
+++ b/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx
@@ -21,12 +21,11 @@ import {
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { ApiDocsConfig, apiDocsConfigRef } from '../../config';
import { ConsumedApisCard } from './ConsumedApisCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
const apiDocsConfig: jest.Mocked = {
@@ -43,13 +42,15 @@ describe('', () => {
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi).with(
- apiDocsConfigRef,
- apiDocsConfig,
- );
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
diff --git a/plugins/api-docs/src/components/ApisCards/HasApisCard.test.tsx b/plugins/api-docs/src/components/ApisCards/HasApisCard.test.tsx
index ac833251e3..4102bebf0e 100644
--- a/plugins/api-docs/src/components/ApisCards/HasApisCard.test.tsx
+++ b/plugins/api-docs/src/components/ApisCards/HasApisCard.test.tsx
@@ -21,12 +21,11 @@ import {
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { ApiDocsConfig, apiDocsConfigRef } from '../../config';
import { HasApisCard } from './HasApisCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
const apiDocsConfig: jest.Mocked = {
@@ -43,13 +42,15 @@ describe('', () => {
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi).with(
- apiDocsConfigRef,
- apiDocsConfig,
- );
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
diff --git a/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx b/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx
index f2719d0f4b..b29075aee9 100644
--- a/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx
+++ b/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx
@@ -21,12 +21,11 @@ import {
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { ApiDocsConfig, apiDocsConfigRef } from '../../config';
import { ProvidedApisCard } from './ProvidedApisCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
const apiDocsConfig: jest.Mocked = {
@@ -43,13 +42,15 @@ describe('', () => {
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi).with(
- apiDocsConfigRef,
- apiDocsConfig,
- );
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
diff --git a/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.test.tsx b/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.test.tsx
index 274962c346..06022eec69 100644
--- a/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.test.tsx
+++ b/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.test.tsx
@@ -21,11 +21,10 @@ import {
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { ConsumingComponentsCard } from './ConsumingComponentsCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
const catalogApi: jest.Mocked = {
@@ -39,10 +38,10 @@ describe('', () => {
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi);
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
diff --git a/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.test.tsx b/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.test.tsx
index 879944749a..275338d2f9 100644
--- a/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.test.tsx
+++ b/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.test.tsx
@@ -21,11 +21,10 @@ import {
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { ProvidingComponentsCard } from './ProvidingComponentsCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
const catalogApi: jest.Mocked = {
@@ -39,10 +38,10 @@ describe('', () => {
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi);
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
diff --git a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx
index 4a74b238f7..8d0accb254 100644
--- a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx
+++ b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx
@@ -61,12 +61,13 @@ const useStyles = makeStyles(theme => ({
[`& .opblock .opblock-summary-operation-id,
.opblock .opblock-summary-path,
.opblock .opblock-summary-path__deprecated,
- .opblock .opblock-section-header h4,
+ .opblock h4,
+ .opblock h5,
+ .opblock a,
+ .opblock li,
.parameter__name,
.response-col_status,
.response-col_links,
- .responses-inner h4,
- .responses-inner h5,
.opblock-section-header .btn,
.tab li,
.info li,
@@ -89,6 +90,7 @@ const useStyles = makeStyles(theme => ({
color: theme.palette.text.disabled,
},
[`& .opblock-description-wrapper p,
+ .opblock-description-wrapper li,
.opblock-external-docs-wrapper p,
.opblock-title_normal p,
.response-control-media-type__accept-message,
diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md
index 0658b10ebb..a58b028049 100644
--- a/plugins/app-backend/CHANGELOG.md
+++ b/plugins/app-backend/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-app-backend
+## 0.3.19
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/config-loader@0.8.0
+ - @backstage/backend-common@0.9.10
+
## 0.3.18
### Patch Changes
diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json
index d989457c79..ebb0393192 100644
--- a/plugins/app-backend/package.json
+++ b/plugins/app-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-app-backend",
"description": "A Backstage backend plugin that serves the Backstage frontend app",
- "version": "0.3.18",
+ "version": "0.3.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,8 +30,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.8",
- "@backstage/config-loader": "^0.7.1",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/config-loader": "^0.8.0",
"@backstage/config": "^0.1.11",
"@backstage/types": "^0.1.1",
"@types/express": "^4.17.6",
@@ -42,7 +42,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.1",
+ "@backstage/cli": "^0.9.0",
"@backstage/types": "^0.1.1",
"@types/supertest": "^2.0.8",
"msw": "^0.35.0",
diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md
index a11f561986..5dc0cdb861 100644
--- a/plugins/auth-backend/CHANGELOG.md
+++ b/plugins/auth-backend/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-auth-backend
+## 0.4.8
+
+### Patch Changes
+
+- 892c1d9202: Update OAuthAdapter to create identity.token from identity.idToken if it does not exist, and prevent overwrites to identity.toke. Update login page commonProvider to prefer .token over .idToken
+- Updated dependencies
+ - @backstage/catalog-client@0.5.2
+ - @backstage/catalog-model@0.9.7
+ - @backstage/backend-common@0.9.10
+ - @backstage/test-utils@0.1.22
+
## 0.4.7
### Patch Changes
diff --git a/plugins/auth-backend/README.md b/plugins/auth-backend/README.md
index 1fea3346a7..fe2cd05c22 100644
--- a/plugins/auth-backend/README.md
+++ b/plugins/auth-backend/README.md
@@ -34,7 +34,7 @@ Follow this link, [Create new OAuth App](https://github.com/settings/application
1. Set Application Name to `backstage-dev` or something along those lines.
1. You can set the Homepage URL to whatever you want to.
1. The Authorization Callback URL should match the redirect URI set in Backstage.
- 1. Set this to `http://localhost:7000/api/auth/github` for local development.
+ 1. Set this to `http://localhost:7007/api/auth/github` for local development.
1. Set this to `http://{APP_FQDN}:{APP_BACKEND_PORT}/api/auth/github` for non-local deployments.
```bash
@@ -58,7 +58,7 @@ Follow this link, [Add new application](https://gitlab.com/-/profile/application
1. Set Application Name to `backstage-dev` or something along those lines.
1. The Authorization Callback URL should match the redirect URI set in Backstage.
- 1. Set this to `http://localhost:7000/api/auth/gitlab/handler/frame` for local development.
+ 1. Set this to `http://localhost:7007/api/auth/gitlab/handler/frame` for local development.
1. Set this to `http://{APP_FQDN}:{APP_BACKEND_PORT}/api/auth/gitlab/handler/frame` for non-local deployments.
1. Select the following scopes from the list:
- [x] `read_user` Grants read-only access to the authenticated user's profile through the /user API endpoint, which includes username, public email, and full name. Also grants access to read-only API endpoints under /users.
@@ -91,9 +91,9 @@ export AUTH_GITLAB_CLIENT_SECRET=x
Add a new Okta application using the following URI conventions:
-Login redirect URI's: `http://localhost:7000/api/auth/okta/handler/frame`
-Logout redirect URI's: `http://localhost:7000/api/auth/okta/logout`
-Initiate login URI's: `http://localhost:7000/api/auth/okta/start`
+Login redirect URI's: `http://localhost:7007/api/auth/okta/handler/frame`
+Logout redirect URI's: `http://localhost:7007/api/auth/okta/logout`
+Initiate login URI's: `http://localhost:7007/api/auth/okta/start`
Then configure the following environment variables to be used in the `app-config.yaml` file:
@@ -122,7 +122,7 @@ Click [here](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMe
- Give the app a name. e.g. `backstage-dev`
- Select `Accounts in this organizational directory only` under supported account types.
- Enter the callback URL for your backstage backend instance:
- - For local development, this is likely `http://localhost:7000/api/auth/microsoft/handler/frame`
+ - For local development, this is likely `http://localhost:7007/api/auth/microsoft/handler/frame`
- For non-local deployments, this will be `https://{APP_FQDN}:{APP_BACKEND_PORT}/auth/microsoft/handler/frame`
- Click `Register`.
diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json
index e9ec29970b..3a9e8102eb 100644
--- a/plugins/auth-backend/package.json
+++ b/plugins/auth-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-auth-backend",
"description": "A Backstage backend plugin that handles authentication",
- "version": "0.4.7",
+ "version": "0.4.8",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,12 +30,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.9",
- "@backstage/catalog-client": "^0.5.1",
- "@backstage/catalog-model": "^0.9.6",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.4",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/test-utils": "^0.1.22",
"@google-cloud/firestore": "^4.15.1",
"@types/express": "^4.17.6",
"@types/passport": "^1.0.3",
@@ -73,7 +73,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
+ "@backstage/cli": "^0.9.0",
"@types/body-parser": "^1.19.0",
"@types/cookie-parser": "^1.4.2",
"@types/express-session": "^1.17.2",
diff --git a/plugins/auth-backend/scripts/start-saml-idp.sh b/plugins/auth-backend/scripts/start-saml-idp.sh
index b312a4b85e..e12b725191 100755
--- a/plugins/auth-backend/scripts/start-saml-idp.sh
+++ b/plugins/auth-backend/scripts/start-saml-idp.sh
@@ -18,4 +18,4 @@ fi
echo "Downloading and starting SAML-IdP"
export NPM_CONFIG_REGISTRY=https://registry.npmjs.org
-exec npx saml-idp --acsUrl "http://localhost:7000/api/auth/saml/handler/frame" --audience "http://localhost:7000" --port 7001
+exec npx saml-idp --acsUrl "http://localhost:7007/api/auth/saml/handler/frame" --audience "http://localhost:7007" --port 7001
diff --git a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts
index dfb3a0a79a..fa61d69d80 100644
--- a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts
+++ b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts
@@ -176,7 +176,7 @@ describe('OAuthAdapter', () => {
const mockResponse = {
cookie: jest.fn().mockReturnThis(),
- send: jest.fn().mockReturnThis(),
+ end: jest.fn().mockReturnThis(),
status: jest.fn().mockReturnThis(),
} as unknown as express.Response;
@@ -187,6 +187,7 @@ describe('OAuthAdapter', () => {
'',
expect.objectContaining({ path: '/auth/test-provider' }),
);
+ expect(mockResponse.end).toHaveBeenCalledTimes(1);
});
it('gets new access-token when refreshing', async () => {
@@ -230,21 +231,14 @@ describe('OAuthAdapter', () => {
const mockRequest = {
header: () => 'XMLHttpRequest',
- cookies: {
- 'test-provider-refresh-token': 'token',
- },
- query: {},
} as unknown as express.Request;
- const mockResponse = {
- send: jest.fn().mockReturnThis(),
- status: jest.fn().mockReturnThis(),
- } as unknown as express.Response;
+ const mockResponse = {} as unknown as express.Response;
- await oauthProvider.refresh(mockRequest, mockResponse);
- expect(mockResponse.send).toHaveBeenCalledTimes(1);
- expect(mockResponse.send).toHaveBeenCalledWith(
- 'Refresh token not supported for provider: test-provider',
+ await expect(
+ oauthProvider.refresh(mockRequest, mockResponse),
+ ).rejects.toThrow(
+ 'Refresh token is not supported for provider test-provider',
);
});
});
diff --git a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts
index 24b9a0f210..e1a6fdf2f9 100644
--- a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts
+++ b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts
@@ -22,7 +22,12 @@ import {
BackstageIdentity,
AuthProviderConfig,
} from '../../providers/types';
-import { InputError, isError, NotAllowedError } from '@backstage/errors';
+import {
+ AuthenticationError,
+ InputError,
+ isError,
+ NotAllowedError,
+} from '@backstage/errors';
import { TokenIssuer } from '../../identity/types';
import { readState, verifyNonce } from './helpers';
import { postMessageResponse, ensuresXRequestedWith } from '../flow';
@@ -166,29 +171,24 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
async logout(req: express.Request, res: express.Response): Promise {
if (!ensuresXRequestedWith(req)) {
- res.status(401).send('Invalid X-Requested-With header');
- return;
+ throw new AuthenticationError('Invalid X-Requested-With header');
}
// remove refresh token cookie if it is set
this.removeRefreshTokenCookie(res);
- res.status(200).send('logout!');
+ res.status(200).end();
}
async refresh(req: express.Request, res: express.Response): Promise {
if (!ensuresXRequestedWith(req)) {
- res.status(401).send('Invalid X-Requested-With header');
- return;
+ throw new AuthenticationError('Invalid X-Requested-With header');
}
if (!this.handlers.refresh || this.options.disableRefresh) {
- res
- .status(400)
- .send(
- `Refresh token not supported for provider: ${this.options.providerId}`,
- );
- return;
+ throw new InputError(
+ `Refresh token is not supported for provider ${this.options.providerId}`,
+ );
}
try {
@@ -197,7 +197,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
// throw error if refresh token is missing in the request
if (!refreshToken) {
- throw new Error('Missing session cookie');
+ throw new InputError('Missing session cookie');
}
const scope = req.query.scope?.toString() ?? '';
@@ -220,7 +220,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
res.status(200).json(response);
} catch (error) {
- res.status(401).send(String(error));
+ throw new AuthenticationError('Refresh failed', error);
}
}
diff --git a/plugins/auth-backend/src/lib/oauth/OAuthEnvironmentHandler.ts b/plugins/auth-backend/src/lib/oauth/OAuthEnvironmentHandler.ts
index a2f427e741..95a0547a5e 100644
--- a/plugins/auth-backend/src/lib/oauth/OAuthEnvironmentHandler.ts
+++ b/plugins/auth-backend/src/lib/oauth/OAuthEnvironmentHandler.ts
@@ -16,7 +16,7 @@
import express from 'express';
import { Config } from '@backstage/config';
-import { InputError } from '@backstage/errors';
+import { InputError, NotFoundError } from '@backstage/errors';
import { readState } from './helpers';
import { AuthProviderRouteHandlers } from '../../providers/types';
@@ -42,26 +42,26 @@ export class OAuthEnvironmentHandler implements AuthProviderRouteHandlers {
) {}
async start(req: express.Request, res: express.Response): Promise {
- const provider = this.getProviderForEnv(req, res);
- await provider?.start(req, res);
+ const provider = this.getProviderForEnv(req);
+ await provider.start(req, res);
}
async frameHandler(
req: express.Request,
res: express.Response,
): Promise {
- const provider = this.getProviderForEnv(req, res);
- await provider?.frameHandler(req, res);
+ const provider = this.getProviderForEnv(req);
+ await provider.frameHandler(req, res);
}
async refresh(req: express.Request, res: express.Response): Promise {
- const provider = this.getProviderForEnv(req, res);
- await provider?.refresh?.(req, res);
+ const provider = this.getProviderForEnv(req);
+ await provider.refresh?.(req, res);
}
async logout(req: express.Request, res: express.Response): Promise {
- const provider = this.getProviderForEnv(req, res);
- await provider?.logout?.(req, res);
+ const provider = this.getProviderForEnv(req);
+ await provider.logout?.(req, res);
}
private getRequestFromEnv(req: express.Request): string | undefined {
@@ -77,26 +77,20 @@ export class OAuthEnvironmentHandler implements AuthProviderRouteHandlers {
return env;
}
- private getProviderForEnv(
- req: express.Request,
- res: express.Response,
- ): AuthProviderRouteHandlers | undefined {
+ private getProviderForEnv(req: express.Request): AuthProviderRouteHandlers {
const env: string | undefined = this.getRequestFromEnv(req);
if (!env) {
throw new InputError(`Must specify 'env' query to select environment`);
}
- if (!this.handlers.has(env)) {
- res.status(404).send(
- `Missing configuration.
-
-
- For this flow to work you need to supply a valid configuration for the "${env}" environment of provider.`,
+ const handler = this.handlers.get(env);
+ if (!handler) {
+ throw new NotFoundError(
+ `No configuration available for the '${env}' environment of this provider.`,
);
- return undefined;
}
- return this.handlers.get(env);
+ return handler;
}
}
diff --git a/plugins/azure-devops-backend/CHANGELOG.md b/plugins/azure-devops-backend/CHANGELOG.md
index d2fe981eb0..06fc4833c4 100644
--- a/plugins/azure-devops-backend/CHANGELOG.md
+++ b/plugins/azure-devops-backend/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-azure-devops-backend
+## 0.2.1
+
+### Patch Changes
+
+- 2b5ccd2964: Improved Date handling for the Azure DevOps set of plugins by using strings and letting the frontend handle the conversion to DateTime
+- Updated dependencies
+ - @backstage/backend-common@0.9.10
+ - @backstage/plugin-azure-devops-common@0.1.0
+
## 0.2.0
### Minor Changes
diff --git a/plugins/azure-devops-backend/README.md b/plugins/azure-devops-backend/README.md
index 6101794cd1..79db9f5ff1 100644
--- a/plugins/azure-devops-backend/README.md
+++ b/plugins/azure-devops-backend/README.md
@@ -63,7 +63,7 @@ Here's how to get the backend up and running:
```
4. Now run `yarn start-backend` from the repo root
-5. Finally open `http://localhost:7000/api/azure-devops/health` in a browser and it should return `{"status":"ok"}`
+5. Finally open `http://localhost:7007/api/azure-devops/health` in a browser and it should return `{"status":"ok"}`
## Links
diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json
index 901ad0b960..6d213cbce6 100644
--- a/plugins/azure-devops-backend/package.json
+++ b/plugins/azure-devops-backend/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-azure-devops-backend",
- "version": "0.2.0",
+ "version": "0.2.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,9 +20,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.9",
+ "@backstage/backend-common": "^0.9.10",
"@backstage/config": "^0.1.11",
- "@backstage/plugin-azure-devops-common": "^0.0.2",
+ "@backstage/plugin-azure-devops-common": "^0.1.0",
"@types/express": "^4.17.6",
"azure-devops-node-api": "^11.0.1",
"express": "^4.17.1",
@@ -31,7 +31,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
+ "@backstage/cli": "^0.9.0",
"@types/supertest": "^2.0.8",
"supertest": "^4.0.2",
"msw": "^0.35.0"
diff --git a/plugins/azure-devops-backend/src/run.ts b/plugins/azure-devops-backend/src/run.ts
index addfdfd6d7..53d4e4334a 100644
--- a/plugins/azure-devops-backend/src/run.ts
+++ b/plugins/azure-devops-backend/src/run.ts
@@ -18,7 +18,7 @@ import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
-const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7000;
+const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
diff --git a/plugins/azure-devops-common/CHANGELOG.md b/plugins/azure-devops-common/CHANGELOG.md
index b414cd3ce6..4a834fb068 100644
--- a/plugins/azure-devops-common/CHANGELOG.md
+++ b/plugins/azure-devops-common/CHANGELOG.md
@@ -1,5 +1,11 @@
# @backstage/plugin-azure-devops-common
+## 0.1.0
+
+### Minor Changes
+
+- 2b5ccd2964: Improved Date handling for the Azure DevOps set of plugins by using strings and letting the frontend handle the conversion to DateTime
+
## 0.0.2
### Patch Changes
diff --git a/plugins/azure-devops-common/package.json b/plugins/azure-devops-common/package.json
index a1ddddcbe0..fe9df644b1 100644
--- a/plugins/azure-devops-common/package.json
+++ b/plugins/azure-devops-common/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-azure-devops-common",
- "version": "0.0.2",
+ "version": "0.1.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -29,7 +29,7 @@
"clean": "backstage-cli clean"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2"
+ "@backstage/cli": "^0.9.0"
},
"files": [
"dist"
diff --git a/plugins/azure-devops/CHANGELOG.md b/plugins/azure-devops/CHANGELOG.md
index 2f75f64236..0bcd9bc686 100644
--- a/plugins/azure-devops/CHANGELOG.md
+++ b/plugins/azure-devops/CHANGELOG.md
@@ -1,5 +1,19 @@
# @backstage/plugin-azure-devops
+## 0.1.4
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- b5eac957f2: Added entity view for Azure Repo Pull Requests
+- 2b5ccd2964: Improved Date handling for the Azure DevOps set of plugins by using strings and letting the frontend handle the conversion to DateTime
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+ - @backstage/plugin-azure-devops-common@0.1.0
+
## 0.1.3
### Patch Changes
diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md
index f33bd3bdb6..7b39dae443 100644
--- a/plugins/azure-devops/README.md
+++ b/plugins/azure-devops/README.md
@@ -84,7 +84,7 @@ To get the Azure Pipelines component working you'll need to do the following two
**Notes:**
- The `if` prop is optional on the `EntitySwitch.Case`, you can remove it if you always want to see the tab even if the entity being viewed does not have the needed annotation
-- The `defaultLimit` proper on the `EntityAzurePipelinesContent` will set the max number of Builds you would like to see, if not set this will default to 10
+- The `defaultLimit` property on the `EntityAzurePipelinesContent` will set the max number of Builds you would like to see, if not set this will default to 10
### Azure Repos Component
@@ -98,12 +98,12 @@ To get the Azure Repos component working you'll need to do the following two ste
yarn add @backstage/plugin-azure-devops
```
-2. Second we need to add the `EntityAzureReposContent` extension to the entity page in your app:
+2. Second we need to add the `EntityAzurePullRequestsContent` extension to the entity page in your app:
```tsx
// In packages/app/src/components/catalog/EntityPage.tsx
import {
- EntityAzureReposContent,
+ EntityAzurePullRequestsContent,
isAzureDevOpsAvailable,
} from '@backstage/plugin-azure-devops';
@@ -112,7 +112,7 @@ To get the Azure Repos component working you'll need to do the following two ste
// ...
-
+
// ...
@@ -122,7 +122,7 @@ To get the Azure Repos component working you'll need to do the following two ste
- You'll need to add the `EntityLayout.Route` above from step 2 to all the entity sections you want to see Pull Requests in. For example if you wanted to see Pull Requests when looking at Website entities then you would need to add this to the `websiteEntityPage` section.
- The `if` prop is optional on the `EntityLayout.Route`, you can remove it if you always want to see the tab even if the entity being viewed does not have the needed annotation
-- The `defaultLimit` proper on the `EntityAzureReposContent` will set the max number of Pull Requests you would like to see, if not set this will default to 10
+- The `defaultLimit` property on the `EntityAzurePullRequestsContent` will set the max number of Pull Requests you would like to see, if not set this will default to 10
## Limitations
diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json
index 3f1876b974..9d235b0641 100644
--- a/plugins/azure-devops/package.json
+++ b/plugins/azure-devops/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-azure-devops",
- "version": "0.1.3",
+ "version": "0.1.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -27,12 +27,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.6",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.4",
- "@backstage/plugin-azure-devops-common": "^0.0.2",
- "@backstage/plugin-catalog-react": "^0.6.3",
+ "@backstage/plugin-azure-devops-common": "^0.1.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -45,10 +45,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json
index 51a181612a..2186c8d52e 100644
--- a/plugins/badges-backend/package.json
+++ b/plugins/badges-backend/package.json
@@ -31,9 +31,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.7",
- "@backstage/catalog-client": "^0.5.0",
- "@backstage/catalog-model": "^0.9.5",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.10",
"@backstage/errors": "^0.1.3",
"@types/express": "^4.17.6",
@@ -46,7 +46,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
+ "@backstage/cli": "^0.9.0",
"@types/supertest": "^2.0.8",
"supertest": "^6.1.3"
},
diff --git a/plugins/badges-backend/src/run.ts b/plugins/badges-backend/src/run.ts
index addfdfd6d7..53d4e4334a 100644
--- a/plugins/badges-backend/src/run.ts
+++ b/plugins/badges-backend/src/run.ts
@@ -18,7 +18,7 @@ import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
-const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7000;
+const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
diff --git a/plugins/badges-backend/src/service/router.test.ts b/plugins/badges-backend/src/service/router.test.ts
index 51ad1e7e11..286a2335f1 100644
--- a/plugins/badges-backend/src/service/router.test.ts
+++ b/plugins/badges-backend/src/service/router.test.ts
@@ -73,7 +73,7 @@ describe('createRouter', () => {
config = new ConfigReader({
backend: {
baseUrl: 'http://127.0.0.1',
- listen: { port: 7000 },
+ listen: { port: 7007 },
},
});
discovery = SingleHostDiscovery.fromConfig(config);
diff --git a/plugins/badges/CHANGELOG.md b/plugins/badges/CHANGELOG.md
index 3a6ed61717..44bc597d0a 100644
--- a/plugins/badges/CHANGELOG.md
+++ b/plugins/badges/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-badges
+## 0.2.14
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.2.13
### Patch Changes
diff --git a/plugins/badges/package.json b/plugins/badges/package.json
index 0c792808bc..4d02d64237 100644
--- a/plugins/badges/package.json
+++ b/plugins/badges/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-badges",
"description": "A Backstage plugin that generates README badges for your entities",
- "version": "0.2.13",
+ "version": "0.2.14",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -27,11 +27,11 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.3",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -42,10 +42,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/badges/src/components/EntityBadgesDialog.test.tsx b/plugins/badges/src/components/EntityBadgesDialog.test.tsx
index 1f5ee94e04..ea44eb20fc 100644
--- a/plugins/badges/src/components/EntityBadgesDialog.test.tsx
+++ b/plugins/badges/src/components/EntityBadgesDialog.test.tsx
@@ -16,12 +16,11 @@
import React from 'react';
import { Entity } from '@backstage/catalog-model';
-import { renderWithEffects } from '@backstage/test-utils';
+import { renderWithEffects, TestApiProvider } from '@backstage/test-utils';
import { BadgesApi, badgesApiRef } from '../api';
import { EntityBadgesDialog } from './EntityBadgesDialog';
import { EntityProvider } from '@backstage/plugin-catalog-react';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { ErrorApi, errorApiRef } from '@backstage/core-plugin-api';
describe('EntityBadgesDialog', () => {
@@ -42,16 +41,16 @@ describe('EntityBadgesDialog', () => {
const mockEntity = { metadata: { name: 'mock' } } as Entity;
const rendered = await renderWithEffects(
-
- ,
+ ,
);
await expect(
diff --git a/plugins/bazaar-backend/CHANGELOG.md b/plugins/bazaar-backend/CHANGELOG.md
new file mode 100644
index 0000000000..88e646b5e3
--- /dev/null
+++ b/plugins/bazaar-backend/CHANGELOG.md
@@ -0,0 +1,10 @@
+# @backstage/plugin-bazaar-backend
+
+## 0.1.2
+
+### Patch Changes
+
+- f6ba309d9e: A Bazaar project has been extended with the following fields: size, start date (optional), end date (optional) and a responsible person.
+- Updated dependencies
+ - @backstage/backend-common@0.9.10
+ - @backstage/backend-test-utils@0.1.9
diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json
index a9ac0153b8..a6610493e2 100644
--- a/plugins/bazaar-backend/package.json
+++ b/plugins/bazaar-backend/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-bazaar-backend",
- "version": "0.1.1",
+ "version": "0.1.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,8 +20,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.7",
- "@backstage/backend-test-utils": "^0.1.8",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/backend-test-utils": "^0.1.9",
"@backstage/config": "^0.1.5",
"@types/express": "^4.17.6",
"express": "^4.17.1",
@@ -31,7 +31,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0"
+ "@backstage/cli": "^0.9.0"
},
"files": [
"dist",
diff --git a/plugins/bazaar-backend/src/run.ts b/plugins/bazaar-backend/src/run.ts
index 54d2716290..0a3ed2b7f0 100644
--- a/plugins/bazaar-backend/src/run.ts
+++ b/plugins/bazaar-backend/src/run.ts
@@ -18,7 +18,7 @@ import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
-const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7000;
+const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
diff --git a/plugins/bazaar/CHANGELOG.md b/plugins/bazaar/CHANGELOG.md
index 731f62b9e9..8988bf5d62 100644
--- a/plugins/bazaar/CHANGELOG.md
+++ b/plugins/bazaar/CHANGELOG.md
@@ -1,5 +1,19 @@
# @backstage/plugin-bazaar
+## 0.1.4
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- f6ba309d9e: A Bazaar project has been extended with the following fields: size, start date (optional), end date (optional) and a responsible person.
+- Updated dependencies
+ - @backstage/plugin-catalog@0.7.3
+ - @backstage/cli@0.9.0
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.1.3
### Patch Changes
diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json
index 094741bf36..fd07a3b5c7 100644
--- a/plugins/bazaar/package.json
+++ b/plugins/bazaar/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-bazaar",
- "version": "0.1.3",
+ "version": "0.1.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,12 +21,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/cli": "^0.8.2",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog": "^0.7.2",
- "@backstage/plugin-catalog-react": "^0.6.3",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog": "^0.7.3",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
@@ -41,8 +41,8 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/dev-utils": "^0.2.12",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/dev-utils": "^0.2.13",
"@testing-library/jest-dom": "^5.10.1",
"cross-fetch": "^3.0.6"
},
diff --git a/plugins/bitrise/CHANGELOG.md b/plugins/bitrise/CHANGELOG.md
index 7e364ca294..874cbe2c6c 100644
--- a/plugins/bitrise/CHANGELOG.md
+++ b/plugins/bitrise/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-bitrise
+## 0.1.17
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.1.16
### Patch Changes
diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json
index 5ebfd453a2..92cd9693e1 100644
--- a/plugins/bitrise/package.json
+++ b/plugins/bitrise/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-bitrise",
"description": "A Backstage plugin that integrates towards Bitrise",
- "version": "0.1.16",
+ "version": "0.1.17",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,10 +21,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -39,10 +39,10 @@
"recharts": "^1.8.5"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/bitrise/src/components/BitriseBuildsTableComponent/BitriseBuildsTableComponent.test.tsx b/plugins/bitrise/src/components/BitriseBuildsTableComponent/BitriseBuildsTableComponent.test.tsx
index a206e28de6..82faa3e39c 100644
--- a/plugins/bitrise/src/components/BitriseBuildsTableComponent/BitriseBuildsTableComponent.test.tsx
+++ b/plugins/bitrise/src/components/BitriseBuildsTableComponent/BitriseBuildsTableComponent.test.tsx
@@ -21,14 +21,11 @@ import { setupServer } from 'msw/node';
import {
setupRequestMockHandlers,
renderInTestApp,
+ TestApiRegistry,
} from '@backstage/test-utils';
import { useBitriseBuilds } from '../../hooks/useBitriseBuilds';
import { BitriseBuildsTable } from './BitriseBuildsTableComponent';
-import {
- ApiProvider,
- ApiRegistry,
- UrlPatternDiscovery,
-} from '@backstage/core-app-api';
+import { ApiProvider, UrlPatternDiscovery } from '@backstage/core-app-api';
jest.mock('../../hooks/useBitriseBuilds', () => ({
useBitriseBuilds: jest.fn(),
@@ -40,10 +37,13 @@ describe('BitriseBuildsFetchComponent', () => {
setupRequestMockHandlers(server);
const mockBaseUrl = 'http://backstage:9191';
const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl);
- let apis: ApiRegistry;
+ let apis: TestApiRegistry;
beforeEach(() => {
- apis = ApiRegistry.with(bitriseApiRef, new BitriseClientApi(discoveryApi));
+ apis = TestApiRegistry.from([
+ bitriseApiRef,
+ new BitriseClientApi(discoveryApi),
+ ]);
});
it('should display `no records` message if there are no builds', async () => {
diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json
index a8c3b71345..5e3cec24d9 100644
--- a/plugins/catalog-backend-module-ldap/package.json
+++ b/plugins/catalog-backend-module-ldap/package.json
@@ -29,10 +29,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.6",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.4",
- "@backstage/plugin-catalog-backend": "^0.17.2",
+ "@backstage/plugin-catalog-backend": "^0.17.4",
"@backstage/types": "^0.1.1",
"@types/ldapjs": "^2.2.0",
"ldapjs": "^2.2.0",
@@ -40,7 +40,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.8.1",
+ "@backstage/cli": "^0.9.0",
"@types/lodash": "^4.14.151"
},
"files": [
diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json
index b3c9494f78..222f56b022 100644
--- a/plugins/catalog-backend-module-msgraph/package.json
+++ b/plugins/catalog-backend-module-msgraph/package.json
@@ -30,9 +30,9 @@
},
"dependencies": {
"@azure/msal-node": "^1.1.0",
- "@backstage/catalog-model": "^0.9.5",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.10",
- "@backstage/plugin-catalog-backend": "^0.17.3",
+ "@backstage/plugin-catalog-backend": "^0.17.4",
"@microsoft/microsoft-graph-types": "^2.6.0",
"cross-fetch": "^3.0.6",
"lodash": "^4.17.21",
@@ -41,9 +41,9 @@
"qs": "^6.9.4"
},
"devDependencies": {
- "@backstage/backend-common": "^0.9.9",
- "@backstage/cli": "^0.8.2",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/test-utils": "^0.1.22",
"@types/lodash": "^4.14.151",
"msw": "^0.35.0"
},
diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md
index abb50a345c..92b57f3483 100644
--- a/plugins/catalog-backend/CHANGELOG.md
+++ b/plugins/catalog-backend/CHANGELOG.md
@@ -1,5 +1,21 @@
# @backstage/plugin-catalog-backend
+## 0.17.4
+
+### Patch Changes
+
+- 5d2a7303bd: This fixes a bug where locations couldn't be added unless the processing engine is started.
+ It's now possible to run the catalog backend without starting the processing engine and still allowing locations registrations.
+
+ This is done by refactor the `EntityProvider.connect` to happen outside the engine.
+
+- 06934f2f52: Adjust entity query construction to ensure sub-queries are always isolated from one another.
+- b90fc74d70: adds getDefaultProcessor method to CatalogBuilder
+- Updated dependencies
+ - @backstage/catalog-client@0.5.2
+ - @backstage/catalog-model@0.9.7
+ - @backstage/backend-common@0.9.10
+
## 0.17.3
### Patch Changes
diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md
index 6660912dda..7363a803c8 100644
--- a/plugins/catalog-backend/api-report.md
+++ b/plugins/catalog-backend/api-report.md
@@ -174,6 +174,26 @@ export class AwsS3DiscoveryProcessor implements CatalogProcessor {
): Promise;
}
+// Warning: (ae-missing-release-tag) "AzureDevOpsDiscoveryProcessor" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public
+export class AzureDevOpsDiscoveryProcessor implements CatalogProcessor {
+ constructor(options: { integrations: ScmIntegrations; logger: Logger_2 });
+ // (undocumented)
+ static fromConfig(
+ config: Config,
+ options: {
+ logger: Logger_2;
+ },
+ ): AzureDevOpsDiscoveryProcessor;
+ // (undocumented)
+ readLocation(
+ location: LocationSpec,
+ _optional: boolean,
+ emit: CatalogProcessorEmit,
+ ): Promise;
+}
+
// Warning: (ae-missing-release-tag) "BitbucketDiscoveryProcessor" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@@ -846,8 +866,7 @@ export type EntitiesResponse = {
// @public
export type EntitiesSearchFilter = {
key: string;
- matchValueIn?: string[];
- matchValueExists?: boolean;
+ values?: string[];
};
// Warning: (ae-missing-release-tag) "entity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
@@ -877,6 +896,9 @@ export type EntityFilter =
| {
anyOf: EntityFilter[];
}
+ | {
+ not: EntityFilter;
+ }
| EntitiesSearchFilter;
// Warning: (ae-missing-release-tag) "EntityPagination" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
@@ -1546,9 +1568,9 @@ export class UrlReaderProcessor implements CatalogProcessor {
// Warnings were encountered during analysis:
//
-// src/catalog/types.d.ts:97:8 - (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
-// src/catalog/types.d.ts:98:8 - (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
-// src/catalog/types.d.ts:99:8 - (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
+// src/catalog/types.d.ts:94:8 - (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
+// src/catalog/types.d.ts:95:8 - (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
+// src/catalog/types.d.ts:96:8 - (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
// src/ingestion/processors/GithubMultiOrgReaderProcessor.d.ts:23:9 - (ae-forgotten-export) The symbol "GithubMultiOrgConfig" needs to be exported by the entry point index.d.ts
// src/ingestion/types.d.ts:8:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/legacy/database/types.d.ts:98:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json
index f13ff2d66c..a9a35d5858 100644
--- a/plugins/catalog-backend/package.json
+++ b/plugins/catalog-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend",
"description": "The Backstage backend plugin that provides the Backstage catalog",
- "version": "0.17.3",
+ "version": "0.17.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,9 +30,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.9",
- "@backstage/catalog-client": "^0.5.1",
- "@backstage/catalog-model": "^0.9.6",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.4",
"@backstage/integration": "^0.6.9",
@@ -62,9 +62,9 @@
"yup": "^0.32.9"
},
"devDependencies": {
- "@backstage/backend-test-utils": "^0.1.8",
- "@backstage/cli": "^0.8.2",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/backend-test-utils": "^0.1.9",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/test-utils": "^0.1.22",
"@types/core-js": "^2.5.4",
"@types/git-url-parse": "^9.0.0",
"@types/lodash": "^4.14.151",
diff --git a/plugins/catalog-backend/src/catalog/types.ts b/plugins/catalog-backend/src/catalog/types.ts
index df693bfd42..2a18783679 100644
--- a/plugins/catalog-backend/src/catalog/types.ts
+++ b/plugins/catalog-backend/src/catalog/types.ts
@@ -25,6 +25,7 @@ import { Entity, EntityRelationSpec } from '@backstage/catalog-model';
export type EntityFilter =
| { allOf: EntityFilter[] }
| { anyOf: EntityFilter[] }
+ | { not: EntityFilter }
| EntitiesSearchFilter;
/**
@@ -50,16 +51,10 @@ export type EntitiesSearchFilter = {
/**
* Match on plain equality of values.
*
- * If undefined, this factor is not taken into account. Otherwise, match on
- * values that are equal to any of the given array items. Matches are always
- * case insensitive.
+ * Match on values that are equal to any of the given array items. Matches are
+ * always case insensitive.
*/
- matchValueIn?: string[];
-
- /**
- * Match on existence of key.
- */
- matchValueExists?: boolean;
+ values?: string[];
};
export type PageInfo =
diff --git a/plugins/catalog-backend/src/ingestion/processors/AzureDevOpsDiscoveryProcessor.test.ts b/plugins/catalog-backend/src/ingestion/processors/AzureDevOpsDiscoveryProcessor.test.ts
new file mode 100644
index 0000000000..ab053e8748
--- /dev/null
+++ b/plugins/catalog-backend/src/ingestion/processors/AzureDevOpsDiscoveryProcessor.test.ts
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { getVoidLogger } from '@backstage/backend-common';
+import { LocationSpec } from '@backstage/catalog-model';
+import { ConfigReader } from '@backstage/config';
+import { codeSearch } from './azure';
+import {
+ AzureDevOpsDiscoveryProcessor,
+ parseUrl,
+} from './AzureDevOpsDiscoveryProcessor';
+
+jest.mock('./azure');
+const mockCodeSearch = codeSearch as jest.MockedFunction;
+
+describe('AzureDevOpsDiscoveryProcessor', () => {
+ describe('parseUrl', () => {
+ it('parses well formed URLs', () => {
+ expect(parseUrl('https://dev.azure.com/my-org/my-proj')).toEqual({
+ baseUrl: 'https://dev.azure.com',
+ org: 'my-org',
+ project: 'my-proj',
+ repo: '',
+ catalogPath: '/catalog-info.yaml',
+ });
+
+ expect(
+ parseUrl(
+ 'https://dev.azure.com/spotify/engineering/_git/backstage?path=/catalog.yaml',
+ ),
+ ).toEqual({
+ baseUrl: 'https://dev.azure.com',
+ org: 'spotify',
+ project: 'engineering',
+ repo: 'backstage',
+ catalogPath: '/catalog.yaml',
+ });
+
+ expect(
+ parseUrl(
+ 'https://azuredevops.mycompany.com/spotify/engineering/_git/backstage?path=/src/*/catalog.yaml',
+ ),
+ ).toEqual({
+ baseUrl: 'https://azuredevops.mycompany.com',
+ org: 'spotify',
+ project: 'engineering',
+ repo: 'backstage',
+ catalogPath: '/src/*/catalog.yaml',
+ });
+ });
+
+ it('throws on incorrectly formed URLs', () => {
+ expect(() => parseUrl('https://dev.azure.com')).toThrow();
+ expect(() => parseUrl('https://dev.azure.com//')).toThrow();
+ expect(() => parseUrl('https://dev.azure.com//foo')).toThrow();
+ });
+ });
+
+ describe('reject unrelated entries', () => {
+ it('rejects unknown types', async () => {
+ const processor = AzureDevOpsDiscoveryProcessor.fromConfig(
+ new ConfigReader({
+ integrations: {
+ azure: [{ host: 'dev.azure.com', token: 'blob' }],
+ },
+ }),
+ { logger: getVoidLogger() },
+ );
+ const location: LocationSpec = {
+ type: 'not-azure-discovery',
+ target: 'https://dev.azure.com',
+ };
+ await expect(
+ processor.readLocation(location, false, () => {}),
+ ).resolves.toBeFalsy();
+ });
+ });
+
+ it('rejects unknown targets', async () => {
+ const processor = AzureDevOpsDiscoveryProcessor.fromConfig(
+ new ConfigReader({
+ integrations: {
+ github: [
+ { host: 'dev.azure.com', token: 'blob' },
+ { host: 'azure.myorg.com', token: 'blob' },
+ ],
+ },
+ }),
+ { logger: getVoidLogger() },
+ );
+ const location: LocationSpec = {
+ type: 'azure-discovery',
+ target: 'https://not.azure.com/org/project',
+ };
+ await expect(
+ processor.readLocation(location, false, () => {}),
+ ).rejects.toThrow(
+ /There is no Azure integration that matches https:\/\/not.azure.com\/org\/project. Please add a configuration entry for it under integrations.azure/,
+ );
+ });
+
+ describe('handles repositories', () => {
+ const processor = AzureDevOpsDiscoveryProcessor.fromConfig(
+ new ConfigReader({
+ integrations: {
+ github: [{ host: 'dev.azure.com', token: 'blob' }],
+ },
+ }),
+ { logger: getVoidLogger() },
+ );
+
+ beforeEach(() => {
+ mockCodeSearch.mockClear();
+ });
+
+ it('output all locations found on from code search', async () => {
+ const location: LocationSpec = {
+ type: 'azure-discovery',
+ target: 'https://dev.azure.com/shopify/engineering',
+ };
+ mockCodeSearch.mockResolvedValueOnce([
+ {
+ fileName: 'catalog-info.yaml',
+ path: '/catalog-info.yaml',
+ repository: {
+ name: 'backstage',
+ },
+ },
+ {
+ fileName: 'catalog-info.yaml',
+ path: '/src/catalog-info.yaml',
+ repository: {
+ name: 'ios-app',
+ },
+ },
+ ]);
+ const emitter = jest.fn();
+
+ await processor.readLocation(location, false, emitter);
+
+ expect(mockCodeSearch).toHaveBeenCalledWith(
+ { host: 'dev.azure.com' },
+ 'shopify',
+ 'engineering',
+ '',
+ '/catalog-info.yaml',
+ );
+ expect(emitter).toHaveBeenCalledTimes(2);
+ expect(emitter).toHaveBeenCalledWith({
+ type: 'location',
+ location: {
+ type: 'url',
+ target:
+ 'https://dev.azure.com/shopify/engineering/_git/backstage?path=/catalog-info.yaml',
+ },
+ optional: true,
+ });
+ expect(emitter).toHaveBeenCalledWith({
+ type: 'location',
+ location: {
+ type: 'url',
+ target:
+ 'https://dev.azure.com/shopify/engineering/_git/ios-app?path=/src/catalog-info.yaml',
+ },
+ optional: true,
+ });
+ });
+
+ it('output single locations from code search', async () => {
+ const location: LocationSpec = {
+ type: 'azure-discovery',
+ target: 'https://dev.azure.com/shopify/engineering/_git/backstage',
+ };
+ mockCodeSearch.mockResolvedValueOnce([
+ {
+ fileName: 'catalog-info.yaml',
+ path: '/catalog-info.yaml',
+ repository: {
+ name: 'backstage',
+ },
+ },
+ ]);
+ const emitter = jest.fn();
+
+ await processor.readLocation(location, false, emitter);
+
+ expect(mockCodeSearch).toHaveBeenCalledWith(
+ { host: 'dev.azure.com' },
+ 'shopify',
+ 'engineering',
+ 'backstage',
+ '/catalog-info.yaml',
+ );
+ expect(emitter).toHaveBeenCalledTimes(1);
+ expect(emitter).toHaveBeenCalledWith({
+ type: 'location',
+ location: {
+ type: 'url',
+ target:
+ 'https://dev.azure.com/shopify/engineering/_git/backstage?path=/catalog-info.yaml',
+ },
+ optional: true,
+ });
+ });
+
+ it('output single locations with different file name from code search', async () => {
+ const location: LocationSpec = {
+ type: 'azure-discovery',
+ target:
+ 'https://dev.azure.com/shopify/engineering?path=/src/*/catalog.yaml',
+ };
+ mockCodeSearch.mockResolvedValueOnce([
+ {
+ fileName: 'catalog.yaml',
+ path: '/src/main/catalog.yaml',
+ repository: {
+ name: 'backstage',
+ },
+ },
+ ]);
+ const emitter = jest.fn();
+
+ await processor.readLocation(location, false, emitter);
+
+ expect(mockCodeSearch).toHaveBeenCalledWith(
+ { host: 'dev.azure.com' },
+ 'shopify',
+ 'engineering',
+ '',
+ '/src/*/catalog.yaml',
+ );
+ expect(emitter).toHaveBeenCalledTimes(1);
+ expect(emitter).toHaveBeenCalledWith({
+ type: 'location',
+ location: {
+ type: 'url',
+ target:
+ 'https://dev.azure.com/shopify/engineering/_git/backstage?path=/src/main/catalog.yaml',
+ },
+ optional: true,
+ });
+ });
+
+ it('output nothing when code search does not find anything', async () => {
+ const location: LocationSpec = {
+ type: 'azure-discovery',
+ target: 'https://dev.azure.com/shopify/engineering/_git/backstage',
+ };
+ mockCodeSearch.mockResolvedValueOnce([]);
+ const emitter = jest.fn();
+
+ await processor.readLocation(location, false, emitter);
+
+ expect(mockCodeSearch).toHaveBeenCalledWith(
+ { host: 'dev.azure.com' },
+ 'shopify',
+ 'engineering',
+ 'backstage',
+ '/catalog-info.yaml',
+ );
+ expect(emitter).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/plugins/catalog-backend/src/ingestion/processors/AzureDevOpsDiscoveryProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/AzureDevOpsDiscoveryProcessor.ts
new file mode 100644
index 0000000000..58ee2155e9
--- /dev/null
+++ b/plugins/catalog-backend/src/ingestion/processors/AzureDevOpsDiscoveryProcessor.ts
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { LocationSpec } from '@backstage/catalog-model';
+import { Config } from '@backstage/config';
+import { ScmIntegrations } from '@backstage/integration';
+import { Logger } from 'winston';
+import * as results from './results';
+import { CatalogProcessor, CatalogProcessorEmit } from './types';
+import { codeSearch } from './azure';
+
+/**
+ * Extracts repositories out of an Azure DevOps org.
+ *
+ * The following will create locations for all projects which have a catalog-info.yaml
+ * on the default branch. The first is shorthand for the second.
+ *
+ * target: "https://dev.azure.com/org/project"
+ * or
+ * target: https://dev.azure.com/org/project?path=/catalog-info.yaml
+ *
+ * You may also explicitly specify a single repo:
+ *
+ * target: https://dev.azure.com/org/project/_git/repo
+ **/
+export class AzureDevOpsDiscoveryProcessor implements CatalogProcessor {
+ private readonly integrations: ScmIntegrations;
+ private readonly logger: Logger;
+
+ static fromConfig(config: Config, options: { logger: Logger }) {
+ const integrations = ScmIntegrations.fromConfig(config);
+
+ return new AzureDevOpsDiscoveryProcessor({
+ ...options,
+ integrations,
+ });
+ }
+
+ constructor(options: { integrations: ScmIntegrations; logger: Logger }) {
+ this.integrations = options.integrations;
+ this.logger = options.logger;
+ }
+
+ async readLocation(
+ location: LocationSpec,
+ _optional: boolean,
+ emit: CatalogProcessorEmit,
+ ): Promise {
+ if (location.type !== 'azure-discovery') {
+ return false;
+ }
+
+ const azureConfig = this.integrations.azure.byUrl(location.target)?.config;
+ if (!azureConfig) {
+ throw new Error(
+ `There is no Azure integration that matches ${location.target}. Please add a configuration entry for it under integrations.azure`,
+ );
+ }
+
+ const { baseUrl, org, project, repo, catalogPath } = parseUrl(
+ location.target,
+ );
+ this.logger.info(
+ `Reading Azure DevOps repositories from ${location.target}`,
+ );
+
+ const files = await codeSearch(
+ azureConfig,
+ org,
+ project,
+ repo,
+ catalogPath,
+ );
+
+ this.logger.debug(
+ `Found ${files.length} files in Azure DevOps from ${location.target}.`,
+ );
+
+ for (const file of files) {
+ emit(
+ results.location(
+ {
+ type: 'url',
+ target: `${baseUrl}/${org}/${project}/_git/${file.repository.name}?path=${file.path}`,
+ },
+ // Not all locations may actually exist, since the user defined them as a wildcard pattern.
+ // Thus, we emit them as optional and let the downstream processor find them while not outputting
+ // an error if it couldn't.
+ true,
+ ),
+ );
+ }
+
+ return true;
+ }
+}
+
+/**
+ * parseUrl extracts segments from the Azure DevOps URL.
+ **/
+export function parseUrl(urlString: string): {
+ baseUrl: string;
+ org: string;
+ project: string;
+ repo: string;
+ catalogPath: string;
+} {
+ const url = new URL(urlString);
+ const path = url.pathname.substr(1).split('/');
+
+ const catalogPath = url.searchParams.get('path') || '/catalog-info.yaml';
+
+ if (path.length === 2 && path[0].length && path[1].length) {
+ return {
+ baseUrl: url.origin,
+ org: decodeURIComponent(path[0]),
+ project: decodeURIComponent(path[1]),
+ repo: '',
+ catalogPath,
+ };
+ } else if (
+ path.length === 4 &&
+ path[0].length &&
+ path[1].length &&
+ path[2].length &&
+ path[3].length
+ ) {
+ return {
+ baseUrl: url.origin,
+ org: decodeURIComponent(path[0]),
+ project: decodeURIComponent(path[1]),
+ repo: decodeURIComponent(path[3]),
+ catalogPath,
+ };
+ }
+
+ throw new Error(`Failed to parse ${urlString}`);
+}
diff --git a/plugins/catalog-backend/src/ingestion/processors/azure/azure.test.ts b/plugins/catalog-backend/src/ingestion/processors/azure/azure.test.ts
new file mode 100644
index 0000000000..67cc120bab
--- /dev/null
+++ b/plugins/catalog-backend/src/ingestion/processors/azure/azure.test.ts
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { setupServer } from 'msw/node';
+import { setupRequestMockHandlers } from '@backstage/test-utils';
+import { rest } from 'msw';
+import { codeSearch, CodeSearchResponse } from './azure';
+
+describe('azure', () => {
+ const server = setupServer();
+ setupRequestMockHandlers(server);
+
+ describe('codeSearch', () => {
+ it('returns empty when nothing is found', async () => {
+ const response: CodeSearchResponse = { count: 0, results: [] };
+
+ server.use(
+ rest.post(
+ `https://almsearch.dev.azure.com/shopify/engineering/_apis/search/codesearchresults`,
+ (req, res, ctx) => {
+ expect(req.headers.get('Authorization')).toBe('Basic OkFCQw==');
+ expect(req.body).toEqual({
+ searchText: 'path:/catalog-info.yaml repo:*',
+ $skip: 0,
+ $top: 1000,
+ });
+ return res(ctx.json(response));
+ },
+ ),
+ );
+
+ await expect(
+ codeSearch(
+ { host: 'dev.azure.com', token: 'ABC' },
+ 'shopify',
+ 'engineering',
+ '',
+ '/catalog-info.yaml',
+ ),
+ ).resolves.toEqual([]);
+ });
+ });
+
+ it('returns entries when request matches some files', async () => {
+ const response: CodeSearchResponse = {
+ count: 2,
+ results: [
+ {
+ fileName: 'catalog-info.yaml',
+ path: '/catalog-info.yaml',
+ repository: {
+ name: 'backstage',
+ },
+ },
+ {
+ fileName: 'catalog-info.yaml',
+ path: '/catalog-info.yaml',
+ repository: {
+ name: 'ios-app',
+ },
+ },
+ ],
+ };
+
+ server.use(
+ rest.post(
+ `https://almsearch.dev.azure.com/shopify/engineering/_apis/search/codesearchresults`,
+ (req, res, ctx) => {
+ expect(req.headers.get('Authorization')).toBe('Basic OkFCQw==');
+ expect(req.body).toEqual({
+ searchText: 'path:/catalog-info.yaml repo:*',
+ $skip: 0,
+ $top: 1000,
+ });
+ return res(ctx.json(response));
+ },
+ ),
+ );
+
+ await expect(
+ codeSearch(
+ { host: 'dev.azure.com', token: 'ABC' },
+ 'shopify',
+ 'engineering',
+ '',
+ '/catalog-info.yaml',
+ ),
+ ).resolves.toEqual(response.results);
+ });
+
+ it('searches in specific repo if parameter is set', async () => {
+ const response: CodeSearchResponse = {
+ count: 1,
+ results: [
+ {
+ fileName: 'catalog-info.yaml',
+ path: '/catalog-info.yaml',
+ repository: {
+ name: 'backstage',
+ },
+ },
+ ],
+ };
+
+ server.use(
+ rest.post(
+ `https://almsearch.dev.azure.com/shopify/engineering/_apis/search/codesearchresults`,
+ (req, res, ctx) => {
+ expect(req.headers.get('Authorization')).toBe('Basic OkFCQw==');
+ expect(req.body).toEqual({
+ searchText: 'path:/catalog-info.yaml repo:backstage',
+ $skip: 0,
+ $top: 1000,
+ });
+ return res(ctx.json(response));
+ },
+ ),
+ );
+
+ await expect(
+ codeSearch(
+ { host: 'dev.azure.com', token: 'ABC' },
+ 'shopify',
+ 'engineering',
+ 'backstage',
+ '/catalog-info.yaml',
+ ),
+ ).resolves.toEqual(response.results);
+ });
+
+ it('can search using onpremise api', async () => {
+ const response: CodeSearchResponse = {
+ count: 1,
+ results: [
+ {
+ fileName: 'catalog-info.yaml',
+ path: '/catalog-info.yaml',
+ repository: {
+ name: 'backstage',
+ },
+ },
+ ],
+ };
+
+ server.use(
+ rest.post(
+ `https://azuredevops.mycompany.com/shopify/engineering/_apis/search/codesearchresults`,
+ (req, res, ctx) => {
+ expect(req.headers.get('Authorization')).toBe('Basic OkFCQw==');
+ expect(req.body).toEqual({
+ searchText: 'path:/catalog-info.yaml repo:*',
+ $skip: 0,
+ $top: 1000,
+ });
+ return res(ctx.json(response));
+ },
+ ),
+ );
+
+ await expect(
+ codeSearch(
+ { host: 'azuredevops.mycompany.com', token: 'ABC' },
+ 'shopify',
+ 'engineering',
+ '',
+ '/catalog-info.yaml',
+ ),
+ ).resolves.toEqual(response.results);
+ });
+
+ it('searches multiple pages if response contains many items', async () => {
+ const totalCount = 2401;
+ const generateItems = (count: number) => {
+ return Array.from(Array(count).keys()).map(_ => ({
+ fileName: 'catalog-info.yaml',
+ path: '/catalog-info.yaml',
+ repository: {
+ name: 'backstage',
+ },
+ }));
+ };
+
+ server.use(
+ rest.post(
+ `https://almsearch.dev.azure.com/shopify/engineering/_apis/search/codesearchresults`,
+ (req, res, ctx) => {
+ expect(req.headers.get('Authorization')).toBe('Basic OkFCQw==');
+ expect(req.body).toMatchObject({
+ searchText: 'path:/catalog-info.yaml repo:backstage',
+ $top: 1000,
+ });
+
+ const body = req.body as { $skip: number; $top: number };
+ const countItemsToReturn =
+ body.$top + body.$skip > totalCount
+ ? totalCount - body.$skip
+ : body.$top;
+
+ return res(
+ ctx.json({
+ count: totalCount,
+ results: generateItems(countItemsToReturn),
+ }),
+ );
+ },
+ ),
+ );
+
+ await expect(
+ codeSearch(
+ { host: 'dev.azure.com', token: 'ABC' },
+ 'shopify',
+ 'engineering',
+ 'backstage',
+ '/catalog-info.yaml',
+ ),
+ ).resolves.toHaveLength(totalCount);
+ });
+});
diff --git a/plugins/catalog-backend/src/ingestion/processors/azure/azure.ts b/plugins/catalog-backend/src/ingestion/processors/azure/azure.ts
new file mode 100644
index 0000000000..0c7b17483a
--- /dev/null
+++ b/plugins/catalog-backend/src/ingestion/processors/azure/azure.ts
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import fetch from 'cross-fetch';
+import {
+ AzureIntegrationConfig,
+ getAzureRequestOptions,
+} from '@backstage/integration';
+
+export interface CodeSearchResponse {
+ count: number;
+ results: CodeSearchResultItem[];
+}
+
+export interface CodeSearchResultItem {
+ fileName: string;
+ path: string;
+ repository: {
+ name: string;
+ };
+}
+
+const isCloud = (host: string) => host === 'dev.azure.com';
+const PAGE_SIZE = 1000;
+
+// codeSearch returns all files that matches the given search path.
+export async function codeSearch(
+ azureConfig: AzureIntegrationConfig,
+ org: string,
+ project: string,
+ repo: string,
+ path: string,
+): Promise {
+ const searchBaseUrl = isCloud(azureConfig.host)
+ ? 'https://almsearch.dev.azure.com'
+ : `https://${azureConfig.host}`;
+ const searchUrl = `${searchBaseUrl}/${org}/${project}/_apis/search/codesearchresults?api-version=6.0-preview.1`;
+
+ let items: CodeSearchResultItem[] = [];
+ let hasMorePages = true;
+
+ do {
+ const response = await fetch(searchUrl, {
+ ...getAzureRequestOptions(azureConfig, {
+ 'Content-Type': 'application/json',
+ }),
+ method: 'POST',
+ body: JSON.stringify({
+ searchText: `path:${path} repo:${repo || '*'}`,
+ $skip: items.length,
+ $top: PAGE_SIZE,
+ }),
+ });
+
+ if (response.status !== 200) {
+ throw new Error(
+ `Azure DevOps search failed with response status ${response.status}`,
+ );
+ }
+
+ const body: CodeSearchResponse = await response.json();
+ items = [...items, ...body.results];
+ hasMorePages = body.count > items.length;
+ } while (hasMorePages);
+
+ return items;
+}
diff --git a/plugins/catalog-backend/src/ingestion/processors/azure/index.ts b/plugins/catalog-backend/src/ingestion/processors/azure/index.ts
new file mode 100644
index 0000000000..d4ff56c4c0
--- /dev/null
+++ b/plugins/catalog-backend/src/ingestion/processors/azure/index.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2021 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 * from './azure';
diff --git a/plugins/catalog-backend/src/ingestion/processors/index.ts b/plugins/catalog-backend/src/ingestion/processors/index.ts
index 4f3c502a8e..63feac51af 100644
--- a/plugins/catalog-backend/src/ingestion/processors/index.ts
+++ b/plugins/catalog-backend/src/ingestion/processors/index.ts
@@ -26,6 +26,7 @@ export { BuiltinKindsEntityProcessor } from './BuiltinKindsEntityProcessor';
export { CodeOwnersProcessor } from './CodeOwnersProcessor';
export { FileReaderProcessor } from './FileReaderProcessor';
export { GithubDiscoveryProcessor } from './GithubDiscoveryProcessor';
+export { AzureDevOpsDiscoveryProcessor } from './AzureDevOpsDiscoveryProcessor';
export { GithubOrgReaderProcessor } from './GithubOrgReaderProcessor';
export { GithubMultiOrgReaderProcessor } from './GithubMultiOrgReaderProcessor';
export { GitLabDiscoveryProcessor } from './GitLabDiscoveryProcessor';
diff --git a/plugins/catalog-backend/src/legacy/database/CommonDatabase.test.ts b/plugins/catalog-backend/src/legacy/database/CommonDatabase.test.ts
index ca2e6c2934..8b72b470a6 100644
--- a/plugins/catalog-backend/src/legacy/database/CommonDatabase.test.ts
+++ b/plugins/catalog-backend/src/legacy/database/CommonDatabase.test.ts
@@ -536,9 +536,7 @@ describe('CommonDatabase', () => {
filter: {
anyOf: [
{
- allOf: [
- { key: 'metadata.annotations.foo', matchValueExists: true },
- ],
+ allOf: [{ key: 'metadata.annotations.foo' }],
},
],
},
@@ -558,30 +556,6 @@ describe('CommonDatabase', () => {
},
]),
);
-
- const nonExistRows = await db.transaction(async tx =>
- db.entities(tx, {
- filter: {
- anyOf: [
- {
- allOf: [
- { key: 'metadata.annotations.foo', matchValueExists: false },
- ],
- },
- ],
- },
- }),
- );
-
- expect(nonExistRows.entities.length).toEqual(1);
- expect(nonExistRows.entities).toEqual(
- expect.arrayContaining([
- {
- locationId: undefined,
- entity: expect.objectContaining({ kind: 'k3' }),
- },
- ]),
- );
});
});
diff --git a/plugins/catalog-backend/src/legacy/database/CommonDatabase.ts b/plugins/catalog-backend/src/legacy/database/CommonDatabase.ts
index 6a150f7583..3ea8696437 100644
--- a/plugins/catalog-backend/src/legacy/database/CommonDatabase.ts
+++ b/plugins/catalog-backend/src/legacy/database/CommonDatabase.ts
@@ -224,7 +224,8 @@ export class CommonDatabase implements Database {
if (
request?.filter &&
(request.filter.hasOwnProperty('key') ||
- request.filter.hasOwnProperty('allOf'))
+ request.filter.hasOwnProperty('allOf') ||
+ request.filter.hasOwnProperty('not'))
) {
throw new Error(
'Filters for the legacy CommonDatabase must obey the { anyOf: [{ allOf: [] }] } format.',
@@ -236,13 +237,14 @@ export class CommonDatabase implements Database {
for (const filter of singleFilter.allOf) {
if (
filter.hasOwnProperty('anyOf') ||
- filter.hasOwnProperty('allOf')
+ filter.hasOwnProperty('allOf') ||
+ filter.hasOwnProperty('not')
) {
throw new Error(
'Nested filters are not supported in the legacy CommonDatabase',
);
}
- const { key, matchValueIn, matchValueExists } = filter;
+ const { key, values } = filter;
// NOTE(freben): This used to be a set of OUTER JOIN, which may seem to
// make a lot of sense. However, it had abysmal performance on sqlite
// when datasets grew large, so we're using IN instead.
@@ -250,24 +252,19 @@ export class CommonDatabase implements Database {
.select('entity_id')
.where(function keyFilter() {
this.andWhere({ key: key.toLowerCase() });
- if (matchValueExists !== false && matchValueIn) {
- if (matchValueIn.length === 1) {
- this.andWhere({ value: matchValueIn[0].toLowerCase() });
- } else if (matchValueIn.length > 1) {
+ if (values) {
+ if (values.length === 1) {
+ this.andWhere({ value: values[0].toLowerCase() });
+ } else if (values.length > 1) {
this.andWhere(
'value',
'in',
- matchValueIn.map(v => v.toLowerCase()),
+ values.map(v => v.toLowerCase()),
);
}
}
});
- // Explicitly evaluate matchValueExists as a boolean since it may be undefined
- this.andWhere(
- 'id',
- matchValueExists === false ? 'not in' : 'in',
- matchQuery,
- );
+ this.andWhere('id', 'in', matchQuery);
}
});
}
diff --git a/plugins/catalog-backend/src/legacy/service/CatalogBuilder.ts b/plugins/catalog-backend/src/legacy/service/CatalogBuilder.ts
index b8e45c7cf3..6fb52e245e 100644
--- a/plugins/catalog-backend/src/legacy/service/CatalogBuilder.ts
+++ b/plugins/catalog-backend/src/legacy/service/CatalogBuilder.ts
@@ -42,6 +42,7 @@ import {
CodeOwnersProcessor,
FileReaderProcessor,
GithubDiscoveryProcessor,
+ AzureDevOpsDiscoveryProcessor,
GithubOrgReaderProcessor,
GitLabDiscoveryProcessor,
LocationEntityProcessor,
@@ -317,6 +318,7 @@ export class CatalogBuilder {
new FileReaderProcessor(),
BitbucketDiscoveryProcessor.fromConfig(config, { logger }),
GithubDiscoveryProcessor.fromConfig(config, { logger }),
+ AzureDevOpsDiscoveryProcessor.fromConfig(config, { logger }),
GithubOrgReaderProcessor.fromConfig(config, { logger }),
GitLabDiscoveryProcessor.fromConfig(config, { logger }),
new UrlReaderProcessor({ reader, logger }),
diff --git a/plugins/catalog-backend/src/legacy/service/router.test.ts b/plugins/catalog-backend/src/legacy/service/router.test.ts
index edc7d852ac..0ff5a44ed0 100644
--- a/plugins/catalog-backend/src/legacy/service/router.test.ts
+++ b/plugins/catalog-backend/src/legacy/service/router.test.ts
@@ -115,11 +115,11 @@ describe('createRouter readonly disabled', () => {
anyOf: [
{
allOf: [
- { key: 'a', matchValueIn: ['1', '2'] },
- { key: 'b', matchValueIn: ['3'] },
+ { key: 'a', values: ['1', '2'] },
+ { key: 'b', values: ['3'] },
],
},
- { allOf: [{ key: 'c', matchValueIn: ['4'] }] },
+ { allOf: [{ key: 'c', values: ['4'] }] },
],
},
});
diff --git a/plugins/catalog-backend/src/run.ts b/plugins/catalog-backend/src/run.ts
index 54d2716290..0a3ed2b7f0 100644
--- a/plugins/catalog-backend/src/run.ts
+++ b/plugins/catalog-backend/src/run.ts
@@ -18,7 +18,7 @@ import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
-const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7000;
+const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
diff --git a/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts b/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts
index 20e141b921..8f1af6f615 100644
--- a/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts
+++ b/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts
@@ -59,7 +59,7 @@ describe('DefaultCatalogCollator', () => {
beforeAll(() => {
mockDiscoveryApi = {
- getBaseUrl: jest.fn().mockResolvedValue('http://localhost:7000'),
+ getBaseUrl: jest.fn().mockResolvedValue('http://localhost:7007'),
getExternalBaseUrl: jest.fn(),
};
collator = new DefaultCatalogCollator({ discovery: mockDiscoveryApi });
@@ -67,7 +67,7 @@ describe('DefaultCatalogCollator', () => {
});
beforeEach(() => {
server.use(
- rest.get('http://localhost:7000/entities', (req, res, ctx) => {
+ rest.get('http://localhost:7007/entities', (req, res, ctx) => {
if (req.url.searchParams.has('filter')) {
const filter = req.url.searchParams.get('filter');
if (filter === 'kind=Foo,kind=Bar') {
diff --git a/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts b/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts
index a28a7645c4..3e19b38ea6 100644
--- a/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts
+++ b/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts
@@ -15,7 +15,7 @@
*/
import { PluginEndpointDiscovery } from '@backstage/backend-common';
-import { Entity } from '@backstage/catalog-model';
+import { Entity, UserEntity } from '@backstage/catalog-model';
import { IndexableDocument, DocumentCollator } from '@backstage/search-common';
import { Config } from '@backstage/config';
import {
@@ -81,6 +81,24 @@ export class DefaultCatalogCollator implements DocumentCollator {
return formatted.toLowerCase();
}
+ private isUserEntity(entity: Entity): entity is UserEntity {
+ return entity.kind.toLocaleUpperCase('en-US') === 'USER';
+ }
+
+ private getDocumentText(entity: Entity): string {
+ let documentText = entity.metadata.description || '';
+ if (this.isUserEntity(entity)) {
+ if (entity.spec?.profile?.displayName && documentText) {
+ // combine displayName and description
+ const displayName = entity.spec?.profile?.displayName;
+ documentText = displayName.concat(' : ', documentText);
+ } else {
+ documentText = entity.spec?.profile?.displayName || documentText;
+ }
+ }
+ return documentText;
+ }
+
async execute() {
const response = await this.catalogClient.getEntities({
filter: this.filter,
@@ -93,7 +111,7 @@ export class DefaultCatalogCollator implements DocumentCollator {
kind: entity.kind,
name: entity.metadata.name,
}),
- text: entity.metadata.description || '',
+ text: this.getDocumentText(entity),
componentType: entity.spec?.type?.toString() || 'other',
namespace: entity.metadata.namespace || 'default',
kind: entity.kind,
diff --git a/plugins/catalog-backend/src/service/DefaultLocationService.test.ts b/plugins/catalog-backend/src/service/DefaultLocationService.test.ts
index a089989d20..562bae4867 100644
--- a/plugins/catalog-backend/src/service/DefaultLocationService.test.ts
+++ b/plugins/catalog-backend/src/service/DefaultLocationService.test.ts
@@ -148,6 +148,57 @@ describe('DefaultLocationServiceTest', () => {
expect(result.exists).toBe(true);
});
+ it('should fail when there are duplicate entities using dry run', async () => {
+ store.listLocations.mockResolvedValueOnce([]);
+ orchestrator.process.mockResolvedValueOnce({
+ ok: true,
+ state: {},
+ completedEntity: {
+ apiVersion: 'backstage.io/v1alpha1',
+ kind: 'Location',
+ metadata: {
+ name: 'foo',
+ },
+ },
+ deferredEntities: [
+ {
+ entity: {
+ apiVersion: 'backstage.io/v1alpha1',
+ kind: 'Location',
+ metadata: {
+ name: 'foo',
+ },
+ },
+ locationKey: 'file:///tmp/mock.yaml',
+ },
+ ],
+ relations: [],
+ errors: [],
+ });
+
+ orchestrator.process.mockResolvedValueOnce({
+ ok: true,
+ state: {},
+ completedEntity: {
+ apiVersion: 'backstage.io/v1alpha1',
+ kind: 'Location',
+ metadata: {
+ name: 'foo',
+ },
+ },
+ deferredEntities: [],
+ relations: [],
+ errors: [],
+ });
+
+ await expect(
+ locationService.createLocation(
+ { type: 'url', target: 'https://backstage.io/catalog-info.yaml' },
+ true,
+ ),
+ ).rejects.toThrowError('Duplicate nested entity: location:default/foo');
+ });
+
it('should return exists false when the location does not exist beforehand', async () => {
orchestrator.process.mockResolvedValueOnce({
ok: true,
diff --git a/plugins/catalog-backend/src/service/DefaultLocationService.ts b/plugins/catalog-backend/src/service/DefaultLocationService.ts
index 2166341935..8dd2274842 100644
--- a/plugins/catalog-backend/src/service/DefaultLocationService.ts
+++ b/plugins/catalog-backend/src/service/DefaultLocationService.ts
@@ -19,6 +19,7 @@ import {
LocationSpec,
LOCATION_ANNOTATION,
ORIGIN_LOCATION_ANNOTATION,
+ stringifyEntityRef,
} from '@backstage/catalog-model';
import {
CatalogProcessingOrchestrator,
@@ -54,6 +55,43 @@ export class DefaultLocationService implements LocationService {
return this.store.deleteLocation(id);
}
+ private async processEntities(
+ unprocessedEntities: DeferredEntity[],
+ ): Promise {
+ const entities: Entity[] = [];
+ while (unprocessedEntities.length) {
+ const currentEntity = unprocessedEntities.pop();
+ if (!currentEntity) {
+ continue;
+ }
+ const processed = await this.orchestrator.process({
+ entity: currentEntity.entity,
+ state: {}, // we process without the existing cache
+ });
+
+ if (processed.ok) {
+ if (
+ entities.some(
+ e =>
+ stringifyEntityRef(e) ===
+ stringifyEntityRef(processed.completedEntity),
+ )
+ ) {
+ throw new Error(
+ `Duplicate nested entity: ${stringifyEntityRef(
+ processed.completedEntity,
+ )}`,
+ );
+ }
+ unprocessedEntities.push(...processed.deferredEntities);
+ entities.push(processed.completedEntity);
+ } else {
+ throw Error(processed.errors.map(String).join(', '));
+ }
+ }
+ return entities;
+ }
+
private async dryRunCreateLocation(
spec: LocationSpec,
): Promise<{ location: Location; entities: Entity[]; exists?: boolean }> {
@@ -86,24 +124,7 @@ export class DefaultLocationService implements LocationService {
const unprocessedEntities: DeferredEntity[] = [
{ entity, locationKey: `${spec.type}:${spec.target}` },
];
- const entities: Entity[] = [];
- while (unprocessedEntities.length) {
- const currentEntity = unprocessedEntities.pop();
- if (!currentEntity) {
- continue;
- }
- const processed = await this.orchestrator.process({
- entity: currentEntity.entity,
- state: {}, // we process without the existing cache
- });
-
- if (processed.ok) {
- unprocessedEntities.push(...processed.deferredEntities);
- entities.push(processed.completedEntity);
- } else {
- throw Error(processed.errors.map(String).join(', '));
- }
- }
+ const entities: Entity[] = await this.processEntities(unprocessedEntities);
return {
exists: await existsPromise,
diff --git a/plugins/catalog-backend/src/service/NextCatalogBuilder.ts b/plugins/catalog-backend/src/service/NextCatalogBuilder.ts
index eed420cd53..c9ebc8f723 100644
--- a/plugins/catalog-backend/src/service/NextCatalogBuilder.ts
+++ b/plugins/catalog-backend/src/service/NextCatalogBuilder.ts
@@ -44,6 +44,7 @@ import {
CatalogProcessorParser,
CodeOwnersProcessor,
FileReaderProcessor,
+ AzureDevOpsDiscoveryProcessor,
GithubDiscoveryProcessor,
GithubOrgReaderProcessor,
GitLabDiscoveryProcessor,
@@ -292,6 +293,7 @@ export class NextCatalogBuilder {
return [
new FileReaderProcessor(),
BitbucketDiscoveryProcessor.fromConfig(config, { logger }),
+ AzureDevOpsDiscoveryProcessor.fromConfig(config, { logger }),
GithubDiscoveryProcessor.fromConfig(config, { logger }),
GithubOrgReaderProcessor.fromConfig(config, { logger }),
GitLabDiscoveryProcessor.fromConfig(config, { logger }),
diff --git a/plugins/catalog-backend/src/service/NextEntitiesCatalog.test.ts b/plugins/catalog-backend/src/service/NextEntitiesCatalog.test.ts
index 32d5fa843e..d0f284c11c 100644
--- a/plugins/catalog-backend/src/service/NextEntitiesCatalog.test.ts
+++ b/plugins/catalog-backend/src/service/NextEntitiesCatalog.test.ts
@@ -282,7 +282,6 @@ describe('NextEntitiesCatalog', () => {
const testFilter = {
key: 'spec.test',
- matchValueExists: true,
};
const request = { filter: testFilter };
const { entities } = await catalog.entities(request);
@@ -293,7 +292,42 @@ describe('NextEntitiesCatalog', () => {
);
it.each(databases.eachSupportedId())(
- 'should return correct entity for nested filter',
+ 'should return correct entity for negation filter',
+ async databaseId => {
+ const { knex } = await createDatabase(databaseId);
+ const entity1: Entity = {
+ apiVersion: 'a',
+ kind: 'k',
+ metadata: { name: 'one' },
+ spec: {},
+ };
+ const entity2: Entity = {
+ apiVersion: 'a',
+ kind: 'k',
+ metadata: { name: 'two' },
+ spec: {
+ test: 'test value',
+ },
+ };
+ await addEntityToSearch(knex, entity1);
+ await addEntityToSearch(knex, entity2);
+ const catalog = new NextEntitiesCatalog(knex);
+
+ const testFilter = {
+ not: {
+ key: 'spec.test',
+ },
+ };
+ const request = { filter: testFilter };
+ const { entities } = await catalog.entities(request);
+
+ expect(entities.length).toBe(1);
+ expect(entities[0]).toEqual(entity1);
+ },
+ );
+
+ it.each(databases.eachSupportedId())(
+ 'should return correct entities for nested filter',
async databaseId => {
const { knex } = await createDatabase(databaseId);
const entity1: Entity = {
@@ -328,24 +362,27 @@ describe('NextEntitiesCatalog', () => {
const testFilter1 = {
key: 'metadata.org',
- matchValueExists: true,
- matchValueIn: ['b'],
+ values: ['b'],
};
const testFilter2 = {
key: 'metadata.desc',
- matchValueExists: true,
};
const testFilter3 = {
key: 'metadata.color',
- matchValueExists: true,
- matchValueIn: ['blue'],
+ values: ['blue'],
+ };
+ const testFilter4 = {
+ not: {
+ key: 'metadata.color',
+ values: ['red'],
+ },
};
const request = {
filter: {
allOf: [
testFilter1,
{
- anyOf: [testFilter2, testFilter3],
+ anyOf: [testFilter2, testFilter3, testFilter4],
},
],
},
@@ -357,5 +394,78 @@ describe('NextEntitiesCatalog', () => {
expect(entities).toContainEqual(entity4);
},
);
+
+ it.each(databases.eachSupportedId())(
+ 'should return correct entities for complex negation filter',
+ async databaseId => {
+ const { knex } = await createDatabase(databaseId);
+ const entity1: Entity = {
+ apiVersion: 'a',
+ kind: 'k',
+ metadata: { name: 'one', org: 'a', desc: 'description' },
+ spec: {},
+ };
+ const entity2: Entity = {
+ apiVersion: 'a',
+ kind: 'k',
+ metadata: { name: 'two', org: 'b', desc: 'description' },
+ spec: {},
+ };
+ await addEntityToSearch(knex, entity1);
+ await addEntityToSearch(knex, entity2);
+ const catalog = new NextEntitiesCatalog(knex);
+
+ const testFilter1 = {
+ key: 'metadata.org',
+ values: ['b'],
+ };
+ const testFilter2 = {
+ key: 'metadata.desc',
+ };
+ const request = {
+ filter: {
+ not: {
+ allOf: [testFilter1, testFilter2],
+ },
+ },
+ };
+ const { entities } = await catalog.entities(request);
+
+ expect(entities.length).toBe(1);
+ expect(entities).toContainEqual(entity1);
+ },
+ );
+
+ it.each(databases.eachSupportedId())(
+ 'should return no matches for an empty values array',
+ // NOTE: An empty values array is not a sensible input in a realistic scenario.
+ async databaseId => {
+ const { knex } = await createDatabase(databaseId);
+ const entity1: Entity = {
+ apiVersion: 'a',
+ kind: 'k',
+ metadata: { name: 'one' },
+ spec: {},
+ };
+ const entity2: Entity = {
+ apiVersion: 'a',
+ kind: 'k',
+ metadata: { name: 'two' },
+ spec: {},
+ };
+ await addEntityToSearch(knex, entity1);
+ await addEntityToSearch(knex, entity2);
+ const catalog = new NextEntitiesCatalog(knex);
+
+ const testFilter = {
+ key: 'kind',
+ values: [],
+ };
+ const request = { filter: testFilter };
+ const { entities } = await catalog.entities(request);
+
+ expect(entities.length).toBe(0);
+ },
+ );
});
});
diff --git a/plugins/catalog-backend/src/service/NextEntitiesCatalog.ts b/plugins/catalog-backend/src/service/NextEntitiesCatalog.ts
index 1c615f862a..f9b3abf190 100644
--- a/plugins/catalog-backend/src/service/NextEntitiesCatalog.ts
+++ b/plugins/catalog-backend/src/service/NextEntitiesCatalog.ts
@@ -78,33 +78,29 @@ function stringifyPagination(input: { limit: number; offset: number }) {
function addCondition(
queryBuilder: Knex.QueryBuilder,
db: Knex,
- { key, matchValueIn, matchValueExists }: EntitiesSearchFilter,
+ filter: EntitiesSearchFilter,
+ negate: boolean = false,
) {
// NOTE(freben): This used to be a set of OUTER JOIN, which may seem to
// make a lot of sense. However, it had abysmal performance on sqlite
// when datasets grew large, so we're using IN instead.
const matchQuery = db('search')
.select('entity_id')
- .where(function keyFilter() {
- this.andWhere({ key: key.toLowerCase() });
- if (matchValueExists !== false && matchValueIn) {
- if (matchValueIn.length === 1) {
- this.andWhere({ value: matchValueIn[0].toLowerCase() });
- } else if (matchValueIn.length > 1) {
+ .where({ key: filter.key.toLowerCase() })
+ .andWhere(function keyFilter() {
+ if (filter.values) {
+ if (filter.values.length === 1) {
+ this.where({ value: filter.values[0].toLowerCase() });
+ } else {
this.andWhere(
'value',
'in',
- matchValueIn.map(v => v.toLowerCase()),
+ filter.values.map(v => v.toLowerCase()),
);
}
}
});
- // Explicitly evaluate matchValueExists as a boolean since it may be undefined
- queryBuilder.andWhere(
- 'entity_id',
- matchValueExists === false ? 'not in' : 'in',
- matchQuery,
- );
+ queryBuilder.andWhere('entity_id', negate ? 'not in' : 'in', matchQuery);
}
function isEntitiesSearchFilter(
@@ -113,46 +109,45 @@ function isEntitiesSearchFilter(
return filter.hasOwnProperty('key');
}
-function isAndEntityFilter(
- filter: { allOf: EntityFilter[] } | EntityFilter,
-): filter is { allOf: EntityFilter[] } {
- return filter.hasOwnProperty('allOf');
-}
-
function isOrEntityFilter(
filter: { anyOf: EntityFilter[] } | EntityFilter,
): filter is { anyOf: EntityFilter[] } {
return filter.hasOwnProperty('anyOf');
}
+function isNegationEntityFilter(
+ filter: { not: EntityFilter } | EntityFilter,
+): filter is { not: EntityFilter } {
+ return filter.hasOwnProperty('not');
+}
+
function parseFilter(
filter: EntityFilter,
query: Knex.QueryBuilder,
db: Knex,
+ negate: boolean = false,
): Knex.QueryBuilder {
if (isEntitiesSearchFilter(filter)) {
return query.andWhere(function filterFunction() {
- addCondition(this, db, filter);
+ addCondition(this, db, filter, negate);
});
}
- if (isOrEntityFilter(filter)) {
- return query.andWhere(function filterFunction() {
+ if (isNegationEntityFilter(filter)) {
+ return parseFilter(filter.not, query, db, !negate);
+ }
+
+ return query[negate ? 'andWhereNot' : 'andWhere'](function filterFunction() {
+ if (isOrEntityFilter(filter)) {
for (const subFilter of filter.anyOf ?? []) {
this.orWhere(subQuery => parseFilter(subFilter, subQuery, db));
}
- });
- }
-
- if (isAndEntityFilter(filter)) {
- return query.andWhere(function filterFunction() {
+ } else {
for (const subFilter of filter.allOf ?? []) {
this.andWhere(subQuery => parseFilter(subFilter, subQuery, db));
}
- });
- }
-
- return query;
+ }
+ });
}
export class NextEntitiesCatalog implements EntitiesCatalog {
diff --git a/plugins/catalog-backend/src/service/NextRouter.test.ts b/plugins/catalog-backend/src/service/NextRouter.test.ts
index 57911c74fb..6bc4481425 100644
--- a/plugins/catalog-backend/src/service/NextRouter.test.ts
+++ b/plugins/catalog-backend/src/service/NextRouter.test.ts
@@ -104,11 +104,11 @@ describe('createNextRouter readonly disabled', () => {
anyOf: [
{
allOf: [
- { key: 'a', matchValueIn: ['1', '2'] },
- { key: 'b', matchValueIn: ['3'] },
+ { key: 'a', values: ['1', '2'] },
+ { key: 'b', values: ['3'] },
],
},
- { allOf: [{ key: 'c', matchValueIn: ['4'] }] },
+ { allOf: [{ key: 'c', values: ['4'] }] },
],
},
});
diff --git a/plugins/catalog-backend/src/service/request/basicEntityFilter.ts b/plugins/catalog-backend/src/service/request/basicEntityFilter.ts
index 1cf9ca95f0..36448e0304 100644
--- a/plugins/catalog-backend/src/service/request/basicEntityFilter.ts
+++ b/plugins/catalog-backend/src/service/request/basicEntityFilter.ts
@@ -30,9 +30,9 @@ export function basicEntityFilter(
const f =
key in filtersByKey
? filtersByKey[key]
- : (filtersByKey[key] = { key, matchValueIn: [] });
+ : (filtersByKey[key] = { key, values: [] });
- f.matchValueIn!.push(...values);
+ f.values!.push(...values);
}
return { anyOf: [{ allOf: Object.values(filtersByKey) }] };
diff --git a/plugins/catalog-backend/src/service/request/parseEntityFilterParams.test.ts b/plugins/catalog-backend/src/service/request/parseEntityFilterParams.test.ts
index fc22a638de..f9fc596cb9 100644
--- a/plugins/catalog-backend/src/service/request/parseEntityFilterParams.test.ts
+++ b/plugins/catalog-backend/src/service/request/parseEntityFilterParams.test.ts
@@ -28,7 +28,7 @@ describe('parseEntityFilterParams', () => {
it('supports single-string format', () => {
const result = parseEntityFilterParams({ filter: 'a=1' })!;
expect(result).toEqual({
- anyOf: [{ allOf: [{ key: 'a', matchValueIn: ['1'] }] }],
+ anyOf: [{ allOf: [{ key: 'a', values: ['1'] }] }],
});
});
@@ -38,8 +38,8 @@ describe('parseEntityFilterParams', () => {
});
expect(result).toEqual({
anyOf: [
- { allOf: [{ key: 'a', matchValueIn: ['1'] }] },
- { allOf: [{ key: 'b', matchValueIn: ['2'] }] },
+ { allOf: [{ key: 'a', values: ['1'] }] },
+ { allOf: [{ key: 'b', values: ['2'] }] },
],
});
});
@@ -50,11 +50,11 @@ describe('parseEntityFilterParams', () => {
});
expect(result).toEqual({
anyOf: [
- { allOf: [{ key: 'a', matchValueIn: ['1'] }] },
+ { allOf: [{ key: 'a', values: ['1'] }] },
{
allOf: [
- { key: 'b', matchValueIn: ['2', '3'] },
- { key: 'c', matchValueIn: ['4'] },
+ { key: 'b', values: ['2', '3'] },
+ { key: 'c', values: ['4'] },
],
},
],
@@ -70,17 +70,17 @@ describe('parseEntityFilterString', () => {
it('works for the happy path', () => {
expect(parseEntityFilterString('')).toBeUndefined();
expect(parseEntityFilterString('a=1,b=2,a=3,c,d=')).toEqual([
- { key: 'a', matchValueIn: ['1', '3'] },
- { key: 'b', matchValueIn: ['2'] },
- { key: 'c', matchValueExists: true },
- { key: 'd', matchValueIn: [''] },
+ { key: 'a', values: ['1', '3'] },
+ { key: 'b', values: ['2'] },
+ { key: 'c' },
+ { key: 'd', values: [''] },
]);
});
it('trims values', () => {
expect(parseEntityFilterString(' a = 1 , b = 2 , a = 3 ')).toEqual([
- { key: 'a', matchValueIn: ['1', '3'] },
- { key: 'b', matchValueIn: ['2'] },
+ { key: 'a', values: ['1', '3'] },
+ { key: 'b', values: ['2'] },
]);
});
diff --git a/plugins/catalog-backend/src/service/request/parseEntityFilterParams.ts b/plugins/catalog-backend/src/service/request/parseEntityFilterParams.ts
index 452958b7ae..1ea5d44b2c 100644
--- a/plugins/catalog-backend/src/service/request/parseEntityFilterParams.ts
+++ b/plugins/catalog-backend/src/service/request/parseEntityFilterParams.ts
@@ -75,11 +75,9 @@ export function parseEntityFilterString(
const f =
key in filtersByKey ? filtersByKey[key] : (filtersByKey[key] = { key });
- if (value === undefined) {
- f.matchValueExists = true;
- } else {
- f.matchValueIn = f.matchValueIn || [];
- f.matchValueIn.push(value);
+ if (value !== undefined) {
+ f.values = f.values || [];
+ f.values.push(value);
}
}
diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md
index a156be8fe0..c107a4e758 100644
--- a/plugins/catalog-graph/CHANGELOG.md
+++ b/plugins/catalog-graph/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/plugin-catalog-graph
+## 0.2.2
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-client@0.5.2
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.2.1
### Patch Changes
diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json
index e58d66b1f2..13869cfd38 100644
--- a/plugins/catalog-graph/package.json
+++ b/plugins/catalog-graph/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog-graph",
- "version": "0.2.1",
+ "version": "0.2.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,11 +21,11 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-client": "^0.5.0",
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -41,10 +41,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.test.tsx b/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.test.tsx
index 9fe482a30b..3c167946d4 100644
--- a/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.test.tsx
+++ b/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.test.tsx
@@ -14,14 +14,19 @@
* limitations under the License.
*/
import { Entity } from '@backstage/catalog-model';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import { analyticsApiRef } from '@backstage/core-plugin-api';
import {
CatalogApi,
catalogApiRef,
EntityProvider,
} from '@backstage/plugin-catalog-react';
-import { MockAnalyticsApi, renderInTestApp } from '@backstage/test-utils';
+import {
+ MockAnalyticsApi,
+ renderInTestApp,
+ TestApiProvider,
+ TestApiRegistry,
+} from '@backstage/test-utils';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { catalogEntityRouteRef, catalogGraphRouteRef } from '../../routes';
@@ -31,7 +36,7 @@ describe('', () => {
let entity: Entity;
let wrapper: JSX.Element;
let catalog: jest.Mocked;
- let apis: ApiRegistry;
+ let apis: TestApiRegistry;
beforeAll(() => {
Object.defineProperty(window.SVGElement.prototype, 'getBBox', {
@@ -61,7 +66,7 @@ describe('', () => {
refreshEntity: jest.fn(),
getEntityAncestors: jest.fn(),
};
- apis = ApiRegistry.with(catalogApiRef, catalog);
+ apis = TestApiRegistry.from([catalogApiRef, catalog]);
wrapper = (
@@ -123,9 +128,9 @@ describe('', () => {
test('captures analytics event on click', async () => {
const analyticsSpy = new MockAnalyticsApi();
const { findByText } = await renderInTestApp(
-
+
{wrapper}
- ,
+ ,
{
mountedRoutes: {
'/entity/{kind}/{namespace}/{name}': catalogEntityRouteRef,
diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.test.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.test.tsx
index b992d0c976..7bd1045fff 100644
--- a/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.test.tsx
+++ b/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.test.tsx
@@ -14,10 +14,13 @@
* limitations under the License.
*/
import { RELATION_HAS_PART, RELATION_PART_OF } from '@backstage/catalog-model';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { analyticsApiRef } from '@backstage/core-plugin-api';
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
-import { MockAnalyticsApi, renderInTestApp } from '@backstage/test-utils';
+import {
+ MockAnalyticsApi,
+ renderInTestApp,
+ TestApiProvider,
+} from '@backstage/test-utils';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { catalogEntityRouteRef } from '../../routes';
@@ -90,10 +93,9 @@ describe('', () => {
refreshEntity: jest.fn(),
getEntityAncestors: jest.fn(),
};
- const apis = ApiRegistry.with(catalogApiRef, catalog);
wrapper = (
-
+
', () => {
selectedKinds: ['b'],
}}
/>
-
+
);
});
@@ -172,9 +174,9 @@ describe('', () => {
test('should capture analytics event when selecting other entity', async () => {
const analyticsSpy = new MockAnalyticsApi();
const { getByText, findAllByTestId } = await renderInTestApp(
-
+
{wrapper}
- ,
+ ,
{
mountedRoutes: {
'/entity/{kind}/{namespace}/{name}': catalogEntityRouteRef,
@@ -195,9 +197,9 @@ describe('', () => {
test('should capture analytics event when navigating to entity', async () => {
const analyticsSpy = new MockAnalyticsApi();
const { getByText, findAllByTestId } = await renderInTestApp(
-
+
{wrapper}
- ,
+ ,
{
mountedRoutes: {
'/entity/{kind}/{namespace}/{name}': catalogEntityRouteRef,
diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.test.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.test.tsx
index 2d6c5cc93d..be0c4dc5e5 100644
--- a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.test.tsx
+++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.test.tsx
@@ -21,9 +21,8 @@ import {
RELATION_PART_OF,
stringifyEntityRef,
} from '@backstage/catalog-model';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import userEvent from '@testing-library/user-event';
import React, { FunctionComponent } from 'react';
import { EntityRelationsGraph } from './EntityRelationsGraph';
@@ -158,10 +157,11 @@ describe('', () => {
refreshEntity: jest.fn(),
getEntityAncestors: jest.fn(),
};
- const apis = ApiRegistry.with(catalogApiRef, catalog);
Wrapper = ({ children }) => (
- {children}
+
+ {children}
+
);
});
diff --git a/plugins/catalog-graphql/package.json b/plugins/catalog-graphql/package.json
index 5df4f9ba5c..a7070a1634 100644
--- a/plugins/catalog-graphql/package.json
+++ b/plugins/catalog-graphql/package.json
@@ -31,7 +31,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.6",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.11",
"@backstage/types": "^0.1.1",
"@graphql-modules/core": "^0.7.17",
@@ -43,8 +43,8 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.8.1",
- "@backstage/test-utils": "^0.1.20",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/test-utils": "^0.1.22",
"@graphql-codegen/cli": "^1.21.3",
"@graphql-codegen/typescript": "^1.17.7",
"@graphql-codegen/typescript-resolvers": "^1.17.7",
diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md
index d06f38698b..6397718fd7 100644
--- a/plugins/catalog-import/CHANGELOG.md
+++ b/plugins/catalog-import/CHANGELOG.md
@@ -1,5 +1,18 @@
# @backstage/plugin-catalog-import
+## 0.7.4
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-client@0.5.2
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+ - @backstage/integration-react@0.1.14
+
## 0.7.3
### Patch Changes
diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json
index 242231bf81..933a84f13e 100644
--- a/plugins/catalog-import/package.json
+++ b/plugins/catalog-import/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-import",
"description": "A Backstage plugin the helps you import entities into your catalog",
- "version": "0.7.3",
+ "version": "0.7.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,14 +31,14 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-client": "^0.5.0",
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.3",
"@backstage/integration": "^0.6.8",
- "@backstage/integration-react": "^0.1.12",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/integration-react": "^0.1.14",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
@@ -55,10 +55,10 @@
"yaml": "^1.10.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/catalog-import/src/components/DefaultImportPage/DefaultImportPage.test.tsx b/plugins/catalog-import/src/components/DefaultImportPage/DefaultImportPage.test.tsx
index 69ae38207d..784cbfbe9e 100644
--- a/plugins/catalog-import/src/components/DefaultImportPage/DefaultImportPage.test.tsx
+++ b/plugins/catalog-import/src/components/DefaultImportPage/DefaultImportPage.test.tsx
@@ -15,14 +15,10 @@
*/
import { CatalogClient } from '@backstage/catalog-client';
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import { configApiRef } from '@backstage/core-plugin-api';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import React from 'react';
import { catalogImportApiRef, CatalogImportClient } from '../../api';
import { DefaultImportPage } from './DefaultImportPage';
@@ -43,15 +39,13 @@ describe('', () => {
},
};
- let apis: ApiRegistry;
+ let apis: TestApiRegistry;
beforeEach(() => {
- apis = ApiRegistry.with(
- configApiRef,
- new ConfigReader({ integrations: {} }),
- )
- .with(catalogApiRef, new CatalogClient({ discoveryApi: {} as any }))
- .with(
+ apis = TestApiRegistry.from(
+ [configApiRef, new ConfigReader({ integrations: {} })],
+ [catalogApiRef, new CatalogClient({ discoveryApi: {} as any })],
+ [
catalogImportApiRef,
new CatalogImportClient({
discoveryApi: {} as any,
@@ -63,7 +57,8 @@ describe('', () => {
catalogApi: {} as any,
configApi: {} as any,
}),
- );
+ ],
+ );
});
it('renders without exploding', async () => {
diff --git a/plugins/catalog-import/src/components/ImportInfoCard/ImportInfoCard.test.tsx b/plugins/catalog-import/src/components/ImportInfoCard/ImportInfoCard.test.tsx
index 4e0c3694cd..9a27532c57 100644
--- a/plugins/catalog-import/src/components/ImportInfoCard/ImportInfoCard.test.tsx
+++ b/plugins/catalog-import/src/components/ImportInfoCard/ImportInfoCard.test.tsx
@@ -14,19 +14,19 @@
* limitations under the License.
*/
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import { configApiRef } from '@backstage/core-plugin-api';
-import { renderInTestApp } from '@backstage/test-utils';
+import {
+ renderInTestApp,
+ TestApiProvider,
+ TestApiRegistry,
+} from '@backstage/test-utils';
import React from 'react';
import { CatalogImportApi, catalogImportApiRef } from '../../api';
import { ImportInfoCard } from './ImportInfoCard';
describe('', () => {
- let apis: ApiRegistry;
+ let apis: TestApiRegistry;
let catalogImportApi: jest.Mocked;
beforeEach(() => {
@@ -35,26 +35,29 @@ describe('', () => {
submitPullRequest: jest.fn(),
};
- apis = ApiRegistry.with(
- configApiRef,
- new ConfigReader({
- integrations: {
- github: [{ token: 'my-token' }],
- },
- }),
- ).with(catalogImportApiRef, catalogImportApi);
+ apis = TestApiRegistry.from(
+ [
+ configApiRef,
+ new ConfigReader({
+ integrations: {
+ github: [{ token: 'my-token' }],
+ },
+ }),
+ ],
+ [catalogImportApiRef, catalogImportApi],
+ );
});
it('renders without exploding', async () => {
- apis = ApiRegistry.with(
- configApiRef,
- new ConfigReader({ integrations: {} }),
- ).with(catalogImportApiRef, catalogImportApi);
-
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
);
expect(getByText('Register an existing component')).toBeInTheDocument();
diff --git a/plugins/catalog-import/src/components/ImportPage/ImportPage.test.tsx b/plugins/catalog-import/src/components/ImportPage/ImportPage.test.tsx
index 92a6077792..1778af73dc 100644
--- a/plugins/catalog-import/src/components/ImportPage/ImportPage.test.tsx
+++ b/plugins/catalog-import/src/components/ImportPage/ImportPage.test.tsx
@@ -15,14 +15,10 @@
*/
import { CatalogClient } from '@backstage/catalog-client';
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import { configApiRef } from '@backstage/core-plugin-api';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import React from 'react';
import { useOutlet } from 'react-router';
import { catalogImportApiRef, CatalogImportClient } from '../../api';
@@ -49,15 +45,13 @@ describe('', () => {
},
};
- let apis: ApiRegistry;
+ let apis: TestApiRegistry;
beforeEach(() => {
- apis = ApiRegistry.with(
- configApiRef,
- new ConfigReader({ integrations: {} }),
- )
- .with(catalogApiRef, new CatalogClient({ discoveryApi: {} as any }))
- .with(
+ apis = TestApiRegistry.from(
+ [configApiRef, new ConfigReader({ integrations: {} })],
+ [catalogApiRef, new CatalogClient({ discoveryApi: {} as any })],
+ [
catalogImportApiRef,
new CatalogImportClient({
discoveryApi: {} as any,
@@ -67,7 +61,8 @@ describe('', () => {
catalogApi: {} as any,
configApi: new ConfigReader({}),
}),
- );
+ ],
+ );
});
afterEach(() => jest.resetAllMocks());
diff --git a/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.test.tsx b/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.test.tsx
index 4a72a653ea..8d28fb8604 100644
--- a/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.test.tsx
+++ b/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.test.tsx
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { errorApiRef } from '@backstage/core-plugin-api';
+import { TestApiProvider } from '@backstage/test-utils';
import { act, render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
@@ -34,14 +34,14 @@ describe('', () => {
};
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
-
{children}
-
+
);
const location = {
diff --git a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx
index 0a55d6337b..3b6f353155 100644
--- a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx
+++ b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { errorApiRef } from '@backstage/core-plugin-api';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
+import { TestApiProvider } from '@backstage/test-utils';
import { TextField } from '@material-ui/core';
import { act, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
@@ -54,13 +54,15 @@ describe('', () => {
};
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
-
{children}
-
+
);
const onPrepareFn = jest.fn();
diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md
index 79dfa5e72a..e6d00b2f8f 100644
--- a/plugins/catalog-react/CHANGELOG.md
+++ b/plugins/catalog-react/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/plugin-catalog-react
+## 0.6.4
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-client@0.5.2
+ - @backstage/catalog-model@0.9.7
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+ - @backstage/core-app-api@0.1.21
+
## 0.6.3
### Patch Changes
diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json
index 9778163391..2ae853650a 100644
--- a/plugins/catalog-react/package.json
+++ b/plugins/catalog-react/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-react",
"description": "A frontend library that helps other Backstage plugins interact with the catalog",
- "version": "0.6.3",
+ "version": "0.6.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -29,11 +29,11 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-client": "^0.5.1",
- "@backstage/catalog-model": "^0.9.6",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-app-api": "^0.1.21",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.4",
"@backstage/integration": "^0.6.9",
"@backstage/types": "^0.1.1",
@@ -51,8 +51,8 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/catalog-react/src/components/EntityTypePicker/EntityTypePicker.test.tsx b/plugins/catalog-react/src/components/EntityTypePicker/EntityTypePicker.test.tsx
index 8eba11aeca..f6e9d296df 100644
--- a/plugins/catalog-react/src/components/EntityTypePicker/EntityTypePicker.test.tsx
+++ b/plugins/catalog-react/src/components/EntityTypePicker/EntityTypePicker.test.tsx
@@ -17,16 +17,15 @@
import React from 'react';
import { fireEvent, waitFor } from '@testing-library/react';
import { capitalize } from 'lodash';
-import { CatalogApi } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
import { EntityTypePicker } from './EntityTypePicker';
import { MockEntityListContextProvider } from '../../testUtils/providers';
import { catalogApiRef } from '../../api';
import { EntityKindFilter, EntityTypeFilter } from '../../filters';
-import { AlertApi, alertApiRef } from '@backstage/core-plugin-api';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
-import { renderWithEffects } from '@backstage/test-utils';
+import { alertApiRef } from '@backstage/core-plugin-api';
+import { ApiProvider } from '@backstage/core-app-api';
+import { renderWithEffects, TestApiRegistry } from '@backstage/test-utils';
const entities: Entity[] = [
{
@@ -61,11 +60,20 @@ const entities: Entity[] = [
},
];
-const apis = ApiRegistry.with(catalogApiRef, {
- getEntities: jest.fn().mockResolvedValue({ items: entities }),
-} as unknown as CatalogApi).with(alertApiRef, {
- post: jest.fn(),
-} as unknown as AlertApi);
+const apis = TestApiRegistry.from(
+ [
+ catalogApiRef,
+ {
+ getEntities: jest.fn().mockResolvedValue({ items: entities }),
+ },
+ ],
+ [
+ alertApiRef,
+ {
+ post: jest.fn(),
+ },
+ ],
+);
describe('', () => {
it('renders available entity types', async () => {
diff --git a/plugins/catalog-react/src/components/UnregisterEntityDialog/UnregisterEntityDialog.test.tsx b/plugins/catalog-react/src/components/UnregisterEntityDialog/UnregisterEntityDialog.test.tsx
index eccf824c2e..2b29bba4fd 100644
--- a/plugins/catalog-react/src/components/UnregisterEntityDialog/UnregisterEntityDialog.test.tsx
+++ b/plugins/catalog-react/src/components/UnregisterEntityDialog/UnregisterEntityDialog.test.tsx
@@ -24,7 +24,7 @@ import { CatalogClient } from '@backstage/catalog-client';
import { catalogApiRef } from '../../api';
import { entityRouteRef } from '../../routes';
import { screen, waitFor } from '@testing-library/react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import * as state from './useUnregisterEntityDialogState';
import {
@@ -32,7 +32,6 @@ import {
alertApiRef,
DiscoveryApi,
} from '@backstage/core-plugin-api';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('UnregisterEntityDialog', () => {
const discoveryApi: DiscoveryApi = {
@@ -49,11 +48,6 @@ describe('UnregisterEntityDialog', () => {
},
};
- const apis = ApiRegistry.with(
- catalogApiRef,
- new CatalogClient({ discoveryApi }),
- ).with(alertApiRef, alertApi);
-
const entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
@@ -68,7 +62,14 @@ describe('UnregisterEntityDialog', () => {
};
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
const stateSpy = jest.spyOn(state, 'useUnregisterEntityDialogState');
diff --git a/plugins/catalog-react/src/components/UnregisterEntityDialog/useUnregisterEntityDialogState.test.tsx b/plugins/catalog-react/src/components/UnregisterEntityDialog/useUnregisterEntityDialogState.test.tsx
index 8b4f436aed..8d6083f111 100644
--- a/plugins/catalog-react/src/components/UnregisterEntityDialog/useUnregisterEntityDialogState.test.tsx
+++ b/plugins/catalog-react/src/components/UnregisterEntityDialog/useUnregisterEntityDialogState.test.tsx
@@ -31,7 +31,7 @@ import {
UseUnregisterEntityDialogState,
useUnregisterEntityDialogState,
} from './useUnregisterEntityDialogState';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { TestApiProvider } from '@backstage/test-utils';
function defer(): { promise: Promise; resolve: (value: T) => void } {
let resolve: (value: T) => void = () => {};
@@ -51,9 +51,9 @@ describe('useUnregisterEntityDialogState', () => {
const catalogApi = catalogApiMock as Partial as CatalogApi;
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
-
+
{children}
-
+
);
let entity: Entity;
diff --git a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx
index 4662e58dd2..f6a4c59374 100644
--- a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx
+++ b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx
@@ -26,9 +26,9 @@ import { MockEntityListContextProvider } from '../../testUtils/providers';
import { EntityTagFilter, UserListFilter } from '../../filters';
import { CatalogApi } from '@backstage/catalog-client';
import { catalogApiRef } from '../../api';
-import { MockStorageApi } from '@backstage/test-utils';
+import { MockStorageApi, TestApiRegistry } from '@backstage/test-utils';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import {
ConfigApi,
configApiRef,
@@ -62,12 +62,12 @@ const mockIdentityApi = {
getIdToken: async () => undefined,
} as Partial;
-const apis = ApiRegistry.from([
+const apis = TestApiRegistry.from(
[configApiRef, mockConfigApi],
[catalogApiRef, mockCatalogApi],
[identityApiRef, mockIdentityApi],
[storageApiRef, MockStorageApi.create()],
-]);
+);
const mockIsOwnedEntity = (entity: Entity) =>
entity.metadata.name === 'component-1';
diff --git a/plugins/catalog-react/src/hooks/useEntityKinds.test.tsx b/plugins/catalog-react/src/hooks/useEntityKinds.test.tsx
index d801e508a6..cdcac8c194 100644
--- a/plugins/catalog-react/src/hooks/useEntityKinds.test.tsx
+++ b/plugins/catalog-react/src/hooks/useEntityKinds.test.tsx
@@ -15,12 +15,12 @@
*/
import React, { PropsWithChildren } from 'react';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { CatalogApi } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
import { catalogApiRef } from '../api';
import { renderHook } from '@testing-library/react-hooks';
import { useEntityKinds } from './useEntityKinds';
+import { TestApiProvider } from '@backstage/test-utils';
const entities: Entity[] = [
{
@@ -59,9 +59,9 @@ const mockCatalogApi: Partial = {
const wrapper = ({ children }: PropsWithChildren<{}>) => {
return (
-
+
{children}
-
+
);
};
diff --git a/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx b/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx
index e448ee73f1..b96f63304a 100644
--- a/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx
+++ b/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx
@@ -16,7 +16,6 @@
import { CatalogApi } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import {
ConfigApi,
configApiRef,
@@ -24,7 +23,7 @@ import {
identityApiRef,
storageApiRef,
} from '@backstage/core-plugin-api';
-import { MockStorageApi } from '@backstage/test-utils';
+import { MockStorageApi, TestApiProvider } from '@backstage/test-utils';
import { act, renderHook } from '@testing-library/react-hooks';
import qs from 'qs';
import React, { PropsWithChildren } from 'react';
@@ -76,16 +75,6 @@ const mockCatalogApi: Partial = {
getEntities: jest.fn().mockImplementation(async () => ({ items: entities })),
getEntityByName: async () => undefined,
};
-const apis = ApiRegistry.from([
- [configApiRef, mockConfigApi],
- [catalogApiRef, mockCatalogApi],
- [identityApiRef, mockIdentityApi],
- [storageApiRef, MockStorageApi.create()],
- [
- starredEntitiesApiRef,
- new DefaultStarredEntitiesApi({ storageApi: MockStorageApi.create() }),
- ],
-]);
const wrapper = ({
userFilter,
@@ -94,13 +83,26 @@ const wrapper = ({
userFilter?: UserListFilterKind;
}>) => {
return (
-
+
{children}
-
+
);
};
diff --git a/plugins/catalog-react/src/hooks/useEntityOwnership.test.tsx b/plugins/catalog-react/src/hooks/useEntityOwnership.test.tsx
index 4edad98c12..f01c13839d 100644
--- a/plugins/catalog-react/src/hooks/useEntityOwnership.test.tsx
+++ b/plugins/catalog-react/src/hooks/useEntityOwnership.test.tsx
@@ -21,8 +21,8 @@ import {
RELATION_OWNED_BY,
UserEntity,
} from '@backstage/catalog-model';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { IdentityApi, identityApiRef } from '@backstage/core-plugin-api';
+import { TestApiProvider } from '@backstage/test-utils';
import { renderHook } from '@testing-library/react-hooks';
import React from 'react';
import { catalogApiRef } from '../api';
@@ -50,14 +50,14 @@ describe('useEntityOwnership', () => {
const catalogApi = mockCatalogApi as unknown as CatalogApi;
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
-
{children}
-
+
);
const ownedEntity: ComponentEntity = {
diff --git a/plugins/catalog-react/src/hooks/useStarredEntities.test.tsx b/plugins/catalog-react/src/hooks/useStarredEntities.test.tsx
index 4f41ef090f..aef876a1b2 100644
--- a/plugins/catalog-react/src/hooks/useStarredEntities.test.tsx
+++ b/plugins/catalog-react/src/hooks/useStarredEntities.test.tsx
@@ -15,9 +15,8 @@
*/
import { Entity } from '@backstage/catalog-model';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { StorageApi } from '@backstage/core-plugin-api';
-import { MockStorageApi } from '@backstage/test-utils';
+import { MockStorageApi, TestApiProvider } from '@backstage/test-utils';
import { act, renderHook } from '@testing-library/react-hooks';
import React, { PropsWithChildren } from 'react';
import { DefaultStarredEntitiesApi, starredEntitiesApiRef } from '../apis';
@@ -47,14 +46,16 @@ describe('useStarredEntities', () => {
beforeEach(() => {
mockStorage = MockStorageApi.create();
wrapper = ({ children }: PropsWithChildren<{}>) => (
-
{children}
-
+
);
});
diff --git a/plugins/catalog-react/src/hooks/useStarredEntity.test.tsx b/plugins/catalog-react/src/hooks/useStarredEntity.test.tsx
index b8577aec0c..8ffc891092 100644
--- a/plugins/catalog-react/src/hooks/useStarredEntity.test.tsx
+++ b/plugins/catalog-react/src/hooks/useStarredEntity.test.tsx
@@ -15,7 +15,7 @@
*/
import { Entity, EntityName } from '@backstage/catalog-model';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { TestApiProvider } from '@backstage/test-utils';
import { renderHook } from '@testing-library/react-hooks';
import React, { PropsWithChildren } from 'react';
import Observable from 'zen-observable';
@@ -31,11 +31,9 @@ describe('useStarredEntity', () => {
beforeEach(() => {
wrapper = ({ children }: PropsWithChildren<{}>) => (
-
+
{children}
-
+
);
});
diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md
index 0030f702ec..7fda738d32 100644
--- a/plugins/catalog/CHANGELOG.md
+++ b/plugins/catalog/CHANGELOG.md
@@ -1,5 +1,20 @@
# @backstage/plugin-catalog
+## 0.7.3
+
+### Patch Changes
+
+- 38d6df6bb9: Remove the "View Api" icon in the AboutCard, as the information is misleading for some users and is
+ duplicated in the tabs above.
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-client@0.5.2
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+ - @backstage/integration-react@0.1.14
+
## 0.7.2
### Patch Changes
diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json
index 9697741dde..ddee20c488 100644
--- a/plugins/catalog/package.json
+++ b/plugins/catalog/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog",
"description": "The Backstage plugin for browsing the Backstage catalog",
- "version": "0.7.2",
+ "version": "0.7.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,13 +31,13 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-client": "^0.5.0",
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.3",
- "@backstage/integration-react": "^0.1.12",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/integration-react": "^0.1.14",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -51,10 +51,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx
index d6f13ed22d..afbed3bdc7 100644
--- a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx
+++ b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx
@@ -15,11 +15,7 @@
*/
import { RELATION_OWNED_BY } from '@backstage/catalog-model';
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ConfigReader } from '@backstage/core-app-api';
import {
ScmIntegrationsApi,
scmIntegrationsApiRef,
@@ -30,7 +26,7 @@ import {
CatalogApi,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { viewTechDocRouteRef } from '../../routes';
@@ -71,21 +67,25 @@ describe('', () => {
},
],
};
- const apis = ApiRegistry.with(
- scmIntegrationsApiRef,
- ScmIntegrationsApi.fromConfig(
- new ConfigReader({
- integrations: {},
- }),
- ),
- ).with(catalogApiRef, catalogApi);
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': entityRouteRef,
@@ -116,28 +116,32 @@ describe('', () => {
lifecycle: 'production',
},
};
- const apis = ApiRegistry.with(
- scmIntegrationsApiRef,
- ScmIntegrationsApi.fromConfig(
- new ConfigReader({
- integrations: {
- github: [
- {
- host: 'github.com',
- token: '...',
- },
- ],
- },
- }),
- ),
- ).with(catalogApiRef, catalogApi);
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': entityRouteRef,
@@ -167,28 +171,32 @@ describe('', () => {
lifecycle: 'production',
},
};
- const apis = ApiRegistry.with(
- scmIntegrationsApiRef,
- ScmIntegrationsApi.fromConfig(
- new ConfigReader({
- integrations: {
- github: [
- {
- host: 'github.com',
- token: '...',
- },
- ],
- },
- }),
- ),
- ).with(catalogApiRef, catalogApi);
const { getByTitle } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': entityRouteRef,
@@ -216,17 +224,21 @@ describe('', () => {
lifecycle: 'production',
},
};
- const apis = ApiRegistry.with(
- scmIntegrationsApiRef,
- ScmIntegrationsApi.fromConfig(new ConfigReader({})),
- ).with(catalogApiRef, catalogApi);
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': entityRouteRef,
@@ -253,17 +265,21 @@ describe('', () => {
lifecycle: 'production',
},
};
- const apis = ApiRegistry.with(
- scmIntegrationsApiRef,
- ScmIntegrationsApi.fromConfig(new ConfigReader({})),
- ).with(catalogApiRef, catalogApi);
const { getByTitle } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': entityRouteRef,
@@ -295,17 +311,21 @@ describe('', () => {
lifecycle: 'production',
},
};
- const apis = ApiRegistry.with(
- scmIntegrationsApiRef,
- ScmIntegrationsApi.fromConfig(new ConfigReader({})),
- ).with(catalogApiRef, catalogApi);
const { queryByTitle } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': entityRouteRef,
@@ -332,28 +352,32 @@ describe('', () => {
lifecycle: 'production',
},
};
- const apis = ApiRegistry.with(
- scmIntegrationsApiRef,
- ScmIntegrationsApi.fromConfig(
- new ConfigReader({
- integrations: {
- github: [
- {
- host: 'github.com',
- token: '...',
- },
- ],
- },
- }),
- ),
- ).with(catalogApiRef, catalogApi);
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/docs/:namespace/:kind/:name': viewTechDocRouteRef,
@@ -381,28 +405,32 @@ describe('', () => {
lifecycle: 'production',
},
};
- const apis = ApiRegistry.with(
- scmIntegrationsApiRef,
- ScmIntegrationsApi.fromConfig(
- new ConfigReader({
- integrations: {
- github: [
- {
- host: 'github.com',
- token: '...',
- },
- ],
- },
- }),
- ),
- ).with(catalogApiRef, catalogApi);
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': entityRouteRef,
@@ -429,28 +457,32 @@ describe('', () => {
lifecycle: 'production',
},
};
- const apis = ApiRegistry.with(
- scmIntegrationsApiRef,
- ScmIntegrationsApi.fromConfig(
- new ConfigReader({
- integrations: {
- github: [
- {
- host: 'github.com',
- token: '...',
- },
- ],
- },
- }),
- ),
- ).with(catalogApiRef, catalogApi);
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': entityRouteRef,
diff --git a/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.test.tsx b/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.test.tsx
index 2730665fb6..b320d6d220 100644
--- a/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.test.tsx
+++ b/plugins/catalog/src/components/CatalogKindHeader/CatalogKindHeader.test.tsx
@@ -18,13 +18,12 @@ import React from 'react';
import { fireEvent } from '@testing-library/react';
import { Entity } from '@backstage/catalog-model';
import {
- CatalogApi,
catalogApiRef,
EntityKindFilter,
MockEntityListContextProvider,
} from '@backstage/plugin-catalog-react';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
-import { renderWithEffects } from '@backstage/test-utils';
+import { ApiProvider } from '@backstage/core-app-api';
+import { renderWithEffects, TestApiRegistry } from '@backstage/test-utils';
import { CatalogKindHeader } from './CatalogKindHeader';
const entities: Entity[] = [
@@ -58,9 +57,12 @@ const entities: Entity[] = [
},
];
-const apis = ApiRegistry.with(catalogApiRef, {
- getEntities: jest.fn().mockResolvedValue({ items: entities }),
-} as Partial);
+const apis = TestApiRegistry.from([
+ catalogApiRef,
+ {
+ getEntities: jest.fn().mockResolvedValue({ items: entities }),
+ },
+]);
describe('', () => {
it('renders available kinds', async () => {
diff --git a/plugins/catalog/src/components/CatalogPage/CatalogPage.test.tsx b/plugins/catalog/src/components/CatalogPage/CatalogPage.test.tsx
index 6b33b33b08..0a46580c12 100644
--- a/plugins/catalog/src/components/CatalogPage/CatalogPage.test.tsx
+++ b/plugins/catalog/src/components/CatalogPage/CatalogPage.test.tsx
@@ -20,7 +20,6 @@ import {
RELATION_MEMBER_OF,
RELATION_OWNED_BY,
} from '@backstage/catalog-model';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { TableColumn, TableProps } from '@backstage/core-components';
import {
IdentityApi,
@@ -38,6 +37,7 @@ import {
mockBreakpoint,
MockStorageApi,
renderWithEffects,
+ TestApiProvider,
wrapInTestApp,
} from '@backstage/test-utils';
import DashboardIcon from '@material-ui/icons/Dashboard';
@@ -129,8 +129,8 @@ describe('CatalogPage', () => {
const renderWrapped = (children: React.ReactNode) =>
renderWithEffects(
wrapInTestApp(
- {
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({ storageApi }),
],
- ])}
+ ]}
>
{children}
- ,
+ ,
{
mountedRoutes: {
'/create': createComponentRouteRef,
diff --git a/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx b/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx
index 822913a385..4c6adcf400 100644
--- a/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx
+++ b/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx
@@ -19,7 +19,7 @@ import {
Entity,
VIEW_URL_ANNOTATION,
} from '@backstage/catalog-model';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import {
entityRouteRef,
DefaultStarredEntitiesApi,
@@ -27,7 +27,11 @@ import {
starredEntitiesApiRef,
UserListFilter,
} from '@backstage/plugin-catalog-react';
-import { MockStorageApi, renderInTestApp } from '@backstage/test-utils';
+import {
+ MockStorageApi,
+ renderInTestApp,
+ TestApiRegistry,
+} from '@backstage/test-utils';
import { act, fireEvent } from '@testing-library/react';
import * as React from 'react';
import { CatalogTable } from './CatalogTable';
@@ -51,10 +55,10 @@ const entities: Entity[] = [
];
describe('CatalogTable component', () => {
- const mockApis = ApiRegistry.with(
+ const mockApis = TestApiRegistry.from([
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({ storageApi: MockStorageApi.create() }),
- );
+ ]);
beforeEach(() => {
window.open = jest.fn();
diff --git a/plugins/catalog/src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.test.tsx b/plugins/catalog/src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.test.tsx
index 7dd823a8f0..e43104b67d 100644
--- a/plugins/catalog/src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.test.tsx
+++ b/plugins/catalog/src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.test.tsx
@@ -21,28 +21,20 @@ import {
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { DependencyOfComponentsCard } from './DependencyOfComponentsCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
- const catalogApi: jest.Mocked = {
- getLocationById: jest.fn(),
- getEntityByName: jest.fn(),
- getEntities: jest.fn(),
- addLocation: jest.fn(),
- getLocationByEntity: jest.fn(),
- removeEntityByUid: jest.fn(),
- } as any;
+ const getEntities: jest.MockedFunction = jest.fn();
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi);
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
@@ -97,7 +89,7 @@ describe('', () => {
},
],
};
- catalogApi.getEntities.mockResolvedValue({
+ getEntities.mockResolvedValue({
items: [
{
apiVersion: 'v1',
diff --git a/plugins/catalog/src/components/DependsOnComponentsCard/DependsOnComponentsCard.test.tsx b/plugins/catalog/src/components/DependsOnComponentsCard/DependsOnComponentsCard.test.tsx
index b9fd75def9..b654136d18 100644
--- a/plugins/catalog/src/components/DependsOnComponentsCard/DependsOnComponentsCard.test.tsx
+++ b/plugins/catalog/src/components/DependsOnComponentsCard/DependsOnComponentsCard.test.tsx
@@ -21,28 +21,20 @@ import {
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { DependsOnComponentsCard } from './DependsOnComponentsCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
- const catalogApi: jest.Mocked = {
- getLocationById: jest.fn(),
- getEntityByName: jest.fn(),
- getEntities: jest.fn(),
- addLocation: jest.fn(),
- getLocationByEntity: jest.fn(),
- removeEntityByUid: jest.fn(),
- } as any;
+ const getEntities: jest.MockedFunction = jest.fn();
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi);
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
@@ -97,7 +89,7 @@ describe('', () => {
},
],
};
- catalogApi.getEntities.mockResolvedValue({
+ getEntities.mockResolvedValue({
items: [
{
apiVersion: 'v1',
diff --git a/plugins/catalog/src/components/DependsOnResourcesCard/DependsOnResourcesCard.test.tsx b/plugins/catalog/src/components/DependsOnResourcesCard/DependsOnResourcesCard.test.tsx
index bee759254c..40685705aa 100644
--- a/plugins/catalog/src/components/DependsOnResourcesCard/DependsOnResourcesCard.test.tsx
+++ b/plugins/catalog/src/components/DependsOnResourcesCard/DependsOnResourcesCard.test.tsx
@@ -21,28 +21,20 @@ import {
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { DependsOnResourcesCard } from './DependsOnResourcesCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
- const catalogApi: jest.Mocked = {
- getLocationById: jest.fn(),
- getEntityByName: jest.fn(),
- getEntities: jest.fn(),
- addLocation: jest.fn(),
- getLocationByEntity: jest.fn(),
- removeEntityByUid: jest.fn(),
- } as any;
+ const getEntities: jest.MockedFunction = jest.fn();
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi);
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
@@ -97,7 +89,7 @@ describe('', () => {
},
],
};
- catalogApi.getEntities.mockResolvedValue({
+ getEntities.mockResolvedValue({
items: [
{
apiVersion: 'v1',
diff --git a/plugins/catalog/src/components/EntityLayout/EntityLayout.test.tsx b/plugins/catalog/src/components/EntityLayout/EntityLayout.test.tsx
index 2216070984..3f3fc804e1 100644
--- a/plugins/catalog/src/components/EntityLayout/EntityLayout.test.tsx
+++ b/plugins/catalog/src/components/EntityLayout/EntityLayout.test.tsx
@@ -16,7 +16,7 @@
import { CatalogApi } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import { AlertApi, alertApiRef } from '@backstage/core-plugin-api';
import {
AsyncEntityProvider,
@@ -26,7 +26,11 @@ import {
entityRouteRef,
starredEntitiesApiRef,
} from '@backstage/plugin-catalog-react';
-import { MockStorageApi, renderInTestApp } from '@backstage/test-utils';
+import {
+ MockStorageApi,
+ renderInTestApp,
+ TestApiRegistry,
+} from '@backstage/test-utils';
import { fireEvent } from '@testing-library/react';
import React from 'react';
import { act } from 'react-dom/test-utils';
@@ -40,12 +44,14 @@ const mockEntity = {
},
} as Entity;
-const mockApis = ApiRegistry.with(catalogApiRef, {} as CatalogApi)
- .with(alertApiRef, {} as AlertApi)
- .with(
+const mockApis = TestApiRegistry.from(
+ [catalogApiRef, {} as CatalogApi],
+ [alertApiRef, {} as AlertApi],
+ [
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({ storageApi: MockStorageApi.create() }),
- );
+ ],
+);
describe('EntityLayout', () => {
it('renders simplest case', async () => {
diff --git a/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.test.tsx b/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.test.tsx
index 862ef9504b..f58e6b9b66 100644
--- a/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.test.tsx
+++ b/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.test.tsx
@@ -20,10 +20,9 @@ import { ORIGIN_LOCATION_ANNOTATION } from '@backstage/catalog-model';
import { CatalogApi } from '@backstage/catalog-client';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
import { screen, waitFor } from '@testing-library/react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { AlertApi, alertApiRef } from '@backstage/core-plugin-api';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('DeleteEntityDialog', () => {
const alertApi: jest.Mocked = {
@@ -34,10 +33,6 @@ describe('DeleteEntityDialog', () => {
const catalogClient: jest.Mocked = {
removeEntityByUid: jest.fn(),
} as any;
- const apis = ApiRegistry.with(catalogApiRef, catalogClient).with(
- alertApiRef,
- alertApi,
- );
const entity = {
apiVersion: 'backstage.io/v1alpha1',
@@ -54,7 +49,14 @@ describe('DeleteEntityDialog', () => {
};
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
afterEach(() => {
diff --git a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx
index 9e26184a8d..a8aac405fe 100644
--- a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx
+++ b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx
@@ -15,23 +15,16 @@
*/
import {
- CatalogApi,
catalogApiRef,
catalogRouteRef,
EntityProvider,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import React from 'react';
import { EntityOrphanWarning } from './EntityOrphanWarning';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
- const catalogClient: jest.Mocked = {
- removeEntityByUid: jest.fn(),
- } as any;
- const apis = ApiRegistry.with(catalogApiRef, catalogClient);
-
it('renders EntityOrphanWarning if the entity is orphan', async () => {
const entity = {
apiVersion: 'v1',
@@ -50,11 +43,20 @@ describe('', () => {
};
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/create': catalogRouteRef,
diff --git a/plugins/catalog/src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.test.tsx b/plugins/catalog/src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.test.tsx
index c406d0ed3c..fcc4475f6a 100644
--- a/plugins/catalog/src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.test.tsx
+++ b/plugins/catalog/src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.test.tsx
@@ -21,17 +21,17 @@ import {
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import React from 'react';
import { EntityProcessingErrorsPanel } from './EntityProcessingErrorsPanel';
import { Entity, getEntityName } from '@backstage/catalog-model';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
describe('', () => {
- const catalogClient: jest.Mocked = {
- getEntityAncestors: jest.fn(),
- } as any;
- const apis = ApiRegistry.with(catalogApiRef, catalogClient);
+ const getEntityAncestors: jest.MockedFunction<
+ CatalogApi['getEntityAncestors']
+ > = jest.fn();
+ const apis = TestApiRegistry.from([catalogApiRef, { getEntityAncestors }]);
it('renders EntityProcessErrors if the entity has errors', async () => {
const entity: Entity = {
@@ -97,7 +97,7 @@ describe('', () => {
},
};
- catalogClient.getEntityAncestors.mockResolvedValue({
+ getEntityAncestors.mockResolvedValue({
root: getEntityName(entity),
items: [{ entity, parents: [] }],
});
@@ -198,7 +198,7 @@ describe('', () => {
],
},
};
- catalogClient.getEntityAncestors.mockResolvedValue({
+ getEntityAncestors.mockResolvedValue({
root: getEntityName(entity),
items: [
{ entity, parents: [getEntityName(parent)] },
diff --git a/plugins/catalog/src/components/EntitySwitch/EntitySwitch.test.tsx b/plugins/catalog/src/components/EntitySwitch/EntitySwitch.test.tsx
index 7f8bf35b74..8768e9728e 100644
--- a/plugins/catalog/src/components/EntitySwitch/EntitySwitch.test.tsx
+++ b/plugins/catalog/src/components/EntitySwitch/EntitySwitch.test.tsx
@@ -21,17 +21,14 @@ import React from 'react';
import { isKind } from './conditions';
import { EntitySwitch } from './EntitySwitch';
import { featureFlagsApiRef } from '@backstage/core-plugin-api';
-import {
- LocalStorageFeatureFlags,
- ApiProvider,
- ApiRegistry,
-} from '@backstage/core-app-api';
+import { LocalStorageFeatureFlags } from '@backstage/core-app-api';
+import { TestApiProvider } from '@backstage/test-utils';
const mockFeatureFlagsApi = new LocalStorageFeatureFlags();
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
-
+
{children}
-
+
);
describe('EntitySwitch', () => {
diff --git a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.test.tsx b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.test.tsx
index d484ab026a..45f7561d6e 100644
--- a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.test.tsx
+++ b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.test.tsx
@@ -21,28 +21,20 @@ import {
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { HasComponentsCard } from './HasComponentsCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
- const catalogApi: jest.Mocked = {
- getLocationById: jest.fn(),
- getEntityByName: jest.fn(),
- getEntities: jest.fn(),
- addLocation: jest.fn(),
- getLocationByEntity: jest.fn(),
- removeEntityByUid: jest.fn(),
- } as any;
+ const getEntities: jest.MockedFunction = jest.fn();
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi);
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
@@ -97,7 +89,7 @@ describe('', () => {
},
],
};
- catalogApi.getEntities.mockResolvedValue({
+ getEntities.mockResolvedValue({
items: [
{
apiVersion: 'v1',
diff --git a/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.test.tsx b/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.test.tsx
index 45604ceb56..a01922d988 100644
--- a/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.test.tsx
+++ b/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.test.tsx
@@ -21,28 +21,20 @@ import {
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { HasResourcesCard } from './HasResourcesCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
- const catalogApi: jest.Mocked = {
- getLocationById: jest.fn(),
- getEntityByName: jest.fn(),
- getEntities: jest.fn(),
- addLocation: jest.fn(),
- getLocationByEntity: jest.fn(),
- removeEntityByUid: jest.fn(),
- } as any;
+ const getEntities: jest.MockedFunction = jest.fn();
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi);
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
@@ -92,7 +84,7 @@ describe('', () => {
},
],
};
- catalogApi.getEntities.mockResolvedValue({
+ getEntities.mockResolvedValue({
items: [
{
apiVersion: 'v1',
diff --git a/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.test.tsx b/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.test.tsx
index 431e757656..e517bd38ae 100644
--- a/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.test.tsx
+++ b/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.test.tsx
@@ -21,28 +21,20 @@ import {
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { HasSubcomponentsCard } from './HasSubcomponentsCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
- const catalogApi: jest.Mocked = {
- getLocationById: jest.fn(),
- getEntityByName: jest.fn(),
- getEntities: jest.fn(),
- addLocation: jest.fn(),
- getLocationByEntity: jest.fn(),
- removeEntityByUid: jest.fn(),
- } as any;
+ const getEntities: jest.MockedFunction = jest.fn();
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi);
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
@@ -97,7 +89,7 @@ describe('', () => {
},
],
};
- catalogApi.getEntities.mockResolvedValue({
+ getEntities.mockResolvedValue({
items: [
{
apiVersion: 'v1',
diff --git a/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.test.tsx b/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.test.tsx
index 3fcfed6099..050550101f 100644
--- a/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.test.tsx
+++ b/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.test.tsx
@@ -21,28 +21,20 @@ import {
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { HasSystemsCard } from './HasSystemsCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
- const catalogApi: jest.Mocked = {
- getLocationById: jest.fn(),
- getEntityByName: jest.fn(),
- getEntities: jest.fn(),
- addLocation: jest.fn(),
- getLocationByEntity: jest.fn(),
- removeEntityByUid: jest.fn(),
- } as any;
+ const getEntities: jest.MockedFunction = jest.fn();
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi);
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
@@ -95,7 +87,7 @@ describe('', () => {
},
],
};
- catalogApi.getEntities.mockResolvedValue({
+ getEntities.mockResolvedValue({
items: [
{
apiVersion: 'v1',
diff --git a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx
index 2b35d0f3b6..e0ec48fbed 100644
--- a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx
+++ b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx
@@ -21,10 +21,9 @@ import {
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { Entity, RELATION_PART_OF } from '@backstage/catalog-model';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import React from 'react';
import { SystemDiagramCard } from './SystemDiagramCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
beforeAll(() => {
@@ -55,11 +54,11 @@ describe('', () => {
};
const { queryByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': entityRouteRef,
@@ -114,11 +113,11 @@ describe('', () => {
};
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': entityRouteRef,
@@ -173,11 +172,11 @@ describe('', () => {
};
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': entityRouteRef,
diff --git a/plugins/circleci/CHANGELOG.md b/plugins/circleci/CHANGELOG.md
index 78cd6d9711..18e227627b 100644
--- a/plugins/circleci/CHANGELOG.md
+++ b/plugins/circleci/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-circleci
+## 0.2.29
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.2.28
### Patch Changes
diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json
index c57d19ea00..7228044f4f 100644
--- a/plugins/circleci/package.json
+++ b/plugins/circleci/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-circleci",
"description": "A Backstage plugin that integrates towards Circle CI",
- "version": "0.2.28",
+ "version": "0.2.29",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,10 +32,10 @@
"postpack": "backstage-cli postpack"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.3",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -52,10 +52,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/cloudbuild/CHANGELOG.md b/plugins/cloudbuild/CHANGELOG.md
index dfd17e9908..735f5d2167 100644
--- a/plugins/cloudbuild/CHANGELOG.md
+++ b/plugins/cloudbuild/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-cloudbuild
+## 0.2.28
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.2.27
### Patch Changes
diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json
index 6521816f73..4125a8c82e 100644
--- a/plugins/cloudbuild/package.json
+++ b/plugins/cloudbuild/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-cloudbuild",
"description": "A Backstage plugin that integrates towards Google Cloud Build",
- "version": "0.2.27",
+ "version": "0.2.28",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,10 +31,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -49,10 +49,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/code-coverage-backend/README.md b/plugins/code-coverage-backend/README.md
index 101bee3e3f..4cfc187a3d 100644
--- a/plugins/code-coverage-backend/README.md
+++ b/plugins/code-coverage-backend/README.md
@@ -31,11 +31,11 @@ POST a Cobertura XML file to `/report`
Example:
```json
-// curl -X POST -H "Content-Type:text/xml" -d @cobertura.xml "localhost:7000/api/code-coverage/report?entity=component:default/entity-name&coverageType=cobertura"
+// curl -X POST -H "Content-Type:text/xml" -d @cobertura.xml "localhost:7007/api/code-coverage/report?entity=component:default/entity-name&coverageType=cobertura"
{
"links": [
{
- "href": "http://localhost:7000/api/code-coverage/report?entity=component:default/entity-name",
+ "href": "http://localhost:7007/api/code-coverage/report?entity=component:default/entity-name",
"rel": "coverage"
}
]
@@ -49,11 +49,11 @@ POST a JaCoCo XML file to `/report`
Example:
```json
-// curl -X POST -H "Content-Type:text/xml" -d @jacoco.xml "localhost:7000/api/code-coverage/report?entity=component:default/entity-name&coverageType=jacoco"
+// curl -X POST -H "Content-Type:text/xml" -d @jacoco.xml "localhost:7007/api/code-coverage/report?entity=component:default/entity-name&coverageType=jacoco"
{
"links": [
{
- "href": "http://localhost:7000/api/code-coverage/report?entity=component:default/entity-name",
+ "href": "http://localhost:7007/api/code-coverage/report?entity=component:default/entity-name",
"rel": "coverage"
}
]
@@ -67,7 +67,7 @@ GET `/report`
Example:
```json
-// curl localhost:7000/api/code-coverage/report?entity=component:default/entity-name
+// curl localhost:7007/api/code-coverage/report?entity=component:default/entity-name
{
"aggregate": {
"branch": {
@@ -111,7 +111,7 @@ GET `/history`
Example
```json
-// curl localhost:7000/api/code-coverage/history?entity=component:default/entity-name
+// curl localhost:7007/api/code-coverage/history?entity=component:default/entity-name
{
"entity": {
"kind": "Component",
diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json
index 53d52a9246..90320d0e41 100644
--- a/plugins/code-coverage-backend/package.json
+++ b/plugins/code-coverage-backend/package.json
@@ -20,9 +20,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.7",
- "@backstage/catalog-client": "^0.5.0",
- "@backstage/catalog-model": "^0.9.5",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.10",
"@backstage/errors": "^0.1.3",
"@backstage/integration": "^0.6.8",
@@ -37,7 +37,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
+ "@backstage/cli": "^0.9.0",
"@types/express-xml-bodyparser": "^0.3.2",
"@types/supertest": "^2.0.8",
"msw": "^0.35.0",
diff --git a/plugins/code-coverage-backend/src/run.ts b/plugins/code-coverage-backend/src/run.ts
index 54d2716290..0a3ed2b7f0 100644
--- a/plugins/code-coverage-backend/src/run.ts
+++ b/plugins/code-coverage-backend/src/run.ts
@@ -18,7 +18,7 @@ import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
-const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7000;
+const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
diff --git a/plugins/code-coverage-backend/src/service/router.test.ts b/plugins/code-coverage-backend/src/service/router.test.ts
index 462606bbab..4e6a66fdd8 100644
--- a/plugins/code-coverage-backend/src/service/router.test.ts
+++ b/plugins/code-coverage-backend/src/service/router.test.ts
@@ -42,7 +42,7 @@ function createDatabase(): PluginDatabaseManager {
const testDiscovery: jest.Mocked = {
getBaseUrl: jest
.fn()
- .mockResolvedValue('http://localhost:7000/api/code-coverage'),
+ .mockResolvedValue('http://localhost:7007/api/code-coverage'),
getExternalBaseUrl: jest.fn(),
};
const mockUrlReader = UrlReaders.default({
diff --git a/plugins/code-coverage/CHANGELOG.md b/plugins/code-coverage/CHANGELOG.md
index 572e0f7800..b5b413b9d2 100644
--- a/plugins/code-coverage/CHANGELOG.md
+++ b/plugins/code-coverage/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-code-coverage
+## 0.1.18
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.1.17
### Patch Changes
diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json
index 0d6e998b69..e5b51e90b4 100644
--- a/plugins/code-coverage/package.json
+++ b/plugins/code-coverage/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-code-coverage",
"description": "A Backstage plugin that helps you keep track of your code coverage",
- "version": "0.1.17",
+ "version": "0.1.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,12 +21,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.6",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.11",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.4",
- "@backstage/plugin-catalog-react": "^0.6.3",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -42,10 +42,10 @@
"recharts": "^1.8.5"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md
index c8372532f6..ca889ebdbd 100644
--- a/plugins/config-schema/CHANGELOG.md
+++ b/plugins/config-schema/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-config-schema
+## 0.1.13
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.1.12
### Patch Changes
diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json
index 0708115270..c9abbc7e4e 100644
--- a/plugins/config-schema/package.json
+++ b/plugins/config-schema/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-config-schema",
"description": "A Backstage plugin that lets you browse the configuration schema of your app",
- "version": "0.1.12",
+ "version": "0.1.13",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -22,8 +22,8 @@
},
"dependencies": {
"@backstage/config": "^0.1.11",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.4",
"@backstage/theme": "^0.2.13",
"@backstage/types": "^0.1.1",
@@ -37,10 +37,10 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/config-schema/src/api/StaticSchemaLoader.ts b/plugins/config-schema/src/api/StaticSchemaLoader.ts
index 48a125f38e..71eae63376 100644
--- a/plugins/config-schema/src/api/StaticSchemaLoader.ts
+++ b/plugins/config-schema/src/api/StaticSchemaLoader.ts
@@ -49,7 +49,7 @@ export class StaticSchemaLoader implements ConfigSchemaApi {
return undefined;
}
- throw ResponseError.fromResponse(res);
+ throw await ResponseError.fromResponse(res);
}
return await res.json();
diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md
index 8a7b07af3b..7096af37c6 100644
--- a/plugins/cost-insights/CHANGELOG.md
+++ b/plugins/cost-insights/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-cost-insights
+## 0.11.11
+
+### Patch Changes
+
+- 4576f82858: Fixed generation of sample data in the example Cost Insights client
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.11.10
### Patch Changes
diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json
index 064b24bd0c..da9ba8b1f6 100644
--- a/plugins/cost-insights/package.json
+++ b/plugins/cost-insights/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-cost-insights",
"description": "A Backstage plugin that helps you keep track of your cloud spend",
- "version": "0.11.10",
+ "version": "0.11.11",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,8 +32,8 @@
},
"dependencies": {
"@backstage/config": "^0.1.10",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -55,10 +55,10 @@
"yup": "^0.32.9"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.test.tsx b/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.test.tsx
index 4a38af3dbc..e29bb78f2f 100644
--- a/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.test.tsx
+++ b/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.test.tsx
@@ -15,10 +15,10 @@
*/
import { CostInsightsHeader } from './CostInsightsHeader';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import React from 'react';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import { IdentityApi, identityApiRef } from '@backstage/core-plugin-api';
describe('', () => {
@@ -29,7 +29,7 @@ describe('', () => {
}),
};
- const apis = ApiRegistry.from([[identityApiRef, identityApi]]);
+ const apis = TestApiRegistry.from([identityApiRef, identityApi]);
it('Shows nothing to do when no alerts exist', async () => {
const rendered = await renderInTestApp(
diff --git a/plugins/cost-insights/src/plugin.ts b/plugins/cost-insights/src/plugin.ts
index 1714c5fbd5..a422098e08 100644
--- a/plugins/cost-insights/src/plugin.ts
+++ b/plugins/cost-insights/src/plugin.ts
@@ -34,9 +34,7 @@ export const unlabeledDataflowAlertRef = createRouteRef({
export const costInsightsPlugin = createPlugin({
id: 'cost-insights',
- register({ featureFlags }) {
- featureFlags.register('cost-insights-currencies');
- },
+ featureFlags: [{ name: 'cost-insights-currencies' }],
routes: {
root: rootRouteRef,
growthAlerts: projectGrowthAlertRef,
diff --git a/plugins/cost-insights/src/testUtils/providers.tsx b/plugins/cost-insights/src/testUtils/providers.tsx
index 75450c0bb7..09d2feb71b 100644
--- a/plugins/cost-insights/src/testUtils/providers.tsx
+++ b/plugins/cost-insights/src/testUtils/providers.tsx
@@ -30,8 +30,9 @@ import { Group, Duration } from '../types';
// TODO(Rugvip): Could be good to have a clear place to put test utils that is linted accordingly
// eslint-disable-next-line import/no-extraneous-dependencies
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { IdentityApi, identityApiRef } from '@backstage/core-plugin-api';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import { TestApiProvider } from '@backstage/test-utils';
type PartialPropsWithChildren = PropsWithChildren>;
@@ -199,16 +200,17 @@ export const MockCostInsightsApiProvider = ({
getUserGroups: jest.fn(),
};
- // TODO: defaultConfigApiRef: ConfigApiRef
-
- const defaultContext = ApiRegistry.from([
- [identityApiRef, { ...defaultIdentityApi, ...context.identityApi }],
- [
- costInsightsApiRef,
- { ...defaultCostInsightsApi, ...context.costInsightsApi },
- ],
- // [configApiRef, { ...defaultConfigApiRef, ...context.configApiRef }]
- ]);
-
- return {children};
+ return (
+
+ {children}
+
+ );
};
diff --git a/plugins/explore-react/CHANGELOG.md b/plugins/explore-react/CHANGELOG.md
index 4af81f6d8b..0560527f80 100644
--- a/plugins/explore-react/CHANGELOG.md
+++ b/plugins/explore-react/CHANGELOG.md
@@ -1,5 +1,12 @@
# @backstage/plugin-explore-react
+## 0.0.7
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-plugin-api@0.2.0
+
## 0.0.6
### Patch Changes
diff --git a/plugins/explore-react/package.json b/plugins/explore-react/package.json
index 1dfd24dff8..a67f8b6892 100644
--- a/plugins/explore-react/package.json
+++ b/plugins/explore-react/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-explore-react",
"description": "A frontend library for Backstage plugins that want to interact with the explore plugin",
- "version": "0.0.6",
+ "version": "0.0.7",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -29,12 +29,12 @@
"postpack": "backstage-cli postpack"
},
"dependencies": {
- "@backstage/core-plugin-api": "^0.1.11"
+ "@backstage/core-plugin-api": "^0.2.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
- "@backstage/dev-utils": "^0.2.0",
- "@backstage/test-utils": "^0.1.14",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/explore/CHANGELOG.md b/plugins/explore/CHANGELOG.md
index f051691dc5..73117d7f32 100644
--- a/plugins/explore/CHANGELOG.md
+++ b/plugins/explore/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/plugin-explore
+## 0.3.21
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+ - @backstage/plugin-explore-react@0.0.7
+
## 0.3.20
### Patch Changes
diff --git a/plugins/explore/package.json b/plugins/explore/package.json
index 30890c7176..d9945edc51 100644
--- a/plugins/explore/package.json
+++ b/plugins/explore/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-explore",
"description": "A Backstage plugin for building an exploration page of your software ecosystem",
- "version": "0.3.20",
+ "version": "0.3.21",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,11 +31,11 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.1",
- "@backstage/plugin-explore-react": "^0.0.6",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
+ "@backstage/plugin-explore-react": "^0.0.7",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -49,10 +49,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.test.tsx b/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.test.tsx
index 8927cf088b..d10c262357 100644
--- a/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.test.tsx
+++ b/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.test.tsx
@@ -15,11 +15,10 @@
*/
import { catalogApiRef } from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor, getByText } from '@testing-library/react';
import React from 'react';
import { DefaultExplorePage } from './DefaultExplorePage';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
const catalogApi: jest.Mocked = {
@@ -36,9 +35,9 @@ describe('', () => {
};
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
-
+
{children}
-
+
);
beforeEach(() => {
diff --git a/plugins/explore/src/components/DomainExplorerContent/DomainExplorerContent.test.tsx b/plugins/explore/src/components/DomainExplorerContent/DomainExplorerContent.test.tsx
index d78fc0428d..46a8f1adf2 100644
--- a/plugins/explore/src/components/DomainExplorerContent/DomainExplorerContent.test.tsx
+++ b/plugins/explore/src/components/DomainExplorerContent/DomainExplorerContent.test.tsx
@@ -16,12 +16,11 @@
import { DomainEntity } from '@backstage/catalog-model';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { catalogEntityRouteRef } from '../../routes';
import { DomainExplorerContent } from './DomainExplorerContent';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
const catalogApi: jest.Mocked = {
@@ -38,9 +37,9 @@ describe('', () => {
};
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
-
+
{children}
-
+
);
const mountedRoutes = {
diff --git a/plugins/explore/src/components/ExploreLayout/ExploreLayout.test.tsx b/plugins/explore/src/components/ExploreLayout/ExploreLayout.test.tsx
index 80944628da..7574c685a4 100644
--- a/plugins/explore/src/components/ExploreLayout/ExploreLayout.test.tsx
+++ b/plugins/explore/src/components/ExploreLayout/ExploreLayout.test.tsx
@@ -14,16 +14,12 @@
* limitations under the License.
*/
-import {
- ApiProvider,
- ApiRegistry,
- FeatureFlagged,
-} from '@backstage/core-app-api';
+import { FeatureFlagged } from '@backstage/core-app-api';
import {
FeatureFlagsApi,
featureFlagsApiRef,
} from '@backstage/core-plugin-api';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { ExploreLayout } from './ExploreLayout';
@@ -35,11 +31,11 @@ const featureFlagsApi: jest.Mocked = {
registerFlag: jest.fn(),
};
-const mockApis = ApiRegistry.with(featureFlagsApiRef, featureFlagsApi);
-
describe('', () => {
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
afterEach(() => {
diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.test.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.test.tsx
index 66f54900c9..7c57de84bc 100644
--- a/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.test.tsx
+++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.test.tsx
@@ -20,10 +20,9 @@ import {
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { Entity } from '@backstage/catalog-model';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import React from 'react';
import { GroupsDiagram } from './GroupsDiagram';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
beforeAll(() => {
@@ -57,9 +56,9 @@ describe('', () => {
};
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': entityRouteRef,
diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx
index f0815e0116..5d3f7c358b 100644
--- a/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx
+++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx
@@ -16,11 +16,10 @@
import { Entity } from '@backstage/catalog-model';
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { GroupsExplorerContent } from '../GroupsExplorerContent';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
const catalogApi: jest.Mocked = {
@@ -37,9 +36,9 @@ describe('', () => {
};
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
-
+
{children}
-
+
);
const mountedRoutes = {
diff --git a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.test.tsx b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.test.tsx
index 8accf8fd30..da35c9fa39 100644
--- a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.test.tsx
+++ b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.test.tsx
@@ -18,13 +18,12 @@ import {
ExploreTool,
exploreToolsConfigRef,
} from '@backstage/plugin-explore-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { lightTheme } from '@backstage/theme';
import { ThemeProvider } from '@material-ui/core';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { ToolExplorerContent } from './ToolExplorerContent';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
const exploreToolsConfigApi: jest.Mocked = {
@@ -33,11 +32,9 @@ describe('', () => {
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
-
+
{children}
-
+
);
diff --git a/plugins/firehydrant/CHANGELOG.md b/plugins/firehydrant/CHANGELOG.md
index 2343eb1c2e..b137ed1f73 100644
--- a/plugins/firehydrant/CHANGELOG.md
+++ b/plugins/firehydrant/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-firehydrant
+## 0.1.8
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.1.7
### Patch Changes
diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json
index 4e3fbdd3c8..f332efc150 100644
--- a/plugins/firehydrant/package.json
+++ b/plugins/firehydrant/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-firehydrant",
"description": "A Backstage plugin that integrates towards FireHydrant",
- "version": "0.1.7",
+ "version": "0.1.8",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -22,9 +22,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -35,10 +35,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/firehydrant/src/components/ServiceDetailsCard/ServiceDetailsCard.test.tsx b/plugins/firehydrant/src/components/ServiceDetailsCard/ServiceDetailsCard.test.tsx
index 1123f014da..20dbb77e86 100644
--- a/plugins/firehydrant/src/components/ServiceDetailsCard/ServiceDetailsCard.test.tsx
+++ b/plugins/firehydrant/src/components/ServiceDetailsCard/ServiceDetailsCard.test.tsx
@@ -14,19 +14,19 @@
* limitations under the License.
*/
import React from 'react';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import { fireHydrantApiRef } from '../../api';
import { screen } from '@testing-library/react';
import { ServiceDetailsCard } from './ServiceDetailsCard';
import { Service, Incident } from '../types';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
const mockFireHydrantApi = {
- getServiceDetails: () => {},
- getServiceAnalytics: () => {},
+ getServiceDetails: jest.fn(),
+ getServiceAnalytics: jest.fn(),
};
-const apis = ApiRegistry.from([[fireHydrantApiRef, mockFireHydrantApi]]);
+const apis = TestApiRegistry.from([fireHydrantApiRef, mockFireHydrantApi]);
jest.mock('@backstage/plugin-catalog-react', () => ({
useEntity: () => {
diff --git a/plugins/fossa/CHANGELOG.md b/plugins/fossa/CHANGELOG.md
index f422dfbe41..af99e13c4a 100644
--- a/plugins/fossa/CHANGELOG.md
+++ b/plugins/fossa/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-fossa
+## 0.2.22
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.2.21
### Patch Changes
diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json
index 94528a3126..cc0b486d60 100644
--- a/plugins/fossa/package.json
+++ b/plugins/fossa/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-fossa",
"description": "A Backstage plugin that integrates towards FOSSA",
- "version": "0.2.21",
+ "version": "0.2.22",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,11 +32,11 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.3",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -49,10 +49,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/fossa/src/components/FossaCard/FossaCard.test.tsx b/plugins/fossa/src/components/FossaCard/FossaCard.test.tsx
index 79b401e4a8..046e3e9860 100644
--- a/plugins/fossa/src/components/FossaCard/FossaCard.test.tsx
+++ b/plugins/fossa/src/components/FossaCard/FossaCard.test.tsx
@@ -16,11 +16,10 @@
import { Entity } from '@backstage/catalog-model';
import { EntityProvider } from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import React from 'react';
import { FossaApi, fossaApiRef } from '../../api';
import { FossaCard } from './FossaCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
const fossaApi: jest.Mocked = {
@@ -30,10 +29,10 @@ describe('', () => {
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(fossaApiRef, fossaApi);
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
diff --git a/plugins/fossa/src/components/FossaPage/FossaPage.test.tsx b/plugins/fossa/src/components/FossaPage/FossaPage.test.tsx
index 778f5ee9c6..421ff4431f 100644
--- a/plugins/fossa/src/components/FossaPage/FossaPage.test.tsx
+++ b/plugins/fossa/src/components/FossaPage/FossaPage.test.tsx
@@ -20,11 +20,10 @@ import {
catalogApiRef,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import React from 'react';
import { FossaApi, fossaApiRef } from '../../api';
import { FossaPage } from './FossaPage';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('', () => {
const catalogApi: jest.Mocked = {
@@ -46,13 +45,15 @@ describe('', () => {
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(fossaApiRef, fossaApi).with(
- catalogApiRef,
- catalogApi,
- );
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
diff --git a/plugins/gcp-projects/CHANGELOG.md b/plugins/gcp-projects/CHANGELOG.md
index 28c40f6221..ac8dd570a6 100644
--- a/plugins/gcp-projects/CHANGELOG.md
+++ b/plugins/gcp-projects/CHANGELOG.md
@@ -1,5 +1,30 @@
# @backstage/plugin-gcp-projects
+## 0.3.9
+
+### Patch Changes
+
+- 741bcb168e: UI updates to GCP-projects plugin
+
+ Adds the following to the project list page:
+
+ - pagination
+ - filtering
+ - sorting
+ - rows per page
+ - show/hide columns
+
+ Makes breadcrumb a link back to project list for the project details and new project views.
+
+ In project list page, updates New project button to use RouterLink instead of `href` to avoid login prompt.
+
+ In project details view, links to project details and logs now work, clicking on these will open the project or logs in GCP in new tab.
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.3.8
### Patch Changes
diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json
index 471b9d80f1..cd1c3ac4a1 100644
--- a/plugins/gcp-projects/package.json
+++ b/plugins/gcp-projects/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-gcp-projects",
"description": "A Backstage plugin that helps you manage projects in GCP",
- "version": "0.3.8",
+ "version": "0.3.9",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,8 +31,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -43,10 +43,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/git-release-manager/CHANGELOG.md b/plugins/git-release-manager/CHANGELOG.md
index 72bcf87b2a..1c627ab086 100644
--- a/plugins/git-release-manager/CHANGELOG.md
+++ b/plugins/git-release-manager/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-git-release-manager
+## 0.3.3
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.3.2
### Patch Changes
diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json
index b1b2c11732..7f7ff6184d 100644
--- a/plugins/git-release-manager/package.json
+++ b/plugins/git-release-manager/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-git-release-manager",
"description": "A Backstage plugin that helps you manage releases in git",
- "version": "0.3.2",
+ "version": "0.3.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/integration": "^0.6.8",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
@@ -39,10 +39,10 @@
"recharts": "^1.8.5"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md
index c8fce8e501..5eed309d68 100644
--- a/plugins/github-actions/CHANGELOG.md
+++ b/plugins/github-actions/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-github-actions
+## 0.4.24
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.4.23
### Patch Changes
diff --git a/plugins/github-actions/README.md b/plugins/github-actions/README.md
index d027368c8b..082267d424 100644
--- a/plugins/github-actions/README.md
+++ b/plugins/github-actions/README.md
@@ -11,7 +11,7 @@ TBD
### Generic Requirements
1. Provide OAuth credentials:
- 1. [Create an OAuth App](https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app/) with the callback URL set to `http://localhost:7000/api/auth/github`.
+ 1. [Create an OAuth App](https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app/) with the callback URL set to `http://localhost:7007/api/auth/github`.
2. Take the Client ID and Client Secret from the newly created app's settings page and put them into `AUTH_GITHUB_CLIENT_ID` and `AUTH_GITHUB_CLIENT_SECRET` environment variables.
2. Annotate your component with a correct GitHub Actions repository and owner:
diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json
index 1a4079a5ca..ae7f32be1f 100644
--- a/plugins/github-actions/package.json
+++ b/plugins/github-actions/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-github-actions",
"description": "A Backstage plugin that integrates towards GitHub Actions",
- "version": "0.4.23",
+ "version": "0.4.24",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,11 +33,11 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/integration": "^0.6.8",
- "@backstage/plugin-catalog-react": "^0.6.3",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -52,10 +52,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.test.tsx b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.test.tsx
index 4a4452be5c..0f9573e051 100644
--- a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.test.tsx
+++ b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.test.tsx
@@ -24,16 +24,13 @@ import { useWorkflowRuns } from '../useWorkflowRuns';
import type { Props as RecentWorkflowRunsCardProps } from './RecentWorkflowRunsCard';
import { RecentWorkflowRunsCard } from './RecentWorkflowRunsCard';
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ConfigReader } from '@backstage/core-app-api';
import {
errorApiRef,
configApiRef,
ConfigApi,
} from '@backstage/core-plugin-api';
+import { TestApiProvider } from '@backstage/test-utils';
jest.mock('../useWorkflowRuns', () => ({
useWorkflowRuns: jest.fn(),
@@ -82,16 +79,16 @@ describe('', () => {
render(
-
-
+
,
);
diff --git a/plugins/github-deployments/CHANGELOG.md b/plugins/github-deployments/CHANGELOG.md
index 5259ea11b2..701b167135 100644
--- a/plugins/github-deployments/CHANGELOG.md
+++ b/plugins/github-deployments/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-github-deployments
+## 0.1.21
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+ - @backstage/integration-react@0.1.14
+
## 0.1.20
### Patch Changes
diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json
index 78061951f5..062113a8ef 100644
--- a/plugins/github-deployments/package.json
+++ b/plugins/github-deployments/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-github-deployments",
"description": "A Backstage plugin that integrates towards GitHub Deployments",
- "version": "0.1.20",
+ "version": "0.1.21",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,13 +21,13 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.3",
"@backstage/integration": "^0.6.8",
- "@backstage/integration-react": "^0.1.12",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/integration-react": "^0.1.14",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -39,10 +39,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx b/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx
index 08eeb4a3ce..dba5bbfe1c 100644
--- a/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx
+++ b/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx
@@ -19,6 +19,7 @@ import { fireEvent } from '@testing-library/react';
import {
setupRequestMockHandlers,
renderInTestApp,
+ TestApiRegistry,
} from '@backstage/test-utils';
import {
GithubDeployment,
@@ -42,11 +43,7 @@ import { Entity } from '@backstage/catalog-model';
import { GithubDeploymentsTable } from './GithubDeploymentsTable';
import { Box } from '@material-ui/core';
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import {
errorApiRef,
configApiRef,
@@ -95,14 +92,14 @@ const githubAuthApi: OAuthApi = {
getAccessToken: async _ => 'access_token',
};
-const apis = ApiRegistry.from([
+const apis = TestApiRegistry.from(
[configApiRef, configApi],
[errorApiRef, errorApiMock],
[
githubDeploymentsApiRef,
new GithubDeploymentsApiClient({ scmIntegrationsApi, githubAuthApi }),
],
-]);
+);
const assertFetchedData = async () => {
const rendered = await renderInTestApp(
diff --git a/plugins/gitops-profiles/CHANGELOG.md b/plugins/gitops-profiles/CHANGELOG.md
index 08f256cdb5..42f3533d31 100644
--- a/plugins/gitops-profiles/CHANGELOG.md
+++ b/plugins/gitops-profiles/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-gitops-profiles
+## 0.3.9
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.3.8
### Patch Changes
diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json
index c290599c2c..dfbd6297cf 100644
--- a/plugins/gitops-profiles/package.json
+++ b/plugins/gitops-profiles/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-gitops-profiles",
"description": "A Backstage plugin that helps you manage GitOps profiles",
- "version": "0.3.8",
+ "version": "0.3.9",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,8 +32,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -44,10 +44,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/gitops-profiles/src/components/ProfileCatalog/ProfileCatalog.test.tsx b/plugins/gitops-profiles/src/components/ProfileCatalog/ProfileCatalog.test.tsx
index 8dba498507..e158bcf6ad 100644
--- a/plugins/gitops-profiles/src/components/ProfileCatalog/ProfileCatalog.test.tsx
+++ b/plugins/gitops-profiles/src/components/ProfileCatalog/ProfileCatalog.test.tsx
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import { lightTheme } from '@backstage/theme';
import { ThemeProvider } from '@material-ui/core';
import React from 'react';
@@ -23,7 +23,6 @@ import ProfileCatalog from './ProfileCatalog';
import {
ApiProvider,
- ApiRegistry,
GithubAuth,
OAuthRequestManager,
UrlPatternDiscovery,
@@ -34,7 +33,7 @@ import { githubAuthApiRef } from '@backstage/core-plugin-api';
describe('ProfileCatalog', () => {
it('should render', async () => {
const oauthRequestApi = new OAuthRequestManager();
- const apis = ApiRegistry.from([
+ const apis = TestApiRegistry.from(
[gitOpsApiRef, new GitOpsRestApi('http://localhost:3008')],
[
githubAuthApiRef,
@@ -45,7 +44,7 @@ describe('ProfileCatalog', () => {
oauthRequestApi,
}),
],
- ]);
+ );
const { getByText } = await renderInTestApp(
diff --git a/plugins/graphiql/CHANGELOG.md b/plugins/graphiql/CHANGELOG.md
index aa58dbd332..f6c8b9fde8 100644
--- a/plugins/graphiql/CHANGELOG.md
+++ b/plugins/graphiql/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-graphiql
+## 0.2.21
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.2.20
### Patch Changes
diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json
index df1ad6f887..5c72a4c728 100644
--- a/plugins/graphiql/package.json
+++ b/plugins/graphiql/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-graphiql",
"description": "Backstage plugin for browsing GraphQL APIs",
- "version": "0.2.20",
+ "version": "0.2.21",
"private": false,
"publishConfig": {
"access": "public",
@@ -31,8 +31,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -44,10 +44,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx b/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx
index b4321343a1..2bd173f720 100644
--- a/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx
+++ b/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx
@@ -73,7 +73,12 @@ export const GraphiQLBrowser = ({ endpoints }: GraphiQLBrowserProps) => {
-
+
diff --git a/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.test.tsx b/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.test.tsx
index 4e426d4364..ae84b549ec 100644
--- a/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.test.tsx
+++ b/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.test.tsx
@@ -19,14 +19,10 @@ import { GraphiQLPage } from './GraphiQLPage';
import { ThemeProvider } from '@material-ui/core';
import { lightTheme } from '@backstage/theme';
import { act } from 'react-dom/test-utils';
-import { renderWithEffects } from '@backstage/test-utils';
+import { renderWithEffects, TestApiProvider } from '@backstage/test-utils';
import { GraphQLBrowseApi, graphQlBrowseApiRef } from '../../lib/api';
import { configApiRef } from '@backstage/core-plugin-api';
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ConfigReader } from '@backstage/core-app-api';
jest.mock('../GraphiQLBrowser', () => ({
GraphiQLBrowser: () => '',
@@ -43,17 +39,17 @@ describe('GraphiQLPage', () => {
};
const rendered = await renderWithEffects(
-
,
- ,
+ ,
);
act(() => {
jest.advanceTimersByTime(250);
@@ -71,16 +67,16 @@ describe('GraphiQLPage', () => {
};
const rendered = await renderWithEffects(
-
- ,
+ ,
);
rendered.getByText('GraphiQL');
@@ -95,16 +91,16 @@ describe('GraphiQLPage', () => {
};
const rendered = await renderWithEffects(
-
- ,
+ ,
);
rendered.getByText('GraphiQL');
diff --git a/plugins/graphql-backend/package.json b/plugins/graphql-backend/package.json
index 9d90dd8782..335545021e 100644
--- a/plugins/graphql-backend/package.json
+++ b/plugins/graphql-backend/package.json
@@ -31,7 +31,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.7",
+ "@backstage/backend-common": "^0.9.10",
"@backstage/config": "^0.1.8",
"@backstage/plugin-catalog-graphql": "^0.2.12",
"@graphql-modules/core": "^0.7.17",
@@ -47,7 +47,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
+ "@backstage/cli": "^0.9.0",
"@types/supertest": "^2.0.8",
"eslint-plugin-graphql": "^4.0.0",
"msw": "^0.35.0",
diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md
index 06beb827a6..09e379a625 100644
--- a/plugins/home/CHANGELOG.md
+++ b/plugins/home/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-home
+## 0.4.6
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.4.5
### Patch Changes
diff --git a/plugins/home/package.json b/plugins/home/package.json
index 8020d7af03..ef13ce3a00 100644
--- a/plugins/home/package.json
+++ b/plugins/home/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-home",
"description": "A Backstage plugin that helps you build a home page",
- "version": "0.4.5",
+ "version": "0.4.6",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -35,10 +35,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/ilert/CHANGELOG.md b/plugins/ilert/CHANGELOG.md
index f43f2add09..1bff4b22ef 100644
--- a/plugins/ilert/CHANGELOG.md
+++ b/plugins/ilert/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-ilert
+## 0.1.17
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.1.16
### Patch Changes
diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json
index 69c4025181..6011dd4f46 100644
--- a/plugins/ilert/package.json
+++ b/plugins/ilert/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-ilert",
"description": "A Backstage plugin that integrates towards iLert",
- "version": "0.1.16",
+ "version": "0.1.17",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,11 +21,11 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.3",
- "@backstage/plugin-catalog-react": "^0.6.3",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@date-io/luxon": "1.x",
"@material-ui/core": "^4.12.2",
@@ -39,10 +39,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/jenkins-backend/package.json b/plugins/jenkins-backend/package.json
index 7049fc0a32..ac9efb3ffd 100644
--- a/plugins/jenkins-backend/package.json
+++ b/plugins/jenkins-backend/package.json
@@ -22,9 +22,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.9",
- "@backstage/catalog-client": "^0.5.1",
- "@backstage/catalog-model": "^0.9.5",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.10",
"@types/express": "^4.17.6",
"cross-fetch": "^3.0.6",
@@ -35,7 +35,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
+ "@backstage/cli": "^0.9.0",
"@types/jenkins": "^0.23.1",
"@types/supertest": "^2.0.8",
"msw": "^0.35.0",
diff --git a/plugins/jenkins-backend/src/run.ts b/plugins/jenkins-backend/src/run.ts
index b96989e4b8..068a2b9d5f 100644
--- a/plugins/jenkins-backend/src/run.ts
+++ b/plugins/jenkins-backend/src/run.ts
@@ -18,7 +18,7 @@ import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
-const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7000;
+const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
diff --git a/plugins/jenkins/CHANGELOG.md b/plugins/jenkins/CHANGELOG.md
index 84db4728bc..369676b195 100644
--- a/plugins/jenkins/CHANGELOG.md
+++ b/plugins/jenkins/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-jenkins
+## 0.5.12
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.5.11
### Patch Changes
diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json
index 80d8b40322..4456b15284 100644
--- a/plugins/jenkins/package.json
+++ b/plugins/jenkins/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-jenkins",
"description": "A Backstage plugin that integrates towards Jenkins",
- "version": "0.5.11",
+ "version": "0.5.12",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,10 +32,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -48,10 +48,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx b/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx
index 39187fe859..b1eaf2c24c 100644
--- a/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx
+++ b/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx
@@ -205,6 +205,10 @@ export const CITableView = ({
onChangePageSize,
total,
}: Props) => {
+ const projectsInPage = projects?.slice(
+ page * pageSize,
+ Math.min(projects.length, (page + 1) * pageSize),
+ );
return (
retry(),
},
]}
- data={projects ?? []}
+ data={projectsInPage ?? []}
onPageChange={onChangePage}
onRowsPerPageChange={onChangePageSize}
title={
diff --git a/plugins/jenkins/src/components/Cards/Cards.test.tsx b/plugins/jenkins/src/components/Cards/Cards.test.tsx
index 2508461710..0af91da179 100644
--- a/plugins/jenkins/src/components/Cards/Cards.test.tsx
+++ b/plugins/jenkins/src/components/Cards/Cards.test.tsx
@@ -15,11 +15,10 @@
*/
import React from 'react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { LatestRunCard } from './Cards';
import { EntityProvider } from '@backstage/plugin-catalog-react';
import { JenkinsApi, jenkinsApiRef } from '../../api';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { Project } from '../../api/JenkinsApi';
describe('', () => {
@@ -41,14 +40,12 @@ describe('', () => {
};
it('should show success status of latest build', async () => {
- const apis = ApiRegistry.from([[jenkinsApiRef, jenkinsApi]]);
-
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
);
expect(getByText('Completed')).toBeInTheDocument();
@@ -59,14 +56,12 @@ describe('', () => {
getProjects: () => Promise.reject(new Error('Unauthorized')),
};
- const apis = ApiRegistry.from([[jenkinsApiRef, jenkinsApiWithError]]);
-
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
);
expect(getByText("Error: Can't connect to Jenkins")).toBeInTheDocument();
@@ -82,14 +77,12 @@ describe('', () => {
}),
};
- const apis = ApiRegistry.from([[jenkinsApiRef, jenkinsApiWithError]]);
-
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
);
expect(getByText("Error: Can't find Jenkins project")).toBeInTheDocument();
diff --git a/plugins/kafka-backend/CHANGELOG.md b/plugins/kafka-backend/CHANGELOG.md
index 88111cd1de..482c1f75b1 100644
--- a/plugins/kafka-backend/CHANGELOG.md
+++ b/plugins/kafka-backend/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-kafka-backend
+## 0.2.11
+
+### Patch Changes
+
+- 9145449220: Update Kafka configuration types
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/backend-common@0.9.10
+
## 0.2.10
### Patch Changes
diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json
index e271decc8b..dea803890f 100644
--- a/plugins/kafka-backend/package.json
+++ b/plugins/kafka-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-kafka-backend",
"description": "A Backstage backend plugin that integrates towards Kafka",
- "version": "0.2.10",
+ "version": "0.2.11",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,8 +32,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.7",
- "@backstage/catalog-model": "^0.9.5",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.10",
"@backstage/errors": "^0.1.3",
"@types/express": "^4.17.6",
@@ -44,7 +44,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
+ "@backstage/cli": "^0.9.0",
"@types/jest-when": "^2.7.2",
"@types/lodash": "^4.14.151",
"jest-when": "^3.1.0",
diff --git a/plugins/kafka/CHANGELOG.md b/plugins/kafka/CHANGELOG.md
index 2fe42565da..33ec4bd95a 100644
--- a/plugins/kafka/CHANGELOG.md
+++ b/plugins/kafka/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-kafka
+## 0.2.21
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.2.20
### Patch Changes
diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json
index 888c79db59..a6fbe36e99 100644
--- a/plugins/kafka/package.json
+++ b/plugins/kafka/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-kafka",
"description": "A Backstage plugin that integrates towards Kafka",
- "version": "0.2.20",
+ "version": "0.2.21",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,10 +21,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.3",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -35,10 +35,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/kafka/src/components/ConsumerGroupOffsets/useConsumerGroupsOffsetsForEntity.test.tsx b/plugins/kafka/src/components/ConsumerGroupOffsets/useConsumerGroupsOffsetsForEntity.test.tsx
index a90d3d608e..0be9cabacd 100644
--- a/plugins/kafka/src/components/ConsumerGroupOffsets/useConsumerGroupsOffsetsForEntity.test.tsx
+++ b/plugins/kafka/src/components/ConsumerGroupOffsets/useConsumerGroupsOffsetsForEntity.test.tsx
@@ -26,8 +26,8 @@ import {
import { useConsumerGroupsOffsetsForEntity } from './useConsumerGroupsOffsetsForEntity';
import * as data from './__fixtures__/consumer-group-offsets.json';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { errorApiRef } from '@backstage/core-plugin-api';
+import { TestApiProvider } from '@backstage/test-utils';
const consumerGroupOffsets = data as ConsumerGroupOffsetsResponse;
@@ -59,14 +59,14 @@ describe('useConsumerGroupOffsets', () => {
const wrapper = ({ children }: PropsWithChildren<{}>) => {
return (
-
{children}
-
+
);
};
diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json
index be2903dff5..4edc7b238a 100644
--- a/plugins/kubernetes-backend/package.json
+++ b/plugins/kubernetes-backend/package.json
@@ -32,8 +32,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.7",
- "@backstage/catalog-model": "^0.9.5",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.10",
"@backstage/errors": "^0.1.3",
"@backstage/plugin-kubernetes-common": "^0.1.4",
@@ -55,7 +55,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
+ "@backstage/cli": "^0.9.0",
"@types/aws4": "^1.5.1",
"supertest": "^6.1.3",
"aws-sdk-mock": "^5.2.1",
diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json
index 28dfc94c49..3c9cb5e357 100644
--- a/plugins/kubernetes-common/package.json
+++ b/plugins/kubernetes-common/package.json
@@ -35,11 +35,11 @@
"url": "https://github.com/backstage/backstage/issues"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
+ "@backstage/catalog-model": "^0.9.7",
"@kubernetes/client-node": "^0.15.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0"
+ "@backstage/cli": "^0.9.0"
},
"jest": {
"roots": [
diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md
index a757041b32..0ae3a6c012 100644
--- a/plugins/kubernetes/CHANGELOG.md
+++ b/plugins/kubernetes/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-kubernetes
+## 0.4.20
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.4.19
### Patch Changes
diff --git a/plugins/kubernetes/dev/index.tsx b/plugins/kubernetes/dev/index.tsx
index a2c1114c2d..12de5f098f 100644
--- a/plugins/kubernetes/dev/index.tsx
+++ b/plugins/kubernetes/dev/index.tsx
@@ -29,7 +29,7 @@ import {
} from '@backstage/plugin-kubernetes-common';
import fixture1 from '../src/__fixtures__/1-deployments.json';
import fixture2 from '../src/__fixtures__/2-deployments.json';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { TestApiProvider } from '@backstage/test-utils';
const mockEntity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
@@ -80,32 +80,26 @@ createDevApp()
path: '/fixture-1',
title: 'Fixture 1',
element: (
-
-
+
),
})
.addPage({
path: '/fixture-2',
title: 'Fixture 2',
element: (
-
-
+
),
})
.registerPlugin(kubernetesPlugin)
diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json
index 9dbca8aff8..618f814c21 100644
--- a/plugins/kubernetes/package.json
+++ b/plugins/kubernetes/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-kubernetes",
"description": "A Backstage plugin that integrates towards Kubernetes",
- "version": "0.4.19",
+ "version": "0.4.20",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,11 +31,11 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.6",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.11",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.3",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/plugin-kubernetes-common": "^0.1.5",
"@backstage/theme": "^0.2.13",
"@kubernetes/client-node": "^0.15.0",
@@ -51,10 +51,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.test.ts b/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.test.ts
index afc53d9509..31e07a0f14 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.test.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.test.ts
@@ -78,21 +78,6 @@ describe('clusterLinks', () => {
'https://k8s.foo.com/#/service/bar/foobar?namespace=bar',
);
});
- it('should return an url on the deployment properly url encoded', () => {
- const url = formatClusterLink({
- dashboardUrl: 'https://k8s.foo.com/',
- object: {
- metadata: {
- name: 'foobar',
- namespace: 'bar bar',
- },
- },
- kind: 'Deployment',
- });
- expect(url).toBe(
- 'https://k8s.foo.com/#/deployment/bar%20bar/foobar?namespace=bar+bar',
- );
- });
});
describe('standard app', () => {
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.ts b/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.ts
index 83e970248b..a8f83a9c76 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.ts
@@ -40,8 +40,5 @@ export function formatClusterLink(options: FormatClusterLinkOptions) {
object: options.object,
kind: options.kind,
});
- // Note that we can't rely on 'url.href' since it will put the search before the hash
- // and this won't be properly recognized by SPAs such as Angular in the standard dashboard.
- // Note also that pathname, hash and search will be properly url encoded.
- return `${url.origin}${url.pathname}${url.hash}${url.search}`;
+ return url.toString();
}
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.test.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.test.ts
index df2529a8ac..f0b85cad49 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.test.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.test.ts
@@ -17,19 +17,126 @@ import { openshiftFormatter } from './openshift';
describe('clusterLinks - OpenShift formatter', () => {
it('should return an url on the workloads when there is a namespace only', () => {
- expect(() =>
- openshiftFormatter({
- dashboardUrl: new URL('https://k8s.foo.com'),
- object: {
- metadata: {
- name: 'foobar',
- namespace: 'bar',
- },
+ const url = openshiftFormatter({
+ dashboardUrl: new URL('https://k8s.foo.com'),
+ object: {
+ metadata: {
+ namespace: 'bar',
},
- kind: 'Deployment',
- }),
- ).toThrowError(
- 'OpenShift formatter is not yet implemented. Please, contribute!',
+ },
+ kind: 'foo',
+ });
+ expect(url.href).toBe('https://k8s.foo.com/k8s/cluster/projects/bar');
+ });
+ it('should return an url on the workloads when the kind is not recognizeed', () => {
+ const url = openshiftFormatter({
+ dashboardUrl: new URL('https://k8s.foo.com'),
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'UnknownKind',
+ });
+ expect(url.href).toBe('https://k8s.foo.com/k8s/cluster/projects/bar');
+ });
+ it('should return an url on the deployment', () => {
+ const url = openshiftFormatter({
+ dashboardUrl: new URL('https://k8s.foo.com/'),
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Deployment',
+ });
+ expect(url.href).toBe('https://k8s.foo.com/k8s/ns/bar/deployments/foobar');
+ });
+ it('should return an url on the deployment and keep the path prefix 1', () => {
+ const url = openshiftFormatter({
+ dashboardUrl: new URL('https://k8s.foo.com/some/prefix/'),
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Deployment',
+ });
+ expect(url.href).toBe(
+ 'https://k8s.foo.com/some/prefix/k8s/ns/bar/deployments/foobar',
+ );
+ });
+ it('should return an url on the deployment and keep the path prefix 2', () => {
+ const url = openshiftFormatter({
+ dashboardUrl: new URL('https://k8s.foo.com/some/prefix'),
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Deployment',
+ });
+ expect(url.href).toBe(
+ 'https://k8s.foo.com/some/prefix/k8s/ns/bar/deployments/foobar',
+ );
+ });
+ it('should return an url on the service', () => {
+ const url = openshiftFormatter({
+ dashboardUrl: new URL('https://k8s.foo.com/'),
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Service',
+ });
+ expect(url.href).toBe('https://k8s.foo.com/k8s/ns/bar/services/foobar');
+ });
+ it('should return an url on the ingress', () => {
+ const url = openshiftFormatter({
+ dashboardUrl: new URL('https://k8s.foo.com/'),
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Ingress',
+ });
+ expect(url.href).toBe('https://k8s.foo.com/k8s/ns/bar/ingresses/foobar');
+ });
+ it('should return an url on the deployment for a hpa', () => {
+ const url = openshiftFormatter({
+ dashboardUrl: new URL('https://k8s.foo.com/'),
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'HorizontalPodAutoscaler',
+ });
+ expect(url.href).toBe(
+ 'https://k8s.foo.com/k8s/ns/bar/horizontalpodautoscalers/foobar',
+ );
+ });
+ it('should return an url on the PV', () => {
+ const url = openshiftFormatter({
+ dashboardUrl: new URL('https://k8s.foo.com/'),
+ object: {
+ metadata: {
+ name: 'foobar',
+ },
+ },
+ kind: 'PersistentVolume',
+ });
+ expect(url.href).toBe(
+ 'https://k8s.foo.com/k8s/cluster/persistentvolumes/foobar',
);
});
});
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.ts
index bacb747ebb..6c20cd4720 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.ts
@@ -15,10 +15,40 @@
*/
import { ClusterLinksFormatterOptions } from '../../../types/types';
-export function openshiftFormatter(
- _options: ClusterLinksFormatterOptions,
-): URL {
- throw new Error(
- 'OpenShift formatter is not yet implemented. Please, contribute!',
+const kindMappings: Record = {
+ deployment: 'deployments',
+ ingress: 'ingresses',
+ service: 'services',
+ horizontalpodautoscaler: 'horizontalpodautoscalers',
+ persistentvolume: 'persistentvolumes',
+};
+
+export function openshiftFormatter(options: ClusterLinksFormatterOptions): URL {
+ const basePath = new URL(options.dashboardUrl.href);
+ const name = encodeURIComponent(options.object.metadata?.name ?? '');
+ const namespace = encodeURIComponent(
+ options.object.metadata?.namespace ?? '',
);
+ const validKind = kindMappings[options.kind.toLocaleLowerCase('en-US')];
+ if (!basePath.pathname.endsWith('/')) {
+ // a dashboard url with a path should end with a slash otherwise
+ // the new combined URL will replace the last segment with the appended path!
+ // https://foobar.com/abc/def + k8s/cluster/projects/test --> https://foobar.com/abc/k8s/cluster/projects/test
+ // https://foobar.com/abc/def/ + k8s/cluster/projects/test --> https://foobar.com/abc/def/k8s/cluster/projects/test
+ basePath.pathname += '/';
+ }
+ let path = '';
+ if (namespace) {
+ if (name && validKind) {
+ path = `k8s/ns/${namespace}/${validKind}/${name}`;
+ } else {
+ path = `k8s/cluster/projects/${namespace}`;
+ }
+ } else if (validKind) {
+ path = `k8s/cluster/${validKind}`;
+ if (name) {
+ path += `/${name}`;
+ }
+ }
+ return new URL(path, basePath);
}
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts
index a3a274496e..1ace39ec59 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts
@@ -23,14 +23,24 @@ const kindMappings: Record = {
};
export function rancherFormatter(options: ClusterLinksFormatterOptions): URL {
- const result = new URL(options.dashboardUrl.href);
- const name = options.object.metadata?.name;
- const namespace = options.object.metadata?.namespace;
+ const basePath = new URL(options.dashboardUrl.href);
+ const name = encodeURIComponent(options.object.metadata?.name ?? '');
+ const namespace = encodeURIComponent(
+ options.object.metadata?.namespace ?? '',
+ );
const validKind = kindMappings[options.kind.toLocaleLowerCase('en-US')];
- if (validKind && name && namespace) {
- result.pathname += `explorer/${validKind}/${namespace}/${name}`;
- } else if (namespace) {
- result.pathname += 'explorer/workload';
+ if (!basePath.pathname.endsWith('/')) {
+ // a dashboard url with a path should end with a slash otherwise
+ // the new combined URL will replace the last segment with the appended path!
+ // https://foobar.com/abc/def + explorer/service/test --> https://foobar.com/abc/explorer/service/test
+ // https://foobar.com/abc/def/ + explorer/service/test --> https://foobar.com/abc/def/explorer/service/test
+ basePath.pathname += '/';
}
- return result;
+ let path = '';
+ if (validKind && name && namespace) {
+ path = `explorer/${validKind}/${namespace}/${name}`;
+ } else if (namespace) {
+ path = 'explorer/workload';
+ }
+ return new URL(path, basePath);
}
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.test.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.test.ts
index 76bbf5643d..0b3c21a627 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.test.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.test.ts
@@ -67,6 +67,51 @@ describe('clusterLinks - standard formatter', () => {
'https://k8s.foo.com/#/deployment/bar/foobar?namespace=bar',
);
});
+ it('should return an url on the deployment with a prefix 1', () => {
+ const url = standardFormatter({
+ dashboardUrl: new URL('https://k8s.foo.com/some/prefix'),
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Deployment',
+ });
+ expect(formatUrl(url)).toBe(
+ 'https://k8s.foo.com/some/prefix/#/deployment/bar/foobar?namespace=bar',
+ );
+ });
+ it('should return an url on the deployment with a prefix 2', () => {
+ const url = standardFormatter({
+ dashboardUrl: new URL('https://k8s.foo.com/some/prefix/'),
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Deployment',
+ });
+ expect(formatUrl(url)).toBe(
+ 'https://k8s.foo.com/some/prefix/#/deployment/bar/foobar?namespace=bar',
+ );
+ });
+ it('should return an url on the deployment properly url encoded', () => {
+ const url = standardFormatter({
+ dashboardUrl: new URL('https://k8s.foo.com/'),
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar bar',
+ },
+ },
+ kind: 'Deployment',
+ });
+ expect(formatUrl(url)).toBe(
+ 'https://k8s.foo.com/#/deployment/bar%20bar/foobar?namespace=bar%20bar',
+ );
+ });
it('should return an url on the service', () => {
const url = standardFormatter({
dashboardUrl: new URL('https://k8s.foo.com/'),
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.ts
index fb26cf220d..e28c9fae2b 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.ts
@@ -24,16 +24,22 @@ const kindMappings: Record = {
export function standardFormatter(options: ClusterLinksFormatterOptions) {
const result = new URL(options.dashboardUrl.href);
- const name = options.object.metadata?.name;
- const namespace = options.object.metadata?.namespace;
+ const name = encodeURIComponent(options.object.metadata?.name ?? '');
+ const namespace = encodeURIComponent(
+ options.object.metadata?.namespace ?? '',
+ );
const validKind = kindMappings[options.kind.toLocaleLowerCase('en-US')];
- if (namespace) {
- result.searchParams.set('namespace', namespace);
+ if (!result.pathname.endsWith('/')) {
+ result.pathname += '/';
}
if (validKind && name && namespace) {
result.hash = `/${validKind}/${namespace}/${name}`;
} else if (namespace) {
result.hash = '/workloads';
}
+ if (namespace) {
+ // Note that Angular SPA requires a hash and the query parameter should be part of it
+ result.hash += `?namespace=${namespace}`;
+ }
return result;
}
diff --git a/plugins/lighthouse/CHANGELOG.md b/plugins/lighthouse/CHANGELOG.md
index 4ff76d4f1b..48ef9a178d 100644
--- a/plugins/lighthouse/CHANGELOG.md
+++ b/plugins/lighthouse/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-lighthouse
+## 0.2.30
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.2.29
### Patch Changes
diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json
index f0dca639fc..e53f6ee261 100644
--- a/plugins/lighthouse/package.json
+++ b/plugins/lighthouse/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-lighthouse",
"description": "A Backstage plugin that integrates towards Lighthouse",
- "version": "0.2.29",
+ "version": "0.2.30",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,11 +32,11 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.10",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -47,10 +47,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/lighthouse/src/components/AuditList/AuditListForEntity.test.tsx b/plugins/lighthouse/src/components/AuditList/AuditListForEntity.test.tsx
index 1433a186fb..53de33d21b 100644
--- a/plugins/lighthouse/src/components/AuditList/AuditListForEntity.test.tsx
+++ b/plugins/lighthouse/src/components/AuditList/AuditListForEntity.test.tsx
@@ -30,8 +30,9 @@ import { useWebsiteForEntity } from '../../hooks/useWebsiteForEntity';
import * as data from '../../__fixtures__/website-list-response.json';
import { AuditListForEntity } from './AuditListForEntity';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import { errorApiRef } from '@backstage/core-plugin-api';
+import { TestApiRegistry } from '@backstage/test-utils';
jest.mock('../../hooks/useWebsiteForEntity', () => ({
useWebsiteForEntity: jest.fn(),
@@ -41,7 +42,7 @@ const websiteListResponse = data as WebsiteListResponse;
const entityWebsite = websiteListResponse.items[0];
describe('', () => {
- let apis: ApiRegistry;
+ let apis: TestApiRegistry;
const mockErrorApi: jest.Mocked = {
post: jest.fn(),
@@ -49,10 +50,10 @@ describe('', () => {
};
beforeEach(() => {
- apis = ApiRegistry.from([
+ apis = TestApiRegistry.from(
[lighthouseApiRef, new LighthouseRestApi('http://lighthouse')],
[errorApiRef, mockErrorApi],
- ]);
+ );
(useWebsiteForEntity as jest.Mock).mockReturnValue({
value: entityWebsite,
diff --git a/plugins/lighthouse/src/components/AuditList/AuditListTable.test.tsx b/plugins/lighthouse/src/components/AuditList/AuditListTable.test.tsx
index 4c92997755..d8a54928b2 100644
--- a/plugins/lighthouse/src/components/AuditList/AuditListTable.test.tsx
+++ b/plugins/lighthouse/src/components/AuditList/AuditListTable.test.tsx
@@ -16,7 +16,11 @@
import React from 'react';
import { render } from '@testing-library/react';
-import { wrapInTestApp, setupRequestMockHandlers } from '@backstage/test-utils';
+import {
+ wrapInTestApp,
+ setupRequestMockHandlers,
+ TestApiRegistry,
+} from '@backstage/test-utils';
import AuditListTable from './AuditListTable';
import {
@@ -28,19 +32,20 @@ import { formatTime } from '../../utils';
import { setupServer } from 'msw/node';
import * as data from '../../__fixtures__/website-list-response.json';
-import { ApiRegistry, ApiProvider } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
const websiteListResponse = data as WebsiteListResponse;
describe('AuditListTable', () => {
- let apis: ApiRegistry;
+ let apis: TestApiRegistry;
const server = setupServer();
setupRequestMockHandlers(server);
beforeEach(() => {
- apis = ApiRegistry.from([
- [lighthouseApiRef, new LighthouseRestApi('http://lighthouse')],
+ apis = TestApiRegistry.from([
+ lighthouseApiRef,
+ new LighthouseRestApi('http://lighthouse'),
]);
});
diff --git a/plugins/lighthouse/src/components/AuditList/index.test.tsx b/plugins/lighthouse/src/components/AuditList/index.test.tsx
index ea3587fea9..2b422cce7a 100644
--- a/plugins/lighthouse/src/components/AuditList/index.test.tsx
+++ b/plugins/lighthouse/src/components/AuditList/index.test.tsx
@@ -23,7 +23,11 @@ jest.mock('react-router-dom', () => {
};
});
-import { setupRequestMockHandlers, wrapInTestApp } from '@backstage/test-utils';
+import {
+ setupRequestMockHandlers,
+ TestApiRegistry,
+ wrapInTestApp,
+} from '@backstage/test-utils';
import { fireEvent, render } from '@testing-library/react';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
@@ -35,20 +39,21 @@ import {
} from '../../api';
import * as data from '../../__fixtures__/website-list-response.json';
import AuditList from './index';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
const { useNavigate } = jest.requireMock('react-router-dom');
const websiteListResponse = data as WebsiteListResponse;
describe('AuditList', () => {
- let apis: ApiRegistry;
+ let apis: TestApiRegistry;
const server = setupServer();
setupRequestMockHandlers(server);
beforeEach(() => {
- apis = ApiRegistry.from([
- [lighthouseApiRef, new LighthouseRestApi('http://lighthouse')],
+ apis = TestApiRegistry.from([
+ lighthouseApiRef,
+ new LighthouseRestApi('http://lighthouse'),
]);
});
diff --git a/plugins/lighthouse/src/components/AuditView/index.test.tsx b/plugins/lighthouse/src/components/AuditView/index.test.tsx
index ed1bbbcaf9..00b2843a50 100644
--- a/plugins/lighthouse/src/components/AuditView/index.test.tsx
+++ b/plugins/lighthouse/src/components/AuditView/index.test.tsx
@@ -26,7 +26,11 @@ jest.mock('react-router-dom', () => {
};
});
-import { setupRequestMockHandlers, wrapInTestApp } from '@backstage/test-utils';
+import {
+ setupRequestMockHandlers,
+ TestApiRegistry,
+ wrapInTestApp,
+} from '@backstage/test-utils';
import { render } from '@testing-library/react';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
@@ -35,14 +39,14 @@ import { Audit, lighthouseApiRef, LighthouseRestApi, Website } from '../../api';
import { formatTime } from '../../utils';
import * as data from '../../__fixtures__/website-response.json';
import AuditView from './index';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
const { useParams }: { useParams: jest.Mock } =
jest.requireMock('react-router-dom');
const websiteResponse = data as Website;
describe('AuditView', () => {
- let apis: ApiRegistry;
+ let apis: TestApiRegistry;
let id: string;
const server = setupServer();
@@ -55,8 +59,9 @@ describe('AuditView', () => {
),
);
- apis = ApiRegistry.from([
- [lighthouseApiRef, new LighthouseRestApi('https://lighthouse')],
+ apis = TestApiRegistry.from([
+ lighthouseApiRef,
+ new LighthouseRestApi('https://lighthouse'),
]);
id = websiteResponse.audits.find(a => a.status === 'COMPLETED')
?.id as string;
diff --git a/plugins/lighthouse/src/components/CreateAudit/index.test.tsx b/plugins/lighthouse/src/components/CreateAudit/index.test.tsx
index 84493e243f..59847b516e 100644
--- a/plugins/lighthouse/src/components/CreateAudit/index.test.tsx
+++ b/plugins/lighthouse/src/components/CreateAudit/index.test.tsx
@@ -23,7 +23,11 @@ jest.mock('react-router-dom', () => {
};
});
-import { setupRequestMockHandlers, wrapInTestApp } from '@backstage/test-utils';
+import {
+ setupRequestMockHandlers,
+ TestApiRegistry,
+ wrapInTestApp,
+} from '@backstage/test-utils';
import { fireEvent, render, waitFor } from '@testing-library/react';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
@@ -32,7 +36,7 @@ import { Audit, lighthouseApiRef, LighthouseRestApi } from '../../api';
import * as data from '../../__fixtures__/create-audit-response.json';
import CreateAudit from './index';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import { ErrorApi, errorApiRef } from '@backstage/core-plugin-api';
const { useNavigate }: { useNavigate: jest.Mock } =
@@ -41,17 +45,17 @@ const createAuditResponse = data as Audit;
// TODO add act() to these tests without breaking them!
describe('CreateAudit', () => {
- let apis: ApiRegistry;
+ let apis: TestApiRegistry;
let errorApi: ErrorApi;
const server = setupServer();
setupRequestMockHandlers(server);
beforeEach(() => {
errorApi = { post: jest.fn(), error$: jest.fn() };
- apis = ApiRegistry.from([
+ apis = TestApiRegistry.from(
[lighthouseApiRef, new LighthouseRestApi('http://lighthouse')],
[errorApiRef, errorApi],
- ]);
+ );
});
it('renders the form', () => {
diff --git a/plugins/lighthouse/src/hooks/useWebsiteForEntity.test.tsx b/plugins/lighthouse/src/hooks/useWebsiteForEntity.test.tsx
index 64f7483081..13da0f6f4f 100644
--- a/plugins/lighthouse/src/hooks/useWebsiteForEntity.test.tsx
+++ b/plugins/lighthouse/src/hooks/useWebsiteForEntity.test.tsx
@@ -21,8 +21,8 @@ import { lighthouseApiRef, WebsiteListResponse } from '../api';
import * as data from '../__fixtures__/website-list-response.json';
import { useWebsiteForEntity } from './useWebsiteForEntity';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { errorApiRef } from '@backstage/core-plugin-api';
+import { TestApiProvider } from '@backstage/test-utils';
const websiteListResponse = data as WebsiteListResponse;
const website = websiteListResponse.items[0];
@@ -55,14 +55,14 @@ describe('useWebsiteForEntity', () => {
const wrapper = ({ children }: PropsWithChildren<{}>) => {
return (
-
{children}
-
+
);
};
diff --git a/plugins/newrelic/CHANGELOG.md b/plugins/newrelic/CHANGELOG.md
index 7ffd4b06d1..89b77e9866 100644
--- a/plugins/newrelic/CHANGELOG.md
+++ b/plugins/newrelic/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-newrelic
+## 0.3.9
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.3.8
### Patch Changes
diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json
index 271daa566e..16029f1783 100644
--- a/plugins/newrelic/package.json
+++ b/plugins/newrelic/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-newrelic",
"description": "A Backstage plugin that integrates towards New Relic",
- "version": "0.3.8",
+ "version": "0.3.9",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,8 +32,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -43,10 +43,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md
index 6e1cc7064f..f46095f46a 100644
--- a/plugins/org/CHANGELOG.md
+++ b/plugins/org/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-org
+## 0.3.28
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.3.27
### Patch Changes
diff --git a/plugins/org/package.json b/plugins/org/package.json
index 5348f67523..db6cfe4d0b 100644
--- a/plugins/org/package.json
+++ b/plugins/org/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-org",
"description": "A Backstage plugin that helps you create entity pages for your organization",
- "version": "0.3.27",
+ "version": "0.3.28",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,10 +21,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -37,10 +37,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx
index 0a5a0cfef1..b6b549d934 100644
--- a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx
+++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx
@@ -15,8 +15,8 @@
*/
import { Entity, GroupEntity } from '@backstage/catalog-model';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { catalogApiRef, EntityProvider } from '@backstage/plugin-catalog-react';
+import { TestApiProvider } from '@backstage/test-utils';
import { Grid } from '@material-ui/core';
import React from 'react';
import { MemoryRouter } from 'react-router';
@@ -99,12 +99,9 @@ const catalogApi = (items: Entity[]) => ({
getEntities: () => Promise.resolve({ items }),
});
-const apiRegistry = (items: Entity[]) =>
- ApiRegistry.from([[catalogApiRef, catalogApi(items)]]);
-
export const Default = () => (
-
+
@@ -112,13 +109,13 @@ export const Default = () => (
-
+
);
export const Empty = () => (
-
+
@@ -126,6 +123,6 @@ export const Empty = () => (
-
+
);
diff --git a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx
index 75cb9efd7f..b0c68d9a83 100644
--- a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx
+++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx
@@ -20,10 +20,13 @@ import {
catalogApiRef,
EntityProvider,
} from '@backstage/plugin-catalog-react';
-import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils';
+import {
+ renderWithEffects,
+ TestApiProvider,
+ wrapInTestApp,
+} from '@backstage/test-utils';
import React from 'react';
import { MembersListCard } from './MembersListCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('MemberTab Test', () => {
const groupEntity: GroupEntity = {
@@ -103,17 +106,15 @@ describe('MemberTab Test', () => {
}),
};
- const apis = ApiRegistry.from([[catalogApiRef, catalogApi]]);
-
it('Display Profile Card', async () => {
const rendered = await renderWithEffects(
wrapInTestApp(
-
+
,
- ,
+ ,
),
);
diff --git a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.stories.tsx b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.stories.tsx
index 14fed985b6..6a20035dfa 100644
--- a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.stories.tsx
+++ b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.stories.tsx
@@ -15,14 +15,14 @@
*/
import { GroupEntity } from '@backstage/catalog-model';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import {
CatalogApi,
catalogApiRef,
catalogRouteRef,
EntityProvider,
} from '@backstage/plugin-catalog-react';
-import { wrapInTestApp } from '@backstage/test-utils';
+import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils';
import {
BackstageTheme,
createTheme,
@@ -86,11 +86,11 @@ const catalogApi: Partial = {
getEntities: () => Promise.resolve({ items: [serviceA, serviceB, websiteA] }),
};
-const apiRegistry = ApiRegistry.from([[catalogApiRef, catalogApi]]);
+const apis = TestApiRegistry.from([catalogApiRef, catalogApi]);
export const Default = () =>
wrapInTestApp(
-
+
@@ -123,7 +123,7 @@ const monochromeTheme = (outer: BackstageTheme) =>
export const Themed = () =>
wrapInTestApp(
-
+
diff --git a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.test.tsx b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.test.tsx
index b5ffd37083..8d6fc1a002 100644
--- a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.test.tsx
+++ b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.test.tsx
@@ -21,11 +21,10 @@ import {
EntityProvider,
catalogRouteRef,
} from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { queryByText } from '@testing-library/react';
import React from 'react';
import { OwnershipCard } from './OwnershipCard';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('OwnershipCard', () => {
const groupEntity: GroupEntity = {
@@ -121,11 +120,11 @@ describe('OwnershipCard', () => {
});
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/create': catalogRouteRef,
@@ -157,11 +156,11 @@ describe('OwnershipCard', () => {
});
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/create': catalogRouteRef,
@@ -205,11 +204,11 @@ describe('OwnershipCard', () => {
});
const { getByText } = await renderInTestApp(
-
+
- ,
+ ,
{
mountedRoutes: {
'/create': catalogRouteRef,
diff --git a/plugins/pagerduty/CHANGELOG.md b/plugins/pagerduty/CHANGELOG.md
index 11ae548db8..bb74598f2a 100644
--- a/plugins/pagerduty/CHANGELOG.md
+++ b/plugins/pagerduty/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-pagerduty
+## 0.3.18
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.3.17
### Patch Changes
diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json
index 7b42a15bc6..7981b2c104 100644
--- a/plugins/pagerduty/package.json
+++ b/plugins/pagerduty/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-pagerduty",
"description": "A Backstage plugin that integrates towards PagerDuty",
- "version": "0.3.17",
+ "version": "0.3.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,10 +31,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -48,10 +48,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/pagerduty/src/components/ChangeEvents/ChangeEvents.test.tsx b/plugins/pagerduty/src/components/ChangeEvents/ChangeEvents.test.tsx
index 446c867f35..723e7b7b19 100644
--- a/plugins/pagerduty/src/components/ChangeEvents/ChangeEvents.test.tsx
+++ b/plugins/pagerduty/src/components/ChangeEvents/ChangeEvents.test.tsx
@@ -16,15 +16,15 @@
import React from 'react';
import { render, waitFor } from '@testing-library/react';
import { ChangeEvent } from '../types';
-import { wrapInTestApp } from '@backstage/test-utils';
+import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils';
import { pagerDutyApiRef } from '../../api';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import { ChangeEvents } from './ChangeEvents';
const mockPagerDutyApi = {
- getChangeEventsByServiceId: () => [],
+ getChangeEventsByServiceId: jest.fn(),
};
-const apis = ApiRegistry.from([[pagerDutyApiRef, mockPagerDutyApi]]);
+const apis = TestApiRegistry.from([pagerDutyApiRef, mockPagerDutyApi]);
describe('Incidents', () => {
it('Renders an empty state when there are no change events', async () => {
diff --git a/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx b/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx
index 52aa9a860f..47f18002fe 100644
--- a/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx
+++ b/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx
@@ -16,15 +16,15 @@
import React from 'react';
import { render, waitFor } from '@testing-library/react';
import { EscalationPolicy } from './EscalationPolicy';
-import { wrapInTestApp } from '@backstage/test-utils';
+import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils';
import { User } from '../types';
import { pagerDutyApiRef } from '../../api';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
const mockPagerDutyApi = {
- getOnCallByPolicyId: () => [],
+ getOnCallByPolicyId: jest.fn(),
};
-const apis = ApiRegistry.from([[pagerDutyApiRef, mockPagerDutyApi]]);
+const apis = TestApiRegistry.from([pagerDutyApiRef, mockPagerDutyApi]);
describe('Escalation', () => {
it('Handles an empty response', async () => {
diff --git a/plugins/pagerduty/src/components/Incident/Incidents.test.tsx b/plugins/pagerduty/src/components/Incident/Incidents.test.tsx
index d66acc0879..74e7d82e8b 100644
--- a/plugins/pagerduty/src/components/Incident/Incidents.test.tsx
+++ b/plugins/pagerduty/src/components/Incident/Incidents.test.tsx
@@ -16,15 +16,15 @@
import React from 'react';
import { render, waitFor } from '@testing-library/react';
import { Incidents } from './Incidents';
-import { wrapInTestApp } from '@backstage/test-utils';
+import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils';
import { pagerDutyApiRef } from '../../api';
import { Incident } from '../types';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
const mockPagerDutyApi = {
- getIncidentsByServiceId: () => [],
+ getIncidentsByServiceId: jest.fn(),
};
-const apis = ApiRegistry.from([[pagerDutyApiRef, mockPagerDutyApi]]);
+const apis = TestApiRegistry.from([pagerDutyApiRef, mockPagerDutyApi]);
describe('Incidents', () => {
it('Renders an empty state when there are no incidents', async () => {
diff --git a/plugins/pagerduty/src/components/PagerDutyCard/index.test.tsx b/plugins/pagerduty/src/components/PagerDutyCard/index.test.tsx
index d644aa019a..e0a857ccc7 100644
--- a/plugins/pagerduty/src/components/PagerDutyCard/index.test.tsx
+++ b/plugins/pagerduty/src/components/PagerDutyCard/index.test.tsx
@@ -18,12 +18,12 @@ import { render, waitFor, fireEvent, act } from '@testing-library/react';
import { PagerDutyCard } from '../PagerDutyCard';
import { Entity } from '@backstage/catalog-model';
import { EntityProvider } from '@backstage/plugin-catalog-react';
-import { wrapInTestApp } from '@backstage/test-utils';
+import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils';
import { pagerDutyApiRef, UnauthorizedError, PagerDutyClient } from '../../api';
import { Service, User } from '../types';
-import { alertApiRef, createApiRef } from '@backstage/core-plugin-api';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { alertApiRef } from '@backstage/core-plugin-api';
+import { ApiProvider } from '@backstage/core-app-api';
const mockPagerDutyApi: Partial = {
getServiceByIntegrationKey: async () => [],
@@ -31,16 +31,10 @@ const mockPagerDutyApi: Partial = {
getIncidentsByServiceId: async () => [],
};
-const apis = ApiRegistry.from([
+const apis = TestApiRegistry.from(
[pagerDutyApiRef, mockPagerDutyApi],
- [
- alertApiRef,
- createApiRef({
- id: 'core.alert',
- description: 'Used to report alerts and forward them to the app',
- }),
- ],
-]);
+ [alertApiRef, {}],
+);
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
diff --git a/plugins/pagerduty/src/components/TriggerButton/index.test.tsx b/plugins/pagerduty/src/components/TriggerButton/index.test.tsx
index 21f0dd5f1d..3776bcaf1c 100644
--- a/plugins/pagerduty/src/components/TriggerButton/index.test.tsx
+++ b/plugins/pagerduty/src/components/TriggerButton/index.test.tsx
@@ -15,16 +15,15 @@
*/
import React from 'react';
import { act, fireEvent, screen, waitFor } from '@testing-library/react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import { pagerDutyApiRef } from '../../api';
import { Entity } from '@backstage/catalog-model';
import { EntityProvider } from '@backstage/plugin-catalog-react';
import { TriggerButton } from './';
-import { ApiRegistry, ApiProvider } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import {
alertApiRef,
- createApiRef,
IdentityApi,
identityApiRef,
} from '@backstage/core-plugin-api';
@@ -39,17 +38,11 @@ describe('TriggerButton', () => {
triggerAlarm: mockTriggerAlarmFn,
};
- const apis = ApiRegistry.from([
- [
- alertApiRef,
- createApiRef({
- id: 'core.alert',
- description: 'Used to report alerts and forward them to the app',
- }),
- ],
+ const apis = TestApiRegistry.from(
+ [alertApiRef, {}],
[identityApiRef, mockIdentityApi],
[pagerDutyApiRef, mockPagerDutyApi],
- ]);
+ );
it('renders the trigger button, opens and closes dialog', async () => {
const entity: Entity = {
diff --git a/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx b/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx
index 444e820b98..d6f378b4bf 100644
--- a/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx
+++ b/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx
@@ -15,16 +15,15 @@
*/
import React from 'react';
import { fireEvent, act } from '@testing-library/react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import { pagerDutyApiRef } from '../../api';
import { Entity } from '@backstage/catalog-model';
import { EntityProvider } from '@backstage/plugin-catalog-react';
import { TriggerDialog } from './TriggerDialog';
-import { ApiRegistry, ApiProvider } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import {
alertApiRef,
- createApiRef,
IdentityApi,
identityApiRef,
} from '@backstage/core-plugin-api';
@@ -39,17 +38,11 @@ describe('TriggerDialog', () => {
triggerAlarm: mockTriggerAlarmFn,
};
- const apis = ApiRegistry.from([
- [
- alertApiRef,
- createApiRef({
- id: 'core.alert',
- description: 'Used to report alerts and forward them to the app',
- }),
- ],
+ const apis = TestApiRegistry.from(
+ [alertApiRef, {}],
[identityApiRef, mockIdentityApi],
[pagerDutyApiRef, mockPagerDutyApi],
- ]);
+ );
it('open the dialog and trigger an alarm', async () => {
const entity: Entity = {
diff --git a/plugins/permission-common/api-report.md b/plugins/permission-common/api-report.md
index cbf1877c75..043b27554c 100644
--- a/plugins/permission-common/api-report.md
+++ b/plugins/permission-common/api-report.md
@@ -3,6 +3,8 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
+import { Config } from '@backstage/config';
+
// @public
export type AuthorizeRequest = {
permission: Permission;
@@ -67,7 +69,7 @@ export type PermissionAttributes = {
// @public
export class PermissionClient {
- constructor(options: { discoveryApi: DiscoveryApi; enabled?: boolean });
+ constructor(options: { discoveryApi: DiscoveryApi; configApi: Config });
authorize(
requests: AuthorizeRequest[],
options?: AuthorizeRequestOptions,
diff --git a/plugins/permission-common/package.json b/plugins/permission-common/package.json
index 5e79c1ba7b..9e1d60f782 100644
--- a/plugins/permission-common/package.json
+++ b/plugins/permission-common/package.json
@@ -38,13 +38,14 @@
"url": "https://github.com/backstage/backstage/issues"
},
"dependencies": {
+ "@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.2",
"cross-fetch": "^3.0.6",
"uuid": "^8.0.0",
"zod": "^3.11.6"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
+ "@backstage/cli": "^0.9.0",
"@types/jest": "^26.0.7",
"msw": "^0.35.0"
}
diff --git a/plugins/permission-common/src/PermissionClient.test.ts b/plugins/permission-common/src/PermissionClient.test.ts
index 06e2ae0561..b2e66986a1 100644
--- a/plugins/permission-common/src/PermissionClient.test.ts
+++ b/plugins/permission-common/src/PermissionClient.test.ts
@@ -16,6 +16,7 @@
import { RestContext, rest } from 'msw';
import { setupServer } from 'msw/node';
+import { ConfigReader } from '@backstage/config';
import { PermissionClient } from './PermissionClient';
import { AuthorizeRequest, AuthorizeResult, Identified } from './types/api';
import { DiscoveryApi } from './types/discovery';
@@ -32,7 +33,7 @@ const discoveryApi: DiscoveryApi = {
};
const client: PermissionClient = new PermissionClient({
discoveryApi,
- enabled: true,
+ configApi: new ConfigReader({ permission: { enabled: true } }),
});
const mockPermission: Permission = {
@@ -145,7 +146,7 @@ describe('PermissionClient', () => {
).rejects.toThrowError(/invalid input/i);
});
- it('should allow all when authorization is not enabled', async () => {
+ it('should allow all when permission.enabled is false', async () => {
mockAuthorizeHandler.mockImplementationOnce(
(req, res, { json }: RestContext) => {
const responses = req.body.map((a: Identified) => ({
@@ -156,7 +157,32 @@ describe('PermissionClient', () => {
return res(json(responses));
},
);
- const disabled = new PermissionClient({ discoveryApi, enabled: false });
+ const disabled = new PermissionClient({
+ discoveryApi,
+ configApi: new ConfigReader({ permission: { enabled: false } }),
+ });
+ const response = await disabled.authorize([mockAuthorizeRequest]);
+ expect(response[0]).toEqual(
+ expect.objectContaining({ result: AuthorizeResult.ALLOW }),
+ );
+ expect(mockAuthorizeHandler).not.toBeCalled();
+ });
+
+ it('should allow all when permission.enabled is not configured', async () => {
+ mockAuthorizeHandler.mockImplementationOnce(
+ (req, res, { json }: RestContext) => {
+ const responses = req.body.map((a: Identified) => ({
+ id: a.id,
+ outcome: AuthorizeResult.DENY,
+ }));
+
+ return res(json(responses));
+ },
+ );
+ const disabled = new PermissionClient({
+ discoveryApi,
+ configApi: new ConfigReader({}),
+ });
const response = await disabled.authorize([mockAuthorizeRequest]);
expect(response[0]).toEqual(
expect.objectContaining({ result: AuthorizeResult.ALLOW }),
diff --git a/plugins/permission-common/src/PermissionClient.ts b/plugins/permission-common/src/PermissionClient.ts
index 5b17ccd333..f98d40a3c4 100644
--- a/plugins/permission-common/src/PermissionClient.ts
+++ b/plugins/permission-common/src/PermissionClient.ts
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import { Config } from '@backstage/config';
import { ResponseError } from '@backstage/errors';
import fetch from 'cross-fetch';
import * as uuid from 'uuid';
@@ -74,9 +75,10 @@ export class PermissionClient {
private readonly enabled: boolean;
private readonly discoveryApi: DiscoveryApi;
- constructor(options: { discoveryApi: DiscoveryApi; enabled?: boolean }) {
+ constructor(options: { discoveryApi: DiscoveryApi; configApi: Config }) {
this.discoveryApi = options.discoveryApi;
- this.enabled = options.enabled ?? false;
+ this.enabled =
+ options.configApi.getOptionalBoolean('permission.enabled') ?? false;
}
/**
diff --git a/plugins/permission-node/.eslintrc.js b/plugins/permission-node/.eslintrc.js
new file mode 100644
index 0000000000..16a033dbc6
--- /dev/null
+++ b/plugins/permission-node/.eslintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+ extends: [require.resolve('@backstage/cli/config/eslint.backend')],
+};
diff --git a/plugins/permission-node/README.md b/plugins/permission-node/README.md
new file mode 100644
index 0000000000..82dfe54f9c
--- /dev/null
+++ b/plugins/permission-node/README.md
@@ -0,0 +1,7 @@
+# @backstage/plugin-permission-node
+
+> NOTE: THIS PACKAGE IS EXPERIMENTAL, HERE BE DRAGONS
+
+Common permission and authorization utilities for backend plugins. For more
+information, see the [authorization
+PRFC](https://github.com/backstage/backstage/pull/7761).
diff --git a/plugins/permission-node/api-report.md b/plugins/permission-node/api-report.md
new file mode 100644
index 0000000000..e5fe9a7087
--- /dev/null
+++ b/plugins/permission-node/api-report.md
@@ -0,0 +1,130 @@
+## API Report File for "@backstage/plugin-permission-node"
+
+> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
+
+```ts
+import { AuthorizeRequest } from '@backstage/plugin-permission-common';
+import { AuthorizeResult } from '@backstage/plugin-permission-common';
+import { BackstageIdentity } from '@backstage/plugin-auth-backend';
+import { PermissionCondition } from '@backstage/plugin-permission-common';
+import { PermissionCriteria } from '@backstage/plugin-permission-common';
+import { Router } from 'express';
+
+// @public
+export type ApplyConditionsRequest = {
+ resourceRef: string;
+ resourceType: string;
+ conditions: PermissionCriteria;
+};
+
+// @public
+export type ApplyConditionsResponse = {
+ result: AuthorizeResult.ALLOW | AuthorizeResult.DENY;
+};
+
+// @public
+export type Condition = TRule extends PermissionRule<
+ any,
+ any,
+ infer TParams
+>
+ ? (...params: TParams) => PermissionCondition
+ : never;
+
+// @public
+export type ConditionalPolicyResult = {
+ result: AuthorizeResult.CONDITIONAL;
+ conditions: {
+ pluginId: string;
+ resourceType: string;
+ conditions: PermissionCriteria;
+ };
+};
+
+// @public
+export type Conditions<
+ TRules extends Record>,
+> = {
+ [Name in keyof TRules]: Condition;
+};
+
+// @public
+export type ConditionTransformer = (
+ conditions: PermissionCriteria,
+) => PermissionCriteria;
+
+// @public
+export const createConditionExports: <
+ TResource,
+ TRules extends Record>,
+>(options: {
+ pluginId: string;
+ resourceType: string;
+ rules: TRules;
+}) => {
+ conditions: Conditions;
+ createConditions: (conditions: PermissionCriteria) => {
+ pluginId: string;
+ resourceType: string;
+ conditions: PermissionCriteria;
+ };
+};
+
+// @public
+export const createConditionFactory: (
+ rule: PermissionRule,
+) => (...params: TParams) => {
+ rule: string;
+ params: TParams;
+};
+
+// @public
+export const createConditionTransformer: <
+ TQuery,
+ TRules extends PermissionRule[],
+>(
+ permissionRules: [...TRules],
+) => ConditionTransformer;
+
+// @public
+export const createPermissionIntegrationRouter: ({
+ resourceType,
+ rules,
+ getResource,
+}: {
+ resourceType: string;
+ rules: PermissionRule[];
+ getResource: (resourceRef: string) => Promise;
+}) => Router;
+
+// @public
+export interface PermissionPolicy {
+ // (undocumented)
+ handle(
+ request: PolicyAuthorizeRequest,
+ user?: BackstageIdentity,
+ ): Promise;
+}
+
+// @public
+export type PermissionRule<
+ TResource,
+ TQuery,
+ TParams extends unknown[] = unknown[],
+> = {
+ name: string;
+ description: string;
+ apply(resource: TResource, ...params: TParams): boolean;
+ toQuery(...params: TParams): PermissionCriteria;
+};
+
+// @public
+export type PolicyAuthorizeRequest = Omit;
+
+// @public
+export type PolicyResult =
+ | {
+ result: AuthorizeResult.ALLOW | AuthorizeResult.DENY;
+ }
+ | ConditionalPolicyResult;
+```
diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json
new file mode 100644
index 0000000000..e22e2d2de4
--- /dev/null
+++ b/plugins/permission-node/package.json
@@ -0,0 +1,46 @@
+{
+ "name": "@backstage/plugin-permission-node",
+ "description": "Common permission and authorization utilities for backend plugins",
+ "version": "0.0.0",
+ "main": "src/index.ts",
+ "types": "src/index.ts",
+ "license": "Apache-2.0",
+ "publishConfig": {
+ "access": "public",
+ "main": "dist/index.cjs.js",
+ "types": "dist/index.d.ts"
+ },
+ "homepage": "https://backstage.io",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/backstage/backstage",
+ "directory": "plugins/permission-node"
+ },
+ "keywords": [
+ "backstage",
+ "permissions"
+ ],
+ "scripts": {
+ "build": "backstage-cli backend:build",
+ "lint": "backstage-cli lint",
+ "test": "backstage-cli test",
+ "prepack": "backstage-cli prepack",
+ "postpack": "backstage-cli postpack",
+ "clean": "backstage-cli clean"
+ },
+ "dependencies": {
+ "@backstage/plugin-auth-backend": "^0.4.6",
+ "@backstage/plugin-permission-common": "^0.1.0",
+ "@types/express": "^4.17.6",
+ "express": "^4.17.1",
+ "zod": "^3.11.6"
+ },
+ "devDependencies": {
+ "@backstage/cli": "^0.9.0",
+ "@types/supertest": "^2.0.8",
+ "supertest": "^6.1.3"
+ },
+ "files": [
+ "dist"
+ ]
+}
diff --git a/plugins/permission-node/src/index.ts b/plugins/permission-node/src/index.ts
new file mode 100644
index 0000000000..39527bac71
--- /dev/null
+++ b/plugins/permission-node/src/index.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2021 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.
+ */
+
+/**
+ * Common permission and authorization utilities for backend plugins
+ *
+ * @packageDocumentation
+ */
+export * from './integration';
+export * from './policy';
+export * from './types';
diff --git a/plugins/permission-node/src/integration/createConditionExports.test.ts b/plugins/permission-node/src/integration/createConditionExports.test.ts
new file mode 100644
index 0000000000..6f0f8f8632
--- /dev/null
+++ b/plugins/permission-node/src/integration/createConditionExports.test.ts
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { createConditionExports } from './createConditionExports';
+
+const testIntegration = () =>
+ createConditionExports({
+ pluginId: 'test-plugin',
+ resourceType: 'test-resource',
+ rules: {
+ testRule1: {
+ name: 'testRule1',
+ description: 'Test rule 1',
+ apply: jest.fn(
+ (_resource: any, _firstParam: string, _secondParam: number) => true,
+ ),
+ toQuery: jest.fn((firstParam: string, secondParam: number) => ({
+ query: 'testRule1',
+ params: [firstParam, secondParam],
+ })),
+ },
+ testRule2: {
+ name: 'testRule2',
+ description: 'Test rule 2',
+ apply: jest.fn((_firstParam: object) => false),
+ toQuery: jest.fn((firstParam: object) => ({
+ query: 'testRule2',
+ params: [firstParam],
+ })),
+ },
+ },
+ });
+
+describe('createConditionExports', () => {
+ describe('conditions', () => {
+ it('creates condition factories for the supplied rules', () => {
+ const { conditions } = testIntegration();
+
+ expect(conditions.testRule1('a', 1)).toEqual({
+ rule: 'testRule1',
+ params: ['a', 1],
+ });
+
+ expect(conditions.testRule2({ baz: 'quux' })).toEqual({
+ rule: 'testRule2',
+ params: [{ baz: 'quux' }],
+ });
+ });
+ });
+
+ describe('createConditions', () => {
+ it('wraps conditions in an object with resourceType and pluginId', () => {
+ const { createConditions } = testIntegration();
+
+ expect(
+ createConditions({ allOf: [{ rule: 'testRule1', params: ['a', 1] }] }),
+ ).toEqual({
+ pluginId: 'test-plugin',
+ resourceType: 'test-resource',
+ conditions: {
+ allOf: [{ rule: 'testRule1', params: ['a', 1] }],
+ },
+ });
+ });
+ });
+});
diff --git a/plugins/permission-node/src/integration/createConditionExports.ts b/plugins/permission-node/src/integration/createConditionExports.ts
new file mode 100644
index 0000000000..30cff6628a
--- /dev/null
+++ b/plugins/permission-node/src/integration/createConditionExports.ts
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ PermissionCondition,
+ PermissionCriteria,
+} from '@backstage/plugin-permission-common';
+import { PermissionRule } from '../types';
+import { createConditionFactory } from './createConditionFactory';
+
+/**
+ * A utility type for mapping a single {@link PermissionRule} to its
+ * corresponding {@link @backstage/plugin-permission-common#PermissionCondition}.
+ *
+ * @public
+ */
+export type Condition = TRule extends PermissionRule<
+ any,
+ any,
+ infer TParams
+>
+ ? (...params: TParams) => PermissionCondition
+ : never;
+
+/**
+ * A utility type for mapping {@link PermissionRule}s to their corresponding
+ * {@link @backstage/plugin-permission-common#PermissionCondition}s.
+ *
+ * @public
+ */
+export type Conditions<
+ TRules extends Record>,
+> = {
+ [Name in keyof TRules]: Condition;
+};
+
+/**
+ * Creates the recommended condition-related exports for a given plugin based on the built-in
+ * {@link PermissionRule}s it supports.
+ *
+ * @remarks
+ *
+ * The function returns a `conditions` object containing a
+ * {@link @backstage/plugin-permission-common#PermissionCondition} factory for each of the
+ * supplied {@link PermissionRule}s, along with a `createConditions` function which builds the
+ * wrapper object needed to enclose conditions when authoring {@link PermissionPolicy} implementations.
+ *
+ * Plugin authors should generally call this method with all the built-in {@link PermissionRule}s
+ * the plugin supports, and export the resulting `conditions` object and `createConditions`
+ * function so that they can be used by {@link PermissionPolicy} authors.
+ *
+ * @public
+ */
+export const createConditionExports = <
+ TResource,
+ TRules extends Record>,
+>(options: {
+ pluginId: string;
+ resourceType: string;
+ rules: TRules;
+}): {
+ conditions: Conditions;
+ createConditions: (conditions: PermissionCriteria) => {
+ pluginId: string;
+ resourceType: string;
+ conditions: PermissionCriteria;
+ };
+} => {
+ const { pluginId, resourceType, rules } = options;
+
+ return {
+ conditions: Object.entries(rules).reduce(
+ (acc, [key, rule]) => ({
+ ...acc,
+ [key]: createConditionFactory(rule),
+ }),
+ {} as Conditions,
+ ),
+ createConditions: (
+ conditions: PermissionCriteria,
+ ) => ({
+ pluginId,
+ resourceType,
+ conditions,
+ }),
+ };
+};
diff --git a/plugins/permission-node/src/integration/createConditionFactory.test.ts b/plugins/permission-node/src/integration/createConditionFactory.test.ts
new file mode 100644
index 0000000000..8dd43f5da6
--- /dev/null
+++ b/plugins/permission-node/src/integration/createConditionFactory.test.ts
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { createConditionFactory } from './createConditionFactory';
+
+describe('createConditionFactory', () => {
+ const testRule = {
+ name: 'test-rule',
+ description: 'test-description',
+ apply: jest.fn(),
+ toQuery: jest.fn(),
+ };
+
+ it('returns a function', () => {
+ expect(createConditionFactory(testRule)).toEqual(expect.any(Function));
+ });
+
+ describe('return value', () => {
+ it('constructs a condition with the rule name and supplied params', () => {
+ const conditionFactory = createConditionFactory(testRule);
+ expect(conditionFactory('a', 'b', 1, 2)).toEqual({
+ rule: 'test-rule',
+ params: ['a', 'b', 1, 2],
+ });
+ });
+ });
+});
diff --git a/plugins/permission-node/src/integration/createConditionFactory.ts b/plugins/permission-node/src/integration/createConditionFactory.ts
new file mode 100644
index 0000000000..84a8dc86a6
--- /dev/null
+++ b/plugins/permission-node/src/integration/createConditionFactory.ts
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { PermissionRule } from '../types';
+
+/**
+ * Creates a condition factory function for a given authorization rule and parameter types.
+ *
+ * @remarks
+ *
+ * For example, an isEntityOwner rule for catalog entities might take an array of entityRef strings.
+ * The rule itself defines _how_ to check a given resource, whereas a condition also includes _what_
+ * to verify.
+ *
+ * Plugin authors should generally use the {@link createConditionExports} in order to efficiently
+ * create multiple condition factories. This helper should generally only be used to construct
+ * condition factories for third-party rules that aren't part of the backend plugin with which
+ * they're intended to integrate.
+ *
+ * @public
+ */
+export const createConditionFactory =
+ (rule: PermissionRule) =>
+ (...params: TParams) => ({
+ rule: rule.name,
+ params,
+ });
diff --git a/plugins/permission-node/src/integration/createConditionTransformer.test.ts b/plugins/permission-node/src/integration/createConditionTransformer.test.ts
new file mode 100644
index 0000000000..8a93a4ea27
--- /dev/null
+++ b/plugins/permission-node/src/integration/createConditionTransformer.test.ts
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ PermissionCondition,
+ PermissionCriteria,
+} from '@backstage/plugin-permission-common';
+import { createConditionTransformer } from './createConditionTransformer';
+
+const transformConditions = createConditionTransformer([
+ {
+ name: 'test-rule-1',
+ description: 'Test rule 1',
+ apply: jest.fn(),
+ toQuery: jest.fn(
+ (firstParam: string, secondParam: number) =>
+ `test-rule-1:${firstParam}/${secondParam}`,
+ ),
+ },
+ {
+ name: 'test-rule-2',
+ description: 'Test rule 2',
+ apply: jest.fn(),
+ toQuery: jest.fn(
+ (firstParam: object) => `test-rule-2:${JSON.stringify(firstParam)}`,
+ ),
+ },
+]);
+
+describe('createConditionTransformer', () => {
+ const testCases: {
+ conditions: PermissionCriteria;
+ expectedResult: PermissionCriteria;
+ }[] = [
+ {
+ conditions: { rule: 'test-rule-1', params: ['abc', 123] },
+ expectedResult: 'test-rule-1:abc/123',
+ },
+ {
+ conditions: { rule: 'test-rule-2', params: [{ foo: 0 }] },
+ expectedResult: 'test-rule-2:{"foo":0}',
+ },
+ {
+ conditions: {
+ anyOf: [
+ { rule: 'test-rule-1', params: ['a', 1] },
+ { rule: 'test-rule-2', params: [{}] },
+ ],
+ },
+ expectedResult: {
+ anyOf: ['test-rule-1:a/1', 'test-rule-2:{}'],
+ },
+ },
+ {
+ conditions: {
+ allOf: [
+ { rule: 'test-rule-1', params: ['a', 1] },
+ { rule: 'test-rule-2', params: [{}] },
+ ],
+ },
+ expectedResult: {
+ allOf: ['test-rule-1:a/1', 'test-rule-2:{}'],
+ },
+ },
+ {
+ conditions: {
+ not: { rule: 'test-rule-2', params: [{}] },
+ },
+ expectedResult: {
+ not: 'test-rule-2:{}',
+ },
+ },
+ {
+ conditions: {
+ allOf: [
+ {
+ anyOf: [
+ { rule: 'test-rule-1', params: ['a', 1] },
+ { rule: 'test-rule-2', params: [{}] },
+ ],
+ },
+ {
+ not: {
+ allOf: [
+ { rule: 'test-rule-1', params: ['b', 2] },
+ { rule: 'test-rule-2', params: [{ c: 3 }] },
+ ],
+ },
+ },
+ ],
+ },
+ expectedResult: {
+ allOf: [
+ {
+ anyOf: ['test-rule-1:a/1', 'test-rule-2:{}'],
+ },
+ {
+ not: {
+ allOf: ['test-rule-1:b/2', 'test-rule-2:{"c":3}'],
+ },
+ },
+ ],
+ },
+ },
+ {
+ conditions: {
+ allOf: [
+ {
+ anyOf: [
+ { rule: 'test-rule-1', params: ['a', 1] },
+ { rule: 'test-rule-2', params: [{ b: 2 }] },
+ ],
+ },
+ {
+ not: {
+ allOf: [
+ { rule: 'test-rule-1', params: ['c', 3] },
+ { not: { rule: 'test-rule-2', params: [{ d: 4 }] } },
+ ],
+ },
+ },
+ ],
+ },
+ expectedResult: {
+ allOf: [
+ {
+ anyOf: ['test-rule-1:a/1', 'test-rule-2:{"b":2}'],
+ },
+ {
+ not: {
+ allOf: ['test-rule-1:c/3', { not: 'test-rule-2:{"d":4}' }],
+ },
+ },
+ ],
+ },
+ },
+ ];
+
+ it.each(testCases)(
+ 'works with criteria %#',
+ ({ conditions, expectedResult }) => {
+ expect(transformConditions(conditions)).toEqual(expectedResult);
+ },
+ );
+});
diff --git a/plugins/permission-node/src/integration/createConditionTransformer.ts b/plugins/permission-node/src/integration/createConditionTransformer.ts
new file mode 100644
index 0000000000..0e736b832c
--- /dev/null
+++ b/plugins/permission-node/src/integration/createConditionTransformer.ts
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {
+ PermissionCondition,
+ PermissionCriteria,
+} from '@backstage/plugin-permission-common';
+import { PermissionRule } from '../types';
+import {
+ createGetRule,
+ isAndCriteria,
+ isNotCriteria,
+ isOrCriteria,
+} from './util';
+
+const mapConditions = (
+ criteria: PermissionCriteria,
+ getRule: (name: string) => PermissionRule,
+): PermissionCriteria => {
+ if (isAndCriteria(criteria)) {
+ return {
+ allOf: criteria.allOf.map(child => mapConditions(child, getRule)),
+ };
+ } else if (isOrCriteria(criteria)) {
+ return {
+ anyOf: criteria.anyOf.map(child => mapConditions(child, getRule)),
+ };
+ } else if (isNotCriteria(criteria)) {
+ return {
+ not: mapConditions(criteria.not, getRule),
+ };
+ }
+
+ return getRule(criteria.rule).toQuery(...criteria.params);
+};
+
+/**
+ * A function which accepts {@link @backstage/plugin-permission-common#PermissionCondition}s
+ * logically grouped in a {@link @backstage/plugin-permission-common#PermissionCriteria}
+ * object, and transforms the {@link @backstage/plugin-permission-common#PermissionCondition}s
+ * into plugin specific query fragments while retaining the enclosing criteria shape.
+ *
+ * @public
+ */
+export type ConditionTransformer = (
+ conditions: PermissionCriteria,
+) => PermissionCriteria;
+
+/**
+ * A higher-order helper function which accepts an array of
+ * {@link PermissionRule}s, and returns a {@link ConditionTransformer}
+ * which transforms input conditions into equivalent plugin-specific
+ * query fragments using the supplied rules.
+ *
+ * @public
+ */
+export const createConditionTransformer = <
+ TQuery,
+ TRules extends PermissionRule[],
+>(
+ permissionRules: [...TRules],
+): ConditionTransformer => {
+ const getRule = createGetRule(permissionRules);
+
+ return conditions => mapConditions(conditions, getRule);
+};
diff --git a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts
new file mode 100644
index 0000000000..af216dfcb8
--- /dev/null
+++ b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { AuthorizeResult } from '@backstage/plugin-permission-common';
+import express, { Express, Router } from 'express';
+import request from 'supertest';
+import { createPermissionIntegrationRouter } from './createPermissionIntegrationRouter';
+
+const mockGetResource: jest.MockedFunction<
+ (resourceRef: string) => Promise
+> = jest.fn((resourceRef: string) =>
+ Promise.resolve({
+ resourceRef,
+ }),
+);
+
+const testRule1 = {
+ name: 'test-rule-1',
+ description: 'Test rule 1',
+ apply: jest.fn(
+ (_resource: any, _firstParam: string, _secondParam: number) => true,
+ ),
+ toQuery: jest.fn(),
+};
+
+const testRule2 = {
+ name: 'test-rule-2',
+ description: 'Test rule 2',
+ apply: jest.fn((_firstParam: object) => false),
+ toQuery: jest.fn(),
+};
+
+describe('createPermissionIntegrationRouter', () => {
+ let app: Express;
+ let router: Router;
+
+ beforeEach(() => {
+ router = createPermissionIntegrationRouter({
+ resourceType: 'test-resource',
+ getResource: mockGetResource,
+ rules: [testRule1, testRule2],
+ });
+
+ app = express().use(router);
+ });
+
+ it('works', async () => {
+ expect(router).toBeDefined();
+ });
+
+ describe('POST /permissions/apply-conditions', () => {
+ it.each([
+ { rule: 'test-rule-1', params: ['abc', 123] },
+ {
+ anyOf: [
+ { rule: 'test-rule-1', params: ['a', 1] },
+ { rule: 'test-rule-2', params: [{}] },
+ ],
+ },
+
+ {
+ not: { rule: 'test-rule-2', params: [{}] },
+ },
+ {
+ allOf: [
+ {
+ anyOf: [
+ { rule: 'test-rule-1', params: ['a', 1] },
+ { rule: 'test-rule-2', params: [{}] },
+ ],
+ },
+ {
+ not: {
+ allOf: [
+ { rule: 'test-rule-1', params: ['b', 2] },
+ { rule: 'test-rule-2', params: [{ c: 3 }] },
+ ],
+ },
+ },
+ ],
+ },
+ ])('returns 200/ALLOW when criteria match (case %#)', async conditions => {
+ const response = await request(app)
+ .post('/permissions/apply-conditions')
+ .send({
+ resourceRef: 'default:test/resource',
+ resourceType: 'test-resource',
+ conditions,
+ });
+
+ expect(response.status).toEqual(200);
+ expect(response.body).toEqual({ result: AuthorizeResult.ALLOW });
+ });
+
+ it.each([
+ { rule: 'test-rule-2', params: [{ foo: 0 }] },
+ {
+ allOf: [
+ { rule: 'test-rule-1', params: ['a', 1] },
+ { rule: 'test-rule-2', params: [{}] },
+ ],
+ },
+ {
+ allOf: [
+ {
+ anyOf: [
+ { rule: 'test-rule-1', params: ['a', 1] },
+ { rule: 'test-rule-2', params: [{ b: 2 }] },
+ ],
+ },
+ {
+ not: {
+ allOf: [
+ { rule: 'test-rule-1', params: ['c', 3] },
+ { not: { rule: 'test-rule-2', params: [{ d: 4 }] } },
+ ],
+ },
+ },
+ ],
+ },
+ ])(
+ 'returns 200/DENY when criteria do not match (case %#)',
+ async conditions => {
+ const response = await request(app)
+ .post('/permissions/apply-conditions')
+ .send({
+ resourceRef: 'default:test/resource',
+ resourceType: 'test-resource',
+ conditions,
+ });
+
+ expect(response.status).toEqual(200);
+ expect(response.body).toEqual({ result: AuthorizeResult.DENY });
+ },
+ );
+
+ it('returns 400 when called with incorrect resource type', async () => {
+ const response = await request(app)
+ .post('/permissions/apply-conditions')
+ .send({
+ resourceRef: 'default:test/resource',
+ resourceType: 'test-incorrect-resource',
+ conditions: {
+ anyOf: [],
+ },
+ });
+
+ expect(response.status).toEqual(400);
+ expect(response.error && response.error.text).toMatch(
+ /unexpected resource type: test-incorrect-resource/i,
+ );
+ });
+
+ it('returns 400 when resource is not found', async () => {
+ mockGetResource.mockReturnValueOnce(Promise.resolve(undefined));
+
+ const response = await request(app)
+ .post('/permissions/apply-conditions')
+ .send({
+ resourceRef: 'default:test/resource',
+ resourceType: 'test-resource',
+ conditions: {
+ not: {
+ rule: 'testRule1',
+ params: ['a', 1],
+ },
+ },
+ });
+
+ expect(response.status).toEqual(400);
+ expect(response.error && response.error.text).toMatch(
+ /resource for ref default:test\/resource not found/i,
+ );
+ });
+
+ it.each([
+ undefined,
+ {},
+ { resourceType: 'test-resource-type' },
+ { resourceRef: 'test/resource-ref' },
+ {
+ resourceType: 'test-resource-type',
+ resourceRef: 'test/resource-ref',
+ },
+ { conditions: { anyOf: [] } },
+ ])(`returns 400 for invalid input %#`, async input => {
+ const response = await request(app)
+ .post('/permissions/apply-conditions')
+ .send(input);
+
+ expect(response.status).toEqual(400);
+ expect(response.error && response.error.text).toMatch(
+ /invalid request body/i,
+ );
+ });
+ });
+});
diff --git a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts
new file mode 100644
index 0000000000..99e282b144
--- /dev/null
+++ b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import express, { Response, Router } from 'express';
+import { z } from 'zod';
+import {
+ AuthorizeResult,
+ PermissionCondition,
+ PermissionCriteria,
+} from '@backstage/plugin-permission-common';
+import { PermissionRule } from '../types';
+import {
+ createGetRule,
+ isAndCriteria,
+ isNotCriteria,
+ isOrCriteria,
+} from './util';
+
+const permissionCriteriaSchema: z.ZodSchema<
+ PermissionCriteria
+> = z.lazy(() =>
+ z.union([
+ z.object({ anyOf: z.array(permissionCriteriaSchema) }),
+ z.object({ allOf: z.array(permissionCriteriaSchema) }),
+ z.object({ not: permissionCriteriaSchema }),
+ z.object({
+ rule: z.string(),
+ params: z.array(z.unknown()),
+ }),
+ ]),
+);
+
+const applyConditionsRequestSchema = z.object({
+ resourceRef: z.string(),
+ resourceType: z.string(),
+ conditions: permissionCriteriaSchema,
+});
+
+/**
+ * A request to load the referenced resource and apply conditions in order to
+ * finalize a conditional authorization response.
+ *
+ * @public
+ */
+export type ApplyConditionsRequest = {
+ resourceRef: string;
+ resourceType: string;
+ conditions: PermissionCriteria;
+};
+
+/**
+ * The result of applying the conditions, expressed as a definitive authorize
+ * result of ALLOW or DENY.
+ *
+ * @public
+ */
+export type ApplyConditionsResponse = {
+ result: AuthorizeResult.ALLOW | AuthorizeResult.DENY;
+};
+
+const applyConditions = (
+ criteria: PermissionCriteria,
+ resource: TResource,
+ getRule: (name: string) => PermissionRule,
+): boolean => {
+ if (isAndCriteria(criteria)) {
+ return criteria.allOf.every(child =>
+ applyConditions(child, resource, getRule),
+ );
+ } else if (isOrCriteria(criteria)) {
+ return criteria.anyOf.some(child =>
+ applyConditions(child, resource, getRule),
+ );
+ } else if (isNotCriteria(criteria)) {
+ return !applyConditions(criteria.not, resource, getRule);
+ }
+
+ return getRule(criteria.rule).apply(resource, ...criteria.params);
+};
+
+/**
+ * Create an express Router which provides an authorization route to allow integration between the
+ * permission backend and other Backstage backend plugins. Plugin owners that wish to support
+ * conditional authorization for their resources should add the router created by this function
+ * to their express app inside their `createRouter` implementation.
+ *
+ * @remarks
+ *
+ * To make this concrete, we can use the Backstage software catalog as an example. The catalog has
+ * conditional rules around access to specific _entities_ in the catalog. The _type_ of resource is
+ * captured here as `resourceType`, a string identifier (`catalog-entity` in this example) that can
+ * be provided with permission definitions. This is merely a _type_ to verify that conditions in an
+ * authorization policy are constructed correctly, not a reference to a specific resource.
+ *
+ * The `rules` parameter is an array of {@link PermissionRule}s that introduce conditional
+ * filtering logic for resources; for the catalog, these are things like `isEntityOwner` or
+ * `hasAnnotation`. Rules describe how to filter a list of resources, and the `conditions` returned
+ * allow these rules to be applied with specific parameters (such as 'group:default/team-a', or
+ * 'backstage.io/edit-url').
+ *
+ * The `getResource` argument should load a resource by reference. For the catalog, this is an
+ * {@link @backstage/catalog-model#EntityRef}. For other plugins, this can be any serialized format.
+ * This is used to construct the `createPermissionIntegrationRouter`, a function to add an
+ * authorization route to your backend plugin. This route will be called by the `permission-backend`
+ * when authorization conditions relating to this plugin need to be evaluated.
+ * @public
+ */
+export const createPermissionIntegrationRouter = ({
+ resourceType,
+ rules,
+ getResource,
+}: {
+ resourceType: string;
+ rules: PermissionRule[];
+ getResource: (resourceRef: string) => Promise;
+}): Router => {
+ const router = Router();
+
+ const getRule = createGetRule(rules);
+
+ router.post(
+ '/permissions/apply-conditions',
+ express.json(),
+ async (
+ req,
+ res: Response<
+ | {
+ result: Omit;
+ }
+ | string
+ >,
+ ) => {
+ const parseResult = applyConditionsRequestSchema.safeParse(req.body);
+
+ if (!parseResult.success) {
+ return res.status(400).send(`Invalid request body.`);
+ }
+
+ const { data: body } = parseResult;
+
+ if (body.resourceType !== resourceType) {
+ return res
+ .status(400)
+ .send(`Unexpected resource type: ${body.resourceType}.`);
+ }
+
+ const resource = await getResource(body.resourceRef);
+
+ if (!resource) {
+ return res
+ .status(400)
+ .send(`Resource for ref ${body.resourceRef} not found.`);
+ }
+
+ return res.status(200).json({
+ result: applyConditions(body.conditions, resource, getRule)
+ ? AuthorizeResult.ALLOW
+ : AuthorizeResult.DENY,
+ });
+ },
+ );
+
+ return router;
+};
diff --git a/plugins/permission-node/src/integration/index.ts b/plugins/permission-node/src/integration/index.ts
new file mode 100644
index 0000000000..f070d57c8f
--- /dev/null
+++ b/plugins/permission-node/src/integration/index.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2021 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 * from './createConditionFactory';
+export * from './createConditionExports';
+export * from './createConditionTransformer';
+export * from './createPermissionIntegrationRouter';
diff --git a/plugins/permission-node/src/integration/util.test.ts b/plugins/permission-node/src/integration/util.test.ts
new file mode 100644
index 0000000000..d27c0a4243
--- /dev/null
+++ b/plugins/permission-node/src/integration/util.test.ts
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ createGetRule,
+ isAndCriteria,
+ isNotCriteria,
+ isOrCriteria,
+} from './util';
+
+describe('permission integration utils', () => {
+ describe('createGetRule', () => {
+ let getRule: ReturnType;
+
+ const testRule1 = {
+ name: 'test-rule-1',
+ description: 'Test rule 1',
+ apply: jest.fn(),
+ toQuery: jest.fn(),
+ };
+
+ const testRule2 = {
+ name: 'test-rule-2',
+ description: 'Test rule 2',
+ apply: jest.fn(),
+ toQuery: jest.fn(),
+ };
+
+ beforeEach(() => {
+ getRule = createGetRule([testRule1, testRule2]);
+ });
+
+ it('returns the rule matching the supplied name', () => {
+ expect(getRule('test-rule-1')).toBe(testRule1);
+ });
+
+ it('throws if there is no rule for the supplied name', () => {
+ expect(() => getRule('test-rule-3')).toThrowError(
+ /unexpected permission rule/i,
+ );
+ });
+ });
+
+ describe('isOrCriteria', () => {
+ it('returns true if input has a top-level "anyOf" property', () => {
+ expect(isOrCriteria({ anyOf: { not: { allOf: [] } } })).toEqual(true);
+ });
+
+ it('returns false if input does not have a top-level "anyOf" property', () => {
+ expect(isOrCriteria({ allOf: { not: { anyOf: [] } } })).toEqual(false);
+ });
+ });
+
+ describe('isAndCriteria', () => {
+ it('returns true if input has a top-level "allOf" property', () => {
+ expect(isAndCriteria({ allOf: { not: { anyOf: [] } } })).toEqual(true);
+ });
+
+ it('returns false if input does not have a top-level "allOf" property', () => {
+ expect(isAndCriteria({ anyOf: { not: { allOf: [] } } })).toEqual(false);
+ });
+ });
+
+ describe('isNotCriteria', () => {
+ it('returns true if input has a top-level "not" property', () => {
+ expect(isNotCriteria({ not: { allOf: [{ anyOf: [] }] } })).toEqual(true);
+ });
+
+ it('returns false if input does not have a top-level "not" property', () => {
+ expect(isNotCriteria({ anyOf: { not: { allOf: [] } } })).toEqual(false);
+ });
+ });
+});
diff --git a/plugins/permission-node/src/integration/util.ts b/plugins/permission-node/src/integration/util.ts
new file mode 100644
index 0000000000..d9457cfefc
--- /dev/null
+++ b/plugins/permission-node/src/integration/util.ts
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { PermissionCriteria } from '@backstage/plugin-permission-common';
+import { PermissionRule } from '../types';
+
+export const isAndCriteria = (
+ filter: PermissionCriteria,
+): filter is { allOf: PermissionCriteria[] } =>
+ Object.prototype.hasOwnProperty.call(filter, 'allOf');
+
+export const isOrCriteria = (
+ filter: PermissionCriteria,
+): filter is { anyOf: PermissionCriteria[] } =>
+ Object.prototype.hasOwnProperty.call(filter, 'anyOf');
+
+export const isNotCriteria = (
+ filter: PermissionCriteria,
+): filter is { not: PermissionCriteria } =>
+ Object.prototype.hasOwnProperty.call(filter, 'not');
+
+export const createGetRule = (
+ rules: PermissionRule[],
+) => {
+ const rulesMap = new Map(Object.values(rules).map(rule => [rule.name, rule]));
+
+ return (name: string): PermissionRule => {
+ const rule = rulesMap.get(name);
+
+ if (!rule) {
+ throw new Error(`Unexpected permission rule: ${name}`);
+ }
+
+ return rule;
+ };
+};
diff --git a/plugins/permission-node/src/policy/index.ts b/plugins/permission-node/src/policy/index.ts
new file mode 100644
index 0000000000..f04c2a094c
--- /dev/null
+++ b/plugins/permission-node/src/policy/index.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2021 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 type {
+ ConditionalPolicyResult,
+ PermissionPolicy,
+ PolicyAuthorizeRequest,
+ PolicyResult,
+} from './types';
diff --git a/plugins/permission-node/src/policy/types.ts b/plugins/permission-node/src/policy/types.ts
new file mode 100644
index 0000000000..44380bad26
--- /dev/null
+++ b/plugins/permission-node/src/policy/types.ts
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ AuthorizeRequest,
+ AuthorizeResult,
+ PermissionCondition,
+ PermissionCriteria,
+} from '@backstage/plugin-permission-common';
+import { BackstageIdentity } from '@backstage/plugin-auth-backend';
+
+/**
+ * An authorization request to be evaluated by the {@link PermissionPolicy}.
+ *
+ * @remarks
+ *
+ * This differs from {@link @backstage/permission-common#AuthorizeRequest} in that `resourceRef`
+ * should never be provided. This forces policies to be written in a way that's compatible with
+ * filtering collections of resources at data load time.
+ *
+ * @public
+ */
+export type PolicyAuthorizeRequest = Omit;
+
+/**
+ * A conditional result to an authorization request, returned by the {@link PermissionPolicy}.
+ *
+ * @remarks
+ *
+ * This indicates that the policy allows authorization for the request, given that the returned
+ * conditions hold when evaluated. The conditions will be evaluated by the corresponding plugin
+ * which knows about the referenced permission rules.
+ *
+ * Similar to {@link @backstage/permission-common#AuthorizeResult}, but with the plugin and resource
+ * identifiers needed to evaluate the returned conditions.
+ * @public
+ */
+export type ConditionalPolicyResult = {
+ result: AuthorizeResult.CONDITIONAL;
+ conditions: {
+ pluginId: string;
+ resourceType: string;
+ conditions: PermissionCriteria;
+ };
+};
+
+/**
+ * The result of evaluating an authorization request with a {@link PermissionPolicy}.
+ *
+ * @public
+ */
+export type PolicyResult =
+ | { result: AuthorizeResult.ALLOW | AuthorizeResult.DENY }
+ | ConditionalPolicyResult;
+
+/**
+ * A policy to evaluate authorization requests for any permissioned action performed in Backstage.
+ *
+ * @remarks
+ *
+ * This takes as input a permission and an optional Backstage identity, and should return ALLOW if
+ * the user is permitted to execute that action; otherwise DENY. For permissions relating to
+ * resources, such a catalog entities, a conditional response can also be returned. This states
+ * that the action is allowed if the conditions provided hold true.
+ *
+ * Conditions are a rule, and parameters to evaluate against that rule. For example, the rule might
+ * be `isOwner` and the parameters a collection of entityRefs; if one of the entityRefs matches
+ * the `owner` field on a catalog entity, this would resolve to ALLOW.
+ *
+ * @public
+ */
+export interface PermissionPolicy {
+ handle(
+ request: PolicyAuthorizeRequest,
+ user?: BackstageIdentity,
+ ): Promise;
+}
diff --git a/plugins/permission-node/src/setupTests.ts b/plugins/permission-node/src/setupTests.ts
new file mode 100644
index 0000000000..a330613afb
--- /dev/null
+++ b/plugins/permission-node/src/setupTests.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2021 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 {};
diff --git a/plugins/permission-node/src/types.ts b/plugins/permission-node/src/types.ts
new file mode 100644
index 0000000000..678befc99c
--- /dev/null
+++ b/plugins/permission-node/src/types.ts
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import type { PermissionCriteria } from '@backstage/plugin-permission-common';
+
+/**
+ * A conditional rule that can be provided in an
+ * {@link @backstage/permission-common#AuthorizeResult} response to an authorization request.
+ *
+ * @remarks
+ *
+ * Rules can either be evaluated against a resource loaded in memory, or used as filters when
+ * loading a collection of resources from a data source. The `apply` and `toQuery` methods implement
+ * these two concepts.
+ *
+ * The two operations should always have the same logical result. If they don’t, the effective
+ * outcome of an authorization operation will sometimes differ depending on how the authorization
+ * check was performed.
+ *
+ * @public
+ */
+export type PermissionRule<
+ TResource,
+ TQuery,
+ TParams extends unknown[] = unknown[],
+> = {
+ name: string;
+ description: string;
+
+ /**
+ * Apply this rule to a resource already loaded from a backing data source. The params are
+ * arguments supplied for the rule; for example, a rule could be `isOwner` with entityRefs as the
+ * params.
+ */
+ apply(resource: TResource, ...params: TParams): boolean;
+
+ /**
+ * Translate this rule to criteria suitable for use in querying a backing data store. The criteria
+ * can be used for loading a collection of resources efficiently with conditional criteria already
+ * applied.
+ */
+ toQuery(...params: TParams): PermissionCriteria;
+};
diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json
index c43ea8b31a..05499d88e8 100644
--- a/plugins/proxy-backend/package.json
+++ b/plugins/proxy-backend/package.json
@@ -29,7 +29,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.7",
+ "@backstage/backend-common": "^0.9.10",
"@backstage/config": "^0.1.8",
"@types/express": "^4.17.6",
"express": "^4.17.1",
@@ -43,7 +43,7 @@
"yup": "^0.32.9"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
+ "@backstage/cli": "^0.9.0",
"@types/http-proxy-middleware": "^0.19.3",
"@types/supertest": "^2.0.8",
"@types/uuid": "^8.0.0",
diff --git a/plugins/proxy-backend/src/run.ts b/plugins/proxy-backend/src/run.ts
index 54d2716290..0a3ed2b7f0 100644
--- a/plugins/proxy-backend/src/run.ts
+++ b/plugins/proxy-backend/src/run.ts
@@ -18,7 +18,7 @@ import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
-const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7000;
+const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
diff --git a/plugins/proxy-backend/src/service/router.test.ts b/plugins/proxy-backend/src/service/router.test.ts
index df999dbe2a..ddb524d3aa 100644
--- a/plugins/proxy-backend/src/service/router.test.ts
+++ b/plugins/proxy-backend/src/service/router.test.ts
@@ -34,9 +34,9 @@ describe('createRouter', () => {
const logger = getVoidLogger();
const config = new ConfigReader({
backend: {
- baseUrl: 'https://example.com:7000',
+ baseUrl: 'https://example.com:7007',
listen: {
- port: 7000,
+ port: 7007,
},
},
});
diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json
index 1d7be09b85..be8b6e65e5 100644
--- a/plugins/rollbar-backend/package.json
+++ b/plugins/rollbar-backend/package.json
@@ -31,7 +31,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.7",
+ "@backstage/backend-common": "^0.9.10",
"@backstage/config": "^0.1.10",
"@types/express": "^4.17.6",
"axios": "^0.21.1",
@@ -48,7 +48,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
+ "@backstage/cli": "^0.9.0",
"@types/supertest": "^2.0.8",
"supertest": "^6.1.3"
},
diff --git a/plugins/rollbar-backend/src/run.ts b/plugins/rollbar-backend/src/run.ts
index 54d2716290..0a3ed2b7f0 100644
--- a/plugins/rollbar-backend/src/run.ts
+++ b/plugins/rollbar-backend/src/run.ts
@@ -18,7 +18,7 @@ import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
-const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7000;
+const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
diff --git a/plugins/rollbar/CHANGELOG.md b/plugins/rollbar/CHANGELOG.md
index 4f7f3c9a16..aee0a74525 100644
--- a/plugins/rollbar/CHANGELOG.md
+++ b/plugins/rollbar/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-rollbar
+## 0.3.19
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.3.18
### Patch Changes
diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json
index 2e2da0a284..ee3fc9f5a6 100644
--- a/plugins/rollbar/package.json
+++ b/plugins/rollbar/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-rollbar",
"description": "A Backstage plugin that integrates towards Rollbar",
- "version": "0.3.18",
+ "version": "0.3.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,10 +32,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -49,10 +49,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json
index 36a6310aa2..90258d3c28 100644
--- a/plugins/scaffolder-backend-module-cookiecutter/package.json
+++ b/plugins/scaffolder-backend-module-cookiecutter/package.json
@@ -20,10 +20,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.9",
+ "@backstage/backend-common": "^0.9.10",
"@backstage/errors": "^0.1.4",
"@backstage/integration": "^0.6.9",
- "@backstage/plugin-scaffolder-backend": "^0.15.12",
+ "@backstage/plugin-scaffolder-backend": "^0.15.13",
"@backstage/config": "^0.1.11",
"@backstage/types": "^0.1.1",
"command-exists": "^1.2.9",
@@ -33,7 +33,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
+ "@backstage/cli": "^0.9.0",
"@types/fs-extra": "^9.0.1",
"@types/mock-fs": "^4.13.0",
"@types/jest": "^26.0.7",
diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json
index f4ace02eca..37b077568e 100644
--- a/plugins/scaffolder-backend-module-rails/package.json
+++ b/plugins/scaffolder-backend-module-rails/package.json
@@ -21,8 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.9",
- "@backstage/plugin-scaffolder-backend": "^0.15.12",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/plugin-scaffolder-backend": "^0.15.13",
"@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.4",
"@backstage/integration": "^0.6.9",
@@ -31,7 +31,7 @@
"fs-extra": "^9.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
+ "@backstage/cli": "^0.9.0",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"@types/command-exists": "^1.2.0",
diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md
index de033eabbd..f71849a1d2 100644
--- a/plugins/scaffolder-backend/CHANGELOG.md
+++ b/plugins/scaffolder-backend/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/plugin-scaffolder-backend
+## 0.15.13
+
+### Patch Changes
+
+- 26eb174ce8: Skip empty file names when scaffolding with nunjucks
+- ecdcbd08ee: Expose template metadata to custom action handler in Scaffolder.
+- Updated dependencies
+ - @backstage/catalog-client@0.5.2
+ - @backstage/catalog-model@0.9.7
+ - @backstage/backend-common@0.9.10
+ - @backstage/plugin-catalog-backend@0.17.4
+
## 0.15.12
### Patch Changes
diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json
index e5d13801ba..36ac76c95f 100644
--- a/plugins/scaffolder-backend/package.json
+++ b/plugins/scaffolder-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-scaffolder-backend",
"description": "The Backstage backend plugin that helps you create new things",
- "version": "0.15.12",
+ "version": "0.15.13",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,18 +30,18 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.9",
- "@backstage/catalog-client": "^0.5.1",
- "@backstage/catalog-model": "^0.9.6",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.4",
"@backstage/integration": "^0.6.9",
- "@backstage/plugin-catalog-backend": "^0.17.3",
+ "@backstage/plugin-catalog-backend": "^0.17.4",
"@backstage/plugin-scaffolder-common": "^0.1.1",
"@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.1.4",
"@backstage/types": "^0.1.1",
- "@gitbeaker/core": "^30.2.0",
- "@gitbeaker/node": "^30.2.0",
+ "@gitbeaker/core": "^34.6.0",
+ "@gitbeaker/node": "^34.6.0",
"@octokit/rest": "^18.5.3",
"@octokit/webhooks": "^9.14.1",
"@types/express": "^4.17.6",
@@ -71,8 +71,8 @@
"yaml": "^1.10.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/test-utils": "^0.1.22",
"@types/command-exists": "^1.2.0",
"@types/fs-extra": "^9.0.1",
"@types/git-url-parse": "^9.0.0",
diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/DefaultWorkflowRunner.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts
similarity index 95%
rename from plugins/scaffolder-backend/src/scaffolder/tasks/DefaultWorkflowRunner.test.ts
rename to plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts
index 1f7877791c..b2e2e85a6c 100644
--- a/plugins/scaffolder-backend/src/scaffolder/tasks/DefaultWorkflowRunner.test.ts
+++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts
@@ -270,6 +270,31 @@ describe('DefaultWorkflowRunner', () => {
);
});
+ it('should not try and parse something that is not parsable', async () => {
+ jest.spyOn(logger, 'error');
+ const task = createMockTaskWithSpec({
+ apiVersion: 'scaffolder.backstage.io/v1beta3',
+ steps: [
+ {
+ id: 'test',
+ name: 'name',
+ action: 'jest-mock-action',
+ input: {
+ foo: 'bob',
+ },
+ },
+ ],
+ output: {},
+ parameters: {
+ input: 'BACKSTAGE',
+ },
+ });
+
+ await runner.execute(task);
+
+ expect(logger.error).not.toHaveBeenCalled();
+ });
+
it('should keep the original types for the input and not parse things that arent meant to be parsed', async () => {
const task = createMockTaskWithSpec({
apiVersion: 'scaffolder.backstage.io/v1beta3',
diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts
index c66d967103..5b42eef459 100644
--- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts
+++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts
@@ -114,9 +114,10 @@ export class NunjucksWorkflowRunner implements WorkflowRunner {
private isSingleTemplateString(input: string) {
const { parser, nodes } = require('nunjucks');
const parsed = parser.parse(input, {}, this.nunjucksOptions);
+
return (
parsed.children.length === 1 &&
- !(parsed.children[0] instanceof nodes.TemplateData)
+ !(parsed.children[0]?.children?.[0] instanceof nodes.TemplateData)
);
}
diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json
index 006d8ad7aa..05d5ae3031 100644
--- a/plugins/scaffolder-common/package.json
+++ b/plugins/scaffolder-common/package.json
@@ -36,10 +36,10 @@
"url": "https://github.com/backstage/backstage/issues"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.6",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/types": "^0.1.1"
},
"devDependencies": {
- "@backstage/cli": "^0.8.1"
+ "@backstage/cli": "^0.9.0"
}
}
diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md
index dd5653240a..8c43d8d010 100644
--- a/plugins/scaffolder/CHANGELOG.md
+++ b/plugins/scaffolder/CHANGELOG.md
@@ -1,5 +1,19 @@
# @backstage/plugin-scaffolder
+## 0.11.11
+
+### Patch Changes
+
+- 8809b6c0dd: Update the json-schema dependency version.
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-client@0.5.2
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+ - @backstage/integration-react@0.1.14
+
## 0.11.10
### Patch Changes
diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json
index 594a8e6423..ce185403bb 100644
--- a/plugins/scaffolder/package.json
+++ b/plugins/scaffolder/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-scaffolder",
"description": "The Backstage plugin that helps you create new things",
- "version": "0.11.10",
+ "version": "0.11.11",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,22 +31,22 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-client": "^0.5.1",
- "@backstage/catalog-model": "^0.9.6",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.11",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.4",
"@backstage/integration": "^0.6.9",
- "@backstage/integration-react": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.3",
+ "@backstage/integration-react": "^0.1.14",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@backstage/types": "^0.1.1",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
- "@rjsf/core": "^3.0.0",
- "@rjsf/material-ui": "^3.0.0",
+ "@rjsf/core": "^3.2.1",
+ "@rjsf/material-ui": "^3.2.1",
"@types/react": "*",
"classnames": "^2.2.6",
"git-url-parse": "^11.6.0",
@@ -66,10 +66,10 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/scaffolder/src/api.ts b/plugins/scaffolder/src/api.ts
index a16ab59053..34e16708ea 100644
--- a/plugins/scaffolder/src/api.ts
+++ b/plugins/scaffolder/src/api.ts
@@ -187,7 +187,7 @@ export class ScaffolderClient implements ScaffolderApi {
});
if (!response.ok) {
- throw ResponseError.fromResponse(response);
+ throw await ResponseError.fromResponse(response);
}
return await response.json();
@@ -302,7 +302,7 @@ export class ScaffolderClient implements ScaffolderApi {
});
if (!response.ok) {
- throw ResponseError.fromResponse(response);
+ throw await ResponseError.fromResponse(response);
}
return await response.json();
diff --git a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx
index 77c8240974..ce0354b817 100644
--- a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx
+++ b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx
@@ -17,8 +17,8 @@ import React from 'react';
import { ScaffolderApi, scaffolderApiRef } from '../../api';
import { ActionsPage } from './ActionsPage';
import { rootRouteRef } from '../../routes';
-import { renderInTestApp } from '@backstage/test-utils';
-import { ApiRegistry, ApiProvider } from '@backstage/core-app-api';
+import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
+import { ApiProvider } from '@backstage/core-app-api';
const scaffolderApiMock: jest.Mocked = {
scaffold: jest.fn(),
@@ -29,7 +29,7 @@ const scaffolderApiMock: jest.Mocked = {
listActions: jest.fn(),
};
-const apis = ApiRegistry.from([[scaffolderApiRef, scaffolderApiMock]]);
+const apis = TestApiRegistry.from([scaffolderApiRef, scaffolderApiMock]);
describe('TemplatePage', () => {
beforeEach(() => jest.resetAllMocks());
diff --git a/plugins/scaffolder/src/components/TemplatePage/TemplatePage.test.tsx b/plugins/scaffolder/src/components/TemplatePage/TemplatePage.test.tsx
index e42bcbdbdc..60e9ee8840 100644
--- a/plugins/scaffolder/src/components/TemplatePage/TemplatePage.test.tsx
+++ b/plugins/scaffolder/src/components/TemplatePage/TemplatePage.test.tsx
@@ -13,7 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { renderInTestApp, renderWithEffects } from '@backstage/test-utils';
+import {
+ renderInTestApp,
+ renderWithEffects,
+ TestApiRegistry,
+} from '@backstage/test-utils';
import { lightTheme } from '@backstage/theme';
import { ThemeProvider } from '@material-ui/core';
import { fireEvent, within } from '@testing-library/react';
@@ -24,7 +28,7 @@ import { ScaffolderApi, scaffolderApiRef } from '../../api';
import { rootRouteRef } from '../../routes';
import { TemplatePage } from './TemplatePage';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import { errorApiRef } from '@backstage/core-plugin-api';
jest.mock('react-router-dom', () => {
@@ -47,10 +51,10 @@ const scaffolderApiMock: jest.Mocked = {
const errorApiMock = { post: jest.fn(), error$: jest.fn() };
-const apis = ApiRegistry.from([
+const apis = TestApiRegistry.from(
[scaffolderApiRef, scaffolderApiMock],
[errorApiRef, errorApiMock],
-]);
+);
describe('TemplatePage', () => {
beforeEach(() => jest.resetAllMocks());
diff --git a/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.test.tsx b/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.test.tsx
index 3d0267ff1f..c70f251eac 100644
--- a/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.test.tsx
+++ b/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.test.tsx
@@ -26,8 +26,8 @@ import {
MockEntityListContextProvider,
} from '@backstage/plugin-catalog-react';
import { AlertApi, alertApiRef } from '@backstage/core-plugin-api';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
-import { renderWithEffects } from '@backstage/test-utils';
+import { ApiProvider } from '@backstage/core-app-api';
+import { renderWithEffects, TestApiRegistry } from '@backstage/test-utils';
const entities: Entity[] = [
{
@@ -62,7 +62,7 @@ const entities: Entity[] = [
},
];
-const apis = ApiRegistry.from([
+const apis = TestApiRegistry.from(
[
catalogApiRef,
{
@@ -77,7 +77,7 @@ const apis = ApiRegistry.from([
post: jest.fn(),
} as unknown as AlertApi,
],
-]);
+);
describe('', () => {
it('renders available entity types', async () => {
diff --git a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.test.tsx b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.test.tsx
index f293969dff..b7e72e3583 100644
--- a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.test.tsx
+++ b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.test.tsx
@@ -16,12 +16,11 @@
import { Entity } from '@backstage/catalog-model';
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { FieldProps } from '@rjsf/core';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { EntityPicker } from './EntityPicker';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
const makeEntity = (kind: string, namespace: string, name: string): Entity => ({
apiVersion: 'backstage.io/v1beta1',
@@ -53,14 +52,15 @@ describe('', () => {
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi);
entities = [
makeEntity('Group', 'default', 'team-a'),
makeEntity('Group', 'default', 'squad-b'),
];
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
diff --git a/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.test.tsx b/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.test.tsx
index 18d6fd7e5c..31992fbc8a 100644
--- a/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.test.tsx
+++ b/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.test.tsx
@@ -16,11 +16,10 @@
import { Entity } from '@backstage/catalog-model';
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { FieldProps } from '@rjsf/core';
import React from 'react';
import { OwnerPicker } from './OwnerPicker';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
const makeEntity = (kind: string, namespace: string, name: string): Entity => ({
apiVersion: 'backstage.io/v1beta1',
@@ -50,14 +49,15 @@ describe('', () => {
let Wrapper: React.ComponentType;
beforeEach(() => {
- const apis = ApiRegistry.with(catalogApiRef, catalogApi);
entities = [
makeEntity('Group', 'default', 'team-a'),
makeEntity('Group', 'default', 'squad-b'),
];
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json
index df0a783396..5ebc7850a9 100644
--- a/plugins/search-backend-module-elasticsearch/package.json
+++ b/plugins/search-backend-module-elasticsearch/package.json
@@ -30,8 +30,8 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/backend-common": "^0.9.9",
- "@backstage/cli": "^0.8.2",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/cli": "^0.9.0",
"@elastic/elasticsearch-mock": "^0.3.0"
},
"files": [
diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json
index a31d908ac4..74e9698ea4 100644
--- a/plugins/search-backend-module-pg/package.json
+++ b/plugins/search-backend-module-pg/package.json
@@ -20,15 +20,15 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.7",
+ "@backstage/backend-common": "^0.9.10",
"@backstage/search-common": "^0.2.0",
"@backstage/plugin-search-backend-node": "^0.4.2",
"lodash": "^4.17.21",
"knex": "^0.95.1"
},
"devDependencies": {
- "@backstage/backend-test-utils": "^0.1.8",
- "@backstage/cli": "^0.8.0"
+ "@backstage/backend-test-utils": "^0.1.9",
+ "@backstage/cli": "^0.9.0"
},
"files": [
"dist",
diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json
index 4514d07756..369c52a4f6 100644
--- a/plugins/search-backend-node/package.json
+++ b/plugins/search-backend-node/package.json
@@ -26,8 +26,8 @@
"@types/lunr": "^2.3.3"
},
"devDependencies": {
- "@backstage/backend-common": "^0.9.8",
- "@backstage/cli": "^0.8.1"
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/cli": "^0.9.0"
},
"files": [
"dist"
diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json
index 18d4484451..2df51e1bb4 100644
--- a/plugins/search-backend/package.json
+++ b/plugins/search-backend/package.json
@@ -20,7 +20,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.7",
+ "@backstage/backend-common": "^0.9.10",
"@backstage/search-common": "^0.2.0",
"@backstage/plugin-search-backend-node": "^0.4.2",
"@types/express": "^4.17.6",
@@ -30,7 +30,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
+ "@backstage/cli": "^0.9.0",
"@types/supertest": "^2.0.8",
"supertest": "^6.1.3"
},
diff --git a/plugins/search-backend/src/run.ts b/plugins/search-backend/src/run.ts
index addfdfd6d7..53d4e4334a 100644
--- a/plugins/search-backend/src/run.ts
+++ b/plugins/search-backend/src/run.ts
@@ -18,7 +18,7 @@ import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
-const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7000;
+const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md
index 808c847914..ef3736b1df 100644
--- a/plugins/search/CHANGELOG.md
+++ b/plugins/search/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/plugin-search
+## 0.4.18
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- 704b267e1c: Smaller UX improvements to search components such as optional autoFocus prop to SearchBar components, decreased debounce value and closing modal on link click of SearchModal, terminology updates of SearchResultPager.
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.4.17
### Patch Changes
diff --git a/plugins/search/package.json b/plugins/search/package.json
index 9d25ec723d..aaddf130bf 100644
--- a/plugins/search/package.json
+++ b/plugins/search/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-search",
"description": "The Backstage plugin that provides your backstage app with search",
- "version": "0.4.17",
+ "version": "0.4.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,12 +30,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.6",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.11",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.4",
- "@backstage/plugin-catalog-react": "^0.6.3",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/search-common": "^0.2.1",
"@backstage/theme": "^0.2.13",
"@backstage/types": "^0.1.1",
@@ -51,10 +51,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/search/src/components/SearchBar/SearchBar.test.tsx b/plugins/search/src/components/SearchBar/SearchBar.test.tsx
index 3a11daa9fa..81f90640c1 100644
--- a/plugins/search/src/components/SearchBar/SearchBar.test.tsx
+++ b/plugins/search/src/components/SearchBar/SearchBar.test.tsx
@@ -21,12 +21,9 @@ import { SearchContextProvider } from '../SearchContext';
import { SearchBar } from './SearchBar';
import { configApiRef } from '@backstage/core-plugin-api';
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import { searchApiRef } from '../../apis';
+import { TestApiRegistry } from '@backstage/test-utils';
jest.mock('@backstage/core-plugin-api', () => ({
...jest.requireActual('@backstage/core-plugin-api'),
@@ -42,10 +39,10 @@ describe('SearchBar', () => {
const query = jest.fn().mockResolvedValue({});
- const apiRegistry = ApiRegistry.from([
+ const apiRegistry = TestApiRegistry.from(
[configApiRef, new ConfigReader({ app: { title: 'Mock title' } })],
[searchApiRef, { query }],
- ]);
+ );
const name = 'Search';
const term = 'term';
diff --git a/plugins/search/src/components/SearchModal/SearchModal.test.tsx b/plugins/search/src/components/SearchModal/SearchModal.test.tsx
index d7f873abf3..ff9622dfb9 100644
--- a/plugins/search/src/components/SearchModal/SearchModal.test.tsx
+++ b/plugins/search/src/components/SearchModal/SearchModal.test.tsx
@@ -15,14 +15,10 @@
*/
import React from 'react';
import { screen } from '@testing-library/react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import userEvent from '@testing-library/user-event';
import { configApiRef } from '@backstage/core-plugin-api';
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import { rootRouteRef } from '../../plugin';
import { searchApiRef } from '../../apis';
@@ -38,10 +34,10 @@ jest.mock('../SearchContext', () => ({
describe('SearchModal', () => {
const query = jest.fn().mockResolvedValue({});
- const apiRegistry = ApiRegistry.from([
+ const apiRegistry = TestApiRegistry.from(
[configApiRef, new ConfigReader({ app: { title: 'Mock app' } })],
[searchApiRef, { query }],
- ]);
+ );
const toggleModal = jest.fn();
diff --git a/plugins/sentry/CHANGELOG.md b/plugins/sentry/CHANGELOG.md
index b0bcaad261..cad08289ed 100644
--- a/plugins/sentry/CHANGELOG.md
+++ b/plugins/sentry/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-sentry
+## 0.3.29
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.3.28
### Patch Changes
diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json
index ee2421bf7f..a04043c789 100644
--- a/plugins/sentry/package.json
+++ b/plugins/sentry/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-sentry",
"description": "A Backstage plugin that integrates towards Sentry",
- "version": "0.3.28",
+ "version": "0.3.29",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,10 +32,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.6",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.3",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -48,10 +48,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/shortcuts/CHANGELOG.md b/plugins/shortcuts/CHANGELOG.md
index 41581cc5b4..fdd9f44231 100644
--- a/plugins/shortcuts/CHANGELOG.md
+++ b/plugins/shortcuts/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-shortcuts
+## 0.1.14
+
+### Patch Changes
+
+- f93e56ae3a: Add tooltip to display shortcut title on hover. This should improve the readability of shortcuts with long names, which are cutoff by ellipsis.
+- Updated dependencies
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.1.13
### Patch Changes
diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json
index e73e047bc1..f0139d5728 100644
--- a/plugins/shortcuts/package.json
+++ b/plugins/shortcuts/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-shortcuts",
"description": "A Backstage plugin that provides a shortcuts feature to the sidebar",
- "version": "0.1.13",
+ "version": "0.1.14",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/theme": "^0.2.13",
"@backstage/types": "^0.1.1",
"@material-ui/core": "^4.12.2",
@@ -38,10 +38,10 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/shortcuts/src/Shortcuts.test.tsx b/plugins/shortcuts/src/Shortcuts.test.tsx
index 9182bcb47d..e0a70d6069 100644
--- a/plugins/shortcuts/src/Shortcuts.test.tsx
+++ b/plugins/shortcuts/src/Shortcuts.test.tsx
@@ -15,25 +15,31 @@
*/
import React from 'react';
-import { MockStorageApi, renderInTestApp } from '@backstage/test-utils';
+import {
+ MockStorageApi,
+ renderInTestApp,
+ TestApiProvider,
+} from '@backstage/test-utils';
import { screen, waitFor } from '@testing-library/react';
import { Shortcuts } from './Shortcuts';
import { LocalStoredShortcuts, shortcutsApiRef } from './api';
import { SidebarContext } from '@backstage/core-components';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
-
-const apis = ApiRegistry.from([
- [shortcutsApiRef, new LocalStoredShortcuts(MockStorageApi.create())],
-]);
describe('Shortcuts', () => {
it('displays an add button', async () => {
await renderInTestApp(
-
+
-
+
,
);
await waitFor(() => !screen.queryByTestId('progress'));
diff --git a/plugins/sonarqube/CHANGELOG.md b/plugins/sonarqube/CHANGELOG.md
index 8886ca3645..7de1ea6552 100644
--- a/plugins/sonarqube/CHANGELOG.md
+++ b/plugins/sonarqube/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-sonarqube
+## 0.2.7
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.2.6
### Patch Changes
diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json
index bb55e68954..f92c21ad7e 100644
--- a/plugins/sonarqube/package.json
+++ b/plugins/sonarqube/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-sonarqube",
"description": "",
- "version": "0.2.6",
+ "version": "0.2.7",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,10 +33,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -49,10 +49,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/splunk-on-call/CHANGELOG.md b/plugins/splunk-on-call/CHANGELOG.md
index 4bd0b9e9bc..b6d77a50cc 100644
--- a/plugins/splunk-on-call/CHANGELOG.md
+++ b/plugins/splunk-on-call/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-splunk-on-call
+## 0.3.15
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.3.14
### Patch Changes
diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json
index 9d9ffdb370..10eb807ba1 100644
--- a/plugins/splunk-on-call/package.json
+++ b/plugins/splunk-on-call/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-splunk-on-call",
"description": "A Backstage plugin that integrates towards Splunk On-Call",
- "version": "0.3.14",
+ "version": "0.3.15",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,10 +31,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -47,10 +47,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx
index 63d617aff2..eb5c99d4e7 100644
--- a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx
+++ b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx
@@ -17,7 +17,7 @@ import React from 'react';
import { act, fireEvent, render, waitFor } from '@testing-library/react';
import { Entity } from '@backstage/catalog-model';
import { EntityProvider } from '@backstage/plugin-catalog-react';
-import { wrapInTestApp } from '@backstage/test-utils';
+import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils';
import {
splunkOnCallApiRef,
SplunkOnCallClient,
@@ -37,13 +37,8 @@ import {
alertApiRef,
ConfigApi,
configApiRef,
- createApiRef,
} from '@backstage/core-plugin-api';
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
const mockSplunkOnCallApi: Partial = {
getUsers: async () => [],
@@ -59,17 +54,11 @@ const configApi: ConfigApi = new ConfigReader({
},
});
-const apis = ApiRegistry.from([
+const apis = TestApiRegistry.from(
[splunkOnCallApiRef, mockSplunkOnCallApi],
[configApiRef, configApi],
- [
- alertApiRef,
- createApiRef({
- id: 'core.alert',
- description: 'Used to report alerts and forward them to the app',
- }),
- ],
-]);
+ [alertApiRef, {}],
+);
const mockEntity = {
apiVersion: 'backstage.io/v1alpha1',
diff --git a/plugins/splunk-on-call/src/components/Escalation/Escalation.test.tsx b/plugins/splunk-on-call/src/components/Escalation/Escalation.test.tsx
index 1319493742..046c6a37f9 100644
--- a/plugins/splunk-on-call/src/components/Escalation/Escalation.test.tsx
+++ b/plugins/splunk-on-call/src/components/Escalation/Escalation.test.tsx
@@ -16,15 +16,15 @@
import React from 'react';
import { render, waitFor } from '@testing-library/react';
import { EscalationPolicy } from './EscalationPolicy';
-import { wrapInTestApp } from '@backstage/test-utils';
+import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils';
import { splunkOnCallApiRef } from '../../api';
import { MOCKED_ON_CALL, MOCKED_USER } from '../../api/mocks';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
const mockSplunkOnCallApi = {
- getOnCallUsers: () => [],
+ getOnCallUsers: jest.fn(),
};
-const apis = ApiRegistry.from([[splunkOnCallApiRef, mockSplunkOnCallApi]]);
+const apis = TestApiRegistry.from([splunkOnCallApiRef, mockSplunkOnCallApi]);
describe('Escalation', () => {
it('Handles an empty response', async () => {
diff --git a/plugins/splunk-on-call/src/components/Incident/Incidents.test.tsx b/plugins/splunk-on-call/src/components/Incident/Incidents.test.tsx
index df4254d3ad..181c2fda77 100644
--- a/plugins/splunk-on-call/src/components/Incident/Incidents.test.tsx
+++ b/plugins/splunk-on-call/src/components/Incident/Incidents.test.tsx
@@ -16,43 +16,39 @@
import React from 'react';
import { render, waitFor } from '@testing-library/react';
import { Incidents } from './Incidents';
-import { wrapInTestApp } from '@backstage/test-utils';
+import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils';
import { splunkOnCallApiRef } from '../../api';
import { MOCK_TEAM, MOCK_INCIDENT } from '../../api/mocks';
import {
alertApiRef,
- createApiRef,
IdentityApi,
identityApiRef,
} from '@backstage/core-plugin-api';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
const mockIdentityApi: Partial = {
getUserId: () => 'test',
};
const mockSplunkOnCallApi = {
- getIncidents: () => [],
- getTeams: () => [],
+ getIncidents: jest.fn(),
+ getTeams: jest.fn(),
};
-const apis = ApiRegistry.from([
- [
- alertApiRef,
- createApiRef({
- id: 'core.alert',
- description: 'Used to report alerts and forward them to the app',
- }),
- ],
+const apis = TestApiRegistry.from(
+ [alertApiRef, {}],
[identityApiRef, mockIdentityApi],
[splunkOnCallApiRef, mockSplunkOnCallApi],
-]);
+);
describe('Incidents', () => {
+ afterEach(() => {
+ jest.resetAllMocks();
+ });
+
it('Renders an empty state when there are no incidents', async () => {
- mockSplunkOnCallApi.getTeams = jest
- .fn()
- .mockImplementationOnce(async () => [MOCK_TEAM]);
+ mockSplunkOnCallApi.getIncidents.mockResolvedValue([]);
+ mockSplunkOnCallApi.getTeams.mockResolvedValue([MOCK_TEAM]);
const { getByText, queryByTestId } = render(
wrapInTestApp(
@@ -69,13 +65,9 @@ describe('Incidents', () => {
});
it('Renders all incidents', async () => {
- mockSplunkOnCallApi.getIncidents = jest
- .fn()
- .mockImplementationOnce(async () => [MOCK_INCIDENT]);
+ mockSplunkOnCallApi.getIncidents.mockResolvedValue([MOCK_INCIDENT]);
+ mockSplunkOnCallApi.getTeams.mockResolvedValue([MOCK_TEAM]);
- mockSplunkOnCallApi.getTeams = jest
- .fn()
- .mockImplementationOnce(async () => [MOCK_TEAM]);
const {
getByText,
getByTitle,
@@ -108,9 +100,10 @@ describe('Incidents', () => {
});
it('Handle errors', async () => {
- mockSplunkOnCallApi.getIncidents = jest
- .fn()
- .mockRejectedValueOnce(new Error('Error occurred'));
+ mockSplunkOnCallApi.getIncidents.mockRejectedValueOnce(
+ new Error('Error occurred'),
+ );
+ mockSplunkOnCallApi.getTeams.mockResolvedValue([]);
const { getByText, queryByTestId } = render(
wrapInTestApp(
diff --git a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.test.tsx b/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.test.tsx
index 94fd40bfe5..0b64a137af 100644
--- a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.test.tsx
+++ b/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.test.tsx
@@ -15,12 +15,12 @@
*/
import React from 'react';
import { render, fireEvent, act } from '@testing-library/react';
-import { wrapInTestApp } from '@backstage/test-utils';
+import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils';
import { splunkOnCallApiRef } from '../../api';
import { TriggerDialog } from './TriggerDialog';
-import { ApiRegistry, ApiProvider } from '@backstage/core-app-api';
-import { alertApiRef, createApiRef } from '@backstage/core-plugin-api';
+import { ApiProvider } from '@backstage/core-app-api';
+import { alertApiRef } from '@backstage/core-plugin-api';
describe('TriggerDialog', () => {
const mockTriggerAlarmFn = jest.fn();
@@ -28,16 +28,10 @@ describe('TriggerDialog', () => {
incidentAction: mockTriggerAlarmFn,
};
- const apis = ApiRegistry.from([
- [
- alertApiRef,
- createApiRef({
- id: 'core.alert',
- description: 'Used to report alerts and forward them to the app',
- }),
- ],
+ const apis = TestApiRegistry.from(
+ [alertApiRef, {}],
[splunkOnCallApiRef, mockSplunkOnCallApi],
- ]);
+ );
it('open the dialog and trigger an alarm', async () => {
const { getByText, getByRole, getByTestId } = render(
diff --git a/plugins/tech-insights-backend-module-jsonfc/README.md b/plugins/tech-insights-backend-module-jsonfc/README.md
index 48c1e69919..c0f992ffc7 100644
--- a/plugins/tech-insights-backend-module-jsonfc/README.md
+++ b/plugins/tech-insights-backend-module-jsonfc/README.md
@@ -24,7 +24,7 @@ and modify the `techInsights.ts` file to contain a reference to the FactCheckers
+ logger,
+}),
- const builder = new DefaultTechInsightsBuilder({
+ const builder = buildTechInsightsContext({
logger,
config,
database,
@@ -59,7 +59,7 @@ export const exampleCheck: TechInsightJsonRuleCheck = {
name: 'demodatacheck', // A human readable name of this check to be displayed in the UI
type: JSON_RULE_ENGINE_CHECK_TYPE, // Type identifier of the check. Used to run logic against, determine persistence option to use and render correct components on the UI
description: 'A fact check for demoing purposes', // A description to be displayed in the UI
- factRefs: ['demo-poc.factretriever'], // References to fact containers that this check uses. See documentation on FactRetrievers for more information on these
+ factIds: ['documentation-number-factretriever'], // References to fact ids that this check uses. See documentation on FactRetrievers for more information on these
rule: {
// The actual rule
conditions: {
diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json
index 8943b0e461..5504cb2d81 100644
--- a/plugins/tech-insights-backend-module-jsonfc/package.json
+++ b/plugins/tech-insights-backend-module-jsonfc/package.json
@@ -31,7 +31,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.0",
+ "@backstage/backend-common": "^0.9.10",
"@backstage/config": "^0.1.8",
"@backstage/errors": "^0.1.1",
"@backstage/plugin-tech-insights-common": "^0.1.0",
@@ -43,7 +43,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
+ "@backstage/cli": "^0.9.0",
"@types/node-cron": "^2.0.4"
},
"files": [
diff --git a/plugins/tech-insights-backend/CHANGELOG.md b/plugins/tech-insights-backend/CHANGELOG.md
new file mode 100644
index 0000000000..abb8eaac6f
--- /dev/null
+++ b/plugins/tech-insights-backend/CHANGELOG.md
@@ -0,0 +1,15 @@
+# @backstage/plugin-tech-insights-backend
+
+## 0.1.1
+
+### Patch Changes
+
+- 5c00e45045: Add catalog fact retrievers
+
+ Add fact retrievers which generate facts related to the completeness
+ of entity data in the catalog.
+
+- Updated dependencies
+ - @backstage/catalog-client@0.5.2
+ - @backstage/catalog-model@0.9.7
+ - @backstage/backend-common@0.9.10
diff --git a/plugins/tech-insights-backend/README.md b/plugins/tech-insights-backend/README.md
index e2cc1c0252..764ad860b8 100644
--- a/plugins/tech-insights-backend/README.md
+++ b/plugins/tech-insights-backend/README.md
@@ -22,7 +22,7 @@ do this by creating a file called `packages/backend/src/plugins/techInsights.ts`
```ts
import {
createRouter,
- DefaultTechInsightsBuilder,
+ buildTechInsightsContext,
} from '@backstage/plugin-tech-insights-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
@@ -33,7 +33,7 @@ export default async function createPlugin({
discovery,
database,
}: PluginEnvironment): Promise {
- const builder = new DefaultTechInsightsBuilder({
+ const builder = buildTechInsightsContext({
logger,
config,
database,
diff --git a/plugins/tech-insights-backend/package.json b/plugins/tech-insights-backend/package.json
index 678bec25c4..5bc616db71 100644
--- a/plugins/tech-insights-backend/package.json
+++ b/plugins/tech-insights-backend/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-tech-insights-backend",
- "version": "0.1.0",
+ "version": "0.1.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,9 +31,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.0",
- "@backstage/catalog-client": "^0.3.16",
- "@backstage/catalog-model": "^0.9.0",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.8",
"@backstage/errors": "^0.1.1",
"@backstage/plugin-tech-insights-common": "^0.1.0",
@@ -52,8 +52,8 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/backend-test-utils": "^0.1.8",
- "@backstage/cli": "^0.8.0",
+ "@backstage/backend-test-utils": "^0.1.9",
+ "@backstage/cli": "^0.9.0",
"@types/supertest": "^2.0.8",
"@types/node-cron": "^3.0.0",
"@types/semver": "^7.3.8",
diff --git a/plugins/tech-insights-common/package.json b/plugins/tech-insights-common/package.json
index 5e02c9e4b0..26d8922329 100644
--- a/plugins/tech-insights-common/package.json
+++ b/plugins/tech-insights-common/package.json
@@ -34,7 +34,7 @@
"luxon": "^2.0.2"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0"
+ "@backstage/cli": "^0.9.0"
},
"files": [
"dist"
diff --git a/plugins/tech-insights-node/package.json b/plugins/tech-insights-node/package.json
index 4a7cf3589b..3c2ba5da08 100644
--- a/plugins/tech-insights-node/package.json
+++ b/plugins/tech-insights-node/package.json
@@ -30,7 +30,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.0",
+ "@backstage/backend-common": "^0.9.10",
"@backstage/config": "^0.1.8",
"@backstage/plugin-tech-insights-common": "^0.1.0 ",
"@types/luxon": "^2.0.5",
@@ -38,7 +38,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0"
+ "@backstage/cli": "^0.9.0"
},
"files": [
"dist"
diff --git a/plugins/tech-radar/CHANGELOG.md b/plugins/tech-radar/CHANGELOG.md
index 8e7b5875a9..cef7885007 100644
--- a/plugins/tech-radar/CHANGELOG.md
+++ b/plugins/tech-radar/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-tech-radar
+## 0.4.12
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.4.11
### Patch Changes
diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json
index 839ad1b399..99fce10345 100644
--- a/plugins/tech-radar/package.json
+++ b/plugins/tech-radar/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-tech-radar",
"description": "A Backstage plugin that lets you display a Tech Radar for your organization",
- "version": "0.4.11",
+ "version": "0.4.12",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,8 +31,8 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -45,10 +45,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/tech-radar/src/components/RadarComponent.test.tsx b/plugins/tech-radar/src/components/RadarComponent.test.tsx
index cce411e897..2b237c8d83 100644
--- a/plugins/tech-radar/src/components/RadarComponent.test.tsx
+++ b/plugins/tech-radar/src/components/RadarComponent.test.tsx
@@ -19,13 +19,12 @@ import { render, waitForElement } from '@testing-library/react';
import { ThemeProvider } from '@material-ui/core';
import { lightTheme } from '@backstage/theme';
import { act } from 'react-dom/test-utils';
-import { withLogCollector } from '@backstage/test-utils';
+import { TestApiProvider, withLogCollector } from '@backstage/test-utils';
import GetBBoxPolyfill from '../utils/polyfills/getBBox';
import { RadarComponent } from './RadarComponent';
import { TechRadarLoaderResponse, techRadarApiRef, TechRadarApi } from '../api';
-import { ApiRegistry, ApiProvider } from '@backstage/core-app-api';
import { errorApiRef } from '@backstage/core-plugin-api';
describe('RadarComponent', () => {
@@ -55,18 +54,18 @@ describe('RadarComponent', () => {
const errorApi = { post: () => {} };
const { getByTestId, queryByTestId } = render(
-
-
+
,
);
@@ -87,18 +86,18 @@ describe('RadarComponent', () => {
const { queryByTestId } = render(
-
-
+
,
);
@@ -115,13 +114,13 @@ describe('RadarComponent', () => {
expect(() => {
render(
-
+
-
+
,
);
}).toThrow();
diff --git a/plugins/tech-radar/src/components/RadarPage.test.tsx b/plugins/tech-radar/src/components/RadarPage.test.tsx
index 7215fc40df..7f4e69e388 100644
--- a/plugins/tech-radar/src/components/RadarPage.test.tsx
+++ b/plugins/tech-radar/src/components/RadarPage.test.tsx
@@ -17,6 +17,7 @@
import {
MockErrorApi,
renderInTestApp,
+ TestApiProvider,
wrapInTestApp,
} from '@backstage/test-utils';
import { lightTheme } from '@backstage/theme';
@@ -28,7 +29,6 @@ import GetBBoxPolyfill from '../utils/polyfills/getBBox';
import { RadarPage } from './RadarPage';
import { TechRadarLoaderResponse, techRadarApiRef, TechRadarApi } from '../api';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { errorApiRef } from '@backstage/core-plugin-api';
describe('RadarPage', () => {
@@ -63,9 +63,9 @@ describe('RadarPage', () => {
const { getByTestId, queryByTestId } = render(
wrapInTestApp(
-
+
-
+
,
),
);
@@ -89,9 +89,9 @@ describe('RadarPage', () => {
const { getByText, getByTestId } = await renderInTestApp(
-
+
-
+
,
);
@@ -115,9 +115,9 @@ describe('RadarPage', () => {
const { getByTestId } = await renderInTestApp(
-
+
-
+
,
);
@@ -142,14 +142,14 @@ describe('RadarPage', () => {
const { queryByTestId } = await renderInTestApp(
-
-
+
,
);
diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md
index 7331ea0147..ad7a8af85e 100644
--- a/plugins/techdocs-backend/CHANGELOG.md
+++ b/plugins/techdocs-backend/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/plugin-techdocs-backend
+## 0.10.8
+
+### Patch Changes
+
+- e21e3c6102: Bumping minimum requirements for `dockerode` and `testcontainers`
+- 9e64a7ac1e: Allow amazon web services s3 buckets to pass an server side encryption configuration so they can publish to encrypted buckets
+- Updated dependencies
+ - @backstage/catalog-client@0.5.2
+ - @backstage/catalog-model@0.9.7
+ - @backstage/backend-common@0.9.10
+ - @backstage/techdocs-common@0.10.7
+
## 0.10.7
### Patch Changes
diff --git a/plugins/techdocs-backend/config.d.ts b/plugins/techdocs-backend/config.d.ts
index da3cd34830..9e563137bd 100644
--- a/plugins/techdocs-backend/config.d.ts
+++ b/plugins/techdocs-backend/config.d.ts
@@ -227,14 +227,14 @@ export interface Config {
};
/**
- * @example http://localhost:7000/api/techdocs
+ * @example http://localhost:7007/api/techdocs
* @visibility frontend
* @deprecated
*/
requestUrl?: string;
/**
- * @example http://localhost:7000/api/techdocs/static/docs
+ * @example http://localhost:7007/api/techdocs/static/docs
* @deprecated
*/
storageUrl?: string;
diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json
index c71833948b..332884c694 100644
--- a/plugins/techdocs-backend/package.json
+++ b/plugins/techdocs-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-techdocs-backend",
"description": "The Backstage backend plugin that renders technical documentation for your components",
- "version": "0.10.7",
+ "version": "0.10.8",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,17 +31,17 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.8",
- "@backstage/catalog-client": "^0.5.0",
- "@backstage/catalog-model": "^0.9.6",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.4",
"@backstage/integration": "^0.6.9",
"@backstage/search-common": "^0.2.1",
- "@backstage/techdocs-common": "^0.10.5",
+ "@backstage/techdocs-common": "^0.10.7",
"@types/express": "^4.17.6",
"cross-fetch": "^3.0.6",
- "dockerode": "^3.2.1",
+ "dockerode": "^3.3.1",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"fs-extra": "9.1.0",
@@ -51,9 +51,9 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.8.1",
- "@backstage/test-utils": "^0.1.20",
- "@types/dockerode": "^3.2.1",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/test-utils": "^0.1.22",
+ "@types/dockerode": "^3.3.0",
"msw": "^0.35.0",
"supertest": "^6.1.3"
},
diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md
index be100b9dea..6b8a8f0ff9 100644
--- a/plugins/techdocs/CHANGELOG.md
+++ b/plugins/techdocs/CHANGELOG.md
@@ -1,5 +1,22 @@
# @backstage/plugin-techdocs
+## 0.12.6
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- c1858c4cf9: Fixed entity triplet case handling for certain locales.
+- f7703981a9: Use a better checkbox rendering in a task list.
+- e266687580: Updates reader component used to display techdocs documentation. A previous change made this component not usable out of a page which don't have entityRef in url parameters. Reader component EntityRef parameter is now used instead of url parameters. Techdocs documentation component can now be used in our custom pages.
+- Updated dependencies
+ - @backstage/plugin-catalog@0.7.3
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/plugin-search@0.4.18
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+ - @backstage/integration-react@0.1.14
+
## 0.12.5
### Patch Changes
diff --git a/plugins/techdocs/config.d.ts b/plugins/techdocs/config.d.ts
index d6bf21b10b..45fd524eff 100644
--- a/plugins/techdocs/config.d.ts
+++ b/plugins/techdocs/config.d.ts
@@ -34,7 +34,7 @@ export interface Config {
legacyUseCaseSensitiveTripletPaths?: boolean;
/**
- * @example http://localhost:7000/api/techdocs
+ * @example http://localhost:7007/api/techdocs
* @visibility frontend
* @deprecated
*/
diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json
index 79841a0621..663c83118e 100644
--- a/plugins/techdocs/package.json
+++ b/plugins/techdocs/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-techdocs",
"description": "The Backstage plugin that renders technical documentation for your components",
- "version": "0.12.5",
+ "version": "0.12.6",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,16 +32,16 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.6",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.11",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.4",
"@backstage/integration": "^0.6.9",
- "@backstage/integration-react": "^0.1.13",
- "@backstage/plugin-catalog": "^0.7.2",
- "@backstage/plugin-catalog-react": "^0.6.3",
- "@backstage/plugin-search": "^0.4.17",
+ "@backstage/integration-react": "^0.1.14",
+ "@backstage/plugin-catalog": "^0.7.3",
+ "@backstage/plugin-catalog-react": "^0.6.4",
+ "@backstage/plugin-search": "^0.4.18",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -61,10 +61,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/techdocs/src/home/components/DefaultTechDocsHome.test.tsx b/plugins/techdocs/src/home/components/DefaultTechDocsHome.test.tsx
index 1d8d7d2b04..8618c4432f 100644
--- a/plugins/techdocs/src/home/components/DefaultTechDocsHome.test.tsx
+++ b/plugins/techdocs/src/home/components/DefaultTechDocsHome.test.tsx
@@ -14,11 +14,7 @@
* limitations under the License.
*/
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import {
ConfigApi,
configApiRef,
@@ -30,7 +26,11 @@ import {
DefaultStarredEntitiesApi,
starredEntitiesApiRef,
} from '@backstage/plugin-catalog-react';
-import { MockStorageApi, renderInTestApp } from '@backstage/test-utils';
+import {
+ MockStorageApi,
+ renderInTestApp,
+ TestApiRegistry,
+} from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
import { rootDocsRouteRef } from '../../routes';
@@ -69,12 +69,12 @@ describe('TechDocs Home', () => {
const storageApi = MockStorageApi.create();
- const apiRegistry = ApiRegistry.from([
+ const apiRegistry = TestApiRegistry.from(
[catalogApiRef, mockCatalogApi],
[configApiRef, configApi],
[storageApiRef, storageApi],
[starredEntitiesApiRef, new DefaultStarredEntitiesApi({ storageApi })],
- ]);
+ );
it('should render a TechDocs home page', async () => {
await renderInTestApp(
diff --git a/plugins/techdocs/src/home/components/LegacyTechDocsHome.test.tsx b/plugins/techdocs/src/home/components/LegacyTechDocsHome.test.tsx
index d9d2c6a345..a8fd472f7c 100644
--- a/plugins/techdocs/src/home/components/LegacyTechDocsHome.test.tsx
+++ b/plugins/techdocs/src/home/components/LegacyTechDocsHome.test.tsx
@@ -15,16 +15,12 @@
*/
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
import { LegacyTechDocsHome } from './LegacyTechDocsHome';
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import { ConfigApi, configApiRef } from '@backstage/core-plugin-api';
import { rootDocsRouteRef } from '../../routes';
@@ -59,10 +55,10 @@ describe('Legacy TechDocs Home', () => {
},
});
- const apiRegistry = ApiRegistry.from([
+ const apiRegistry = TestApiRegistry.from(
[catalogApiRef, mockCatalogApi],
[configApiRef, configApi],
- ]);
+ );
it('should render a TechDocs home page', async () => {
await renderInTestApp(
diff --git a/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx b/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx
index bcbfdeed86..e9c3a55b15 100644
--- a/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx
+++ b/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx
@@ -15,11 +15,11 @@
*/
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
import { TechDocsCustomHome, PanelType } from './TechDocsCustomHome';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import { rootDocsRouteRef } from '../../routes';
jest.mock('@backstage/plugin-catalog-react', () => {
@@ -47,7 +47,7 @@ const mockCatalogApi = {
} as Partial;
describe('TechDocsCustomHome', () => {
- const apiRegistry = ApiRegistry.with(catalogApiRef, mockCatalogApi);
+ const apiRegistry = TestApiRegistry.from([catalogApiRef, mockCatalogApi]);
it('should render a TechDocs home page', async () => {
const tabsConfig = [
diff --git a/plugins/techdocs/src/reader/components/Reader.test.tsx b/plugins/techdocs/src/reader/components/Reader.test.tsx
index 8b5dbced3f..6e8609694d 100644
--- a/plugins/techdocs/src/reader/components/Reader.test.tsx
+++ b/plugins/techdocs/src/reader/components/Reader.test.tsx
@@ -19,12 +19,12 @@ import {
ScmIntegrationsApi,
scmIntegrationsApiRef,
} from '@backstage/integration-react';
-import { wrapInTestApp } from '@backstage/test-utils';
+import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils';
import { act, render } from '@testing-library/react';
import React from 'react';
import { TechDocsStorageApi, techdocsStorageApiRef } from '../../api';
import { Reader } from './Reader';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import { searchApiRef } from '@backstage/plugin-search';
jest.mock('react-router-dom', () => {
@@ -57,11 +57,11 @@ describe('', () => {
results: [],
}),
};
- const apiRegistry = ApiRegistry.from([
+ const apiRegistry = TestApiRegistry.from(
[scmIntegrationsApiRef, scmIntegrationsApi],
[techdocsStorageApiRef, techdocsStorageApi],
[searchApiRef, searchApi],
- ]);
+ );
await act(async () => {
const rendered = render(
diff --git a/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx b/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx
index 6a5af982fd..b297466a62 100644
--- a/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx
+++ b/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx
@@ -21,7 +21,7 @@ import {
ScmIntegrationsApi,
scmIntegrationsApiRef,
} from '@backstage/integration-react';
-import { wrapInTestApp } from '@backstage/test-utils';
+import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils';
import { Header } from '@backstage/core-components';
import {
techdocsApiRef,
@@ -29,7 +29,7 @@ import {
techdocsStorageApiRef,
TechDocsStorageApi,
} from '../../api';
-import { ApiRegistry, ApiProvider } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import { searchApiRef } from '@backstage/plugin-search';
jest.mock('react-router-dom', () => {
@@ -90,12 +90,12 @@ describe('', () => {
results: [],
}),
};
- const apiRegistry = ApiRegistry.from([
+ const apiRegistry = TestApiRegistry.from(
[scmIntegrationsApiRef, scmIntegrationsApi],
[techdocsApiRef, techdocsApi],
[techdocsStorageApiRef, techdocsStorageApi],
[searchApiRef, searchApi],
- ]);
+ );
await act(async () => {
const rendered = render(
@@ -147,12 +147,12 @@ describe('', () => {
results: [],
}),
};
- const apiRegistry = ApiRegistry.from([
+ const apiRegistry = TestApiRegistry.from(
[scmIntegrationsApiRef, scmIntegrationsApi],
[techdocsApiRef, techdocsApi],
[techdocsStorageApiRef, techdocsStorageApi],
[searchApiRef, searchApi],
- ]);
+ );
await act(async () => {
const rendered = render(
diff --git a/plugins/techdocs/src/reader/components/TechDocsSearch.test.tsx b/plugins/techdocs/src/reader/components/TechDocsSearch.test.tsx
index 602a94e758..5b3d714a04 100644
--- a/plugins/techdocs/src/reader/components/TechDocsSearch.test.tsx
+++ b/plugins/techdocs/src/reader/components/TechDocsSearch.test.tsx
@@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { ApiProvider } from '@backstage/core-app-api';
import { searchApiRef } from '@backstage/plugin-search';
-import { wrapInTestApp } from '@backstage/test-utils';
+import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils';
import {
act,
fireEvent,
@@ -54,7 +54,7 @@ describe('', () => {
const querySpy = jest.fn(query);
const searchApi = { query: querySpy };
- const apiRegistry = ApiRegistry.from([[searchApiRef, searchApi]]);
+ const apiRegistry = TestApiRegistry.from([searchApiRef, searchApi]);
await act(async () => {
const rendered = render(
@@ -75,7 +75,7 @@ describe('', () => {
const querySpy = jest.fn(query);
const searchApi = { query: querySpy };
- const apiRegistry = ApiRegistry.from([[searchApiRef, searchApi]]);
+ const apiRegistry = TestApiRegistry.from([searchApiRef, searchApi]);
await act(async () => {
const rendered = render(
diff --git a/plugins/techdocs/src/reader/components/useReaderState.test.tsx b/plugins/techdocs/src/reader/components/useReaderState.test.tsx
index cce8282b3d..e41a114dbe 100644
--- a/plugins/techdocs/src/reader/components/useReaderState.test.tsx
+++ b/plugins/techdocs/src/reader/components/useReaderState.test.tsx
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { NotFoundError } from '@backstage/errors';
+import { TestApiProvider } from '@backstage/test-utils';
import { act, renderHook } from '@testing-library/react-hooks';
import React from 'react';
import { techdocsStorageApiRef } from '../../api';
@@ -38,10 +38,10 @@ describe('useReaderState', () => {
};
beforeEach(() => {
- const apis = ApiRegistry.with(techdocsStorageApiRef, techdocsStorageApi);
-
Wrapper = ({ children }: { children?: React.ReactNode }) => (
- {children}
+
+ {children}
+
);
});
diff --git a/plugins/todo-backend/README.md b/plugins/todo-backend/README.md
index fd3410e42e..5540ca598e 100644
--- a/plugins/todo-backend/README.md
+++ b/plugins/todo-backend/README.md
@@ -46,7 +46,7 @@ async function main() {
// ...
const todoEnv = useHotMemoize(module, () => createEnv('todo'));
// ...
- apiRouter.use('/todo', await kafka(todoEnv));
+ apiRouter.use('/todo', await todo(todoEnv));
```
## Scanned Files
diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json
index c3f0e469aa..be1dc658f1 100644
--- a/plugins/todo-backend/package.json
+++ b/plugins/todo-backend/package.json
@@ -25,9 +25,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.9.7",
- "@backstage/catalog-client": "^0.5.0",
- "@backstage/catalog-model": "^0.9.5",
+ "@backstage/backend-common": "^0.9.10",
+ "@backstage/catalog-client": "^0.5.2",
+ "@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.10",
"@backstage/errors": "^0.1.3",
"@backstage/integration": "^0.6.7",
@@ -40,7 +40,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.8.0",
+ "@backstage/cli": "^0.9.0",
"@types/supertest": "^2.0.8",
"msw": "^0.35.0",
"supertest": "^6.1.3"
diff --git a/plugins/todo/CHANGELOG.md b/plugins/todo/CHANGELOG.md
index 99c33c425e..1a6a352e73 100644
--- a/plugins/todo/CHANGELOG.md
+++ b/plugins/todo/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-todo
+## 0.1.15
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/catalog-model@0.9.7
+ - @backstage/plugin-catalog-react@0.6.4
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.1.14
### Patch Changes
diff --git a/plugins/todo/README.md b/plugins/todo/README.md
index 3e1c370d8a..ad0ad4fc1d 100644
--- a/plugins/todo/README.md
+++ b/plugins/todo/README.md
@@ -56,7 +56,7 @@ async function main() {
// ...
const todoEnv = useHotMemoize(module, () => createEnv('todo'));
// ...
- apiRouter.use('/todo', await kafka(todoEnv));
+ apiRouter.use('/todo', await todo(todoEnv));
```
3. Add the plugin as a tab to your service entities:
diff --git a/plugins/todo/dev/index.tsx b/plugins/todo/dev/index.tsx
index a4221dc710..fe547812ec 100644
--- a/plugins/todo/dev/index.tsx
+++ b/plugins/todo/dev/index.tsx
@@ -22,8 +22,8 @@ import OfflineIcon from '@material-ui/icons/Storage';
import React from 'react';
import { EntityTodoContent, todoApiRef, todoPlugin } from '../src';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { Content, Header, HeaderLabel, Page } from '@backstage/core-components';
+import { TestApiProvider } from '@backstage/test-utils';
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
@@ -60,7 +60,7 @@ createDevApp()
.registerPlugin(todoPlugin)
.addPage({
element: (
-
+
@@ -71,7 +71,7 @@ createDevApp()
-
+
),
title: 'Entity Todo Content',
icon: OfflineIcon,
diff --git a/plugins/todo/package.json b/plugins/todo/package.json
index 5e32d84497..22a8e6b1e2 100644
--- a/plugins/todo/package.json
+++ b/plugins/todo/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-todo",
"description": "A Backstage plugin that lets you browse TODO comments in your source code",
- "version": "0.1.14",
+ "version": "0.1.15",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -27,11 +27,11 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.9.5",
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/catalog-model": "^0.9.7",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.3",
- "@backstage/plugin-catalog-react": "^0.6.1",
+ "@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -41,10 +41,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/todo/src/components/TodoList/TodoList.test.tsx b/plugins/todo/src/components/TodoList/TodoList.test.tsx
index 0e4d64172d..2759fe40f8 100644
--- a/plugins/todo/src/components/TodoList/TodoList.test.tsx
+++ b/plugins/todo/src/components/TodoList/TodoList.test.tsx
@@ -16,11 +16,10 @@
import { Entity } from '@backstage/catalog-model';
import { EntityProvider } from '@backstage/plugin-catalog-react';
-import { renderWithEffects } from '@backstage/test-utils';
+import { renderWithEffects, TestApiProvider } from '@backstage/test-utils';
import React from 'react';
import { TodoApi, todoApiRef } from '../../api';
import { TodoList } from './TodoList';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
describe('TodoList', () => {
it('should render', async () => {
@@ -42,11 +41,11 @@ describe('TodoList', () => {
const mockEntity = { metadata: { name: 'mock' } } as Entity;
const rendered = await renderWithEffects(
-
+
- ,
+ ,
);
await expect(rendered.findByText('FIXME')).resolves.toBeInTheDocument();
diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md
index ae3bc1c72d..a309afb497 100644
--- a/plugins/user-settings/CHANGELOG.md
+++ b/plugins/user-settings/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-user-settings
+## 0.3.11
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- 274a4fc633: Add Props Icon for Sidebar Item SidebarSearchField and Settings
+- Updated dependencies
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.3.10
### Patch Changes
diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json
index dc63957cb9..def12ac1d2 100644
--- a/plugins/user-settings/package.json
+++ b/plugins/user-settings/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-user-settings",
"description": "A Backstage plugin that provides a settings page",
- "version": "0.3.10",
+ "version": "0.3.11",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,8 +31,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -43,10 +43,10 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/user-settings/src/components/AuthProviders/UserSettingsAuthProviders.test.tsx b/plugins/user-settings/src/components/AuthProviders/UserSettingsAuthProviders.test.tsx
index 085a884f2e..4e14dec2ef 100644
--- a/plugins/user-settings/src/components/AuthProviders/UserSettingsAuthProviders.test.tsx
+++ b/plugins/user-settings/src/components/AuthProviders/UserSettingsAuthProviders.test.tsx
@@ -14,22 +14,24 @@
* limitations under the License.
*/
-import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils';
+import {
+ renderWithEffects,
+ TestApiRegistry,
+ wrapInTestApp,
+} from '@backstage/test-utils';
import { fireEvent } from '@testing-library/react';
import React from 'react';
import { UserSettingsAuthProviders } from './UserSettingsAuthProviders';
-import {
- ApiProvider,
- ApiRegistry,
- ConfigReader,
-} from '@backstage/core-app-api';
+import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import { configApiRef, googleAuthApiRef } from '@backstage/core-plugin-api';
const mockSignInHandler = jest.fn().mockReturnValue('');
const mockGoogleAuth = {
sessionState$: () => ({
+ [Symbol.observable]: jest.fn(),
subscribe: () => ({
+ closed: false,
unsubscribe: () => null,
}),
}),
@@ -47,10 +49,10 @@ const createConfig = () =>
const config = createConfig();
-const apiRegistry = ApiRegistry.from([
+const apiRegistry = TestApiRegistry.from(
[configApiRef, config],
[googleAuthApiRef, mockGoogleAuth],
-]);
+);
describe('', () => {
it('displays a provider and calls its sign-in handler on click', async () => {
diff --git a/plugins/user-settings/src/components/General/UserSettingsThemeToggle.test.tsx b/plugins/user-settings/src/components/General/UserSettingsThemeToggle.test.tsx
index caae4d69bc..83d9e23f83 100644
--- a/plugins/user-settings/src/components/General/UserSettingsThemeToggle.test.tsx
+++ b/plugins/user-settings/src/components/General/UserSettingsThemeToggle.test.tsx
@@ -15,16 +15,16 @@
*/
import { AppTheme, appThemeApiRef } from '@backstage/core-plugin-api';
-import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils';
+import {
+ renderWithEffects,
+ TestApiRegistry,
+ wrapInTestApp,
+} from '@backstage/test-utils';
import { lightTheme } from '@backstage/theme';
import { fireEvent } from '@testing-library/react';
import React from 'react';
import { UserSettingsThemeToggle } from './UserSettingsThemeToggle';
-import {
- ApiProvider,
- ApiRegistry,
- AppThemeSelector,
-} from '@backstage/core-app-api';
+import { ApiProvider, AppThemeSelector } from '@backstage/core-app-api';
const mockTheme: AppTheme = {
id: 'light-theme',
@@ -33,8 +33,9 @@ const mockTheme: AppTheme = {
theme: lightTheme,
};
-const apiRegistry = ApiRegistry.from([
- [appThemeApiRef, AppThemeSelector.createWithStorage([mockTheme])],
+const apiRegistry = TestApiRegistry.from([
+ appThemeApiRef,
+ AppThemeSelector.createWithStorage([mockTheme]),
]);
describe('', () => {
diff --git a/plugins/xcmetrics/CHANGELOG.md b/plugins/xcmetrics/CHANGELOG.md
index a7d2d480b7..4ae5c49c32 100644
--- a/plugins/xcmetrics/CHANGELOG.md
+++ b/plugins/xcmetrics/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-xcmetrics
+## 0.2.10
+
+### Patch Changes
+
+- a125278b81: Refactor out the deprecated path and icon from RouteRefs
+- Updated dependencies
+ - @backstage/core-components@0.7.4
+ - @backstage/core-plugin-api@0.2.0
+
## 0.2.9
### Patch Changes
diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json
index bbab66e455..f29f763666 100644
--- a/plugins/xcmetrics/package.json
+++ b/plugins/xcmetrics/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-xcmetrics",
"description": "A Backstage plugin that shows XCode build metrics for your components",
- "version": "0.2.9",
+ "version": "0.2.10",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/core-components": "^0.7.3",
- "@backstage/core-plugin-api": "^0.1.13",
+ "@backstage/core-components": "^0.7.4",
+ "@backstage/core-plugin-api": "^0.2.0",
"@backstage/errors": "^0.1.3",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
@@ -36,10 +36,10 @@
"recharts": "^1.8.5"
},
"devDependencies": {
- "@backstage/cli": "^0.8.2",
- "@backstage/core-app-api": "^0.1.20",
- "@backstage/dev-utils": "^0.2.12",
- "@backstage/test-utils": "^0.1.21",
+ "@backstage/cli": "^0.9.0",
+ "@backstage/core-app-api": "^0.1.22",
+ "@backstage/dev-utils": "^0.2.13",
+ "@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/xcmetrics/src/components/BuildDetails/BuildDetails.test.tsx b/plugins/xcmetrics/src/components/BuildDetails/BuildDetails.test.tsx
index 2d949d7abc..7083d890d6 100644
--- a/plugins/xcmetrics/src/components/BuildDetails/BuildDetails.test.tsx
+++ b/plugins/xcmetrics/src/components/BuildDetails/BuildDetails.test.tsx
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import React from 'react';
-import { renderInTestApp } from '@backstage/test-utils';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { BuildDetails, withRequest } from './BuildDetails';
import { xcmetricsApiRef } from '../../api';
@@ -35,11 +34,9 @@ jest.mock('../BuildTimeline', () => ({
describe('BuildDetails', () => {
it('should render', async () => {
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText('accordion-Host')).toBeInTheDocument();
@@ -61,11 +58,9 @@ describe('BuildDetails with request', () => {
it('should fetch the build and render', async () => {
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText(client.mockBuild.id)).toBeInTheDocument();
@@ -78,11 +73,9 @@ describe('BuildDetails with request', () => {
.mockRejectedValue({ message: errorMessage });
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText(errorMessage)).toBeInTheDocument();
@@ -92,11 +85,9 @@ describe('BuildDetails with request', () => {
client.XcmetricsClient.getBuild = jest.fn().mockReturnValue(undefined);
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(
diff --git a/plugins/xcmetrics/src/components/BuildList/BuildList.test.tsx b/plugins/xcmetrics/src/components/BuildList/BuildList.test.tsx
index eb141209e7..53471f5e9f 100644
--- a/plugins/xcmetrics/src/components/BuildList/BuildList.test.tsx
+++ b/plugins/xcmetrics/src/components/BuildList/BuildList.test.tsx
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import React from 'react';
-import { renderInTestApp } from '@backstage/test-utils';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { BuildList } from './BuildList';
import { xcmetricsApiRef } from '../../api';
import userEvent from '@testing-library/user-event';
@@ -35,11 +34,9 @@ jest.mock('../BuildDetails', () => ({
describe('BuildList', () => {
it('should render', async () => {
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText('Builds')).toBeInTheDocument();
@@ -50,11 +47,9 @@ describe('BuildList', () => {
it('should show build details', async () => {
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
userEvent.click(
@@ -70,11 +65,9 @@ describe('BuildList', () => {
.mockRejectedValue({ message });
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText(message)).toBeInTheDocument();
diff --git a/plugins/xcmetrics/src/components/BuildListFilter/BuildListFilter.test.tsx b/plugins/xcmetrics/src/components/BuildListFilter/BuildListFilter.test.tsx
index b997de68e0..06f4aed1b7 100644
--- a/plugins/xcmetrics/src/components/BuildListFilter/BuildListFilter.test.tsx
+++ b/plugins/xcmetrics/src/components/BuildListFilter/BuildListFilter.test.tsx
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import React from 'react';
-import { renderInTestApp } from '@backstage/test-utils';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import userEvent from '@testing-library/user-event';
import { BuildListFilter } from './BuildListFilter';
import { BuildFilters, xcmetricsApiRef } from '../../api';
@@ -37,14 +36,12 @@ const renderWithFiltersVisible = async (
callback?: (filters: BuildFilters) => void,
) => {
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
userEvent.click(rendered.getByLabelText('show filters'));
@@ -67,14 +64,12 @@ const setProjectFilter = async (rendered: RenderResult, option: string) => {
describe('BuildListFilter', () => {
it('should render', async () => {
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText('Filters (0)')).toBeInTheDocument();
diff --git a/plugins/xcmetrics/src/components/Overview/Overview.test.tsx b/plugins/xcmetrics/src/components/Overview/Overview.test.tsx
index 3d24d2a422..42e3772d04 100644
--- a/plugins/xcmetrics/src/components/Overview/Overview.test.tsx
+++ b/plugins/xcmetrics/src/components/Overview/Overview.test.tsx
@@ -14,9 +14,8 @@
* limitations under the License.
*/
import React from 'react';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { xcmetricsApiRef } from '../../api';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { Overview } from './Overview';
jest.mock('../../api/XcmetricsClient');
@@ -33,11 +32,9 @@ jest.mock('../StatusMatrix', () => ({
describe('Overview', () => {
it('should render', async () => {
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText('XCMetrics Dashboard')).toBeInTheDocument();
@@ -49,9 +46,9 @@ describe('Overview', () => {
api.getBuilds = jest.fn().mockResolvedValue([]);
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText('No builds to show')).toBeInTheDocument();
@@ -64,9 +61,9 @@ describe('Overview', () => {
api.getBuilds = jest.fn().mockRejectedValue({ message: errorMessage });
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText(errorMessage)).toBeInTheDocument();
diff --git a/plugins/xcmetrics/src/components/OverviewTrends/OverviewTrends.test.tsx b/plugins/xcmetrics/src/components/OverviewTrends/OverviewTrends.test.tsx
index 76b47f4943..db7904a8d1 100644
--- a/plugins/xcmetrics/src/components/OverviewTrends/OverviewTrends.test.tsx
+++ b/plugins/xcmetrics/src/components/OverviewTrends/OverviewTrends.test.tsx
@@ -15,9 +15,8 @@
*/
import React from 'react';
import { OverviewTrends } from './OverviewTrends';
-import { renderInTestApp } from '@backstage/test-utils';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { xcmetricsApiRef } from '../../api';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import userEvent from '@testing-library/user-event';
jest.mock('../../api/XcmetricsClient');
@@ -26,11 +25,9 @@ const client = require('../../api/XcmetricsClient');
describe('OverviewTrends', () => {
it('should render', async () => {
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText('Trends for')).toBeInTheDocument();
expect(rendered.getAllByText('Build Count').length).toEqual(3);
@@ -42,20 +39,18 @@ describe('OverviewTrends', () => {
api.getBuildCounts = jest.fn().mockResolvedValue([]);
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText('--')).toBeInTheDocument();
});
it('should change number of days when select is changed', async () => {
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
userEvent.click(rendered.getByText('14 days'));
@@ -76,9 +71,9 @@ describe('OverviewTrends', () => {
.mockRejectedValue({ message: buildTimesError });
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText(buildCountError)).toBeInTheDocument();
expect(rendered.getByText(buildTimesError)).toBeInTheDocument();
diff --git a/plugins/xcmetrics/src/components/StatusCell/StatusCell.test.tsx b/plugins/xcmetrics/src/components/StatusCell/StatusCell.test.tsx
index cac111d13e..6e5b7f73b9 100644
--- a/plugins/xcmetrics/src/components/StatusCell/StatusCell.test.tsx
+++ b/plugins/xcmetrics/src/components/StatusCell/StatusCell.test.tsx
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import React from 'react';
-import { renderInTestApp } from '@backstage/test-utils';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import userEvent from '@testing-library/user-event';
import { StatusCell } from './StatusCell';
import { xcmetricsApiRef } from '../../api';
@@ -27,9 +26,7 @@ const client = require('../../api/XcmetricsClient');
describe('StatusCell', () => {
it('should render', async () => {
const rendered = await renderInTestApp(
-
+
{
size={10}
spacing={10}
/>
- ,
+ ,
);
userEvent.hover(rendered.getByTestId(client.mockBuild.id));
diff --git a/plugins/xcmetrics/src/components/StatusMatrix/StatusMatrix.test.tsx b/plugins/xcmetrics/src/components/StatusMatrix/StatusMatrix.test.tsx
index 7d3854bbda..f18d322b43 100644
--- a/plugins/xcmetrics/src/components/StatusMatrix/StatusMatrix.test.tsx
+++ b/plugins/xcmetrics/src/components/StatusMatrix/StatusMatrix.test.tsx
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import React from 'react';
-import { renderInTestApp } from '@backstage/test-utils';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { StatusMatrix } from './StatusMatrix';
import { xcmetricsApiRef } from '../../api';
@@ -25,11 +24,9 @@ const client = require('../../api/XcmetricsClient');
describe('StatusMatrix', () => {
it('should render', async () => {
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
const cell = rendered.getByTestId(client.mockBuild.id);
diff --git a/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.test.tsx b/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.test.tsx
index 84bd25624c..29d6407b03 100644
--- a/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.test.tsx
+++ b/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.test.tsx
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import React from 'react';
-import { renderInTestApp } from '@backstage/test-utils';
-import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
+import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { XcmetricsLayout } from './XcmetricsLayout';
import { xcmetricsApiRef } from '../../api';
import userEvent from '@testing-library/user-event';
@@ -34,11 +33,9 @@ jest.mock('../BuildList', () => ({
describe('XcmetricsLayout', () => {
it('should render', async () => {
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
expect(rendered.getByText('Overview')).toBeInTheDocument();
@@ -49,11 +46,9 @@ describe('XcmetricsLayout', () => {
it('should show a list of builds when the Builds tab is selected', async () => {
const rendered = await renderInTestApp(
-
+
- ,
+ ,
);
userEvent.click(rendered.getByText('Builds'));
diff --git a/scripts/check-if-release.js b/scripts/check-if-release.js
index 4475ed6207..b61b0e2eb7 100755
--- a/scripts/check-if-release.js
+++ b/scripts/check-if-release.js
@@ -96,7 +96,9 @@ async function main() {
const newVersions = packageVersions.filter(
({ oldVersion, newVersion }) =>
- oldVersion !== newVersion && newVersion !== '',
+ oldVersion !== newVersion &&
+ oldVersion !== '' &&
+ newVersion !== '',
);
if (newVersions.length === 0) {
diff --git a/scripts/list-deprecations.js b/scripts/list-deprecations.js
new file mode 100755
index 0000000000..920b01c7b5
--- /dev/null
+++ b/scripts/list-deprecations.js
@@ -0,0 +1,229 @@
+#!/usr/bin/env node
+/*
+ * Copyright 2021 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.
+ */
+
+/* eslint-disable import/no-extraneous-dependencies */
+
+const _ = require('lodash');
+const fs = require('fs-extra');
+const globby = require('globby');
+const { resolve: resolvePath, relative: relativePath } = require('path');
+const { execFile: execFileCb } = require('child_process');
+const { promisify } = require('util');
+
+const execFile = promisify(execFileCb);
+
+const WORKER_COUNT = 16;
+
+const deprecatedPattern = /@deprecated|DEPRECATION/;
+
+class ReleaseProvider {
+ cache = new Map();
+
+ constructor(rootPath) {
+ this.rootPath = rootPath;
+ }
+
+ async lookup(commitSha, packageDir) {
+ const key = commitSha + packageDir;
+
+ if (this.cache.has(key)) {
+ return this.cache.get(key);
+ }
+
+ const pkgJsonPath = relativePath(
+ this.rootPath,
+ resolvePath(this.rootPath, packageDir, 'package.json'),
+ );
+ const releasePromise = Promise.resolve().then(async () => {
+ // Find all tags that contain the commit
+ const { stdout: tagOutput } = await execFile(
+ 'git',
+ ['tag', '--contains', commitSha],
+ { shell: true },
+ );
+
+ // Filter out just the releases
+ const releases = tagOutput
+ .split('\n')
+ .filter(l => l.startsWith('release-'));
+
+ // Then find the earliest release that affected our package
+ for (const release of releases) {
+ let oldVersion;
+ let newVersion;
+
+ try {
+ const { stdout: content } = await execFile(
+ 'git',
+ ['show', `${release}^:${pkgJsonPath}`],
+ { shell: true },
+ );
+ oldVersion = JSON.parse(content).version;
+ } catch {
+ /* */
+ }
+ try {
+ const { stdout: content } = await execFile(
+ 'git',
+ ['show', `${release}:${pkgJsonPath}`],
+ { shell: true },
+ );
+ newVersion = JSON.parse(content).version;
+ } catch {
+ /* */
+ }
+
+ if (oldVersion !== newVersion) {
+ return release;
+ }
+ }
+ return undefined;
+ });
+
+ this.cache.set(key, releasePromise);
+ return releasePromise;
+ }
+}
+
+async function main() {
+ let packageDirQueue = process.argv.slice(2);
+
+ const rootPath = resolvePath(__dirname, '..');
+
+ if (packageDirQueue.length === 0) {
+ packageDirQueue = await Promise.all([
+ fs.readdir(resolvePath(rootPath, 'packages')),
+ fs.readdir(resolvePath(rootPath, 'plugins')),
+ ]).then(([packages, plugins]) => [
+ ...packages.map(dir => `packages/${dir}`),
+ ...plugins.map(dir => `plugins/${dir}`),
+ ]);
+ }
+
+ const fileQueue = [];
+ const deprecationQueue = [];
+ const releaseProvider = new ReleaseProvider(rootPath);
+ const deprecations = [];
+
+ await Promise.all(
+ Array(WORKER_COUNT)
+ .fill()
+ .map(async () => {
+ // Find all files we want to scan
+ while (packageDirQueue.length) {
+ const packageDir = packageDirQueue.pop();
+ const srcDir = resolvePath(rootPath, packageDir, 'src');
+
+ if (await fs.pathExists(srcDir)) {
+ const files = await globby(['**/*.{js,jsx,ts,tsx}'], {
+ cwd: srcDir,
+ });
+ fileQueue.push(
+ ...files.map(file => ({
+ packageDir,
+ file: resolvePath(srcDir, file),
+ })),
+ );
+ }
+ }
+
+ // Parse files and search for deprecations
+ while (fileQueue.length) {
+ const { packageDir, file } = fileQueue.pop();
+ const content = await fs.readFile(file, 'utf8');
+ if (!deprecatedPattern.test(content)) {
+ continue;
+ }
+
+ const lines = content.split('\n');
+ for (const [index, line] of lines.entries()) {
+ if (deprecatedPattern.test(line)) {
+ deprecationQueue.push({
+ packageDir,
+ file,
+ lineNumber: index + 1,
+ lineContent: line,
+ });
+ }
+ }
+ }
+
+ // Lookup git information for each deprecation
+ while (deprecationQueue.length) {
+ const deprecation = deprecationQueue.pop();
+
+ const { file, packageDir, lineNumber: n, lineContent } = deprecation;
+ const { stdout: blameOutput } = await execFile(
+ 'git',
+ ['blame', '--porcelain', `-L ${n},${n}`, file],
+ { shell: true },
+ );
+
+ const blameInfo = Object.fromEntries(
+ blameOutput
+ .split('\n')
+ .slice(1, -2)
+ .map(line => {
+ const [key] = line.split(' ', 1);
+ return [key, line.slice(key.length + 1)];
+ }),
+ );
+ const [commit] = blameOutput.split(' ', 1);
+ const { author, ['author-time']: authorTime } = blameInfo;
+
+ const release = await releaseProvider.lookup(commit, packageDir);
+
+ deprecations.push({
+ file: relativePath(rootPath, file),
+ release,
+ commit,
+ author,
+ authorTime: new Date(authorTime * 1000),
+ lineContent,
+ lineNumber: n,
+ });
+ }
+ }),
+ );
+
+ const maxAuthor = Math.max(...deprecations.map(d => d.author.length)) + 1;
+
+ // Group and sort by release
+ const sortedByRelease = _.sortBy(
+ Object.entries(_.groupBy(deprecations, 'release')),
+ ([release]) => release,
+ );
+
+ for (const [release, ds] of sortedByRelease) {
+ console.log(`\n### ${release === 'undefined' ? 'Not released' : release}`);
+ for (const d of _.sortBy(ds, 'authorTime', 'file', 'lineNumber')) {
+ console.log(
+ [
+ d.commit.slice(0, 8),
+ d.authorTime.toLocaleDateString().padEnd('00/00/0000'.length + 1),
+ d.author.padEnd(maxAuthor + 1),
+ `${d.file}:${d.lineNumber}`,
+ ].join(' '),
+ );
+ }
+ }
+}
+
+main().catch(err => {
+ console.error(err.stack);
+ process.exit(1);
+});
diff --git a/scripts/migrate-location-types.js b/scripts/migrate-location-types.js
index d6ac5c6a2a..168a5e825c 100755
--- a/scripts/migrate-location-types.js
+++ b/scripts/migrate-location-types.js
@@ -20,7 +20,7 @@
// catalog API endpoint and execute the script. It will delete and add
// back the locations with the correct type one by one.
-const BASE_URL = 'http://localhost:7000/api/catalog'; // Change me
+const BASE_URL = 'http://localhost:7007/api/catalog'; // Change me
const deprecatedTypes = [
'github',
@@ -81,9 +81,9 @@ async function request(method, url, body) {
return;
}
try {
- const body = Buffer.concat(chunks).toString('utf8').trim();
- if (body) {
- resolve(JSON.parse(body));
+ const responseBody = Buffer.concat(chunks).toString('utf8').trim();
+ if (responseBody) {
+ resolve(JSON.parse(responseBody));
} else {
resolve();
}
diff --git a/yarn.lock b/yarn.lock
index debcf79d8e..1e4d402072 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2078,10 +2078,10 @@
core-js-pure "^3.16.0"
regenerator-runtime "^0.13.4"
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.14.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
- version "7.15.4"
- resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a"
- integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.14.6", "@babel/runtime@^7.14.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
+ version "7.16.3"
+ resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5"
+ integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==
dependencies:
regenerator-runtime "^0.13.4"
@@ -2172,7 +2172,7 @@
"@babel/helper-validator-identifier" "^7.14.9"
to-fast-properties "^2.0.0"
-"@backstage/catalog-client@^0.3.16", "@backstage/catalog-client@^0.3.18":
+"@backstage/catalog-client@^0.3.18":
version "0.3.19"
resolved "https://registry.npmjs.org/@backstage/catalog-client/-/catalog-client-0.3.19.tgz#109b0fde1cc2d9a306635f3775fc8f6174172b14"
integrity sha512-0ydcC/1ISNgR8SggOUnMNNHtsRwrKN5GX+AXgTVdZk4qpz1MqG1+fzrNld9V7KVvXdsbGDZAl/b5a7/FJEpCqg==
@@ -2360,6 +2360,24 @@
remark-gfm "^1.0.0"
zen-observable "^0.8.15"
+"@backstage/core-plugin-api@^0.1.10", "@backstage/core-plugin-api@^0.1.3", "@backstage/core-plugin-api@^0.1.4", "@backstage/core-plugin-api@^0.1.6", "@backstage/core-plugin-api@^0.1.8":
+ version "0.1.13"
+ resolved "https://registry.npmjs.org/@backstage/core-plugin-api/-/core-plugin-api-0.1.13.tgz#583c0fe3440450c304f13dcc85eac3bd80f357d7"
+ integrity sha512-BWEqleTXR7m7nsCyt6cEnc+Gx/VT4vLdNr9fc1kXfzSAA7cUT4VKjlVmm5kdyih3BSQ4+0k7Pm/NIf0jfa7rlg==
+ dependencies:
+ "@backstage/config" "^0.1.11"
+ "@backstage/theme" "^0.2.13"
+ "@backstage/types" "^0.1.1"
+ "@backstage/version-bridge" "^0.1.0"
+ "@material-ui/core" "^4.12.2"
+ "@types/react" "*"
+ history "^5.0.0"
+ prop-types "^15.7.2"
+ react "^16.12.0"
+ react-router-dom "6.0.0-beta.0"
+ react-use "^17.2.4"
+ zen-observable "^0.8.15"
+
"@backstage/plugin-catalog-react@^0.4.0":
version "0.4.6"
resolved "https://registry.npmjs.org/@backstage/plugin-catalog-react/-/plugin-catalog-react-0.4.6.tgz#f33f3cd734f110d3c547f7eae4e25d14806ec796"
@@ -2861,35 +2879,36 @@
resolved "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz#30aa825f11d438671d585bd44e7fd564535fc210"
integrity sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==
-"@gitbeaker/core@^30.2.0", "@gitbeaker/core@^30.3.0":
- version "30.3.0"
- resolved "https://registry.npmjs.org/@gitbeaker/core/-/core-30.3.0.tgz#d005891d47cfacb41d4a3cc8bf3ee8c68c53d378"
- integrity sha512-j7GHsFo6AOuRmLaK4F4Kx967jTy6LFZh5vjmRxjlRvX0qlfl3NJKiQIl30fZz1rPXWdQLAq+kwl1i0BKrWhOpA==
+"@gitbeaker/core@^34.6.0":
+ version "34.6.0"
+ resolved "https://registry.npmjs.org/@gitbeaker/core/-/core-34.6.0.tgz#f774ea98ac079ba2edf495fdef738ac3f741178b"
+ integrity sha512-yKF+oxffPyzOnyuHCqLGJrBHhcFHuGHtcmqKhGKtnYPfqcNYA8rt4INAHaE5wMz4ILua9b4sB8p42fki+xn6WA==
dependencies:
- "@gitbeaker/requester-utils" "^30.3.0"
+ "@gitbeaker/requester-utils" "^34.6.0"
form-data "^4.0.0"
li "^1.3.0"
+ mime "^3.0.0"
query-string "^7.0.0"
xcase "^2.0.1"
-"@gitbeaker/node@^30.2.0":
- version "30.3.0"
- resolved "https://registry.npmjs.org/@gitbeaker/node/-/node-30.3.0.tgz#ceebde08a13d3f655fa614a4ced56eb1f0a71ec1"
- integrity sha512-Ythbadb1+yMO2hSgvp3nvaroHTkI4+mdLg1rdV3YNIF1n+kUYXQD2GY7wpAjH0KjAnBAmgxw/JsFmlfnRu3KAg==
+"@gitbeaker/node@^34.6.0":
+ version "34.6.0"
+ resolved "https://registry.npmjs.org/@gitbeaker/node/-/node-34.6.0.tgz#104f122433b65ceb45b0e645001d15cbcc9b1280"
+ integrity sha512-gVV4Wuev43Jbyoy1fszC885+bkvWH4zWiUhtIu0PSAm628j/OxO7idLIqUEMV0hDf6wm/PE/vOSP6PhjE0N+fA==
dependencies:
- "@gitbeaker/core" "^30.3.0"
- "@gitbeaker/requester-utils" "^30.3.0"
+ "@gitbeaker/core" "^34.6.0"
+ "@gitbeaker/requester-utils" "^34.6.0"
delay "^5.0.0"
got "^11.8.2"
xcase "^2.0.1"
-"@gitbeaker/requester-utils@^30.3.0":
- version "30.3.0"
- resolved "https://registry.npmjs.org/@gitbeaker/requester-utils/-/requester-utils-30.3.0.tgz#fbbaae20263ff90952da116d8782f74f47b29c81"
- integrity sha512-b5vCaUqP2Jrqdpt5CkmFET4VFHwJYjnIovwZGYd5H0aKmiPw4NmeW1JtP+65J4xf0c4AOQQj6XSf7TZLuPNAqw==
+"@gitbeaker/requester-utils@^34.6.0":
+ version "34.6.0"
+ resolved "https://registry.npmjs.org/@gitbeaker/requester-utils/-/requester-utils-34.6.0.tgz#4489009b759ca6f9a83f244453f4f610f1ac7349"
+ integrity sha512-H8utxbSP1kEdX0KcyVYrTDTT0A3UcPwrIV1ahyufX9ZLybYSUsA56B8Wx5kJSbWGFT1ffu2f8H2YDMwNCKKsBg==
dependencies:
form-data "^4.0.0"
- query-string "^7.0.0"
+ qs "^6.10.1"
xcase "^2.0.1"
"@google-cloud/common@^3.7.0":
@@ -3636,6 +3655,17 @@
"@types/yargs" "^15.0.0"
chalk "^4.0.0"
+"@jest/types@^27.2.5":
+ version "27.2.5"
+ resolved "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz#420765c052605e75686982d24b061b4cbba22132"
+ integrity sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==
+ dependencies:
+ "@types/istanbul-lib-coverage" "^2.0.0"
+ "@types/istanbul-reports" "^3.0.0"
+ "@types/node" "*"
+ "@types/yargs" "^16.0.0"
+ chalk "^4.0.0"
+
"@josephg/resolvable@^1.0.0":
version "1.0.1"
resolved "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz#69bc4db754d79e1a2f17a650d3466e038d94a5eb"
@@ -5054,19 +5084,19 @@
resolved "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-2.0.0.tgz#1108b9ea661ca6c81e4a8bfa63a09eb27d5bc2db"
integrity sha512-35cfQ4YWlnZnmZKmIxlGPUPLtbkF8lr/A/1Sk1eC0ddLMwQN06dOuLc+dI3YLQS+T+MoNt3DIQ0NynwgKPilig==
-"@octokit/webhooks-types@4.12.0":
- version "4.12.0"
- resolved "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-4.12.0.tgz#add8b98d60ab42e965c4ba31040097f810e222de"
- integrity sha512-G0k7CoS9bK+OI7kPHgqi1KqK4WhrjDQSjy0wJI+0OTx/xvbHUIZDeqatY60ceeRINP/1ExEk6kTARboP0xavEw==
+"@octokit/webhooks-types@4.15.0":
+ version "4.15.0"
+ resolved "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-4.15.0.tgz#1158cba6578237d60957a37963a4a05654f5668b"
+ integrity sha512-s9LgKsUzq/JH3PWDjaD/m1DIlC/QWgBWbmXVqjdxJXJQBA67KZrLWjStVlYPf0mWlVZ1MOKphDyHiOGCbs0+Kg==
"@octokit/webhooks@^9.14.1":
- version "9.17.0"
- resolved "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-9.17.0.tgz#81140b2e127157aa9817d085cd8758545e4a72e4"
- integrity sha512-/+9WSLuDuoqNWnMY4w6ePioILBqsUOiUt0ygQzugYzd112WB+yPIjmUQjAbNXImDsAa1myLpBICAMQDZlULyAA==
+ version "9.18.0"
+ resolved "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-9.18.0.tgz#19cc70e1ef281e33d830ea23e8011d25d8051f7f"
+ integrity sha512-N2hP7vCouKk9UWZxvqgWTPbp34i6g9Om/jk+TZeZ5Z+VsKjXvGtONlEd9H8DM1yOeEC+ARDpfhraX6UsK5tesQ==
dependencies:
"@octokit/request-error" "^2.0.2"
"@octokit/webhooks-methods" "^2.0.0"
- "@octokit/webhooks-types" "4.12.0"
+ "@octokit/webhooks-types" "4.15.0"
aggregate-error "^3.1.0"
"@open-draft/until@^1.0.3":
@@ -5189,25 +5219,25 @@
prop-types "^15.6.1"
react-lifecycles-compat "^3.0.4"
-"@rjsf/core@^3.0.0":
- version "3.2.0"
- resolved "https://registry.npmjs.org/@rjsf/core/-/core-3.2.0.tgz#189ff7fb132cb223463792d75fb1e04e9dd5d9f9"
- integrity sha512-Cgonq9bBWlpE0yeeIv7rAIDuJvO1wAvp9G7tT/UvhODAyb4tDb1q8J/8ubWuRRiEyzYUkuxN0W8uPIzQsJgtTQ==
+"@rjsf/core@^3.2.1":
+ version "3.2.1"
+ resolved "https://registry.npmjs.org/@rjsf/core/-/core-3.2.1.tgz#8a7b24c9a6f01f0ecb093fdfc777172c12b1b009"
+ integrity sha512-dk8ihvxFbcuIwU7G+HiJbFgwyIvaumPt5g5zfnuC26mwTUPlaDGFXKK2yITp8tJ3+hcwS5zEXtAN9wUkfuM4jA==
dependencies:
"@types/json-schema" "^7.0.7"
ajv "^6.7.0"
core-js-pure "^3.6.5"
json-schema-merge-allof "^0.6.0"
- jsonpointer "^4.0.1"
+ jsonpointer "^5.0.0"
lodash "^4.17.15"
nanoid "^3.1.23"
prop-types "^15.7.2"
react-is "^16.9.0"
-"@rjsf/material-ui@^3.0.0":
- version "3.1.0"
- resolved "https://registry.npmjs.org/@rjsf/material-ui/-/material-ui-3.1.0.tgz#ed15fc75de1594f87cd8336b7f2ebc492a432d8b"
- integrity sha512-kWz37spT5SOXkb8Axq4g4BzQjXRylQr6B7eFAg1NPhSK7KrJYwSMSsFJ9Ze2vEBxwEiR0Z0n/4puaamGuGFRBw==
+"@rjsf/material-ui@^3.2.1":
+ version "3.2.1"
+ resolved "https://registry.npmjs.org/@rjsf/material-ui/-/material-ui-3.2.1.tgz#84fbf322485aee3a84101e189161f0687779ec8d"
+ integrity sha512-8UiDeDbjCImFSfOegGu13otQ7OdP9FOYpcLjeouppnhs+MPeIEAtYS+jCcBKmi3reyTagC15/KVSRhde1wS1vg==
"@roadiehq/backstage-plugin-buildkite@^1.0.8":
version "1.0.8"
@@ -5538,16 +5568,16 @@
util-deprecate "^1.0.2"
"@storybook/addon-actions@^6.1.11":
- version "6.3.7"
- resolved "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.3.7.tgz#b25434972bef351aceb3f7ec6fd66e210f256aac"
- integrity sha512-CEAmztbVt47Gw1o6Iw0VP20tuvISCEKk9CS/rCjHtb4ubby6+j/bkp3pkEUQIbyLdHiLWFMz0ZJdyA/U6T6jCw==
+ version "6.3.12"
+ resolved "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.3.12.tgz#69eb5f8f780f1b00456051da6290d4b959ba24a0"
+ integrity sha512-mzuN4Ano4eyicwycM2PueGzzUCAEzt9/6vyptWEIVJu0sjK0J9KtBRlqFi1xGQxmCfimDR/n/vWBBkc7fp2uJA==
dependencies:
- "@storybook/addons" "6.3.7"
- "@storybook/api" "6.3.7"
- "@storybook/client-api" "6.3.7"
- "@storybook/components" "6.3.7"
- "@storybook/core-events" "6.3.7"
- "@storybook/theming" "6.3.7"
+ "@storybook/addons" "6.3.12"
+ "@storybook/api" "6.3.12"
+ "@storybook/client-api" "6.3.12"
+ "@storybook/components" "6.3.12"
+ "@storybook/core-events" "6.3.12"
+ "@storybook/theming" "6.3.12"
core-js "^3.8.2"
fast-deep-equal "^3.1.3"
global "^4.4.0"
@@ -5823,19 +5853,6 @@
qs "^6.10.0"
telejson "^5.3.2"
-"@storybook/channel-postmessage@6.3.7":
- version "6.3.7"
- resolved "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.3.7.tgz#bd4edf84a29aa2cd4a22d26115c60194d289a840"
- integrity sha512-Cmw8HRkeSF1yUFLfEIUIkUICyCXX8x5Ol/5QPbiW9HPE2hbZtYROCcg4bmWqdq59N0Tp9FQNSn+9ZygPgqQtNw==
- dependencies:
- "@storybook/channels" "6.3.7"
- "@storybook/client-logger" "6.3.7"
- "@storybook/core-events" "6.3.7"
- core-js "^3.8.2"
- global "^4.4.0"
- qs "^6.10.0"
- telejson "^5.3.2"
-
"@storybook/channels@6.3.11":
version "6.3.11"
resolved "https://registry.npmjs.org/@storybook/channels/-/channels-6.3.11.tgz#a14ce233367a9072bd1cffef3825f125c27bb0ae"
@@ -5911,30 +5928,6 @@
ts-dedent "^2.0.0"
util-deprecate "^1.0.2"
-"@storybook/client-api@6.3.7":
- version "6.3.7"
- resolved "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.3.7.tgz#cb1dca05467d777bd09aadbbdd1dd22ca537ce14"
- integrity sha512-8wOH19cMIwIIYhZy5O5Wl8JT1QOL5kNuamp9GPmg5ff4DtnG+/uUslskRvsnKyjPvl+WbIlZtBVWBiawVdd/yQ==
- dependencies:
- "@storybook/addons" "6.3.7"
- "@storybook/channel-postmessage" "6.3.7"
- "@storybook/channels" "6.3.7"
- "@storybook/client-logger" "6.3.7"
- "@storybook/core-events" "6.3.7"
- "@storybook/csf" "0.0.1"
- "@types/qs" "^6.9.5"
- "@types/webpack-env" "^1.16.0"
- core-js "^3.8.2"
- global "^4.4.0"
- lodash "^4.17.20"
- memoizerific "^1.11.3"
- qs "^6.10.0"
- regenerator-runtime "^0.13.7"
- stable "^0.1.8"
- store2 "^2.12.0"
- ts-dedent "^2.0.0"
- util-deprecate "^1.0.2"
-
"@storybook/client-logger@6.3.11":
version "6.3.11"
resolved "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.3.11.tgz#d2e0e17f35ed4c5ee282d818b6db3a015ce6b833"
@@ -6633,13 +6626,13 @@
dependencies:
defer-to-connect "^2.0.0"
-"@testing-library/cypress@^7.0.1":
- version "7.0.6"
- resolved "https://registry.npmjs.org/@testing-library/cypress/-/cypress-7.0.6.tgz#5445dac4f4852c26901c356e9d3a69371bd20ccf"
- integrity sha512-atnjqlkEt6spU4Mv7evvpA8fMXeRw7AN2uTKOR1dP6WBvBixVwAYMZY+1fMOaZULWAj9vGLCXXvmw++u3TxuCQ==
+"@testing-library/cypress@^8.0.2":
+ version "8.0.2"
+ resolved "https://registry.npmjs.org/@testing-library/cypress/-/cypress-8.0.2.tgz#b13f0ff2424dec4368b6670dfbfb7e43af8eefc9"
+ integrity sha512-KVdm7n37sg/A4e3wKMD4zUl0NpzzVhx06V9Tf0hZHZ7nrZ4yFva6Zwg2EFF1VzHkEfN/ahUzRtT1qiW+vuWnJw==
dependencies:
- "@babel/runtime" "^7.12.5"
- "@testing-library/dom" "^7.28.1"
+ "@babel/runtime" "^7.14.6"
+ "@testing-library/dom" "^8.1.0"
"@testing-library/dom@^7.28.1":
version "7.29.6"
@@ -6655,6 +6648,20 @@
lz-string "^1.4.4"
pretty-format "^26.6.2"
+"@testing-library/dom@^8.1.0":
+ version "8.11.1"
+ resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-8.11.1.tgz#03fa2684aa09ade589b460db46b4c7be9fc69753"
+ integrity sha512-3KQDyx9r0RKYailW2MiYrSSKEfH0GTkI51UGEvJenvcoDoeRYs0PZpi2SXqtnMClQvCqdtTTpOfFETDTVADpAg==
+ dependencies:
+ "@babel/code-frame" "^7.10.4"
+ "@babel/runtime" "^7.12.5"
+ "@types/aria-query" "^4.2.0"
+ aria-query "^5.0.0"
+ chalk "^4.1.0"
+ dom-accessibility-api "^0.5.9"
+ lz-string "^1.4.4"
+ pretty-format "^27.0.2"
+
"@testing-library/jest-dom@^5.10.1":
version "5.14.1"
resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.14.1.tgz#8501e16f1e55a55d675fe73eecee32cdaddb9766"
@@ -6724,6 +6731,11 @@
axios-cached-dns-resolve "0.5.2"
file-type "16.5.3"
+"@trysound/sax@0.2.0":
+ version "0.2.0"
+ resolved "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
+ integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
+
"@tsconfig/node10@^1.0.7":
version "1.0.8"
resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9"
@@ -6763,6 +6775,13 @@
dependencies:
"@types/glob" "*"
+"@types/archiver@^5.1.1":
+ version "5.1.1"
+ resolved "https://registry.npmjs.org/@types/archiver/-/archiver-5.1.1.tgz#d6d7610de4386b293abd5c1cb1875e0a4f4e1c30"
+ integrity sha512-heuaCk0YH5m274NOLSi66H1zX6GtZoMsdE6TYFcpFFjBjg0FoU4i4/M/a/kNlgNg26Xk3g364mNOYe1JaiEPOQ==
+ dependencies:
+ "@types/glob" "*"
+
"@types/argparse@1.0.38":
version "1.0.38"
resolved "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9"
@@ -7055,19 +7074,19 @@
"@types/ms" "*"
"@types/diff@^5.0.0":
- version "5.0.0"
- resolved "https://registry.npmjs.org/@types/diff/-/diff-5.0.0.tgz#eb71e94feae62548282c4889308a3dfb57e36020"
- integrity sha512-jrm2K65CokCCX4NmowtA+MfXyuprZC13jbRuwprs6/04z/EcFg/MCwYdsHn+zgV4CQBiATiI7AEq7y1sZCtWKA==
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/@types/diff/-/diff-5.0.1.tgz#9c9b9a331d4e41ccccff553f5d7ef964c6cf4042"
+ integrity sha512-XIpxU6Qdvp1ZE6Kr3yrkv1qgUab0fyf4mHYvW8N3Bx3PCsbN6or1q9/q72cv5jIFWolaGH08U9XyYoLLIykyKQ==
"@types/docker-modem@*":
- version "3.0.1"
- resolved "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.1.tgz#2a29c914dd64c4c9213510d2ce75fa85232934df"
- integrity sha512-ZUXPF0WNnvs7AxoQRijt+DW2jsXnWCk8ac28tTYzTpBNnOEIAw83A+pYkCXjTFdJHMTc+wUmwNr71Zy2TRjlWg==
+ version "3.0.2"
+ resolved "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.2.tgz#c49c902e17364fc724e050db5c1d2b298c6379d4"
+ integrity sha512-qC7prjoEYR2QEe6SmCVfB1x3rfcQtUr1n4x89+3e0wSTMQ/KYCyf+/RAA9n2tllkkNc6//JMUZePdFRiGIWfaQ==
dependencies:
"@types/node" "*"
"@types/ssh2" "*"
-"@types/dockerode@^3.2.1":
+"@types/dockerode@^3.2.5", "@types/dockerode@^3.3.0":
version "3.3.0"
resolved "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.0.tgz#d6afcc1de31e211ee900da3a48ef4f1a496cf05a"
integrity sha512-3Mc0b2gnypJB8Gwmr+8UVPkwjpf4kg1gVxw8lAI4Y/EzpK50LixU1wBSPN9D+xqiw2Ubb02JO8oM0xpwzvi2mg==
@@ -8010,10 +8029,10 @@
"@types/node" "*"
"@types/ssh2-streams" "*"
-"@types/ssh2@^0.5.45":
- version "0.5.46"
- resolved "https://registry.npmjs.org/@types/ssh2/-/ssh2-0.5.46.tgz#e12341a242aea0e98ac2dec89e039bf421fd3584"
- integrity sha512-1pC8FHrMPYdkLoUOwTYYifnSEPzAFZRsp3JFC/vokQ+dRrVI+hDBwz0SNmQ3pL6h39OSZlPs0uCG7wKJkftnaA==
+"@types/ssh2@^0.5.48":
+ version "0.5.48"
+ resolved "https://registry.npmjs.org/@types/ssh2/-/ssh2-0.5.48.tgz#0d9e8654a76eaaf4cfeaeb88d74c4489cfcf7aea"
+ integrity sha512-cmQu0gp/6RtDXe1r2xXGgi0V0TeCdueDSRMEvBX8cTRT/sSREkUpgCYZLyh+iI8Ql+VNV8Az9toQoYa/IdgHbQ==
dependencies:
"@types/node" "*"
"@types/ssh2-streams" "*"
@@ -8292,6 +8311,13 @@
dependencies:
"@types/yargs-parser" "*"
+"@types/yargs@^16.0.0":
+ version "16.0.4"
+ resolved "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977"
+ integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==
+ dependencies:
+ "@types/yargs-parser" "*"
+
"@types/yarnpkg__lockfile@^1.1.4":
version "1.1.4"
resolved "https://registry.npmjs.org/@types/yarnpkg__lockfile/-/yarnpkg__lockfile-1.1.4.tgz#445251eb00bd9c1e751f82c7c6bf4f714edfd464"
@@ -8913,7 +8939,7 @@ ajv@^8.0.1:
require-from-string "^2.0.2"
uri-js "^4.2.2"
-alphanum-sort@^1.0.0:
+alphanum-sort@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=
@@ -8986,7 +9012,7 @@ ansi-regex@^4.0.0, ansi-regex@^4.1.0:
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
-ansi-regex@^5.0.0:
+ansi-regex@^5.0.0, ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
@@ -9016,6 +9042,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
"@types/color-name" "^1.1.1"
color-convert "^2.0.1"
+ansi-styles@^5.0.0:
+ version "5.2.0"
+ resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
+ integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
+
ansi-to-html@^0.6.11:
version "0.6.14"
resolved "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.14.tgz#65fe6d08bba5dd9db33f44a20aec331e0010dad8"
@@ -9028,7 +9059,7 @@ any-observable@^0.3.0:
resolved "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b"
integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==
-any-promise@^1.0.0, any-promise@^1.1.0:
+any-promise@^1.0.0:
version "1.3.0"
resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
@@ -9337,6 +9368,11 @@ aria-query@^4.2.2:
"@babel/runtime" "^7.10.2"
"@babel/runtime-corejs3" "^7.10.2"
+aria-query@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz#210c21aaf469613ee8c9a62c7f86525e058db52c"
+ integrity sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==
+
arr-diff@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
@@ -9467,7 +9503,7 @@ asn1.js@^4.0.0:
inherits "^2.0.1"
minimalistic-assert "^1.0.0"
-asn1@^0.2.4, asn1@~0.2.0, asn1@~0.2.3:
+asn1@^0.2.4, asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
@@ -10363,7 +10399,7 @@ browserslist@4.14.2:
escalade "^3.0.2"
node-releases "^1.1.61"
-browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6:
+browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4.16.6:
version "4.18.1"
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.18.1.tgz#60d3920f25b6860eb917c6c7b185576f4d8b017f"
integrity sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ==
@@ -10645,25 +10681,6 @@ call-me-maybe@^1.0.1:
resolved "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b"
integrity sha1-JtII6onje1y95gJQoV8DHBak1ms=
-caller-callsite@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134"
- integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=
- dependencies:
- callsites "^2.0.0"
-
-caller-path@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4"
- integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=
- dependencies:
- caller-callsite "^2.0.0"
-
-callsites@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
- integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=
-
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
@@ -11307,7 +11324,7 @@ color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4:
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
-color-string@^1.5.2, color-string@^1.5.4, color-string@^1.6.0:
+color-string@^1.5.2, color-string@^1.6.0:
version "1.6.0"
resolved "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz#c3915f61fe267672cb7e1e064c9d692219f6c312"
integrity sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==
@@ -11323,14 +11340,6 @@ color@3.0.x:
color-convert "^1.9.1"
color-string "^1.5.2"
-color@^3.0.0:
- version "3.1.3"
- resolved "https://registry.npmjs.org/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e"
- integrity sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==
- dependencies:
- color-convert "^1.9.1"
- color-string "^1.5.4"
-
color@^4.0.1:
version "4.0.1"
resolved "https://registry.npmjs.org/color/-/color-4.0.1.tgz#21df44cd10245a91b1ccf5ba031609b0e10e7d67"
@@ -11339,6 +11348,11 @@ color@^4.0.1:
color-convert "^2.0.1"
color-string "^1.6.0"
+colord@^2.9.1:
+ version "2.9.1"
+ resolved "https://registry.npmjs.org/colord/-/colord-2.9.1.tgz#c961ea0efeb57c9f0f4834458f26cb9cc4a3f90e"
+ integrity sha512-4LBMSt09vR0uLnPVkOUBnmxgoaeN4ewRbx801wY/bXcltXfpR/G46OdWn96XpYmCWuYvO46aBZP4NgX8HpNAcw==
+
colorette@1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b"
@@ -11853,16 +11867,6 @@ cosmiconfig@7.0.0, cosmiconfig@^7.0.0:
path-type "^4.0.0"
yaml "^1.10.0"
-cosmiconfig@^5.0.0:
- version "5.2.1"
- resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
- integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==
- dependencies:
- import-fresh "^2.0.0"
- is-directory "^0.3.1"
- js-yaml "^3.13.1"
- parse-json "^4.0.0"
-
cosmiconfig@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982"
@@ -11884,6 +11888,13 @@ cp-file@^7.0.0:
nested-error-stacks "^2.0.0"
p-event "^4.1.0"
+cpu-features@0.0.2:
+ version "0.0.2"
+ resolved "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.2.tgz#9f636156f1155fd04bdbaa028bb3c2fbef3cea7a"
+ integrity sha512-/2yieBqvMcRj8McNzkycjW2v3OIUOibBfd2dLEJ0nWts8NobAxwiyw9phVNS6oDL8x8tz9F7uNVFEVpJncQpeA==
+ dependencies:
+ nan "^2.14.1"
+
cpy@^8.1.1:
version "8.1.1"
resolved "https://registry.npmjs.org/cpy/-/cpy-8.1.1.tgz#066ed4c6eaeed9577df96dae4db9438c1a90df62"
@@ -12052,17 +12063,11 @@ css-color-converter@^2.0.0:
color-name "^1.1.4"
css-unit-converter "^1.1.2"
-css-color-names@0.0.4, css-color-names@^0.0.4:
- version "0.0.4"
- resolved "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
- integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=
-
-css-declaration-sorter@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22"
- integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==
+css-declaration-sorter@^6.0.3:
+ version "6.1.3"
+ resolved "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.1.3.tgz#e9852e4cf940ba79f509d9425b137d1f94438dc2"
+ integrity sha512-SvjQjNRZgh4ULK1LDJ2AduPKUKxIqmtU7ZAyi47BTV+M90Qvxr9AB6lKlLbDUfXqI9IQeYA8LbAsCZPpJEV3aA==
dependencies:
- postcss "^7.0.1"
timsort "^0.3.0"
css-in-js-utils@^2.0.0:
@@ -12150,6 +12155,14 @@ css-tree@^1.1.2:
mdn-data "2.0.14"
source-map "^0.6.1"
+css-tree@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
+ integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
+ dependencies:
+ mdn-data "2.0.14"
+ source-map "^0.6.1"
+
css-unit-converter@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21"
@@ -12197,73 +12210,55 @@ cssfilter@0.0.10:
resolved "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz#c6d2672632a2e5c83e013e6864a42ce8defd20ae"
integrity sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=
-cssnano-preset-default@^4.0.7:
- version "4.0.7"
- resolved "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76"
- integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==
+cssnano-preset-default@^5.1.7:
+ version "5.1.7"
+ resolved "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.7.tgz#68c3ad1ec6a810482ec7d06b2d70fc34b6b0d70c"
+ integrity sha512-bWDjtTY+BOqrqBtsSQIbN0RLGD2Yr2CnecpP0ydHNafh9ZUEre8c8VYTaH9FEbyOt0eIfEUAYYk5zj92ioO8LA==
dependencies:
- css-declaration-sorter "^4.0.1"
- cssnano-util-raw-cache "^4.0.1"
- postcss "^7.0.0"
- postcss-calc "^7.0.1"
- postcss-colormin "^4.0.3"
- postcss-convert-values "^4.0.1"
- postcss-discard-comments "^4.0.2"
- postcss-discard-duplicates "^4.0.2"
- postcss-discard-empty "^4.0.1"
- postcss-discard-overridden "^4.0.1"
- postcss-merge-longhand "^4.0.11"
- postcss-merge-rules "^4.0.3"
- postcss-minify-font-values "^4.0.2"
- postcss-minify-gradients "^4.0.2"
- postcss-minify-params "^4.0.2"
- postcss-minify-selectors "^4.0.2"
- postcss-normalize-charset "^4.0.1"
- postcss-normalize-display-values "^4.0.2"
- postcss-normalize-positions "^4.0.2"
- postcss-normalize-repeat-style "^4.0.2"
- postcss-normalize-string "^4.0.2"
- postcss-normalize-timing-functions "^4.0.2"
- postcss-normalize-unicode "^4.0.1"
- postcss-normalize-url "^4.0.1"
- postcss-normalize-whitespace "^4.0.2"
- postcss-ordered-values "^4.1.2"
- postcss-reduce-initial "^4.0.3"
- postcss-reduce-transforms "^4.0.2"
- postcss-svgo "^4.0.2"
- postcss-unique-selectors "^4.0.1"
+ css-declaration-sorter "^6.0.3"
+ cssnano-utils "^2.0.1"
+ postcss-calc "^8.0.0"
+ postcss-colormin "^5.2.1"
+ postcss-convert-values "^5.0.2"
+ postcss-discard-comments "^5.0.1"
+ postcss-discard-duplicates "^5.0.1"
+ postcss-discard-empty "^5.0.1"
+ postcss-discard-overridden "^5.0.1"
+ postcss-merge-longhand "^5.0.4"
+ postcss-merge-rules "^5.0.3"
+ postcss-minify-font-values "^5.0.1"
+ postcss-minify-gradients "^5.0.3"
+ postcss-minify-params "^5.0.2"
+ postcss-minify-selectors "^5.1.0"
+ postcss-normalize-charset "^5.0.1"
+ postcss-normalize-display-values "^5.0.1"
+ postcss-normalize-positions "^5.0.1"
+ postcss-normalize-repeat-style "^5.0.1"
+ postcss-normalize-string "^5.0.1"
+ postcss-normalize-timing-functions "^5.0.1"
+ postcss-normalize-unicode "^5.0.1"
+ postcss-normalize-url "^5.0.3"
+ postcss-normalize-whitespace "^5.0.1"
+ postcss-ordered-values "^5.0.2"
+ postcss-reduce-initial "^5.0.1"
+ postcss-reduce-transforms "^5.0.1"
+ postcss-svgo "^5.0.3"
+ postcss-unique-selectors "^5.0.2"
-cssnano-util-get-arguments@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f"
- integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=
+cssnano-utils@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-2.0.1.tgz#8660aa2b37ed869d2e2f22918196a9a8b6498ce2"
+ integrity sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ==
-cssnano-util-get-match@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d"
- integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=
-
-cssnano-util-raw-cache@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282"
- integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==
+cssnano@^5.0.1:
+ version "5.0.11"
+ resolved "https://registry.npmjs.org/cssnano/-/cssnano-5.0.11.tgz#743397a05e04cb87e9df44b7659850adfafc3646"
+ integrity sha512-5SHM31NAAe29jvy0MJqK40zZ/8dGlnlzcfHKw00bWMVFp8LWqtuyPSFwbaoIoxvt71KWJOfg8HMRGrBR3PExCg==
dependencies:
- postcss "^7.0.0"
-
-cssnano-util-same-parent@^4.0.0:
- version "4.0.1"
- resolved "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3"
- integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==
-
-cssnano@^4.1.10:
- version "4.1.10"
- resolved "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2"
- integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==
- dependencies:
- cosmiconfig "^5.0.0"
- cssnano-preset-default "^4.0.7"
- is-resolvable "^1.0.0"
- postcss "^7.0.0"
+ cssnano-preset-default "^5.1.7"
+ is-resolvable "^1.1.0"
+ lilconfig "^2.0.3"
+ yaml "^1.10.2"
csso@^4.0.2:
version "4.0.2"
@@ -12272,6 +12267,13 @@ csso@^4.0.2:
dependencies:
css-tree "1.0.0-alpha.37"
+csso@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529"
+ integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==
+ dependencies:
+ css-tree "^1.1.2"
+
cssom@^0.4.4:
version "0.4.4"
resolved "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10"
@@ -13078,27 +13080,27 @@ dns-txt@^2.0.2:
dependencies:
buffer-indexof "^1.0.0"
-docker-compose@^0.23.10:
- version "0.23.12"
- resolved "https://registry.npmjs.org/docker-compose/-/docker-compose-0.23.12.tgz#fa883b98be08f6926143d06bf9e522ef7ed3210c"
- integrity sha512-KFbSMqQBuHjTGZGmYDOCO0L4SaML3BsWTId5oSUyaBa22vALuFHNv+UdDWs3HcMylHWKsxCbLB7hnM/nCosWZw==
+docker-compose@^0.23.13:
+ version "0.23.13"
+ resolved "https://registry.npmjs.org/docker-compose/-/docker-compose-0.23.13.tgz#77d37bd05b6a966345f631e6d05e961c79514f06"
+ integrity sha512-/9fYC4g3AO+qsqxIZhmbVnFvJJPcYEV2yJbAPPXH+6AytU3urIY8lUAXOlvY8sl4u25pdKu1JrOfAmWC7lJDJg==
dependencies:
yaml "^1.10.2"
docker-modem@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.0.tgz#cb912ad8daed42f858269fb3be6944df281ec12d"
- integrity sha512-WwFajJ8I5geZ/dDZ5FDMDA6TBkWa76xWwGIGw8uzUjNUGCN0to83wJ8Oi1AxrJTC0JBn+7fvIxUctnawtlwXeg==
+ version "3.0.3"
+ resolved "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.3.tgz#ac4bb1f32f81ac2e7120c5e99a068fab2458a32f"
+ integrity sha512-Tgkn2a+yiNP9FoZgMa/D9Wk+D2Db///0KOyKSYZRJa8w4+DzKyzQMkczKSdR/adQ0x46BOpeNkoyEOKjPhCzjw==
dependencies:
debug "^4.1.1"
readable-stream "^3.5.0"
split-ca "^1.0.1"
- ssh2 "^0.8.7"
+ ssh2 "^1.4.0"
-dockerode@^3.2.1:
- version "3.3.0"
- resolved "https://registry.npmjs.org/dockerode/-/dockerode-3.3.0.tgz#bedaf48ef9fa9124275a54a9881a92374c51008e"
- integrity sha512-St08lfOjpYCOXEM8XA0VLu3B3hRjtddODphNW5GFoA0AS3JHgoPQKOz0Qmdzg3P+hUPxhb02g1o1Cu1G+U3lRg==
+dockerode@^3.3.1:
+ version "3.3.1"
+ resolved "https://registry.npmjs.org/dockerode/-/dockerode-3.3.1.tgz#74f66e239e092e7910e2beae6322d35c44b08cdc"
+ integrity sha512-AS2mr8Lp122aa5n6d99HkuTNdRV1wkkhHwBdcnY6V0+28D3DSYwhxAk85/mM9XwD3RMliTxyr63iuvn5ZblFYQ==
dependencies:
docker-modem "^3.0.0"
tar-fs "~2.0.1"
@@ -13130,6 +13132,11 @@ dom-accessibility-api@^0.5.4, dom-accessibility-api@^0.5.6:
resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.6.tgz#3f5d43b52c7a3bd68b5fb63fa47b4e4c1fdf65a9"
integrity sha512-DplGLZd8L1lN64jlT27N9TVSESFR5STaEJvX+thCby7fuCHonfPpAlodYc3vuUYbDuDec5w8AMP7oCM5TWFsqw==
+dom-accessibility-api@^0.5.9:
+ version "0.5.10"
+ resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.10.tgz#caa6d08f60388d0bb4539dd75fe458a9a1d0014c"
+ integrity sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==
+
dom-converter@^0.2.0:
version "0.2.0"
resolved "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768"
@@ -15430,6 +15437,18 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, gl
once "^1.3.0"
path-is-absolute "^1.0.0"
+glob@^7.2.0:
+ version "7.2.0"
+ resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
+ integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.0.4"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
global-dirs@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz#acdf3bb6685bcd55cb35e8a052266569e9469201"
@@ -16011,7 +16030,7 @@ has-yarn@^2.1.0:
resolved "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77"
integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==
-has@^1.0.0, has@^1.0.3:
+has@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
@@ -16135,11 +16154,6 @@ helmet@^4.0.0:
resolved "https://registry.npmjs.org/helmet/-/helmet-4.4.1.tgz#a17e1444d81d7a83ddc6e6f9bc6e2055b994efe7"
integrity sha512-G8tp0wUMI7i8wkMk2xLcEvESg5PiCitFMYgGRc/PwULB0RVhTP5GFdxOwvJwp9XVha8CuS8mnhmE8I/8dx/pbw==
-hex-color-regex@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
- integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
-
highlight.js@^10.1.0, highlight.js@^10.1.1, highlight.js@^10.4.1, highlight.js@^10.6.0:
version "10.7.2"
resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz#89319b861edc66c48854ed1e6da21ea89f847360"
@@ -16212,21 +16226,6 @@ hpagent@^0.1.1:
resolved "https://registry.npmjs.org/hpagent/-/hpagent-0.1.2.tgz#cab39c66d4df2d4377dbd212295d878deb9bdaa9"
integrity sha512-ePqFXHtSQWAFXYmj+JtOTHr84iNrII4/QRlAAPPE+zqnKy4xJo7Ie1Y4kC7AdB+LxLxSTTzBMASsEcy0q8YyvQ==
-hsl-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e"
- integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=
-
-hsla-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38"
- integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg=
-
-html-comment-regex@^1.1.0:
- version "1.1.2"
- resolved "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7"
- integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==
-
html-encoding-sniffer@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"
@@ -16600,14 +16599,6 @@ import-cwd@^3.0.0:
dependencies:
import-from "^3.0.0"
-import-fresh@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546"
- integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY=
- dependencies:
- caller-path "^2.0.0"
- resolve-from "^3.0.0"
-
import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1:
version "3.2.1"
resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66"
@@ -16877,10 +16868,10 @@ ipaddr.js@^2.0.1:
resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0"
integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==
-is-absolute-url@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6"
- integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=
+is-absolute-url@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698"
+ integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==
is-absolute@^1.0.0:
version "1.0.0"
@@ -17000,18 +16991,6 @@ is-ci@^3.0.0:
dependencies:
ci-info "^3.1.1"
-is-color-stop@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345"
- integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=
- dependencies:
- css-color-names "^0.0.4"
- hex-color-regex "^1.1.0"
- hsl-regex "^1.0.0"
- hsla-regex "^1.0.0"
- rgb-regex "^1.0.1"
- rgba-regex "^1.0.0"
-
is-core-module@^2.1.0, is-core-module@^2.2.0:
version "2.4.0"
resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1"
@@ -17066,11 +17045,6 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2:
is-data-descriptor "^1.0.0"
kind-of "^6.0.2"
-is-directory@^0.3.1:
- version "0.3.1"
- resolved "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
- integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=
-
is-docker@^2.0.0, is-docker@^2.1.1:
version "2.2.1"
resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
@@ -17384,7 +17358,7 @@ is-relative@^1.0.0:
dependencies:
is-unc-path "^1.0.0"
-is-resolvable@^1.0.0:
+is-resolvable@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==
@@ -17440,13 +17414,6 @@ is-subdir@^1.1.1:
dependencies:
better-path-resolve "1.0.0"
-is-svg@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75"
- integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==
- dependencies:
- html-comment-regex "^1.1.0"
-
is-symbol@^1.0.2, is-symbol@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937"
@@ -18515,10 +18482,10 @@ jsonpath-plus@^5.0.7:
resolved "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-5.1.0.tgz#2fc4b2e461950626c98525425a3a3518b85af6c3"
integrity sha512-890w2Pjtj0iswAxalRlt2kHthi6HKrXEfZcn+ZNZptv7F3rUGIeDuZo+C+h4vXBHLEsVjJrHeCm35nYeZLzSBQ==
-jsonpointer@^4.0.1:
- version "4.1.0"
- resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.1.0.tgz#501fb89986a2389765ba09e6053299ceb4f2c2cc"
- integrity sha512-CXcRvMyTlnR53xMcKnuMzfCA5i/nfblTnnr74CZb6C4vG39eu6w51t7nKmU5MfLfbTgGItliNyjO/ciNPDqClg==
+jsonpointer@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.0.tgz#f802669a524ec4805fa7389eadbc9921d5dc8072"
+ integrity sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg==
jsonschema@^1.2.6:
version "1.4.0"
@@ -18969,6 +18936,11 @@ libnpmpublish@^4.0.0:
semver "^7.1.3"
ssri "^8.0.0"
+lilconfig@^2.0.3:
+ version "2.0.4"
+ resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz#f4507d043d7058b380b6a8f5cb7bcd4b34cee082"
+ integrity sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==
+
lines-and-columns@^1.1.6:
version "1.1.6"
resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
@@ -20515,6 +20487,11 @@ mime@^2.2.0, mime@^2.4.4, mime@^2.4.6:
resolved "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe"
integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==
+mime@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7"
+ integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==
+
mimic-fn@^1.0.0:
version "1.2.0"
resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
@@ -20711,10 +20688,10 @@ mixin-object@^2.0.1:
for-in "^0.1.3"
is-extendable "^0.1.1"
-mixme@^0.3.1:
- version "0.3.5"
- resolved "https://registry.npmjs.org/mixme/-/mixme-0.3.5.tgz#304652cdaf24a3df0487205e61ac6162c6906ddd"
- integrity sha512-SyV9uPETRig5ZmYev0ANfiGeB+g6N2EnqqEfBbCGmmJ6MgZ3E4qv5aPbnHVdZ60KAHHXV+T3sXopdrnIXQdmjQ==
+mixme@^0.5.1:
+ version "0.5.4"
+ resolved "https://registry.npmjs.org/mixme/-/mixme-0.5.4.tgz#8cb3bd0cd32a513c161bf1ca99d143f0bcf2eff3"
+ integrity sha512-3KYa4m4Vlqx98GPdOHghxSdNtTvcP8E0kkaJ5Dlh+h2DRzF7zpuVVcA8B0QpKd11YJeP9QQ7ASkKzOeu195Wzw==
mkdirp-classic@^0.5.2:
version "0.5.2"
@@ -20928,6 +20905,11 @@ nan@^2.12.1, nan@^2.14.0:
resolved "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
+nan@^2.14.1, nan@^2.15.0:
+ version "2.15.0"
+ resolved "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
+ integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
+
nano-css@^5.1.0, nano-css@^5.3.1:
version "5.3.1"
resolved "https://registry.npmjs.org/nano-css/-/nano-css-5.3.1.tgz#b709383e07ad3be61f64edffacb9d98250b87a1f"
@@ -21324,7 +21306,7 @@ normalize-range@^0.1.2:
resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=
-normalize-url@^3.0.0, normalize-url@^3.3.0:
+normalize-url@^3.3.0:
version "3.3.0"
resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559"
integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==
@@ -21334,6 +21316,11 @@ normalize-url@^4.1.0:
resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a"
integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==
+normalize-url@^6.0.1:
+ version "6.1.0"
+ resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
+ integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
+
npm-bundled@^1.0.1, npm-bundled@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b"
@@ -22783,61 +22770,50 @@ posix-character-classes@^0.1.0:
resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
-postcss-calc@^7.0.1:
- version "7.0.2"
- resolved "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.2.tgz#504efcd008ca0273120568b0792b16cdcde8aac1"
- integrity sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ==
+postcss-calc@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.0.0.tgz#a05b87aacd132740a5db09462a3612453e5df90a"
+ integrity sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g==
dependencies:
- postcss "^7.0.27"
postcss-selector-parser "^6.0.2"
postcss-value-parser "^4.0.2"
-postcss-colormin@^4.0.3:
- version "4.0.3"
- resolved "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381"
- integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==
+postcss-colormin@^5.2.1:
+ version "5.2.1"
+ resolved "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.2.1.tgz#6e444a806fd3c578827dbad022762df19334414d"
+ integrity sha512-VVwMrEYLcHYePUYV99Ymuoi7WhKrMGy/V9/kTS0DkCoJYmmjdOMneyhzYUxcNgteKDVbrewOkSM7Wje/MFwxzA==
dependencies:
- browserslist "^4.0.0"
- color "^3.0.0"
- has "^1.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
+ browserslist "^4.16.6"
+ caniuse-api "^3.0.0"
+ colord "^2.9.1"
+ postcss-value-parser "^4.1.0"
-postcss-convert-values@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f"
- integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==
+postcss-convert-values@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.2.tgz#879b849dc3677c7d6bc94b6a2c1a3f0808798059"
+ integrity sha512-KQ04E2yadmfa1LqXm7UIDwW1ftxU/QWZmz6NKnHnUvJ3LEYbbcX6i329f/ig+WnEByHegulocXrECaZGLpL8Zg==
dependencies:
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
+ postcss-value-parser "^4.1.0"
-postcss-discard-comments@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033"
- integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==
- dependencies:
- postcss "^7.0.0"
+postcss-discard-comments@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz#9eae4b747cf760d31f2447c27f0619d5718901fe"
+ integrity sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==
-postcss-discard-duplicates@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb"
- integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==
- dependencies:
- postcss "^7.0.0"
+postcss-discard-duplicates@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz#68f7cc6458fe6bab2e46c9f55ae52869f680e66d"
+ integrity sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==
-postcss-discard-empty@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765"
- integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==
- dependencies:
- postcss "^7.0.0"
+postcss-discard-empty@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz#ee136c39e27d5d2ed4da0ee5ed02bc8a9f8bf6d8"
+ integrity sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==
-postcss-discard-overridden@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57"
- integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==
- dependencies:
- postcss "^7.0.0"
+postcss-discard-overridden@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz#454b41f707300b98109a75005ca4ab0ff2743ac6"
+ integrity sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q==
postcss-flexbugs-fixes@^4.2.1:
version "4.2.1"
@@ -22865,67 +22841,57 @@ postcss-loader@^4.2.0:
schema-utils "^3.0.0"
semver "^7.3.4"
-postcss-merge-longhand@^4.0.11:
- version "4.0.11"
- resolved "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24"
- integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==
+postcss-merge-longhand@^5.0.4:
+ version "5.0.4"
+ resolved "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.4.tgz#41f4f3270282ea1a145ece078b7679f0cef21c32"
+ integrity sha512-2lZrOVD+d81aoYkZDpWu6+3dTAAGkCKbV5DoRhnIR7KOULVrI/R7bcMjhrH9KTRy6iiHKqmtG+n/MMj1WmqHFw==
dependencies:
- css-color-names "0.0.4"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
- stylehacks "^4.0.0"
+ postcss-value-parser "^4.1.0"
+ stylehacks "^5.0.1"
-postcss-merge-rules@^4.0.3:
- version "4.0.3"
- resolved "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650"
- integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==
+postcss-merge-rules@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.3.tgz#b5cae31f53129812a77e3eb1eeee448f8cf1a1db"
+ integrity sha512-cEKTMEbWazVa5NXd8deLdCnXl+6cYG7m2am+1HzqH0EnTdy8fRysatkaXb2dEnR+fdaDxTvuZ5zoBdv6efF6hg==
dependencies:
- browserslist "^4.0.0"
+ browserslist "^4.16.6"
caniuse-api "^3.0.0"
- cssnano-util-same-parent "^4.0.0"
- postcss "^7.0.0"
- postcss-selector-parser "^3.0.0"
- vendors "^1.0.0"
+ cssnano-utils "^2.0.1"
+ postcss-selector-parser "^6.0.5"
-postcss-minify-font-values@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6"
- integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==
+postcss-minify-font-values@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz#a90cefbfdaa075bd3dbaa1b33588bb4dc268addf"
+ integrity sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA==
dependencies:
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
+ postcss-value-parser "^4.1.0"
-postcss-minify-gradients@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471"
- integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==
+postcss-minify-gradients@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.3.tgz#f970a11cc71e08e9095e78ec3a6b34b91c19550e"
+ integrity sha512-Z91Ol22nB6XJW+5oe31+YxRsYooxOdFKcbOqY/V8Fxse1Y3vqlNRpi1cxCqoACZTQEhl+xvt4hsbWiV5R+XI9Q==
dependencies:
- cssnano-util-get-arguments "^4.0.0"
- is-color-stop "^1.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
+ colord "^2.9.1"
+ cssnano-utils "^2.0.1"
+ postcss-value-parser "^4.1.0"
-postcss-minify-params@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874"
- integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==
+postcss-minify-params@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.2.tgz#1b644da903473fbbb18fbe07b8e239883684b85c"
+ integrity sha512-qJAPuBzxO1yhLad7h2Dzk/F7n1vPyfHfCCh5grjGfjhi1ttCnq4ZXGIW77GSrEbh9Hus9Lc/e/+tB4vh3/GpDg==
dependencies:
- alphanum-sort "^1.0.0"
- browserslist "^4.0.0"
- cssnano-util-get-arguments "^4.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
- uniqs "^2.0.0"
+ alphanum-sort "^1.0.2"
+ browserslist "^4.16.6"
+ cssnano-utils "^2.0.1"
+ postcss-value-parser "^4.1.0"
-postcss-minify-selectors@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8"
- integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==
+postcss-minify-selectors@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz#4385c845d3979ff160291774523ffa54eafd5a54"
+ integrity sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og==
dependencies:
- alphanum-sort "^1.0.0"
- has "^1.0.0"
- postcss "^7.0.0"
- postcss-selector-parser "^3.0.0"
+ alphanum-sort "^1.0.2"
+ postcss-selector-parser "^6.0.5"
postcss-modules-extract-imports@^2.0.0:
version "2.0.0"
@@ -23002,124 +22968,96 @@ postcss-modules@^4.0.0:
postcss-modules-values "^4.0.0"
string-hash "^1.1.1"
-postcss-normalize-charset@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4"
- integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==
- dependencies:
- postcss "^7.0.0"
+postcss-normalize-charset@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz#121559d1bebc55ac8d24af37f67bd4da9efd91d0"
+ integrity sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==
-postcss-normalize-display-values@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a"
- integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==
+postcss-normalize-display-values@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz#62650b965981a955dffee83363453db82f6ad1fd"
+ integrity sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ==
dependencies:
- cssnano-util-get-match "^4.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
+ cssnano-utils "^2.0.1"
+ postcss-value-parser "^4.1.0"
-postcss-normalize-positions@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f"
- integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==
+postcss-normalize-positions@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz#868f6af1795fdfa86fbbe960dceb47e5f9492fe5"
+ integrity sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg==
dependencies:
- cssnano-util-get-arguments "^4.0.0"
- has "^1.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
+ postcss-value-parser "^4.1.0"
-postcss-normalize-repeat-style@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c"
- integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==
+postcss-normalize-repeat-style@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz#cbc0de1383b57f5bb61ddd6a84653b5e8665b2b5"
+ integrity sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w==
dependencies:
- cssnano-util-get-arguments "^4.0.0"
- cssnano-util-get-match "^4.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
+ cssnano-utils "^2.0.1"
+ postcss-value-parser "^4.1.0"
-postcss-normalize-string@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c"
- integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==
+postcss-normalize-string@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz#d9eafaa4df78c7a3b973ae346ef0e47c554985b0"
+ integrity sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA==
dependencies:
- has "^1.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
+ postcss-value-parser "^4.1.0"
-postcss-normalize-timing-functions@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9"
- integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==
+postcss-normalize-timing-functions@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz#8ee41103b9130429c6cbba736932b75c5e2cb08c"
+ integrity sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q==
dependencies:
- cssnano-util-get-match "^4.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
+ cssnano-utils "^2.0.1"
+ postcss-value-parser "^4.1.0"
-postcss-normalize-unicode@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb"
- integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==
+postcss-normalize-unicode@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz#82d672d648a411814aa5bf3ae565379ccd9f5e37"
+ integrity sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA==
dependencies:
- browserslist "^4.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
+ browserslist "^4.16.0"
+ postcss-value-parser "^4.1.0"
-postcss-normalize-url@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1"
- integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==
+postcss-normalize-url@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.3.tgz#42eca6ede57fe69075fab0f88ac8e48916ef931c"
+ integrity sha512-qWiUMbvkRx3kc1Dp5opzUwc7MBWZcSDK2yofCmdvFBCpx+zFPkxBC1FASQ59Pt+flYfj/nTZSkmF56+XG5elSg==
dependencies:
- is-absolute-url "^2.0.0"
- normalize-url "^3.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
+ is-absolute-url "^3.0.3"
+ normalize-url "^6.0.1"
+ postcss-value-parser "^4.1.0"
-postcss-normalize-whitespace@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82"
- integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==
+postcss-normalize-whitespace@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz#b0b40b5bcac83585ff07ead2daf2dcfbeeef8e9a"
+ integrity sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA==
dependencies:
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
+ postcss-value-parser "^4.1.0"
-postcss-ordered-values@^4.1.2:
- version "4.1.2"
- resolved "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee"
- integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==
+postcss-ordered-values@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.2.tgz#1f351426977be00e0f765b3164ad753dac8ed044"
+ integrity sha512-8AFYDSOYWebJYLyJi3fyjl6CqMEG/UVworjiyK1r573I56kb3e879sCJLGvR3merj+fAdPpVplXKQZv+ey6CgQ==
dependencies:
- cssnano-util-get-arguments "^4.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
+ cssnano-utils "^2.0.1"
+ postcss-value-parser "^4.1.0"
-postcss-reduce-initial@^4.0.3:
- version "4.0.3"
- resolved "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df"
- integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==
+postcss-reduce-initial@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz#9d6369865b0f6f6f6b165a0ef5dc1a4856c7e946"
+ integrity sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw==
dependencies:
- browserslist "^4.0.0"
+ browserslist "^4.16.0"
caniuse-api "^3.0.0"
- has "^1.0.0"
- postcss "^7.0.0"
-postcss-reduce-transforms@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29"
- integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==
+postcss-reduce-transforms@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz#93c12f6a159474aa711d5269923e2383cedcf640"
+ integrity sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA==
dependencies:
- cssnano-util-get-match "^4.0.0"
- has "^1.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
-
-postcss-selector-parser@^3.0.0:
- version "3.1.2"
- resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz#b310f5c4c0fdaf76f94902bbaa30db6aa84f5270"
- integrity sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==
- dependencies:
- dot-prop "^5.2.0"
- indexes-of "^1.0.1"
- uniq "^1.0.1"
+ cssnano-utils "^2.0.1"
+ postcss-value-parser "^4.1.0"
postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4:
version "6.0.4"
@@ -23131,36 +23069,36 @@ postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector
uniq "^1.0.1"
util-deprecate "^1.0.2"
-postcss-svgo@^4.0.2:
- version "4.0.2"
- resolved "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258"
- integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==
+postcss-selector-parser@^6.0.5:
+ version "6.0.6"
+ resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea"
+ integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==
dependencies:
- is-svg "^3.0.0"
- postcss "^7.0.0"
- postcss-value-parser "^3.0.0"
- svgo "^1.0.0"
+ cssesc "^3.0.0"
+ util-deprecate "^1.0.2"
-postcss-unique-selectors@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac"
- integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==
+postcss-svgo@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.3.tgz#d945185756e5dfaae07f9edb0d3cae7ff79f9b30"
+ integrity sha512-41XZUA1wNDAZrQ3XgWREL/M2zSw8LJPvb5ZWivljBsUQAGoEKMYm6okHsTjJxKYI4M75RQEH4KYlEM52VwdXVA==
dependencies:
- alphanum-sort "^1.0.0"
- postcss "^7.0.0"
- uniqs "^2.0.0"
+ postcss-value-parser "^4.1.0"
+ svgo "^2.7.0"
-postcss-value-parser@^3.0.0:
- version "3.3.1"
- resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
- integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
+postcss-unique-selectors@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.2.tgz#5d6893daf534ae52626708e0d62250890108c0c1"
+ integrity sha512-w3zBVlrtZm7loQWRPVC0yjUwwpty7OM6DnEHkxcSQXO1bMS3RJ+JUS5LFMSDZHJcvGsRwhZinCWVqn8Kej4EDA==
+ dependencies:
+ alphanum-sort "^1.0.2"
+ postcss-selector-parser "^6.0.5"
postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
-"postcss@5 - 7", postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6:
+"postcss@5 - 7", postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6:
version "7.0.32"
resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d"
integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==
@@ -23311,6 +23249,16 @@ pretty-format@^26.0.0, pretty-format@^26.6.2:
ansi-styles "^4.0.0"
react-is "^17.0.1"
+pretty-format@^27.0.2:
+ version "27.3.1"
+ resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz#7e9486365ccdd4a502061fa761d3ab9ca1b78df5"
+ integrity sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==
+ dependencies:
+ "@jest/types" "^27.2.5"
+ ansi-regex "^5.0.1"
+ ansi-styles "^5.0.0"
+ react-is "^17.0.1"
+
pretty-hrtime@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1"
@@ -25036,11 +24984,6 @@ resolve-from@5.0.0, resolve-from@^5.0.0:
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
-resolve-from@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
- integrity sha1-six699nWiBvItuZTM17rywoYh0g=
-
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
@@ -25152,16 +25095,6 @@ rfc4648@^1.3.0:
resolved "https://registry.npmjs.org/rfc4648/-/rfc4648-1.4.0.tgz#c75b2856ad2e2d588b6ddb985d556f1f7f2a2abd"
integrity sha512-3qIzGhHlMHA6PoT6+cdPKZ+ZqtxkIvg8DZGKA5z6PQ33/uuhoJ+Ws/D/J9rXW6gXodgH8QYlz2UCl+sdUDmNIg==
-rgb-regex@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1"
- integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE=
-
-rgba-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3"
- integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=
-
rifm@^0.7.0:
version "0.7.0"
resolved "https://registry.npmjs.org/rifm/-/rifm-0.7.0.tgz#debe951a9c83549ca6b33e5919f716044c2230be"
@@ -25229,13 +25162,13 @@ rollup-plugin-peer-deps-external@^2.2.2:
integrity sha512-AWdukIM1+k5JDdAqV/Cxd+nejvno2FVLVeZ74NKggm3Q5s9cbbcOgUPGdbxPi4BXu7xGaZ8HG12F+thImYu/0g==
rollup-plugin-postcss@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/rollup-plugin-postcss/-/rollup-plugin-postcss-4.0.0.tgz#2131fb6db0d5dce01a37235e4f6ad4523c681cea"
- integrity sha512-OQzT+YspV01/6dxfyEw8lBO2px3hyL8Xn+k2QGctL7V/Yx2Z1QaMKdYVslP1mqv7RsKt6DROIlnbpmgJ3yxf6g==
+ version "4.0.2"
+ resolved "https://registry.npmjs.org/rollup-plugin-postcss/-/rollup-plugin-postcss-4.0.2.tgz#15e9462f39475059b368ce0e49c800fa4b1f7050"
+ integrity sha512-05EaY6zvZdmvPUDi3uCcAQoESDcYnv8ogJJQRp6V5kZ6J6P7uAVJlrTZcaaA20wTH527YTnKfkAoPxWI/jPp4w==
dependencies:
chalk "^4.1.0"
concat-with-sourcemaps "^1.1.0"
- cssnano "^4.1.10"
+ cssnano "^5.0.1"
import-cwd "^3.0.0"
p-queue "^6.6.2"
pify "^5.0.0"
@@ -25579,10 +25512,12 @@ serialize-error@^8.0.1, serialize-error@^8.1.0:
dependencies:
type-fest "^0.20.2"
-serialize-javascript@^2.1.2:
- version "2.1.2"
- resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61"
- integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==
+serialize-javascript@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa"
+ integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==
+ dependencies:
+ randombytes "^2.1.0"
serialize-javascript@^5.0.1:
version "5.0.1"
@@ -26208,29 +26143,24 @@ sqlstring@^2.3.2:
resolved "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.2.tgz#cdae7169389a1375b18e885f2e60b3e460809514"
integrity sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg==
-ssh-remote-port-forward@^1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/ssh-remote-port-forward/-/ssh-remote-port-forward-1.0.3.tgz#074cebed6d54a42ce4659d6aa24987e433ff5fef"
- integrity sha512-PJ6qGFmB6n0iMCQIp+qzx8qVUE5cgacopvEh63t3NJjEQHOaza/JT9zywmmVlaol/eGtCmpvBXx2A03ih1Y+xg==
+ssh-remote-port-forward@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.npmjs.org/ssh-remote-port-forward/-/ssh-remote-port-forward-1.0.4.tgz#72b0c5df8ec27ca300c75805cc6b266dee07e298"
+ integrity sha512-x0LV1eVDwjf1gmG7TTnfqIzf+3VPRz7vrNIjX6oYLbeCrf/PeVY6hkT68Mg+q02qXxQhrLjB0jfgvhevoCRmLQ==
dependencies:
- "@types/ssh2" "^0.5.45"
- ssh2 "^0.8.9"
+ "@types/ssh2" "^0.5.48"
+ ssh2 "^1.4.0"
-ssh2-streams@~0.4.10:
- version "0.4.10"
- resolved "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.4.10.tgz#48ef7e8a0e39d8f2921c30521d56dacb31d23a34"
- integrity sha512-8pnlMjvnIZJvmTzUIIA5nT4jr2ZWNNVHwyXfMGdRJbug9TpI3kd99ffglgfSWqujVv/0gxwMsDn9j9RVst8yhQ==
+ssh2@^1.4.0:
+ version "1.5.0"
+ resolved "https://registry.npmjs.org/ssh2/-/ssh2-1.5.0.tgz#4dc559ba98a1cbb420e8d42998dfe35d0eda92bc"
+ integrity sha512-iUmRkhH9KGeszQwDW7YyyqjsMTf4z+0o48Cp4xOwlY5LjtbIAvyd3fwnsoUZW/hXmTCRA3yt7S/Jb9uVjErVlA==
dependencies:
- asn1 "~0.2.0"
+ asn1 "^0.2.4"
bcrypt-pbkdf "^1.0.2"
- streamsearch "~0.1.2"
-
-ssh2@^0.8.7, ssh2@^0.8.9:
- version "0.8.9"
- resolved "https://registry.npmjs.org/ssh2/-/ssh2-0.8.9.tgz#54da3a6c4ba3daf0d8477a538a481326091815f3"
- integrity sha512-GmoNPxWDMkVpMFa9LVVzQZHF6EW3WKmBwL+4/GeILf2hFmix5Isxm7Amamo8o7bHiU0tC+wXsGcUXOxp8ChPaw==
- dependencies:
- ssh2-streams "~0.4.10"
+ optionalDependencies:
+ cpu-features "0.0.2"
+ nan "^2.15.0"
sshpk@^1.7.0:
version "1.16.1"
@@ -26424,21 +26354,14 @@ stream-shift@^1.0.0:
resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
-stream-to-array@^2.3.0:
- version "2.3.0"
- resolved "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz#bbf6b39f5f43ec30bc71babcb37557acecf34353"
- integrity sha1-u/azn19D7DC8cbq8s3VXrOzzQ1M=
- dependencies:
- any-promise "^1.1.0"
-
stream-transform@^2.0.1:
- version "2.0.2"
- resolved "https://registry.npmjs.org/stream-transform/-/stream-transform-2.0.2.tgz#3cb7a14c802eb39bc40caaab0535e584f3a65caf"
- integrity sha512-J+D5jWPF/1oX+r9ZaZvEXFbu7znjxSkbNAHJ9L44bt/tCVuOEWZlDqU9qJk7N2xBU1S+K2DPpSKeR/MucmCA1Q==
+ version "2.1.3"
+ resolved "https://registry.npmjs.org/stream-transform/-/stream-transform-2.1.3.tgz#a1c3ecd72ddbf500aa8d342b0b9df38f5aa598e3"
+ integrity sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==
dependencies:
- mixme "^0.3.1"
+ mixme "^0.5.1"
-streamsearch@0.1.2, streamsearch@~0.1.2:
+streamsearch@0.1.2:
version "0.1.2"
resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
@@ -26731,14 +26654,13 @@ style-to-object@0.3.0, style-to-object@^0.3.0:
dependencies:
inline-style-parser "0.1.1"
-stylehacks@^4.0.0:
- version "4.0.3"
- resolved "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"
- integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==
+stylehacks@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.1.tgz#323ec554198520986806388c7fdaebc38d2c06fb"
+ integrity sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA==
dependencies:
- browserslist "^4.0.0"
- postcss "^7.0.0"
- postcss-selector-parser "^3.0.0"
+ browserslist "^4.16.0"
+ postcss-selector-parser "^6.0.4"
stylis@^4.0.6:
version "4.0.7"
@@ -26870,7 +26792,7 @@ svg-parser@^2.0.2:
resolved "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5"
integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==
-svgo@^1.0.0, svgo@^1.2.2:
+svgo@^1.2.2:
version "1.3.2"
resolved "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167"
integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==
@@ -26889,6 +26811,19 @@ svgo@^1.0.0, svgo@^1.2.2:
unquote "~1.1.1"
util.promisify "~1.0.0"
+svgo@^2.7.0:
+ version "2.8.0"
+ resolved "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24"
+ integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==
+ dependencies:
+ "@trysound/sax" "0.2.0"
+ commander "^7.2.0"
+ css-select "^4.1.3"
+ css-tree "^1.1.3"
+ csso "^4.2.0"
+ picocolors "^1.0.0"
+ stable "^0.1.8"
+
swagger-client@3.16.1, swagger-client@^3.16.1:
version "3.16.1"
resolved "https://registry.npmjs.org/swagger-client/-/swagger-client-3.16.1.tgz#df86c9d407ab52c00cb356e714b0ec732bb3ad40"
@@ -27172,15 +27107,15 @@ terser-webpack-plugin@*, terser-webpack-plugin@^5.1.3:
terser "^5.7.2"
terser-webpack-plugin@^1.4.3:
- version "1.4.3"
- resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c"
- integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==
+ version "1.4.5"
+ resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b"
+ integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==
dependencies:
cacache "^12.0.2"
find-cache-dir "^2.1.0"
is-wsl "^1.1.0"
schema-utils "^1.0.0"
- serialize-javascript "^2.1.2"
+ serialize-javascript "^4.0.0"
source-map "^0.6.1"
terser "^4.1.2"
webpack-sources "^1.4.0"
@@ -27237,23 +27172,22 @@ test-exclude@^6.0.0:
glob "^7.1.4"
minimatch "^3.0.4"
-testcontainers@^7.10.0:
- version "7.11.1"
- resolved "https://registry.npmjs.org/testcontainers/-/testcontainers-7.11.1.tgz#b3810badf79433ba02f210683eec1a1c488c107d"
- integrity sha512-lfZeys5bLkADjOaoXfQy0V0+G8sGKr8ESANz7MhSVBwC+OTTxkP3+FVwP48bW4mwRcQ4Hojwbfw10OYT80QZmQ==
+testcontainers@^7.23.0:
+ version "7.23.0"
+ resolved "https://registry.npmjs.org/testcontainers/-/testcontainers-7.23.0.tgz#7d73a5e219a970fb75ff6a23a28dace8b7f3f232"
+ integrity sha512-90H1iijeIjOLp7WVNYKTNkM1sd+dlW5019ns45hSPcOET43WebEZQVJl8/Ag9vwSZD2mjomMum9a/EXk/st4sQ==
dependencies:
- "@types/archiver" "^5.1.0"
- "@types/dockerode" "^3.2.1"
+ "@types/archiver" "^5.1.1"
+ "@types/dockerode" "^3.2.5"
archiver "^5.3.0"
byline "^5.0.0"
- debug "^4.3.1"
- docker-compose "^0.23.10"
- dockerode "^3.2.1"
+ debug "^4.3.2"
+ docker-compose "^0.23.13"
+ dockerode "^3.3.1"
get-port "^5.1.1"
- glob "^7.1.7"
+ glob "^7.2.0"
slash "^3.0.0"
- ssh-remote-port-forward "^1.0.3"
- stream-to-array "^2.3.0"
+ ssh-remote-port-forward "^1.0.4"
tar-fs "^2.1.1"
text-encoding-utf-8@^1.0.1:
@@ -28047,11 +27981,6 @@ uniq@^1.0.1:
resolved "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=
-uniqs@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02"
- integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI=
-
unique-filename@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230"
@@ -28591,11 +28520,6 @@ vasync@^2.2.0:
dependencies:
verror "1.10.0"
-vendors@^1.0.0:
- version "1.0.4"
- resolved "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e"
- integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==
-
verror@1.10.0, verror@^1.8.1:
version "1.10.0"
resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
@@ -29244,9 +29168,9 @@ write-pkg@^4.0.0:
write-json-file "^3.2.0"
ws@7.4.5, ws@^7.4.6:
- version "7.5.5"
- resolved "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881"
- integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==
+ version "7.5.6"
+ resolved "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b"
+ integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==
ws@7.4.6:
version "7.4.6"