From 335a9cebde0929ca24abf3ecd2edc366d5c07d1e Mon Sep 17 00:00:00 2001 From: hram_wh Date: Fri, 23 Sep 2022 11:21:03 +0530 Subject: [PATCH 001/434] customize explore tools content Signed-off-by: hram_wh --- packages/app/src/App.tsx | 10 ++- .../DefaultExplorePage/DefaultExplorePage.tsx | 7 +- .../components/ExplorePage/ExplorePage.tsx | 6 +- .../ToolExplorerContent.tsx | 69 +++++++++++-------- 4 files changed, 60 insertions(+), 32 deletions(-) diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index a6c613ded7..a807df9943 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -106,6 +106,7 @@ import { RequirePermission } from '@backstage/plugin-permission-react'; import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common'; import { PlaylistIndexPage } from '@backstage/plugin-playlist'; import { TwoColumnLayout } from './components/scaffolder/customScaffolderLayouts'; +import { exploreTools } from './exploreTools'; const app = createApp({ apis, @@ -242,7 +243,14 @@ const routes = ( - } /> + + } + /> } diff --git a/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.tsx b/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.tsx index 54beb59619..2f329861ab 100644 --- a/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.tsx +++ b/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.tsx @@ -20,8 +20,9 @@ import { ExploreLayout } from '../ExploreLayout'; import { GroupsExplorerContent } from '../GroupsExplorerContent'; import { ToolExplorerContent } from '../ToolExplorerContent'; import { configApiRef, useApi } from '@backstage/core-plugin-api'; +import { ExploreTool } from '@backstage/plugin-explore-react'; -export const DefaultExplorePage = () => { +export const DefaultExplorePage = (props: {exploreTools?: Array}) => { const configApi = useApi(configApiRef); const organizationName = configApi.getOptionalString('organization.name') ?? 'Backstage'; @@ -38,7 +39,9 @@ export const DefaultExplorePage = () => { - + ); diff --git a/plugins/explore/src/components/ExplorePage/ExplorePage.tsx b/plugins/explore/src/components/ExplorePage/ExplorePage.tsx index 80fe3febec..62e893feb6 100644 --- a/plugins/explore/src/components/ExplorePage/ExplorePage.tsx +++ b/plugins/explore/src/components/ExplorePage/ExplorePage.tsx @@ -17,9 +17,11 @@ import React from 'react'; import { useOutlet } from 'react-router'; import { DefaultExplorePage } from '../DefaultExplorePage'; +import { ExploreTool } from '@backstage/plugin-explore-react'; -export const ExplorePage = () => { + +export const ExplorePage = (props: {exploreTools?: Array}) => { const outlet = useOutlet(); - return <>{outlet || }; + return <>{outlet || }; }; diff --git a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx index 5404c67393..f57d9ea43d 100644 --- a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx +++ b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { exploreToolsConfigRef } from '@backstage/plugin-explore-react'; +import { ExploreTool, exploreToolsConfigRef } from '@backstage/plugin-explore-react'; import React from 'react'; import useAsync from 'react-use/lib/useAsync'; import { ToolCard } from '../ToolCard'; @@ -29,48 +29,63 @@ import { } from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; -const Body = () => { - const exploreToolsConfigApi = useApi(exploreToolsConfigRef); - const { - value: tools, - loading, - error, - } = useAsync(async () => { - return await exploreToolsConfigApi.getTools(); - }, [exploreToolsConfigApi]); +const Body = (props: {exploreTools?: Array}) => { + var exploreTools; + if(!props?.exploreTools){ + const exploreToolsConfigApi = useApi(exploreToolsConfigRef); + const { + value: tools, + loading, + error, + } = useAsync(async () => { + return await exploreToolsConfigApi.getTools(); + }, [exploreToolsConfigApi]); - if (loading) { - return ; - } + if (loading) { + return ; + } - if (error) { - return ; - } + if (error) { + return ; + } - if (!tools?.length) { - return ( - - ); + if (!tools?.length) { + return ( + + ); + } + exploreTools = tools; + } else if(props?.exploreTools) { + exploreTools = props?.exploreTools; + if (!props?.exploreTools?.length) { + return ( + + ); + } } return ( - {tools.map((tool, index) => ( + {exploreTools?.map((tool, index) => ( ))} ); }; -export const ToolExplorerContent = (props: { title?: string }) => ( +export const ToolExplorerContent = (props: { title?: string, exploreTools?: Array}) => ( Discover the tools in your ecosystem. - + ); From d04151817817affcd3c5da1bd6a3c1dab7c439df Mon Sep 17 00:00:00 2001 From: hram_wh Date: Fri, 23 Sep 2022 11:28:16 +0530 Subject: [PATCH 002/434] Prettier fix Signed-off-by: hram_wh --- packages/app/src/App.tsx | 6 +----- .../DefaultExplorePage/DefaultExplorePage.tsx | 8 ++++---- .../src/components/ExplorePage/ExplorePage.tsx | 7 ++++--- .../ToolExplorerContent.tsx | 18 ++++++++++++------ 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index a807df9943..a61990ed24 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -245,11 +245,7 @@ const routes = ( - } + element={} /> }) => { +export const DefaultExplorePage = (props: { + exploreTools?: Array; +}) => { const configApi = useApi(configApiRef); const organizationName = configApi.getOptionalString('organization.name') ?? 'Backstage'; @@ -39,9 +41,7 @@ export const DefaultExplorePage = (props: {exploreTools?: Array}) = - + ); diff --git a/plugins/explore/src/components/ExplorePage/ExplorePage.tsx b/plugins/explore/src/components/ExplorePage/ExplorePage.tsx index 62e893feb6..266c816f74 100644 --- a/plugins/explore/src/components/ExplorePage/ExplorePage.tsx +++ b/plugins/explore/src/components/ExplorePage/ExplorePage.tsx @@ -19,9 +19,10 @@ import { useOutlet } from 'react-router'; import { DefaultExplorePage } from '../DefaultExplorePage'; import { ExploreTool } from '@backstage/plugin-explore-react'; - -export const ExplorePage = (props: {exploreTools?: Array}) => { +export const ExplorePage = (props: { exploreTools?: Array }) => { const outlet = useOutlet(); - return <>{outlet || }; + return ( + <>{outlet || } + ); }; diff --git a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx index f57d9ea43d..c7ed23e185 100644 --- a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx +++ b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx @@ -14,7 +14,10 @@ * limitations under the License. */ -import { ExploreTool, exploreToolsConfigRef } from '@backstage/plugin-explore-react'; +import { + ExploreTool, + exploreToolsConfigRef, +} from '@backstage/plugin-explore-react'; import React from 'react'; import useAsync from 'react-use/lib/useAsync'; import { ToolCard } from '../ToolCard'; @@ -29,9 +32,9 @@ import { } from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; -const Body = (props: {exploreTools?: Array}) => { +const Body = (props: { exploreTools?: Array }) => { var exploreTools; - if(!props?.exploreTools){ + if (!props?.exploreTools) { const exploreToolsConfigApi = useApi(exploreToolsConfigRef); const { value: tools, @@ -59,7 +62,7 @@ const Body = (props: {exploreTools?: Array}) => { ); } exploreTools = tools; - } else if(props?.exploreTools) { + } else if (props?.exploreTools) { exploreTools = props?.exploreTools; if (!props?.exploreTools?.length) { return ( @@ -81,11 +84,14 @@ const Body = (props: {exploreTools?: Array}) => { ); }; -export const ToolExplorerContent = (props: { title?: string, exploreTools?: Array}) => ( +export const ToolExplorerContent = (props: { + title?: string; + exploreTools?: Array; +}) => ( Discover the tools in your ecosystem. - + ); From 5c25ce6d9ede5646b7f7f7366954630b016a2f10 Mon Sep 17 00:00:00 2001 From: hram_wh Date: Fri, 23 Sep 2022 11:47:30 +0530 Subject: [PATCH 003/434] changeset added Signed-off-by: hram_wh --- .changeset/bright-pillows-build.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/bright-pillows-build.md diff --git a/.changeset/bright-pillows-build.md b/.changeset/bright-pillows-build.md new file mode 100644 index 0000000000..65517a6595 --- /dev/null +++ b/.changeset/bright-pillows-build.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-explore': patch +--- + +Added ability to customize the explore plugin tools tab content From 15bed4655e0c34d091eaf296c1fafbe3751d5f1d Mon Sep 17 00:00:00 2001 From: hram_wh Date: Fri, 23 Sep 2022 12:51:12 +0530 Subject: [PATCH 004/434] useApi hook implementation outside of conditional block Signed-off-by: hram_wh --- packages/app/src/App.tsx | 6 +- .../ToolExplorerContent.tsx | 62 +++++++------------ 2 files changed, 25 insertions(+), 43 deletions(-) diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index a61990ed24..a6c613ded7 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -106,7 +106,6 @@ import { RequirePermission } from '@backstage/plugin-permission-react'; import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common'; import { PlaylistIndexPage } from '@backstage/plugin-playlist'; import { TwoColumnLayout } from './components/scaffolder/customScaffolderLayouts'; -import { exploreTools } from './exploreTools'; const app = createApp({ apis, @@ -243,10 +242,7 @@ const routes = ( - } - /> + } /> } diff --git a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx index c7ed23e185..79d8fda6fe 100644 --- a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx +++ b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx @@ -33,51 +33,37 @@ import { import { useApi } from '@backstage/core-plugin-api'; const Body = (props: { exploreTools?: Array }) => { - var exploreTools; - if (!props?.exploreTools) { - const exploreToolsConfigApi = useApi(exploreToolsConfigRef); - const { - value: tools, - loading, - error, - } = useAsync(async () => { - return await exploreToolsConfigApi.getTools(); - }, [exploreToolsConfigApi]); + const exploreToolsConfigApi = useApi(exploreToolsConfigRef); + const { + value: tools, + loading, + error, + } = useAsync(async () => { + if (props?.exploreTools) return props?.exploreTools; + return await exploreToolsConfigApi.getTools(); + }, [exploreToolsConfigApi]); - if (loading) { - return ; - } + if (loading) { + return ; + } - if (error) { - return ; - } + if (error) { + return ; + } - if (!tools?.length) { - return ( - - ); - } - exploreTools = tools; - } else if (props?.exploreTools) { - exploreTools = props?.exploreTools; - if (!props?.exploreTools?.length) { - return ( - - ); - } + if (!tools?.length) { + return ( + + ); } return ( - {exploreTools?.map((tool, index) => ( + {tools?.map((tool, index) => ( ))} From 235285373e20afbebce017c9d52f2708e3af58f6 Mon Sep 17 00:00:00 2001 From: hram_wh Date: Tue, 27 Sep 2022 12:52:53 +0530 Subject: [PATCH 005/434] changes in api reports Signed-off-by: hram_wh --- plugins/explore/api-report.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/explore/api-report.md b/plugins/explore/api-report.md index 9653c0fb63..7816c1c60f 100644 --- a/plugins/explore/api-report.md +++ b/plugins/explore/api-report.md @@ -8,6 +8,7 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { default as default_2 } from 'react'; import { DomainEntity } from '@backstage/catalog-model'; +import { ExploreTool } from '@backstage/plugin-explore-react'; import { ExternalRouteRef } from '@backstage/core-plugin-api'; import { RouteRef } from '@backstage/core-plugin-api'; import { TabProps } from '@material-ui/core'; @@ -44,7 +45,9 @@ export type ExploreLayoutProps = { }; // @public (undocumented) -export const ExplorePage: () => JSX.Element; +export const ExplorePage: (props: { + exploreTools?: ExploreTool[] | undefined; +}) => JSX.Element; // @public (undocumented) const explorePlugin: BackstagePlugin< @@ -90,5 +93,6 @@ export type SubRoute = { // @public (undocumented) export const ToolExplorerContent: (props: { title?: string | undefined; + exploreTools?: ExploreTool[] | undefined; }) => JSX.Element; ``` From aedf8c86d1160ab680c030f96edef39489de3229 Mon Sep 17 00:00:00 2001 From: Axel Hecht Date: Tue, 4 Oct 2022 18:34:49 +0200 Subject: [PATCH 006/434] Add a contrib document to show how to test scaffolder templates locally Signed-off-by: Axel Hecht --- contrib/scaffolder/README.md | 16 ++ .../scaffolder/template-testing-dry-run.md | 168 ++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 contrib/scaffolder/README.md create mode 100644 contrib/scaffolder/template-testing-dry-run.md diff --git a/contrib/scaffolder/README.md b/contrib/scaffolder/README.md new file mode 100644 index 0000000000..8f9b229a30 --- /dev/null +++ b/contrib/scaffolder/README.md @@ -0,0 +1,16 @@ +# Scaffolder contrib tools + +## Testing Templates with Dry-run + +Scaffolder templates support anything that backstage.io and custom actions can do, so testing them is hard without actually running the instance of Backstage that they're designed for. + +The [commandline script](template-testing-dry-run.md) might offer a way for you to do so using the dry-run API used for the Template Editor. Run it against a running instance, either locally or remote, and use it like + +```sh +scaffolder-dry http://localhost:7007/ template-directory values.yml output-directory +``` + +If you're using backend-to-backend authentication, either + +- pass a front-end auth token from a current browser session via `--token $FRONTEND_TOKEN`, +- have the tool create a b2b token for a given base64 encoded backend secret via `--backend-secret $BACKEND_SECRET`. diff --git a/contrib/scaffolder/template-testing-dry-run.md b/contrib/scaffolder/template-testing-dry-run.md new file mode 100644 index 0000000000..89b92e22ef --- /dev/null +++ b/contrib/scaffolder/template-testing-dry-run.md @@ -0,0 +1,168 @@ +```js +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * A CLI that helps you test Backstage software templates + * + * @packageDocumentation + */ + +import { dirname, join, relative } from 'node:path'; +import { readFile, writeFile } from 'node:fs/promises'; +import { gzipSync } from 'node:zlib'; +import { ensureDir } from 'fs-extra'; +import { program } from 'commander'; +import { base64url, exportJWK, generateSecret, jwtVerify, SignJWT } from 'jose'; +import fetch from 'node-fetch'; +import readdir from 'recursive-readdir'; +import { parse } from 'yaml'; +import { version } from '../../../package.json'; +import type { ScaffolderDryRunResponse } from '@backstage/plugin-scaffolder'; + +const TOKEN_ALG = 'HS256'; +const TOKEN_SUB = 'backstage-server'; + +const loadDirectoryContents = async (template_path: string) => { + const files = await await readdir(template_path, ['.git']); + const contents = await Promise.all( + files.map(async p => { + return { + path: relative(template_path, p), + base64Content: (await readFile(p)).toString('base64'), + }; + }), + ); + return contents; +}; + +const writeResultContents = async ( + root: string, + directoryContents: ScaffolderDryRunResponse['directoryContents'], +) => { + const directories = new Set( + directoryContents.map(({ path }) => dirname(join(root, path))), + ); + await Promise.all(Array.from(directories).map(d => ensureDir(d))); + await Promise.all( + directoryContents.map(async ({ path, base64Content, executable }) => + writeFile(join(root, path), Buffer.from(base64Content, 'base64'), { + mode: executable ? 0o755 : 0o644, + }), + ), + ); +}; + +const getToken = async (backendSecret: string) => { + const signingKey = base64url.decode(backendSecret); + return await new SignJWT({}) + .setProtectedHeader({ alg: TOKEN_ALG }) + .setSubject(TOKEN_SUB) + .setExpirationTime('10min') + .sign(signingKey); +}; + +const api = async ( + bodyObj: Record, + { baseURL, token }: { baseURL: string; token: string | false }, +) => { + const body = gzipSync(JSON.stringify(bodyObj)); + return fetch(new URL('/api/scaffolder/v2/dry-run', baseURL), { + method: 'POST', + headers: { + Authorization: `Bearer ${token || ''}`, + 'Content-Type': 'application/json', + 'Content-Encoding': 'gzip', + }, + body, + }); +}; + +const handle = async ( + baseURL: string, + template_path: string, + data: string, + target: string, + { + token, + backendSecret, + }: { token: string | false; backendSecret: string | false }, +) => { + const directoryContents = await loadDirectoryContents(template_path); + const values = parse(await readFile(data, 'utf-8')); + const secrets = {}; + const template = parse( + await readFile(`${template_path}/template.yaml`, 'utf-8'), + ); + if (backendSecret) { + // eslint-disable-next-line no-param-reassign + token = await getToken(backendSecret); + } + const response = await api( + { + directoryContents, + values, + secrets, + template, + }, + { baseURL, token }, + ); + if (!response.ok) { + const contentType = response.headers.get('content-type'); + if (contentType?.startsWith('application/json')) { + const responseData = await response.json(); + if (responseData.error) { + throw responseData.error; + } + if (responseData.errors) { + throw responseData.errors; + } + throw responseData; + } + throw await response.text(); + } + const { log, directoryContents: resultContents } = + (await response.json()) as ScaffolderDryRunResponse; + for (const logEntry of log) { + console.log(logEntry.body.message); + } + await writeResultContents(target, resultContents); +}; + +const main = async (argv: string[]) => { + program + .name('backstage-scaffolder') + .version(version) + .description('Creates a dry-run output of a given template') + .option('-t, --token ', 'JWT to use for auth') + .option('-b, --backend-secret ', 'Base64 encoded backend secret') + .argument('url', 'URL of your Backstage instance') + .argument('template-path', 'Source directory of template') + .argument('data-path', 'YAML file with input to render') + .argument('target', 'Output directory') + .action(handle); + + await program.parseAsync(argv); + process.exit(); +}; + +process.on('unhandledRejection', rejection => { + console.error(rejection); + process.exit(1); +}); + +main(process.argv); +``` From ac11b898ba9789520821060647e3b66a72271a80 Mon Sep 17 00:00:00 2001 From: Axel Hecht Date: Tue, 4 Oct 2022 20:14:18 +0200 Subject: [PATCH 007/434] Fix spelling Signed-off-by: Axel Hecht --- contrib/scaffolder/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/scaffolder/README.md b/contrib/scaffolder/README.md index 8f9b229a30..55ffea290a 100644 --- a/contrib/scaffolder/README.md +++ b/contrib/scaffolder/README.md @@ -4,7 +4,7 @@ Scaffolder templates support anything that backstage.io and custom actions can do, so testing them is hard without actually running the instance of Backstage that they're designed for. -The [commandline script](template-testing-dry-run.md) might offer a way for you to do so using the dry-run API used for the Template Editor. Run it against a running instance, either locally or remote, and use it like +The [command line script](template-testing-dry-run.md) might offer a way for you to do so using the dry-run API used for the Template Editor. Run it against a running instance, either locally or remote, and use it like ```sh scaffolder-dry http://localhost:7007/ template-directory values.yml output-directory From 3e9e8203f34164d459834c714397b9c45f684d01 Mon Sep 17 00:00:00 2001 From: djamaile Date: Wed, 5 Oct 2022 16:42:36 +0200 Subject: [PATCH 008/434] feat: add GroupListPicker component Signed-off-by: djamaile --- .../GroupListPicker/GroupListPicker.test.tsx | 114 ++++++++++++++ .../GroupListPicker/GroupListPicker.tsx | 140 ++++++++++++++++++ .../src/components/GroupListPicker/index.ts | 17 +++ plugins/catalog-react/src/components/index.ts | 1 + 4 files changed, 272 insertions(+) create mode 100644 plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.test.tsx create mode 100644 plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx create mode 100644 plugins/catalog-react/src/components/GroupListPicker/index.ts diff --git a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.test.tsx b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.test.tsx new file mode 100644 index 0000000000..77d1eead6d --- /dev/null +++ b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.test.tsx @@ -0,0 +1,114 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { fireEvent, render, waitFor } from '@testing-library/react'; +import { ApiProvider } from '@backstage/core-app-api'; +import { catalogApiRef } from '../../api'; +import { CatalogApi } from '@backstage/catalog-client'; +import { GroupListPicker } from '../GroupListPicker'; +import { GroupEntity } from '@backstage/catalog-model'; +import { TestApiRegistry } from '@backstage/test-utils'; + +const mockGroups: GroupEntity[] = [ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + namespace: 'default', + name: 'group-a', + }, + spec: { + type: 'org', + profile: { + displayName: 'Group A', + }, + children: [], + }, + }, + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + namespace: 'default', + name: 'group-b', + }, + spec: { + type: 'department', + profile: { + displayName: 'Group B', + }, + children: [], + }, + }, +]; + +const mockCatalogApi = { + getEntities: () => Promise.resolve({ items: mockGroups }), +} as Partial; + +const apis = TestApiRegistry.from([catalogApiRef, mockCatalogApi]); + +describe('', () => { + it('renders group list picker', () => { + const { queryByText } = render( + + + , + ); + + expect(queryByText('test')).toBeInTheDocument(); + }); + + it('open group list picker', () => { + const { getByTestId, getAllByText } = render( + + + , + ); + + fireEvent.click(getByTestId('group-list-picker-button')); + expect(getAllByText('Search unique').length).toBeGreaterThan(0); + }); + + it('can choose a group', async () => { + const { getByText, queryByText, getByTestId } = render( + + + , + ); + + fireEvent.click(getByTestId('group-list-picker-button')); + const input = getByTestId('group-list-picker-input').querySelector('input'); + fireEvent.change(input as HTMLElement, { target: { value: 'GR' } }); + + await waitFor(() => { + expect(queryByText('Group A')).toBeInTheDocument(); + fireEvent.click(getByText('Group A')); + expect(getByText('Group A')).toBeInTheDocument(); + }); + }); +}); diff --git a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx new file mode 100644 index 0000000000..ba0e2841af --- /dev/null +++ b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx @@ -0,0 +1,140 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { catalogApiRef } from '../../api'; +import TextField from '@material-ui/core/TextField'; +import Autocomplete from '@material-ui/lab/Autocomplete'; +import useAsync from 'react-use/lib/useAsync'; +import Popover from '@material-ui/core/Popover'; +import { useApi } from '@backstage/core-plugin-api'; +import { ResponseErrorPanel } from '@backstage/core-components'; +import { GroupEntity } from '@backstage/catalog-model'; +import { makeStyles, Box, Typography } from '@material-ui/core'; +import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown'; +import PeopleIcon from '@material-ui/icons/People'; + +const useStyles = makeStyles({ + btn: { + backgroundColor: 'transparent', + border: 'none', + margin: 0, + padding: 0, + }, + title: { + fontStyle: 'normal', + fontWeight: 700, + fontSize: '24px', + lineHeight: '32px', + letterSpacing: '-0.25px', + }, +}); + +type GroupListPickerProps = { + label: string; + groupTypes: Array; + defaultGroup?: string; +}; +export const GroupListPicker = (props: GroupListPickerProps) => { + const classes = useStyles(); + const catalogApi = useApi(catalogApiRef); + const { label, groupTypes, defaultGroup = '' } = props; + const [anchorEl, setAnchorEl] = React.useState(null); + const [inputValue, setInputValue] = React.useState(''); + const [group, setGroup] = React.useState(defaultGroup); + + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? 'simple-popover' : undefined; + + const { + loading, + error, + value: groups, + } = useAsync(async () => { + const groupsList = await catalogApi.getEntities({ + filter: { + kind: 'Group', + 'spec.type': groupTypes, + }, + }); + + return groupsList.items as GroupEntity[]; + }, [catalogApi]); + + if (error) { + return ; + } + + return ( + <> + + option.spec.type} + getOptionLabel={option => option.spec.profile?.displayName ?? ''} + inputValue={inputValue} + onInputChange={(_, value) => setInputValue(value)} + onChange={(_, newValue) => { + if (newValue) { + setGroup(newValue.spec.profile?.displayName ?? ''); + } + setInputValue(''); + }} + style={{ width: '200px', margin: '8px' }} + renderInput={params => ( + + )} + /> + + + + ); +}; diff --git a/plugins/catalog-react/src/components/GroupListPicker/index.ts b/plugins/catalog-react/src/components/GroupListPicker/index.ts new file mode 100644 index 0000000000..be2819c850 --- /dev/null +++ b/plugins/catalog-react/src/components/GroupListPicker/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { GroupListPicker } from './GroupListPicker'; diff --git a/plugins/catalog-react/src/components/index.ts b/plugins/catalog-react/src/components/index.ts index c604306ead..90fe108ab7 100644 --- a/plugins/catalog-react/src/components/index.ts +++ b/plugins/catalog-react/src/components/index.ts @@ -28,3 +28,4 @@ export * from './InspectEntityDialog'; export * from './UnregisterEntityDialog'; export * from './UserListPicker'; export * from './EntityProcessingStatusPicker'; +export * from './GroupListPicker'; From bcc4686e367323fdda371b01ea9d5c908e06e8f7 Mon Sep 17 00:00:00 2001 From: djamaile Date: Thu, 6 Oct 2022 09:34:43 +0200 Subject: [PATCH 009/434] chore: add changeset Signed-off-by: djamaile --- .changeset/hungry-rocks-bathe.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/hungry-rocks-bathe.md diff --git a/.changeset/hungry-rocks-bathe.md b/.changeset/hungry-rocks-bathe.md new file mode 100644 index 0000000000..7c22f1b368 --- /dev/null +++ b/.changeset/hungry-rocks-bathe.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Added a `AutoComplete` component that will give the user the ability to choose a group From 6797f03690f25534f26ce757d8471bffcd12c155 Mon Sep 17 00:00:00 2001 From: djamaile Date: Thu, 6 Oct 2022 09:49:22 +0200 Subject: [PATCH 010/434] chore: add api-report Signed-off-by: djamaile --- plugins/catalog-react/api-report.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index e8f0b0e6ee..bea429d047 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -446,6 +446,16 @@ export function getEntitySourceLocation( scmIntegrationsApi: ScmIntegrationRegistry, ): EntitySourceLocation | undefined; +// @public (undocumented) +export const GroupListPicker: (props: GroupListPickerProps) => JSX.Element; + +// @public +export type GroupListPickerProps = { + label: string; + groupTypes: Array; + defaultGroup?: string; +}; + // @public (undocumented) export function humanizeEntityRef( entityRef: Entity | CompoundEntityRef, From b8a2a96d13ff31005d90202600492397ab6024a5 Mon Sep 17 00:00:00 2001 From: djamaile Date: Thu, 6 Oct 2022 10:43:21 +0200 Subject: [PATCH 011/434] chore: add api-report Signed-off-by: djamaile --- .../src/components/GroupListPicker/GroupListPicker.tsx | 9 ++++++++- .../src/components/GroupListPicker/index.ts | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx index ba0e2841af..98e7be3624 100644 --- a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx +++ b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx @@ -43,11 +43,18 @@ const useStyles = makeStyles({ }, }); -type GroupListPickerProps = { +/** + * Props for {@link GroupListPicker}. + * + * @public + */ +export type GroupListPickerProps = { label: string; groupTypes: Array; defaultGroup?: string; }; + +/** @public */ export const GroupListPicker = (props: GroupListPickerProps) => { const classes = useStyles(); const catalogApi = useApi(catalogApiRef); diff --git a/plugins/catalog-react/src/components/GroupListPicker/index.ts b/plugins/catalog-react/src/components/GroupListPicker/index.ts index be2819c850..fe1ba8e1ee 100644 --- a/plugins/catalog-react/src/components/GroupListPicker/index.ts +++ b/plugins/catalog-react/src/components/GroupListPicker/index.ts @@ -15,3 +15,4 @@ */ export { GroupListPicker } from './GroupListPicker'; +export type { GroupListPickerProps } from './GroupListPicker'; From a115ce5132c529168d0a657ffc0371301b458d09 Mon Sep 17 00:00:00 2001 From: Mathias Bronner Date: Thu, 6 Oct 2022 12:07:44 +0200 Subject: [PATCH 012/434] fix layout for trigger button Signed-off-by: Mathias Bronner --- .../GroupListPicker/GroupListPicker.tsx | 25 ++++++++++--------- .../CatalogPage/DefaultCatalogPage.tsx | 6 +++++ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx index ba0e2841af..f5ba1c7198 100644 --- a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx +++ b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx @@ -33,13 +33,15 @@ const useStyles = makeStyles({ border: 'none', margin: 0, padding: 0, + width: '100%', }, title: { + fontSize: '24px', fontStyle: 'normal', fontWeight: 700, - fontSize: '24px', - lineHeight: '32px', letterSpacing: '-0.25px', + lineHeight: '32px', + marginBottom: 0, }, }); @@ -51,6 +53,7 @@ type GroupListPickerProps = { export const GroupListPicker = (props: GroupListPickerProps) => { const classes = useStyles(); const catalogApi = useApi(catalogApiRef); + const { label, groupTypes, defaultGroup = '' } = props; const [anchorEl, setAnchorEl] = React.useState(null); const [inputValue, setInputValue] = React.useState(''); @@ -109,9 +112,9 @@ export const GroupListPicker = (props: GroupListPickerProps) => { } setInputValue(''); }} - style={{ width: '200px', margin: '8px' }} + style={{ width: '200px' }} renderInput={params => ( - + )} /> @@ -122,17 +125,15 @@ export const GroupListPicker = (props: GroupListPickerProps) => { className={classes.btn} data-testid="group-list-picker-button" > - - + + {group} - + diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx index 2bae104d90..c465dc7c85 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx @@ -35,6 +35,7 @@ import { UserListFilterKind, UserListPicker, EntityKindPicker, + GroupListPicker, } from '@backstage/plugin-catalog-react'; import React from 'react'; import { createComponentRouteRef } from '../../routes'; @@ -84,6 +85,11 @@ export function DefaultCatalogPage(props: DefaultCatalogPageProps) { + From 0c0ac14bc43dabe459a22e132a3ae28c3825a1e3 Mon Sep 17 00:00:00 2001 From: Mathias Bronner Date: Thu, 6 Oct 2022 13:43:58 +0200 Subject: [PATCH 013/434] clean up dev instance of component Signed-off-by: Mathias Bronner --- .../src/components/CatalogPage/DefaultCatalogPage.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx index c465dc7c85..ac010b539c 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx @@ -85,11 +85,6 @@ export function DefaultCatalogPage(props: DefaultCatalogPageProps) { - From 88d55868e59fb079cfe50098120cb9064a239294 Mon Sep 17 00:00:00 2001 From: Mathias Bronner Date: Thu, 6 Oct 2022 13:50:21 +0200 Subject: [PATCH 014/434] remove unused dep import Signed-off-by: Mathias Bronner --- .../catalog/src/components/CatalogPage/DefaultCatalogPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx index ac010b539c..2bae104d90 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx @@ -35,7 +35,6 @@ import { UserListFilterKind, UserListPicker, EntityKindPicker, - GroupListPicker, } from '@backstage/plugin-catalog-react'; import React from 'react'; import { createComponentRouteRef } from '../../routes'; From aa2676dcbe3aed39bdb6db13144a8343d936dbe8 Mon Sep 17 00:00:00 2001 From: Mathias Bronner Date: Thu, 6 Oct 2022 14:23:16 +0200 Subject: [PATCH 015/434] rename label prop to placeholder and remove obsolete test case Signed-off-by: Mathias Bronner --- .../GroupListPicker/GroupListPicker.test.tsx | 18 ++---------------- .../GroupListPicker/GroupListPicker.tsx | 10 +++++++--- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.test.tsx b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.test.tsx index 77d1eead6d..6b89612354 100644 --- a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.test.tsx +++ b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.test.tsx @@ -67,7 +67,7 @@ describe('', () => { const { queryByText } = render( @@ -77,25 +77,11 @@ describe('', () => { expect(queryByText('test')).toBeInTheDocument(); }); - it('open group list picker', () => { - const { getByTestId, getAllByText } = render( - - - , - ); - - fireEvent.click(getByTestId('group-list-picker-button')); - expect(getAllByText('Search unique').length).toBeGreaterThan(0); - }); - it('can choose a group', async () => { const { getByText, queryByText, getByTestId } = render( , diff --git a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx index eb504880f3..d810d44d57 100644 --- a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx +++ b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx @@ -51,7 +51,7 @@ const useStyles = makeStyles({ * @public */ export type GroupListPickerProps = { - label: string; + placeholder: string; groupTypes: Array; defaultGroup?: string; }; @@ -61,7 +61,7 @@ export const GroupListPicker = (props: GroupListPickerProps) => { const classes = useStyles(); const catalogApi = useApi(catalogApiRef); - const { label, groupTypes, defaultGroup = '' } = props; + const { placeholder, groupTypes, defaultGroup = '' } = props; const [anchorEl, setAnchorEl] = React.useState(null); const [inputValue, setInputValue] = React.useState(''); const [group, setGroup] = React.useState(defaultGroup); @@ -121,7 +121,11 @@ export const GroupListPicker = (props: GroupListPickerProps) => { }} style={{ width: '200px' }} renderInput={params => ( - + )} /> From 3bc5d044f8db78371b6f5b192959faa460b65dac Mon Sep 17 00:00:00 2001 From: djamaile Date: Thu, 6 Oct 2022 14:35:07 +0200 Subject: [PATCH 016/434] chore: run api-report again Signed-off-by: djamaile --- plugins/catalog-react/api-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index bea429d047..5de39164be 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -451,7 +451,7 @@ export const GroupListPicker: (props: GroupListPickerProps) => JSX.Element; // @public export type GroupListPickerProps = { - label: string; + placeholder: string; groupTypes: Array; defaultGroup?: string; }; From 4d114d172d8e7e1803f1340860aff3f31937cedb Mon Sep 17 00:00:00 2001 From: djamaile Date: Fri, 7 Oct 2022 16:37:49 +0200 Subject: [PATCH 017/434] Update plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx Co-authored-by: Philipp Hugenroth Signed-off-by: djamaile --- .../src/components/GroupListPicker/GroupListPicker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx index d810d44d57..76bfbed22c 100644 --- a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx +++ b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx @@ -137,7 +137,7 @@ export const GroupListPicker = (props: GroupListPickerProps) => { data-testid="group-list-picker-button" > - + ({ marginRight: theme.spacing(1) }) } /> {group} From 97a6246539c890cbf3d61edc32882f7ecf153a02 Mon Sep 17 00:00:00 2001 From: djamaile Date: Fri, 7 Oct 2022 17:23:28 +0200 Subject: [PATCH 018/434] chore: clean up and respond to phillip comments Signed-off-by: djamaile --- plugins/catalog-react/api-report.md | 13 ++- .../GroupListPicker/GroupListPicker.tsx | 58 +++---------- .../GroupListPicker/GroupListPickerButton.tsx | 81 +++++++++++++++++++ .../src/components/GroupListPicker/index.ts | 2 + 4 files changed, 107 insertions(+), 47 deletions(-) create mode 100644 plugins/catalog-react/src/components/GroupListPicker/GroupListPickerButton.tsx diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index 5de39164be..e4fcd59857 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -449,9 +449,20 @@ export function getEntitySourceLocation( // @public (undocumented) export const GroupListPicker: (props: GroupListPickerProps) => JSX.Element; +// @public (undocumented) +export const GroupListPickerButton: ( + props: GroupListPickerButtonProps, +) => JSX.Element; + +// @public +export type GroupListPickerButtonProps = { + handleClick: (event: React_2.MouseEvent) => void; + group: string; +}; + // @public export type GroupListPickerProps = { - placeholder: string; + placeholder?: string; groupTypes: Array; defaultGroup?: string; }; diff --git a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx index 76bfbed22c..404ce2fc6f 100644 --- a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx +++ b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx @@ -23,27 +23,7 @@ import Popover from '@material-ui/core/Popover'; import { useApi } from '@backstage/core-plugin-api'; import { ResponseErrorPanel } from '@backstage/core-components'; import { GroupEntity } from '@backstage/catalog-model'; -import { makeStyles, Box, Typography } from '@material-ui/core'; -import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown'; -import PeopleIcon from '@material-ui/icons/People'; - -const useStyles = makeStyles({ - btn: { - backgroundColor: 'transparent', - border: 'none', - margin: 0, - padding: 0, - width: '100%', - }, - title: { - fontSize: '24px', - fontStyle: 'normal', - fontWeight: 700, - letterSpacing: '-0.25px', - lineHeight: '32px', - marginBottom: 0, - }, -}); +import { GroupListPickerButton } from './GroupListPickerButton'; /** * Props for {@link GroupListPicker}. @@ -51,22 +31,21 @@ const useStyles = makeStyles({ * @public */ export type GroupListPickerProps = { - placeholder: string; + placeholder?: string; groupTypes: Array; defaultGroup?: string; }; /** @public */ export const GroupListPicker = (props: GroupListPickerProps) => { - const classes = useStyles(); const catalogApi = useApi(catalogApiRef); - const { placeholder, groupTypes, defaultGroup = '' } = props; - const [anchorEl, setAnchorEl] = React.useState(null); + const { groupTypes, defaultGroup = '', placeholder = '' } = props; + const [anchorEl, setAnchorEl] = React.useState(null); const [inputValue, setInputValue] = React.useState(''); const [group, setGroup] = React.useState(defaultGroup); - const handleClick = (event: React.MouseEvent) => { + const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); }; @@ -110,12 +89,16 @@ export const GroupListPicker = (props: GroupListPickerProps) => { loading={loading} options={groups ?? []} groupBy={option => option.spec.type} - getOptionLabel={option => option.spec.profile?.displayName ?? ''} + getOptionLabel={option => + option.spec.profile?.displayName ?? option.metadata.name + } inputValue={inputValue} onInputChange={(_, value) => setInputValue(value)} onChange={(_, newValue) => { if (newValue) { - setGroup(newValue.spec.profile?.displayName ?? ''); + setGroup( + newValue.spec.profile?.displayName ?? newValue.metadata.name, + ); } setInputValue(''); }} @@ -129,24 +112,7 @@ export const GroupListPicker = (props: GroupListPickerProps) => { )} /> - + ); }; diff --git a/plugins/catalog-react/src/components/GroupListPicker/GroupListPickerButton.tsx b/plugins/catalog-react/src/components/GroupListPicker/GroupListPickerButton.tsx new file mode 100644 index 0000000000..a5a26ee9af --- /dev/null +++ b/plugins/catalog-react/src/components/GroupListPicker/GroupListPickerButton.tsx @@ -0,0 +1,81 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { BackstageTheme } from '@backstage/theme'; +import { Box, makeStyles, Typography } from '@material-ui/core'; +import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown'; +import PeopleIcon from '@material-ui/icons/People'; + +const useStyles = makeStyles((theme: BackstageTheme) => ({ + btn: { + backgroundColor: 'transparent', + border: 'none', + margin: 0, + padding: 0, + width: '100%', + cursor: 'pointer', + }, + title: { + fontSize: '1.5rem', + fontStyle: 'normal', + fontWeight: theme.typography.fontWeightBold, + letterSpacing: '-0.25px', + lineHeight: '32px', + marginBottom: 0, + }, + peopleIcon: { + marginRight: theme.spacing(1), + }, + arrowDownIcon: { + marginLeft: 'auto', + }, +})); + +/** + * Props for {@link GroupListPickerButton}. + * + * @public + */ +export type GroupListPickerButtonProps = { + handleClick: (event: React.MouseEvent) => void; + group: string; +}; + +/** @public */ +export const GroupListPickerButton = (props: GroupListPickerButtonProps) => { + const { handleClick, group } = props; + const classes = useStyles(); + + return ( + + ); +}; diff --git a/plugins/catalog-react/src/components/GroupListPicker/index.ts b/plugins/catalog-react/src/components/GroupListPicker/index.ts index fe1ba8e1ee..20c4502838 100644 --- a/plugins/catalog-react/src/components/GroupListPicker/index.ts +++ b/plugins/catalog-react/src/components/GroupListPicker/index.ts @@ -15,4 +15,6 @@ */ export { GroupListPicker } from './GroupListPicker'; +export { GroupListPickerButton } from './GroupListPickerButton'; export type { GroupListPickerProps } from './GroupListPicker'; +export type { GroupListPickerButtonProps } from './GroupListPickerButton'; From 6494177343044deda7a7dda4cff83711be427315 Mon Sep 17 00:00:00 2001 From: djamaile Date: Fri, 7 Oct 2022 17:32:58 +0200 Subject: [PATCH 019/434] chore: make areadescribedby hard coded Signed-off-by: djamaile --- .../src/components/GroupListPicker/GroupListPicker.tsx | 2 -- .../src/components/GroupListPicker/GroupListPickerButton.tsx | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx index 404ce2fc6f..ccb2690da0 100644 --- a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx +++ b/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx @@ -54,7 +54,6 @@ export const GroupListPicker = (props: GroupListPickerProps) => { }; const open = Boolean(anchorEl); - const id = open ? 'simple-popover' : undefined; const { loading, @@ -85,7 +84,6 @@ export const GroupListPicker = (props: GroupListPickerProps) => { > option.spec.type} diff --git a/plugins/catalog-react/src/components/GroupListPicker/GroupListPickerButton.tsx b/plugins/catalog-react/src/components/GroupListPicker/GroupListPickerButton.tsx index a5a26ee9af..8a952fb93c 100644 --- a/plugins/catalog-react/src/components/GroupListPicker/GroupListPickerButton.tsx +++ b/plugins/catalog-react/src/components/GroupListPicker/GroupListPickerButton.tsx @@ -65,6 +65,7 @@ export const GroupListPickerButton = (props: GroupListPickerButtonProps) => { onClick={handleClick} className={classes.btn} data-testid="group-list-picker-button" + aria-describedby="group-list-popover" > From 847fc588a6387b0d0404f853d2e14f29ca789b9d Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Tue, 11 Oct 2022 13:31:01 +0200 Subject: [PATCH 020/434] fix: page hader Signed-off-by: Matteo Pietro Dazzi --- .changeset/witty-horses-press.md | 5 +++++ .../TechDocsReaderPageHeader.tsx | 22 +++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 .changeset/witty-horses-press.md diff --git a/.changeset/witty-horses-press.md b/.changeset/witty-horses-press.md new file mode 100644 index 0000000000..009f52ef8b --- /dev/null +++ b/.changeset/witty-horses-press.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': minor +--- + +feat: tech doc reader page hader now has a explicit label for code icon diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx index e76cb1d173..250232fa17 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx @@ -37,6 +37,7 @@ import { Header, HeaderLabel } from '@backstage/core-components'; import { useRouteRef, configApiRef, useApi } from '@backstage/core-plugin-api'; import { rootRouteRef } from '../../../routes'; +import { Grid } from '@material-ui/core'; const skeleton = ; @@ -102,7 +103,7 @@ export const TechDocsReaderPageHeader = ( const labels = ( <> - - + + + + + Source + + } + url={locationMetadata.target} /> ) : null} From c62fa237d87c7442a7d793cd454f50969704698b Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Tue, 11 Oct 2022 14:16:38 +0200 Subject: [PATCH 021/434] fix: use entity as fallback Signed-off-by: Matteo Pietro Dazzi --- .changeset/witty-horses-press.md | 2 +- .../TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.changeset/witty-horses-press.md b/.changeset/witty-horses-press.md index 009f52ef8b..fb19aa2304 100644 --- a/.changeset/witty-horses-press.md +++ b/.changeset/witty-horses-press.md @@ -2,4 +2,4 @@ '@backstage/plugin-techdocs': minor --- -feat: tech doc reader page hader now has a explicit label for code icon +Updated TechDocs header to include label for source code icon and updated label to reflect Kind name diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx index 250232fa17..8c548f0f96 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx @@ -17,6 +17,7 @@ import React, { PropsWithChildren, useEffect } from 'react'; import Helmet from 'react-helmet'; +import { Grid } from '@material-ui/core'; import { Skeleton } from '@material-ui/lab'; import CodeIcon from '@material-ui/icons/Code'; @@ -37,7 +38,6 @@ import { Header, HeaderLabel } from '@backstage/core-components'; import { useRouteRef, configApiRef, useApi } from '@backstage/core-plugin-api'; import { rootRouteRef } from '../../../routes'; -import { Grid } from '@material-ui/core'; const skeleton = ; @@ -103,7 +103,7 @@ export const TechDocsReaderPageHeader = ( const labels = ( <> Date: Fri, 14 Oct 2022 14:42:51 +1000 Subject: [PATCH 022/434] Update profile cards to display more information if relevant Signed-off-by: Joe Patterson --- .changeset/tender-jeans-clean.md | 12 ++++ ADOPTERS.md | 1 + .../src/kinds/GroupEntityV1alpha1.ts | 14 +++-- .../src/kinds/UserEntityV1alpha1.ts | 14 +++-- .../src/components/Table/Table.tsx | 2 +- .../GroupProfile/GroupProfileCard.stories.tsx | 43 +++++++++++++ .../Group/GroupProfile/GroupProfileCard.tsx | 48 ++++++++++++++- .../UserProfileCard.stories.tsx | 43 +++++++++++++ .../UserProfileCard/UserProfileCard.test.tsx | 61 +++++++++++++++++++ .../User/UserProfileCard/UserProfileCard.tsx | 50 ++++++++++++++- storybook/.storybook/preview-head.html | 4 ++ 11 files changed, 279 insertions(+), 13 deletions(-) create mode 100644 .changeset/tender-jeans-clean.md create mode 100644 storybook/.storybook/preview-head.html diff --git a/.changeset/tender-jeans-clean.md b/.changeset/tender-jeans-clean.md new file mode 100644 index 0000000000..2729fa393a --- /dev/null +++ b/.changeset/tender-jeans-clean.md @@ -0,0 +1,12 @@ +--- +'@backstage/catalog-model': minor +'@backstage/plugin-org': minor +--- + +Updates the profile of Group and User to allow any extra string key pair value. + +Then updates the user profile and group profile cards to display any links and extra profile details. + +This allows extra customization without going down the full customization route. + +So for example if you wanted to add address, phone number, job title, slack link to users or departments this allows you to within the current spec diff --git a/ADOPTERS.md b/ADOPTERS.md index ca56a00890..d37aabde72 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -215,3 +215,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Ferrovial](https://ferrovial.com) | [Jose Luis Rosado](mailto:jlrosado@ferrovial.com) | Backstage is helping us to improve and acelerate dev experience helping teams to quickly find technical documentation, infrastructure templates, pipelines, software components and quickstarters that have been developed by our squads in a inner source friendly environment. | | [Inter&Co](https://bancointer.com.br) | [Arnaud Lanna](https://github.com/arnaudlanna), [Adriano Silva](https://github.com/adrianovss), [Bruno Grossi](https://github.com/begrossi) | We're using Backstage as our internal Developer Portal to catalog and collect repositories and microservices pieces of information like ownership, deployment time, and documentation. | | [StatusNeo](https://statusneo.com/) | [Karan Nangru](mailto:nangru@statusneo.com), [@NishkarshRaj](https://github.com/NishkarshRaj), and [Gaurav Sarien](mailto:gaurav.sarien@statusneo.com) | Harnessing the power of central catalog inventory and self-serving software templates | +| [Contino](https://www.contino.io/) | [Joseph Patterson](mailto:joseph.patterson@contino.io) | Building out a central catalog for our software community | diff --git a/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts b/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts index 8d88817dbe..9e514b1000 100644 --- a/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts @@ -18,6 +18,14 @@ import type { Entity } from '../entity/Entity'; import schema from '../schema/kinds/Group.v1alpha1.schema.json'; import { ajvCompiledJsonSchemaValidator } from './util'; +interface GroupProfileStatic { + displayName?: string; + email?: string; + picture?: string; +} + +type GroupProfile = Record & GroupProfileStatic; + /** * Backstage catalog Group kind Entity. * @@ -28,11 +36,7 @@ export interface GroupEntityV1alpha1 extends Entity { kind: 'Group'; spec: { type: string; - profile?: { - displayName?: string; - email?: string; - picture?: string; - }; + profile?: GroupProfile; parent?: string; children: string[]; members?: string[]; diff --git a/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts b/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts index 55c9b176ea..53446a5275 100644 --- a/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts @@ -18,6 +18,14 @@ import type { Entity } from '../entity/Entity'; import schema from '../schema/kinds/User.v1alpha1.schema.json'; import { ajvCompiledJsonSchemaValidator } from './util'; +interface UserProfileStatic { + displayName?: string; + email?: string; + picture?: string; +} + +type UserProfile = Record & UserProfileStatic; + /** * Backstage catalog User kind Entity. * @@ -27,11 +35,7 @@ export interface UserEntityV1alpha1 extends Entity { apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1'; kind: 'User'; spec: { - profile?: { - displayName?: string; - email?: string; - picture?: string; - }; + profile?: UserProfile; memberOf?: string[]; }; } diff --git a/packages/core-components/src/components/Table/Table.tsx b/packages/core-components/src/components/Table/Table.tsx index 49538b680a..13f77106e0 100644 --- a/packages/core-components/src/components/Table/Table.tsx +++ b/packages/core-components/src/components/Table/Table.tsx @@ -373,7 +373,7 @@ export function Table(props: TableProps) { const newData = (data as any[]).filter( el => !!Object.entries(selectedFilters) - .filter(([, value]) => !!value.length) + .filter(([, value]) => !!(value as []).length) .every(([key, filterValue]) => { const fieldValue = extractValueByField( el, diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx index fc45d9a8fe..7d28b5a2fa 100644 --- a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx +++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx @@ -87,3 +87,46 @@ export default { ), ], }; + +const extraDetailsEntity: GroupEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: 'team-a', + description: 'Team A', + links: [ + { + url: 'slack://user?team=T00000000&id=U00000000', + title: 'Slack', + icon: 'message', + }, + { + url: 'https://www.google.com', + title: 'Google', + }, + ], + }, + spec: { + profile: { + displayName: 'Team A', + email: 'team-a@example.com', + picture: + 'https://avatars.dicebear.com/api/identicon/team-a@example.com.svg?background=%23fff&margin=25', + Telephone: '123456789', + Location: 'London', + }, + type: 'group', + children: [], + }, + relations: [dummyDepartment], +}; + +export const ExtraDetails = () => ( + + + + + + + +); diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx index dfdb566b20..c12b4b8906 100644 --- a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx +++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx @@ -37,10 +37,13 @@ import { ListItemText, Tooltip, IconButton, + Divider, } from '@material-ui/core'; +import Icon from '@material-ui/core/Icon'; import AccountTreeIcon from '@material-ui/icons/AccountTree'; import EmailIcon from '@material-ui/icons/Email'; import GroupIcon from '@material-ui/icons/Group'; +import LinkIcon from '@material-ui/icons/Link'; import EditIcon from '@material-ui/icons/Edit'; import CachedIcon from '@material-ui/icons/Cached'; import Alert from '@material-ui/lab/Alert'; @@ -53,6 +56,8 @@ import { } from '@backstage/core-components'; import { alertApiRef, useApi } from '@backstage/core-plugin-api'; +const staticProfileKeys = ['displayName', 'email', 'picture']; + const CardTitle = (props: { title: string }) => ( @@ -76,7 +81,7 @@ export const GroupProfileCard = (props: { variant?: InfoCardVariants }) => { } const { - metadata: { name, description, annotations }, + metadata: { name, description, annotations, links }, spec: { profile }, } = group; @@ -94,6 +99,11 @@ export const GroupProfileCard = (props: { variant?: InfoCardVariants }) => { const entityMetadataEditUrl = group.metadata.annotations?.[ANNOTATION_EDIT_URL]; + const profileKeys = + profile !== undefined + ? Object.keys(profile).filter(key => !staticProfileKeys.includes(key)) + : []; + const displayName = profile?.displayName ?? name; const emailHref = profile?.email ? `mailto:${profile.email}` : '#'; const infoCardAction = entityMetadataEditUrl ? ( @@ -190,6 +200,42 @@ export const GroupProfileCard = (props: { variant?: InfoCardVariants }) => { secondary="Child Groups" /> + {links !== undefined && } + {links !== undefined && + links.map(link => { + return ( + + {link.icon ? ( + + + {link.icon} + + + ) : ( + + + + )} + {link.title} + + ); + })} + {profile !== undefined && profileKeys.length > 0 && } + {profile !== undefined && + profileKeys.length > 0 && + profileKeys.map(key => { + const value = profile[key]; + + return ( + + + {key} + + + {value} + + ); + })} diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx index eb7b8fadda..28fc3d3831 100644 --- a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx +++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx @@ -102,3 +102,46 @@ export default { }), ], }; + +const extraDetailsEntity: UserEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + name: 'guest', + description: 'Description for guest', + links: [ + { + url: 'slack://user?team=T00000000&id=U00000000', + title: 'Slack', + icon: 'message', + }, + { + url: 'https://www.google.com', + title: 'Google', + }, + ], + }, + spec: { + profile: { + displayName: 'Guest User', + email: 'guest@example.com', + picture: + 'https://avatars.dicebear.com/api/avataaars/guest@example.com.svg?background=%23fff', + 'Job Title': 'Software Engineer', + Department: 'Engineering', + Location: 'San Francisco, CA', + }, + memberOf: ['team-a'], + }, + relations: [dummyGroup], +}; + +export const ExtraDetails = () => ( + + + + + + + +); diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.test.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.test.tsx index f339a5828c..7eabdf2903 100644 --- a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.test.tsx +++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.test.tsx @@ -155,4 +155,65 @@ describe('Edit Button', () => { ); expect(rendered.getByRole('button')).toBeInTheDocument(); }); + + it('Should show the extra fields if either links or extra profile are filled', async () => { + const annotations: Record = { + 'backstage.io/edit-url': 'https://example.com/user.yaml', + }; + const userEntity: UserEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + name: 'calum.leavy', + description: 'Super awesome human', + annotations, + links: [ + { + url: 'slack://user?team=T00000000&id=U00000000', + title: 'Slack', + icon: 'message', + }, + { + url: 'https://www.google.com', + title: 'Google', + }, + ], + }, + spec: { + profile: { + displayName: 'Calum Leavy', + email: 'calum-leavy@example.com', + 'Job Title': 'Software Engineer', + Department: 'Engineering', + Location: 'San Francisco, CA', + }, + memberOf: ['ExampleGroup'], + }, + relations: [ + { + type: 'memberOf', + targetRef: 'group:default/examplegroup', + }, + ], + }; + + const rendered = await renderWithEffects( + wrapInTestApp( + + + , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ), + ); + expect(rendered.getByText('Software Engineer')).toBeInTheDocument(); + expect(rendered.getByText('Department')).toBeInTheDocument(); + expect(rendered.getByText('San Francisco, CA')).toBeInTheDocument(); + expect(rendered.getByText('Location')).toBeInTheDocument(); + expect(rendered.getByText('Slack')).toBeInTheDocument(); + expect(rendered.getByText('Google')).toBeInTheDocument(); + }); }); diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx index dd75578687..68a27764d8 100644 --- a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx +++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx @@ -33,12 +33,15 @@ import { ListItemIcon, ListItemText, Tooltip, + Divider, } from '@material-ui/core'; import EditIcon from '@material-ui/icons/Edit'; import EmailIcon from '@material-ui/icons/Email'; import GroupIcon from '@material-ui/icons/Group'; import PersonIcon from '@material-ui/icons/Person'; +import LinkIcon from '@material-ui/icons/Link'; import Alert from '@material-ui/lab/Alert'; +import Icon from '@material-ui/core/Icon'; import React from 'react'; import { Avatar, @@ -47,6 +50,8 @@ import { Link, } from '@backstage/core-components'; +const staticProfileKeys = ['displayName', 'email', 'picture']; + const CardTitle = (props: { title?: string }) => props.title ? ( @@ -66,7 +71,7 @@ export const UserProfileCard = (props: { variant?: InfoCardVariants }) => { user.metadata.annotations?.[ANNOTATION_EDIT_URL]; const { - metadata: { name: metaName, description }, + metadata: { name: metaName, description, links }, spec: { profile }, } = user; const displayName = profile?.displayName ?? metaName; @@ -75,6 +80,11 @@ export const UserProfileCard = (props: { variant?: InfoCardVariants }) => { kind: 'Group', }); + const profileKeys = + profile !== undefined + ? Object.keys(profile).filter(key => !staticProfileKeys.includes(key)) + : []; + return ( } @@ -128,6 +138,44 @@ export const UserProfileCard = (props: { variant?: InfoCardVariants }) => { /> + + {links !== undefined && } + {links !== undefined && + links.map(link => { + return ( + + {link.icon ? ( + + + {link.icon} + + + ) : ( + + + + )} + {link.title} + + ); + })} + + {profile !== undefined && profileKeys.length > 0 && } + {profile !== undefined && + profileKeys.length > 0 && + profileKeys.map(key => { + const value = profile[key]; + + return ( + + + {key} + + + {value} + + ); + })} diff --git a/storybook/.storybook/preview-head.html b/storybook/.storybook/preview-head.html new file mode 100644 index 0000000000..a21b9971e8 --- /dev/null +++ b/storybook/.storybook/preview-head.html @@ -0,0 +1,4 @@ + From 69b35ed0d1c0e5340e3037910d9a56c58fe92dd6 Mon Sep 17 00:00:00 2001 From: Joe Patterson Date: Mon, 17 Oct 2022 07:54:14 +1000 Subject: [PATCH 023/434] update api report Signed-off-by: Joe Patterson --- packages/catalog-model/api-report.md | 17 +++++++---------- .../src/kinds/GroupEntityV1alpha1.ts | 9 +++++++-- .../src/kinds/UserEntityV1alpha1.ts | 10 +++++++--- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md index b7456bb2f8..1a58dcb5ca 100644 --- a/packages/catalog-model/api-report.md +++ b/packages/catalog-model/api-report.md @@ -257,11 +257,7 @@ interface GroupEntityV1alpha1 extends Entity { // (undocumented) spec: { type: string; - profile?: { - displayName?: string; - email?: string; - picture?: string; - }; + profile?: GroupProfile; parent?: string; children: string[]; members?: string[]; @@ -491,11 +487,7 @@ interface UserEntityV1alpha1 extends Entity { kind: 'User'; // (undocumented) spec: { - profile?: { - displayName?: string; - email?: string; - picture?: string; - }; + profile?: UserProfile; memberOf?: string[]; }; } @@ -517,4 +509,9 @@ export type Validators = { isValidAnnotationValue(value: unknown): boolean; isValidTag(value: unknown): boolean; }; + +// Warnings were encountered during analysis: +// +// src/kinds/GroupEntityV1alpha1.d.ts:23:9 - (ae-forgotten-export) The symbol "GroupProfile" needs to be exported by the entry point index.d.ts +// src/kinds/UserEntityV1alpha1.d.ts:22:9 - (ae-forgotten-export) The symbol "UserProfile" needs to be exported by the entry point index.d.ts ``` diff --git a/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts b/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts index 9e514b1000..51f5f30f04 100644 --- a/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts @@ -18,13 +18,18 @@ import type { Entity } from '../entity/Entity'; import schema from '../schema/kinds/Group.v1alpha1.schema.json'; import { ajvCompiledJsonSchemaValidator } from './util'; -interface GroupProfileStatic { +export interface GroupProfileStatic { displayName?: string; email?: string; picture?: string; } -type GroupProfile = Record & GroupProfileStatic; +/** + * Backstage Group Profile. + * + * @public + */ +export type GroupProfile = Record & GroupProfileStatic; /** * Backstage catalog Group kind Entity. diff --git a/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts b/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts index 53446a5275..39d3861702 100644 --- a/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts @@ -18,13 +18,17 @@ import type { Entity } from '../entity/Entity'; import schema from '../schema/kinds/User.v1alpha1.schema.json'; import { ajvCompiledJsonSchemaValidator } from './util'; -interface UserProfileStatic { +export interface UserProfileStatic { displayName?: string; email?: string; picture?: string; } - -type UserProfile = Record & UserProfileStatic; +/** + * Backstage User Profile. + * + * @public + */ +export type UserProfile = Record & UserProfileStatic; /** * Backstage catalog User kind Entity. From bc825a7a7bce5d514eb079c2d374b243a2e04b2d Mon Sep 17 00:00:00 2001 From: Joe Patterson Date: Mon, 17 Oct 2022 08:17:28 +1000 Subject: [PATCH 024/434] remove changes not directly related to this change Signed-off-by: Joe Patterson --- ADOPTERS.md | 1 - packages/core-components/src/components/Table/Table.tsx | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ADOPTERS.md b/ADOPTERS.md index d37aabde72..ca56a00890 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -215,4 +215,3 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Ferrovial](https://ferrovial.com) | [Jose Luis Rosado](mailto:jlrosado@ferrovial.com) | Backstage is helping us to improve and acelerate dev experience helping teams to quickly find technical documentation, infrastructure templates, pipelines, software components and quickstarters that have been developed by our squads in a inner source friendly environment. | | [Inter&Co](https://bancointer.com.br) | [Arnaud Lanna](https://github.com/arnaudlanna), [Adriano Silva](https://github.com/adrianovss), [Bruno Grossi](https://github.com/begrossi) | We're using Backstage as our internal Developer Portal to catalog and collect repositories and microservices pieces of information like ownership, deployment time, and documentation. | | [StatusNeo](https://statusneo.com/) | [Karan Nangru](mailto:nangru@statusneo.com), [@NishkarshRaj](https://github.com/NishkarshRaj), and [Gaurav Sarien](mailto:gaurav.sarien@statusneo.com) | Harnessing the power of central catalog inventory and self-serving software templates | -| [Contino](https://www.contino.io/) | [Joseph Patterson](mailto:joseph.patterson@contino.io) | Building out a central catalog for our software community | diff --git a/packages/core-components/src/components/Table/Table.tsx b/packages/core-components/src/components/Table/Table.tsx index 13f77106e0..49538b680a 100644 --- a/packages/core-components/src/components/Table/Table.tsx +++ b/packages/core-components/src/components/Table/Table.tsx @@ -373,7 +373,7 @@ export function Table(props: TableProps) { const newData = (data as any[]).filter( el => !!Object.entries(selectedFilters) - .filter(([, value]) => !!(value as []).length) + .filter(([, value]) => !!value.length) .every(([key, filterValue]) => { const fieldValue = extractValueByField( el, From d7b0a117686ba30d67b7d6e36a57d97ea0ae075b Mon Sep 17 00:00:00 2001 From: Joe Patterson Date: Mon, 17 Oct 2022 11:02:15 +1000 Subject: [PATCH 025/434] updating the pr on the feedback to add docs, remove some items not needed including the preview html Signed-off-by: Joe Patterson --- .../software-catalog/external-integrations.md | 126 ++++++++++++++++++ packages/catalog-model/api-report.md | 19 ++- .../src/kinds/GroupEntityV1alpha1.ts | 12 +- .../src/kinds/UserEntityV1alpha1.ts | 11 +- packages/catalog-model/src/kinds/index.ts | 2 + .../GroupProfile/GroupProfileCard.stories.tsx | 2 +- .../Group/GroupProfile/GroupProfileCard.tsx | 49 +------ .../src/components/Cards/Meta/LinksGroup.tsx | 69 ++++++++++ .../Cards/Meta/ProfileInfoGroup.tsx | 56 ++++++++ .../org/src/components/Cards/Meta/index.ts | 17 +++ .../UserProfileCard.stories.tsx | 2 +- .../User/UserProfileCard/UserProfileCard.tsx | 50 +------ storybook/.storybook/preview-head.html | 4 - 13 files changed, 302 insertions(+), 117 deletions(-) create mode 100644 plugins/org/src/components/Cards/Meta/LinksGroup.tsx create mode 100644 plugins/org/src/components/Cards/Meta/ProfileInfoGroup.tsx create mode 100644 plugins/org/src/components/Cards/Meta/index.ts delete mode 100644 storybook/.storybook/preview-head.html diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index 40f917e2f3..f074f3a641 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -261,6 +261,132 @@ the `connect` call has been made to the provider. Start up the backend - it should now start reading from the previously registered location and you'll see your entities start to appear in Backstage. +### Example User Entity Provider + +If you have a 3rd party entity provider such as an internal HR system that you wish to use you are not limited to using our entity providers, (or simply wish to add to existing entity providers with your own data). + +We can create an entity provider to read entities that are based off that provider. + +We create a basic entity provider as shown above. In the example below we might want to extract our users from an HR system, I am assuming the HR system already has the slackUserId to get that information please see the [Slack Api](https://api.slack.com/methods). + +```typescript +import { + ANNOTATION_LOCATION, + ANNOTATION_ORIGIN_LOCATION, +} from '@backstage/catalog-model' +import { + EntityProvider, + EntityProviderConnection, +} from '@backstage/plugin-catalog-backend' +import { WebClient } from '@slack/web-api' +import {kebabCase} from 'lodash' + +interface Staff { + displayName: string + slackUserId: string + jobTitle: string + photoUrl: string + address: string + email:string +} + +export class UserEntityProvider implements EntityProvider { + private readonly getStaffUrl: string + protected readonly slackTeam: string + protected readonly slackToken: string + protected connection?: EntityProviderConnection + + static fromConfig(config: Config, options: { logger: Logger }) { + const getStaffUrl = config.getString('staff.url') + const slackToken = config.getString('slack.token') + const slackTeam = config.getString('slack.team') + return new UserEntityProvider({ + ...options, + getStaffUrl, + slackToken, + slackTeam, + }) + } + + private constructor(options: { + getStaffUrl: string + slackToken: string + slackTeam: string + }) { + this.getStaffUrl = options.getStaffUrl + this.slackToken = options.slackToken + this.slackTeam = options.slackTeam + } + + async getAllStaff(): Promise{ + await return axios.get(this.getStaffUrl) + } + + public async connect(connection: EntityProviderConnection): Promise { + this.connection = connection + } + + async run(): Promise { + if (!this.connection) { + throw new Error('USer Connection Not initialized') + } + + const userResources: UserEntity[] = [] + const staff = await this.getAllStaff() + + for (const user of staff) { + // we can add any links here in this case it would be adding a slack link to the users so you can directly slack them. + const links = + user.slackUserId != null && user.slackUserId.length > 0 + ? [ + { + url: `slack://user?team=${this.slackTeam}&id=${user.slackUserId}`, + title: 'Slack', + icon: 'message', + }, + ] + : undefined + const userEntity: UserEntity = { + kind: 'User', + apiVersion: 'backstage.io/v1alpha1', + metadata: { + annotations: { + [ANNOTATION_LOCATION]: 'hr-user-https://www.hrurl.com/', + [ANNOTATION_ORIGIN_LOCATION]: 'hr-user-https://www.hrurl.com/', + }, + links, + // name of the entity + name: kebabCase(user.displayName as string), + // name for display purposes could be anything including email + title: user.displayName as string, + }, + spec: { + profile: { + displayName: user.displayName as string, + email: user.email, + picture: user.photoUrl ?? 'fake', + // we can add any string/string here and it will be displayed on a user profile card, eg Job Title, Address, or any other information you want displayed + 'Job Title': user.jobTitle as string, + 'Address': user.address, + }, + memberOf: [], + }, + } + + userResources.push(userEntity) + } + + await this.connection.applyMutation({ + type: 'full', + entities: userResources.map((entity) => ({ + entity, + locationKey: 'hr-user-https://www.hrurl.com/', + })), + }) +} + +``` + ## Custom Processors The other possible way of ingesting data into the catalog is through the use of diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md index 1a58dcb5ca..da4c335051 100644 --- a/packages/catalog-model/api-report.md +++ b/packages/catalog-model/api-report.md @@ -269,6 +269,13 @@ export { GroupEntityV1alpha1 }; // @public export const groupEntityV1alpha1Validator: KindValidator; +// @public +export type GroupProfile = Record & { + displayName?: string; + email?: string; + picture?: string; +}; + // @public (undocumented) export function isApiEntity(entity: Entity): entity is ApiEntityV1alpha1; @@ -497,6 +504,13 @@ export { UserEntityV1alpha1 }; // @public export const userEntityV1alpha1Validator: KindValidator; +// @public +export type UserProfile = Record & { + displayName?: string; + email?: string; + picture?: string; +}; + // @public export type Validators = { isValidApiVersion(value: unknown): boolean; @@ -509,9 +523,4 @@ export type Validators = { isValidAnnotationValue(value: unknown): boolean; isValidTag(value: unknown): boolean; }; - -// Warnings were encountered during analysis: -// -// src/kinds/GroupEntityV1alpha1.d.ts:23:9 - (ae-forgotten-export) The symbol "GroupProfile" needs to be exported by the entry point index.d.ts -// src/kinds/UserEntityV1alpha1.d.ts:22:9 - (ae-forgotten-export) The symbol "UserProfile" needs to be exported by the entry point index.d.ts ``` diff --git a/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts b/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts index 51f5f30f04..50304e5220 100644 --- a/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts @@ -18,18 +18,16 @@ import type { Entity } from '../entity/Entity'; import schema from '../schema/kinds/Group.v1alpha1.schema.json'; import { ajvCompiledJsonSchemaValidator } from './util'; -export interface GroupProfileStatic { - displayName?: string; - email?: string; - picture?: string; -} - /** * Backstage Group Profile. * * @public */ -export type GroupProfile = Record & GroupProfileStatic; +export type GroupProfile = Record & { + displayName?: string; + email?: string; + picture?: string; +}; /** * Backstage catalog Group kind Entity. diff --git a/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts b/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts index 39d3861702..9e034ad6b3 100644 --- a/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts @@ -18,17 +18,16 @@ import type { Entity } from '../entity/Entity'; import schema from '../schema/kinds/User.v1alpha1.schema.json'; import { ajvCompiledJsonSchemaValidator } from './util'; -export interface UserProfileStatic { - displayName?: string; - email?: string; - picture?: string; -} /** * Backstage User Profile. * * @public */ -export type UserProfile = Record & UserProfileStatic; +export type UserProfile = Record & { + displayName?: string; + email?: string; + picture?: string; +}; /** * Backstage catalog User kind Entity. diff --git a/packages/catalog-model/src/kinds/index.ts b/packages/catalog-model/src/kinds/index.ts index 7211c25a8d..dd9d0545c6 100644 --- a/packages/catalog-model/src/kinds/index.ts +++ b/packages/catalog-model/src/kinds/index.ts @@ -33,6 +33,7 @@ export { groupEntityV1alpha1Validator } from './GroupEntityV1alpha1'; export type { GroupEntityV1alpha1 as GroupEntity, GroupEntityV1alpha1, + GroupProfile, } from './GroupEntityV1alpha1'; export { locationEntityV1alpha1Validator } from './LocationEntityV1alpha1'; export type { @@ -55,4 +56,5 @@ export { userEntityV1alpha1Validator } from './UserEntityV1alpha1'; export type { UserEntityV1alpha1 as UserEntity, UserEntityV1alpha1, + UserProfile, } from './UserEntityV1alpha1'; diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx index 7d28b5a2fa..264c4081d7 100644 --- a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx +++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx @@ -98,7 +98,7 @@ const extraDetailsEntity: GroupEntity = { { url: 'slack://user?team=T00000000&id=U00000000', title: 'Slack', - icon: 'message', + icon: 'chat', }, { url: 'https://www.google.com', diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx index c12b4b8906..e6cd183e8f 100644 --- a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx +++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx @@ -37,13 +37,10 @@ import { ListItemText, Tooltip, IconButton, - Divider, } from '@material-ui/core'; -import Icon from '@material-ui/core/Icon'; import AccountTreeIcon from '@material-ui/icons/AccountTree'; import EmailIcon from '@material-ui/icons/Email'; import GroupIcon from '@material-ui/icons/Group'; -import LinkIcon from '@material-ui/icons/Link'; import EditIcon from '@material-ui/icons/Edit'; import CachedIcon from '@material-ui/icons/Cached'; import Alert from '@material-ui/lab/Alert'; @@ -55,8 +52,7 @@ import { Link, } from '@backstage/core-components'; import { alertApiRef, useApi } from '@backstage/core-plugin-api'; - -const staticProfileKeys = ['displayName', 'email', 'picture']; +import { LinksGroup, ProfileInfoGroup } from '../../Meta'; const CardTitle = (props: { title: string }) => ( @@ -99,11 +95,6 @@ export const GroupProfileCard = (props: { variant?: InfoCardVariants }) => { const entityMetadataEditUrl = group.metadata.annotations?.[ANNOTATION_EDIT_URL]; - const profileKeys = - profile !== undefined - ? Object.keys(profile).filter(key => !staticProfileKeys.includes(key)) - : []; - const displayName = profile?.displayName ?? name; const emailHref = profile?.email ? `mailto:${profile.email}` : '#'; const infoCardAction = entityMetadataEditUrl ? ( @@ -200,42 +191,8 @@ export const GroupProfileCard = (props: { variant?: InfoCardVariants }) => { secondary="Child Groups" /> - {links !== undefined && } - {links !== undefined && - links.map(link => { - return ( - - {link.icon ? ( - - - {link.icon} - - - ) : ( - - - - )} - {link.title} - - ); - })} - {profile !== undefined && profileKeys.length > 0 && } - {profile !== undefined && - profileKeys.length > 0 && - profileKeys.map(key => { - const value = profile[key]; - - return ( - - - {key} - - - {value} - - ); - })} + + diff --git a/plugins/org/src/components/Cards/Meta/LinksGroup.tsx b/plugins/org/src/components/Cards/Meta/LinksGroup.tsx new file mode 100644 index 0000000000..e826c1cf9c --- /dev/null +++ b/plugins/org/src/components/Cards/Meta/LinksGroup.tsx @@ -0,0 +1,69 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { EntityLink } from '@backstage/catalog-model'; +import { IconComponent, useApp } from '@backstage/core-plugin-api'; +import LanguageIcon from '@material-ui/icons/Language'; +import { + ListItem, + ListItemIcon, + ListItemText, + Divider, +} from '@material-ui/core'; +import React, { useCallback } from 'react'; + +const WebLink = ({ + href, + Icon, + text, +}: { + href: string; + text?: string; + Icon?: IconComponent; +}) => ( + + {Icon ? : } + {text} + +); + +export const LinksGroup = ({ links }: { links?: EntityLink[] }) => { + const app = useApp(); + const iconResolver = useCallback( + (key?: string): IconComponent => + key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon, + [app], + ); + + if (links === undefined) { + return null; + } + + return ( + <> + + {links.map(link => { + return ( + + ); + })} + + ); +}; diff --git a/plugins/org/src/components/Cards/Meta/ProfileInfoGroup.tsx b/plugins/org/src/components/Cards/Meta/ProfileInfoGroup.tsx new file mode 100644 index 0000000000..177983d4a5 --- /dev/null +++ b/plugins/org/src/components/Cards/Meta/ProfileInfoGroup.tsx @@ -0,0 +1,56 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ListItem, ListItemText, Divider } from '@material-ui/core'; +import React, { useMemo } from 'react'; + +const staticProfileKeys = ['displayName', 'email', 'picture']; + +export const ProfileInfoGroup = ({ + profile, +}: { + profile?: Record; +}) => { + const profileKeys = useMemo( + () => + profile !== undefined + ? Object.keys(profile).filter(key => !staticProfileKeys.includes(key)) + : [], + [profile], + ); + + if (profile === undefined || profileKeys.length === 0) { + return null; + } + + return ( + <> + + {profileKeys.map(key => { + const value = profile[key]; + + return ( + + + {key} + + + {value} + + ); + })} + + ); +}; diff --git a/plugins/org/src/components/Cards/Meta/index.ts b/plugins/org/src/components/Cards/Meta/index.ts new file mode 100644 index 0000000000..5f4e5b4690 --- /dev/null +++ b/plugins/org/src/components/Cards/Meta/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './LinksGroup'; +export * from './ProfileInfoGroup'; diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx index 28fc3d3831..7abfbee389 100644 --- a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx +++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx @@ -113,7 +113,7 @@ const extraDetailsEntity: UserEntity = { { url: 'slack://user?team=T00000000&id=U00000000', title: 'Slack', - icon: 'message', + icon: 'chat', }, { url: 'https://www.google.com', diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx index 68a27764d8..8a56dc58c2 100644 --- a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx +++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx @@ -33,15 +33,12 @@ import { ListItemIcon, ListItemText, Tooltip, - Divider, } from '@material-ui/core'; import EditIcon from '@material-ui/icons/Edit'; import EmailIcon from '@material-ui/icons/Email'; import GroupIcon from '@material-ui/icons/Group'; import PersonIcon from '@material-ui/icons/Person'; -import LinkIcon from '@material-ui/icons/Link'; import Alert from '@material-ui/lab/Alert'; -import Icon from '@material-ui/core/Icon'; import React from 'react'; import { Avatar, @@ -49,8 +46,7 @@ import { InfoCardVariants, Link, } from '@backstage/core-components'; - -const staticProfileKeys = ['displayName', 'email', 'picture']; +import { LinksGroup, ProfileInfoGroup } from '../../Meta'; const CardTitle = (props: { title?: string }) => props.title ? ( @@ -80,11 +76,6 @@ export const UserProfileCard = (props: { variant?: InfoCardVariants }) => { kind: 'Group', }); - const profileKeys = - profile !== undefined - ? Object.keys(profile).filter(key => !staticProfileKeys.includes(key)) - : []; - return ( } @@ -139,43 +130,8 @@ export const UserProfileCard = (props: { variant?: InfoCardVariants }) => { - {links !== undefined && } - {links !== undefined && - links.map(link => { - return ( - - {link.icon ? ( - - - {link.icon} - - - ) : ( - - - - )} - {link.title} - - ); - })} - - {profile !== undefined && profileKeys.length > 0 && } - {profile !== undefined && - profileKeys.length > 0 && - profileKeys.map(key => { - const value = profile[key]; - - return ( - - - {key} - - - {value} - - ); - })} + + diff --git a/storybook/.storybook/preview-head.html b/storybook/.storybook/preview-head.html deleted file mode 100644 index a21b9971e8..0000000000 --- a/storybook/.storybook/preview-head.html +++ /dev/null @@ -1,4 +0,0 @@ - From e96274f1fe17587b33141f12d005019870dba176 Mon Sep 17 00:00:00 2001 From: djamaile Date: Tue, 18 Oct 2022 14:26:18 +0200 Subject: [PATCH 026/434] feat: create new plugin called org-react Signed-off-by: djamaile --- .changeset/great-planes-arrive.md | 5 ++ plugins/catalog-react/api-report.md | 21 ------- plugins/catalog-react/src/components/index.ts | 1 - plugins/org-react/.eslintrc.js | 1 + plugins/org-react/README.md | 13 ++++ plugins/org-react/api-report.md | 15 +++++ plugins/org-react/package.json | 62 +++++++++++++++++++ .../GroupListPicker/GroupListPicker.test.tsx | 2 +- .../GroupListPicker/GroupListPicker.tsx | 21 ++++--- .../GroupListPicker/GroupListPickerButton.tsx | 7 +-- .../src/components/GroupListPicker/index.ts | 2 - plugins/org-react/src/index.ts | 16 +++++ plugins/org-react/src/plugin.test.ts | 22 +++++++ plugins/org-react/src/plugin.ts | 37 +++++++++++ plugins/org-react/src/routes.ts | 20 ++++++ plugins/org-react/src/setupTests.ts | 17 +++++ yarn.lock | 30 +++++++++ 17 files changed, 254 insertions(+), 38 deletions(-) create mode 100644 .changeset/great-planes-arrive.md create mode 100644 plugins/org-react/.eslintrc.js create mode 100644 plugins/org-react/README.md create mode 100644 plugins/org-react/api-report.md create mode 100644 plugins/org-react/package.json rename plugins/{catalog-react => org-react}/src/components/GroupListPicker/GroupListPicker.test.tsx (97%) rename plugins/{catalog-react => org-react}/src/components/GroupListPicker/GroupListPicker.tsx (84%) rename plugins/{catalog-react => org-react}/src/components/GroupListPicker/GroupListPickerButton.tsx (95%) rename plugins/{catalog-react => org-react}/src/components/GroupListPicker/index.ts (83%) create mode 100644 plugins/org-react/src/index.ts create mode 100644 plugins/org-react/src/plugin.test.ts create mode 100644 plugins/org-react/src/plugin.ts create mode 100644 plugins/org-react/src/routes.ts create mode 100644 plugins/org-react/src/setupTests.ts diff --git a/.changeset/great-planes-arrive.md b/.changeset/great-planes-arrive.md new file mode 100644 index 0000000000..92a5b985cd --- /dev/null +++ b/.changeset/great-planes-arrive.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-org-react': minor +--- + +Added a `GroupListPicker` component that will give the user the ability to choose a group diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index e4fcd59857..e8f0b0e6ee 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -446,27 +446,6 @@ export function getEntitySourceLocation( scmIntegrationsApi: ScmIntegrationRegistry, ): EntitySourceLocation | undefined; -// @public (undocumented) -export const GroupListPicker: (props: GroupListPickerProps) => JSX.Element; - -// @public (undocumented) -export const GroupListPickerButton: ( - props: GroupListPickerButtonProps, -) => JSX.Element; - -// @public -export type GroupListPickerButtonProps = { - handleClick: (event: React_2.MouseEvent) => void; - group: string; -}; - -// @public -export type GroupListPickerProps = { - placeholder?: string; - groupTypes: Array; - defaultGroup?: string; -}; - // @public (undocumented) export function humanizeEntityRef( entityRef: Entity | CompoundEntityRef, diff --git a/plugins/catalog-react/src/components/index.ts b/plugins/catalog-react/src/components/index.ts index 90fe108ab7..c604306ead 100644 --- a/plugins/catalog-react/src/components/index.ts +++ b/plugins/catalog-react/src/components/index.ts @@ -28,4 +28,3 @@ export * from './InspectEntityDialog'; export * from './UnregisterEntityDialog'; export * from './UserListPicker'; export * from './EntityProcessingStatusPicker'; -export * from './GroupListPicker'; diff --git a/plugins/org-react/.eslintrc.js b/plugins/org-react/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/org-react/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/org-react/README.md b/plugins/org-react/README.md new file mode 100644 index 0000000000..f89119f85e --- /dev/null +++ b/plugins/org-react/README.md @@ -0,0 +1,13 @@ +# org-react + +Welcome to the org-react plugin! + +_This plugin was created through the Backstage CLI_ + +## Getting started + +Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/org-react](http://localhost:3000/org-react). + +You can also serve the plugin in isolation by running `yarn start` in the plugin directory. +This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. +It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. diff --git a/plugins/org-react/api-report.md b/plugins/org-react/api-report.md new file mode 100644 index 0000000000..d3db0d62c4 --- /dev/null +++ b/plugins/org-react/api-report.md @@ -0,0 +1,15 @@ +## API Report File for "@backstage/plugin-org-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +// Warning: (ae-forgotten-export) The symbol "GroupListPickerProps" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "GroupListPicker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const GroupListPicker: (props: GroupListPickerProps) => JSX.Element; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json new file mode 100644 index 0000000000..b7b87f9aca --- /dev/null +++ b/plugins/org-react/package.json @@ -0,0 +1,62 @@ +{ + "name": "@backstage/plugin-org-react", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "web-library" + }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/org-react" + }, + "keywords": [ + "backstage" + ], + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/catalog-client": "workspace:^", + "@backstage/catalog-model": "workspace:^", + "@backstage/core-components": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/plugin-catalog-react": "workspace:^", + "@backstage/theme": "workspace:^", + "@material-ui/core": "^4.9.13", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.57", + "react-use": "^17.2.4" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/core-app-api": "workspace:^", + "@backstage/dev-utils": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/user-event": "^14.0.0", + "@types/node": "*", + "cross-fetch": "^3.1.5", + "msw": "^0.47.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.test.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx similarity index 97% rename from plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.test.tsx rename to plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx index 6b89612354..5d8599528c 100644 --- a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.test.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { fireEvent, render, waitFor } from '@testing-library/react'; import { ApiProvider } from '@backstage/core-app-api'; -import { catalogApiRef } from '../../api'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; import { CatalogApi } from '@backstage/catalog-client'; import { GroupListPicker } from '../GroupListPicker'; import { GroupEntity } from '@backstage/catalog-model'; diff --git a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx similarity index 84% rename from plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx rename to plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx index ccb2690da0..fe01c91479 100644 --- a/plugins/catalog-react/src/components/GroupListPicker/GroupListPicker.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx @@ -15,14 +15,17 @@ */ import React from 'react'; -import { catalogApiRef } from '../../api'; +import { + catalogApiRef, + humanizeEntityRef, +} from '@backstage/plugin-catalog-react'; import TextField from '@material-ui/core/TextField'; import Autocomplete from '@material-ui/lab/Autocomplete'; import useAsync from 'react-use/lib/useAsync'; import Popover from '@material-ui/core/Popover'; import { useApi } from '@backstage/core-plugin-api'; import { ResponseErrorPanel } from '@backstage/core-components'; -import { GroupEntity } from '@backstage/catalog-model'; +import { Entity, GroupEntity } from '@backstage/catalog-model'; import { GroupListPickerButton } from './GroupListPickerButton'; /** @@ -32,7 +35,7 @@ import { GroupListPickerButton } from './GroupListPickerButton'; */ export type GroupListPickerProps = { placeholder?: string; - groupTypes: Array; + groupTypes?: Array; defaultGroup?: string; }; @@ -63,7 +66,7 @@ export const GroupListPicker = (props: GroupListPickerProps) => { const groupsList = await catalogApi.getEntities({ filter: { kind: 'Group', - 'spec.type': groupTypes, + 'spec.type': groupTypes || [], }, }); @@ -74,6 +77,9 @@ export const GroupListPicker = (props: GroupListPickerProps) => { return ; } + const getHumanEntityRef = (entity: Entity) => + humanizeEntityRef(entity, { defaultNamespace: false }); + return ( <> { options={groups ?? []} groupBy={option => option.spec.type} getOptionLabel={option => - option.spec.profile?.displayName ?? option.metadata.name + option.spec.profile?.displayName ?? getHumanEntityRef(option) } inputValue={inputValue} onInputChange={(_, value) => setInputValue(value)} onChange={(_, newValue) => { if (newValue) { setGroup( - newValue.spec.profile?.displayName ?? newValue.metadata.name, + newValue.spec.profile?.displayName ?? + getHumanEntityRef(newValue), ); } setInputValue(''); }} - style={{ width: '200px' }} + style={{ width: '300px' }} renderInput={params => ( ({ }, })); -/** - * Props for {@link GroupListPickerButton}. - * - * @public - */ -export type GroupListPickerButtonProps = { +type GroupListPickerButtonProps = { handleClick: (event: React.MouseEvent) => void; group: string; }; diff --git a/plugins/catalog-react/src/components/GroupListPicker/index.ts b/plugins/org-react/src/components/GroupListPicker/index.ts similarity index 83% rename from plugins/catalog-react/src/components/GroupListPicker/index.ts rename to plugins/org-react/src/components/GroupListPicker/index.ts index 20c4502838..fe1ba8e1ee 100644 --- a/plugins/catalog-react/src/components/GroupListPicker/index.ts +++ b/plugins/org-react/src/components/GroupListPicker/index.ts @@ -15,6 +15,4 @@ */ export { GroupListPicker } from './GroupListPicker'; -export { GroupListPickerButton } from './GroupListPickerButton'; export type { GroupListPickerProps } from './GroupListPicker'; -export type { GroupListPickerButtonProps } from './GroupListPickerButton'; diff --git a/plugins/org-react/src/index.ts b/plugins/org-react/src/index.ts new file mode 100644 index 0000000000..5e834bbf2f --- /dev/null +++ b/plugins/org-react/src/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { GroupListPicker } from './plugin'; diff --git a/plugins/org-react/src/plugin.test.ts b/plugins/org-react/src/plugin.test.ts new file mode 100644 index 0000000000..4a9d976a89 --- /dev/null +++ b/plugins/org-react/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { orgReactPlugin } from './plugin'; + +describe('org-react', () => { + it('should export plugin', () => { + expect(orgReactPlugin).toBeDefined(); + }); +}); diff --git a/plugins/org-react/src/plugin.ts b/plugins/org-react/src/plugin.ts new file mode 100644 index 0000000000..bc51e3cd73 --- /dev/null +++ b/plugins/org-react/src/plugin.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + createPlugin, + createRoutableExtension, +} from '@backstage/core-plugin-api'; + +import { rootRouteRef } from './routes'; + +export const orgReactPlugin = createPlugin({ + id: 'org-react', + routes: { + root: rootRouteRef, + }, +}); + +export const GroupListPicker = orgReactPlugin.provide( + createRoutableExtension({ + name: 'GroupListPicker', + component: () => + import('./components/GroupListPicker').then(m => m.GroupListPicker), + mountPoint: rootRouteRef, + }), +); diff --git a/plugins/org-react/src/routes.ts b/plugins/org-react/src/routes.ts new file mode 100644 index 0000000000..80acc0eb48 --- /dev/null +++ b/plugins/org-react/src/routes.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createRouteRef } from '@backstage/core-plugin-api'; + +export const rootRouteRef = createRouteRef({ + id: 'org-react', +}); diff --git a/plugins/org-react/src/setupTests.ts b/plugins/org-react/src/setupTests.ts new file mode 100644 index 0000000000..9bb3e72355 --- /dev/null +++ b/plugins/org-react/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import '@testing-library/jest-dom'; +import 'cross-fetch/polyfill'; diff --git a/yarn.lock b/yarn.lock index 9d8a6ff504..1252586b92 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6182,6 +6182,35 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-org-react@^0.0.0, @backstage/plugin-org-react@workspace:plugins/org-react": + version: 0.0.0-use.local + resolution: "@backstage/plugin-org-react@workspace:plugins/org-react" + dependencies: + "@backstage/catalog-client": "workspace:^" + "@backstage/catalog-model": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/core-app-api": "workspace:^" + "@backstage/core-components": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/dev-utils": "workspace:^" + "@backstage/plugin-catalog-react": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@backstage/theme": "workspace:^" + "@material-ui/core": ^4.9.13 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": ^4.0.0-alpha.57 + "@testing-library/jest-dom": ^5.10.1 + "@testing-library/react": ^12.1.3 + "@testing-library/user-event": ^14.0.0 + "@types/node": "*" + cross-fetch: ^3.1.5 + msw: ^0.47.0 + react-use: ^17.2.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 + languageName: unknown + linkType: soft + "@backstage/plugin-org@workspace:^, @backstage/plugin-org@workspace:plugins/org": version: 0.0.0-use.local resolution: "@backstage/plugin-org@workspace:plugins/org" @@ -22153,6 +22182,7 @@ __metadata: "@backstage/plugin-newrelic": "workspace:^" "@backstage/plugin-newrelic-dashboard": "workspace:^" "@backstage/plugin-org": "workspace:^" + "@backstage/plugin-org-react": "workspace:^" "@backstage/plugin-pagerduty": "workspace:^" "@backstage/plugin-permission-react": "workspace:^" "@backstage/plugin-playlist": "workspace:^" From b4e86dc00a3ca1d832f44b86be3c2781d2c3d25a Mon Sep 17 00:00:00 2001 From: djamaile Date: Tue, 18 Oct 2022 15:14:54 +0200 Subject: [PATCH 027/434] fix: yarn lock Signed-off-by: djamaile --- .changeset/hungry-rocks-bathe.md | 5 ----- yarn.lock | 3 +-- 2 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 .changeset/hungry-rocks-bathe.md diff --git a/.changeset/hungry-rocks-bathe.md b/.changeset/hungry-rocks-bathe.md deleted file mode 100644 index 7c22f1b368..0000000000 --- a/.changeset/hungry-rocks-bathe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-react': patch ---- - -Added a `AutoComplete` component that will give the user the ability to choose a group diff --git a/yarn.lock b/yarn.lock index 1252586b92..a5598f14cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6182,7 +6182,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-org-react@^0.0.0, @backstage/plugin-org-react@workspace:plugins/org-react": +"@backstage/plugin-org-react@workspace:plugins/org-react": version: 0.0.0-use.local resolution: "@backstage/plugin-org-react@workspace:plugins/org-react" dependencies: @@ -22182,7 +22182,6 @@ __metadata: "@backstage/plugin-newrelic": "workspace:^" "@backstage/plugin-newrelic-dashboard": "workspace:^" "@backstage/plugin-org": "workspace:^" - "@backstage/plugin-org-react": "workspace:^" "@backstage/plugin-pagerduty": "workspace:^" "@backstage/plugin-permission-react": "workspace:^" "@backstage/plugin-playlist": "workspace:^" From 6e5f08d260b639538b2e0cba148c6fa83860e069 Mon Sep 17 00:00:00 2001 From: djamaile Date: Tue, 18 Oct 2022 15:47:19 +0200 Subject: [PATCH 028/434] chore: update changeset Signed-off-by: djamaile --- .changeset/great-planes-arrive.md | 2 +- .../src/components/GroupListPicker/GroupListPicker.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/great-planes-arrive.md b/.changeset/great-planes-arrive.md index 92a5b985cd..563c061627 100644 --- a/.changeset/great-planes-arrive.md +++ b/.changeset/great-planes-arrive.md @@ -2,4 +2,4 @@ '@backstage/plugin-org-react': minor --- -Added a `GroupListPicker` component that will give the user the ability to choose a group +Implemented the org-react plugin, with it's first component being: a `GroupListPicker` component that will give the user the ability to choose a group diff --git a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx index fe01c91479..fbac4792ae 100644 --- a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx @@ -71,7 +71,7 @@ export const GroupListPicker = (props: GroupListPickerProps) => { }); return groupsList.items as GroupEntity[]; - }, [catalogApi]); + }, [catalogApi, groupTypes]); if (error) { return ; From 8be435714b24d198f03de83fa75e421a3fe2b41c Mon Sep 17 00:00:00 2001 From: djamaile Date: Tue, 18 Oct 2022 16:40:37 +0200 Subject: [PATCH 029/434] fix: export props and mark component public Signed-off-by: djamaile --- plugins/org-react/api-report.md | 10 +++++++--- plugins/org-react/src/index.ts | 1 + plugins/org-react/src/plugin.ts | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/org-react/api-report.md b/plugins/org-react/api-report.md index d3db0d62c4..da164ec053 100644 --- a/plugins/org-react/api-report.md +++ b/plugins/org-react/api-report.md @@ -5,11 +5,15 @@ ```ts /// -// Warning: (ae-forgotten-export) The symbol "GroupListPickerProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "GroupListPicker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const GroupListPicker: (props: GroupListPickerProps) => JSX.Element; +// @public +export type GroupListPickerProps = { + placeholder?: string; + groupTypes?: Array; + defaultGroup?: string; +}; + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/org-react/src/index.ts b/plugins/org-react/src/index.ts index 5e834bbf2f..731702c80c 100644 --- a/plugins/org-react/src/index.ts +++ b/plugins/org-react/src/index.ts @@ -14,3 +14,4 @@ * limitations under the License. */ export { GroupListPicker } from './plugin'; +export type { GroupListPickerProps } from './components/GroupListPicker'; diff --git a/plugins/org-react/src/plugin.ts b/plugins/org-react/src/plugin.ts index bc51e3cd73..0158ff1b06 100644 --- a/plugins/org-react/src/plugin.ts +++ b/plugins/org-react/src/plugin.ts @@ -27,6 +27,7 @@ export const orgReactPlugin = createPlugin({ }, }); +/** @public */ export const GroupListPicker = orgReactPlugin.provide( createRoutableExtension({ name: 'GroupListPicker', From 30de23453d5b5ba84ddbaab6ca717d1134f14411 Mon Sep 17 00:00:00 2001 From: djamaile Date: Tue, 18 Oct 2022 17:29:10 +0200 Subject: [PATCH 030/434] chore: update the README Signed-off-by: djamaile --- .github/CODEOWNERS | 1 + plugins/org-react/README.md | 28 +++++++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cb1dd5d322..89b3d301fa 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -49,6 +49,7 @@ yarn.lock @backstage/reviewers @backst /plugins/kubernetes @backstage/reviewers @backstage/warpspeed /plugins/kubernetes-* @backstage/reviewers @backstage/warpspeed /plugins/newrelic-dashboard @backstage/reviewers @mufaddal7 +/plugins/org-react @backstage/reviewers /plugins/playlist @backstage/reviewers @kuangp /plugins/playlist-* @backstage/reviewers @kuangp /plugins/scaffolder-backend-module-rails @backstage/reviewers @angeliski diff --git a/plugins/org-react/README.md b/plugins/org-react/README.md index f89119f85e..9c51462f91 100644 --- a/plugins/org-react/README.md +++ b/plugins/org-react/README.md @@ -1,13 +1,27 @@ # org-react -Welcome to the org-react plugin! +## features -_This plugin was created through the Backstage CLI_ +- Group list picker component -## Getting started +### GroupListPicker -Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/org-react](http://localhost:3000/org-react). +The `GroupListPicker` component displays a select box which also has autocomplete functionality. -You can also serve the plugin in isolation by running `yarn start` in the plugin directory. -This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. -It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. +To use the `GroupListPicker` component you'll need to import it and add it to your desired place. + +```diff ++ import { GroupListPicker } from '@backstage/plugin-org-react'; + + + ++ + + +``` + +The `GroupListPicker` comes with three optional props: + +- **groupTypes**: gives the user the option which group types the component should load. If no value is provided all group types will be loaded in; +- **defaultGroup**: which group by default should be selected. For example, a group of the logged in user; +- **placeholder**: the placeholder that the select box in the component should display. This might be helpfull in informing your users what the functionality of the component is. From 443a65441963da12fae8d3b6a68df5ffe421cf17 Mon Sep 17 00:00:00 2001 From: djamaile Date: Tue, 18 Oct 2022 17:33:25 +0200 Subject: [PATCH 031/434] fix: make vale happy or else Signed-off-by: djamaile --- plugins/org-react/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/org-react/README.md b/plugins/org-react/README.md index 9c51462f91..10afde4e65 100644 --- a/plugins/org-react/README.md +++ b/plugins/org-react/README.md @@ -22,6 +22,6 @@ To use the `GroupListPicker` component you'll need to import it and add it to yo The `GroupListPicker` comes with three optional props: -- **groupTypes**: gives the user the option which group types the component should load. If no value is provided all group types will be loaded in; -- **defaultGroup**: which group by default should be selected. For example, a group of the logged in user; -- **placeholder**: the placeholder that the select box in the component should display. This might be helpfull in informing your users what the functionality of the component is. +- `groupTypes`: gives the user the option which group types the component should load. If no value is provided all group types will be loaded in; +- `defaultGroup`: which group by default should be selected. For example, a group of the logged in user; +- `placeholder`: the placeholder that the select box in the component should display. This might be helpful in informing your users what the functionality of the component is. From 0f6c6e84fb05371f8c0ecdecc0cf797302c98256 Mon Sep 17 00:00:00 2001 From: Joe Patterson Date: Wed, 19 Oct 2022 14:35:03 +1000 Subject: [PATCH 032/434] Update docs/features/software-catalog/external-integrations.md Co-authored-by: Patrik Oldsberg Signed-off-by: Joe Patterson --- docs/features/software-catalog/external-integrations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index f074f3a641..a93e77dc00 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -328,7 +328,7 @@ export class UserEntityProvider implements EntityProvider { async run(): Promise { if (!this.connection) { - throw new Error('USer Connection Not initialized') + throw new Error('User Connection Not initialized') } const userResources: UserEntity[] = [] From 6d42dfe385bc165e51fcd99838a1c65c7a80c10f Mon Sep 17 00:00:00 2001 From: Joe Patterson Date: Wed, 19 Oct 2022 14:35:25 +1000 Subject: [PATCH 033/434] Update docs/features/software-catalog/external-integrations.md Co-authored-by: Patrik Oldsberg Signed-off-by: Joe Patterson --- docs/features/software-catalog/external-integrations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index a93e77dc00..57ee9baf25 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -318,7 +318,7 @@ export class UserEntityProvider implements EntityProvider { this.slackTeam = options.slackTeam } - async getAllStaff(): Promise{ + async getAllStaff(): Promise{ await return axios.get(this.getStaffUrl) } From dc50ba192b0a2205ab4d4f799944bb6fc5667be6 Mon Sep 17 00:00:00 2001 From: Joe Patterson Date: Wed, 19 Oct 2022 14:35:44 +1000 Subject: [PATCH 034/434] Update docs/features/software-catalog/external-integrations.md Co-authored-by: Patrik Oldsberg Signed-off-by: Joe Patterson --- docs/features/software-catalog/external-integrations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index 57ee9baf25..65f019efa3 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -380,7 +380,7 @@ export class UserEntityProvider implements EntityProvider { type: 'full', entities: userResources.map((entity) => ({ entity, - locationKey: 'hr-user-https://www.hrurl.com/', + locationKey: 'hr-user:https://www.hrurl.com', })), }) } From 0b115001515c3abc4764b3b4b707889caa5f5131 Mon Sep 17 00:00:00 2001 From: Joe Patterson Date: Wed, 19 Oct 2022 15:09:49 +1000 Subject: [PATCH 035/434] update pr to remove profile changes Signed-off-by: Joe Patterson --- .changeset/popular-ants-mix.md | 5 ++ .changeset/tender-jeans-clean.md | 12 ---- .../software-catalog/external-integrations.md | 13 ++--- packages/catalog-model/api-report.md | 26 ++++----- .../src/kinds/GroupEntityV1alpha1.ts | 17 ++---- .../src/kinds/UserEntityV1alpha1.ts | 17 ++---- packages/catalog-model/src/kinds/index.ts | 2 - .../GroupProfile/GroupProfileCard.stories.tsx | 2 - .../Group/GroupProfile/GroupProfileCard.tsx | 3 +- .../Cards/Meta/ProfileInfoGroup.tsx | 56 ------------------- .../org/src/components/Cards/Meta/index.ts | 1 - .../UserProfileCard.stories.tsx | 3 - .../UserProfileCard/UserProfileCard.test.tsx | 7 --- .../User/UserProfileCard/UserProfileCard.tsx | 3 +- 14 files changed, 32 insertions(+), 135 deletions(-) create mode 100644 .changeset/popular-ants-mix.md delete mode 100644 .changeset/tender-jeans-clean.md delete mode 100644 plugins/org/src/components/Cards/Meta/ProfileInfoGroup.tsx diff --git a/.changeset/popular-ants-mix.md b/.changeset/popular-ants-mix.md new file mode 100644 index 0000000000..f0e6b17f8d --- /dev/null +++ b/.changeset/popular-ants-mix.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-org': minor +--- + +Updates the User and Group Profile cards to add the links from the UserEntity or the GroupEntity diff --git a/.changeset/tender-jeans-clean.md b/.changeset/tender-jeans-clean.md deleted file mode 100644 index 2729fa393a..0000000000 --- a/.changeset/tender-jeans-clean.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@backstage/catalog-model': minor -'@backstage/plugin-org': minor ---- - -Updates the profile of Group and User to allow any extra string key pair value. - -Then updates the user profile and group profile cards to display any links and extra profile details. - -This allows extra customization without going down the full customization route. - -So for example if you wanted to add address, phone number, job title, slack link to users or departments this allows you to within the current spec diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index 65f019efa3..65f97fb8da 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -356,18 +356,15 @@ export class UserEntityProvider implements EntityProvider { }, links, // name of the entity - name: kebabCase(user.displayName as string), + name: kebabCase(user.displayName), // name for display purposes could be anything including email - title: user.displayName as string, + title: user.displayName, }, spec: { profile: { - displayName: user.displayName as string, + displayName: user.displayName, email: user.email, - picture: user.photoUrl ?? 'fake', - // we can add any string/string here and it will be displayed on a user profile card, eg Job Title, Address, or any other information you want displayed - 'Job Title': user.jobTitle as string, - 'Address': user.address, + picture: user.photoUrl, }, memberOf: [], }, @@ -380,7 +377,7 @@ export class UserEntityProvider implements EntityProvider { type: 'full', entities: userResources.map((entity) => ({ entity, - locationKey: 'hr-user:https://www.hrurl.com', + locationKey: 'hr-user-https://www.hrurl.com/', })), }) } diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md index da4c335051..b7456bb2f8 100644 --- a/packages/catalog-model/api-report.md +++ b/packages/catalog-model/api-report.md @@ -257,7 +257,11 @@ interface GroupEntityV1alpha1 extends Entity { // (undocumented) spec: { type: string; - profile?: GroupProfile; + profile?: { + displayName?: string; + email?: string; + picture?: string; + }; parent?: string; children: string[]; members?: string[]; @@ -269,13 +273,6 @@ export { GroupEntityV1alpha1 }; // @public export const groupEntityV1alpha1Validator: KindValidator; -// @public -export type GroupProfile = Record & { - displayName?: string; - email?: string; - picture?: string; -}; - // @public (undocumented) export function isApiEntity(entity: Entity): entity is ApiEntityV1alpha1; @@ -494,7 +491,11 @@ interface UserEntityV1alpha1 extends Entity { kind: 'User'; // (undocumented) spec: { - profile?: UserProfile; + profile?: { + displayName?: string; + email?: string; + picture?: string; + }; memberOf?: string[]; }; } @@ -504,13 +505,6 @@ export { UserEntityV1alpha1 }; // @public export const userEntityV1alpha1Validator: KindValidator; -// @public -export type UserProfile = Record & { - displayName?: string; - email?: string; - picture?: string; -}; - // @public export type Validators = { isValidApiVersion(value: unknown): boolean; diff --git a/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts b/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts index 50304e5220..8d88817dbe 100644 --- a/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts @@ -18,17 +18,6 @@ import type { Entity } from '../entity/Entity'; import schema from '../schema/kinds/Group.v1alpha1.schema.json'; import { ajvCompiledJsonSchemaValidator } from './util'; -/** - * Backstage Group Profile. - * - * @public - */ -export type GroupProfile = Record & { - displayName?: string; - email?: string; - picture?: string; -}; - /** * Backstage catalog Group kind Entity. * @@ -39,7 +28,11 @@ export interface GroupEntityV1alpha1 extends Entity { kind: 'Group'; spec: { type: string; - profile?: GroupProfile; + profile?: { + displayName?: string; + email?: string; + picture?: string; + }; parent?: string; children: string[]; members?: string[]; diff --git a/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts b/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts index 9e034ad6b3..55c9b176ea 100644 --- a/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts @@ -18,17 +18,6 @@ import type { Entity } from '../entity/Entity'; import schema from '../schema/kinds/User.v1alpha1.schema.json'; import { ajvCompiledJsonSchemaValidator } from './util'; -/** - * Backstage User Profile. - * - * @public - */ -export type UserProfile = Record & { - displayName?: string; - email?: string; - picture?: string; -}; - /** * Backstage catalog User kind Entity. * @@ -38,7 +27,11 @@ export interface UserEntityV1alpha1 extends Entity { apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1'; kind: 'User'; spec: { - profile?: UserProfile; + profile?: { + displayName?: string; + email?: string; + picture?: string; + }; memberOf?: string[]; }; } diff --git a/packages/catalog-model/src/kinds/index.ts b/packages/catalog-model/src/kinds/index.ts index dd9d0545c6..7211c25a8d 100644 --- a/packages/catalog-model/src/kinds/index.ts +++ b/packages/catalog-model/src/kinds/index.ts @@ -33,7 +33,6 @@ export { groupEntityV1alpha1Validator } from './GroupEntityV1alpha1'; export type { GroupEntityV1alpha1 as GroupEntity, GroupEntityV1alpha1, - GroupProfile, } from './GroupEntityV1alpha1'; export { locationEntityV1alpha1Validator } from './LocationEntityV1alpha1'; export type { @@ -56,5 +55,4 @@ export { userEntityV1alpha1Validator } from './UserEntityV1alpha1'; export type { UserEntityV1alpha1 as UserEntity, UserEntityV1alpha1, - UserProfile, } from './UserEntityV1alpha1'; diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx index 264c4081d7..cfb3d847a4 100644 --- a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx +++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx @@ -112,8 +112,6 @@ const extraDetailsEntity: GroupEntity = { email: 'team-a@example.com', picture: 'https://avatars.dicebear.com/api/identicon/team-a@example.com.svg?background=%23fff&margin=25', - Telephone: '123456789', - Location: 'London', }, type: 'group', children: [], diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx index e6cd183e8f..3a6b7c238d 100644 --- a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx +++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx @@ -52,7 +52,7 @@ import { Link, } from '@backstage/core-components'; import { alertApiRef, useApi } from '@backstage/core-plugin-api'; -import { LinksGroup, ProfileInfoGroup } from '../../Meta'; +import { LinksGroup } from '../../Meta'; const CardTitle = (props: { title: string }) => ( @@ -192,7 +192,6 @@ export const GroupProfileCard = (props: { variant?: InfoCardVariants }) => { /> - diff --git a/plugins/org/src/components/Cards/Meta/ProfileInfoGroup.tsx b/plugins/org/src/components/Cards/Meta/ProfileInfoGroup.tsx deleted file mode 100644 index 177983d4a5..0000000000 --- a/plugins/org/src/components/Cards/Meta/ProfileInfoGroup.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { ListItem, ListItemText, Divider } from '@material-ui/core'; -import React, { useMemo } from 'react'; - -const staticProfileKeys = ['displayName', 'email', 'picture']; - -export const ProfileInfoGroup = ({ - profile, -}: { - profile?: Record; -}) => { - const profileKeys = useMemo( - () => - profile !== undefined - ? Object.keys(profile).filter(key => !staticProfileKeys.includes(key)) - : [], - [profile], - ); - - if (profile === undefined || profileKeys.length === 0) { - return null; - } - - return ( - <> - - {profileKeys.map(key => { - const value = profile[key]; - - return ( - - - {key} - - - {value} - - ); - })} - - ); -}; diff --git a/plugins/org/src/components/Cards/Meta/index.ts b/plugins/org/src/components/Cards/Meta/index.ts index 5f4e5b4690..076af49bf9 100644 --- a/plugins/org/src/components/Cards/Meta/index.ts +++ b/plugins/org/src/components/Cards/Meta/index.ts @@ -14,4 +14,3 @@ * limitations under the License. */ export * from './LinksGroup'; -export * from './ProfileInfoGroup'; diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx index 7abfbee389..a27be7857b 100644 --- a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx +++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx @@ -127,9 +127,6 @@ const extraDetailsEntity: UserEntity = { email: 'guest@example.com', picture: 'https://avatars.dicebear.com/api/avataaars/guest@example.com.svg?background=%23fff', - 'Job Title': 'Software Engineer', - Department: 'Engineering', - Location: 'San Francisco, CA', }, memberOf: ['team-a'], }, diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.test.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.test.tsx index 7eabdf2903..fb0df3d25f 100644 --- a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.test.tsx +++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.test.tsx @@ -183,9 +183,6 @@ describe('Edit Button', () => { profile: { displayName: 'Calum Leavy', email: 'calum-leavy@example.com', - 'Job Title': 'Software Engineer', - Department: 'Engineering', - Location: 'San Francisco, CA', }, memberOf: ['ExampleGroup'], }, @@ -209,10 +206,6 @@ describe('Edit Button', () => { }, ), ); - expect(rendered.getByText('Software Engineer')).toBeInTheDocument(); - expect(rendered.getByText('Department')).toBeInTheDocument(); - expect(rendered.getByText('San Francisco, CA')).toBeInTheDocument(); - expect(rendered.getByText('Location')).toBeInTheDocument(); expect(rendered.getByText('Slack')).toBeInTheDocument(); expect(rendered.getByText('Google')).toBeInTheDocument(); }); diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx index 8a56dc58c2..a35c1c057b 100644 --- a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx +++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx @@ -46,7 +46,7 @@ import { InfoCardVariants, Link, } from '@backstage/core-components'; -import { LinksGroup, ProfileInfoGroup } from '../../Meta'; +import { LinksGroup } from '../../Meta'; const CardTitle = (props: { title?: string }) => props.title ? ( @@ -131,7 +131,6 @@ export const UserProfileCard = (props: { variant?: InfoCardVariants }) => { - From e9cd23670267df80abed0f4eb607dfccc4a11082 Mon Sep 17 00:00:00 2001 From: djamaile Date: Wed, 19 Oct 2022 09:58:51 +0200 Subject: [PATCH 036/434] chore: remove org-react from CODEOWNERS Signed-off-by: djamaile --- .github/CODEOWNERS | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 89b3d301fa..cb1dd5d322 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -49,7 +49,6 @@ yarn.lock @backstage/reviewers @backst /plugins/kubernetes @backstage/reviewers @backstage/warpspeed /plugins/kubernetes-* @backstage/reviewers @backstage/warpspeed /plugins/newrelic-dashboard @backstage/reviewers @mufaddal7 -/plugins/org-react @backstage/reviewers /plugins/playlist @backstage/reviewers @kuangp /plugins/playlist-* @backstage/reviewers @kuangp /plugins/scaffolder-backend-module-rails @backstage/reviewers @angeliski From 420fe8a7866d57eaa1174b11af48514b75ff4474 Mon Sep 17 00:00:00 2001 From: djamaile Date: Wed, 19 Oct 2022 13:06:27 +0200 Subject: [PATCH 037/434] chore: give onChange prop the GroupListPicker component Signed-off-by: djamaile --- plugins/org-react/README.md | 8 ++++-- .../GroupListPicker/GroupListPicker.tsx | 27 +++++++++---------- .../GroupListPicker/GroupListPickerButton.tsx | 2 +- plugins/org-react/src/plugin.ts | 11 ++++---- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/plugins/org-react/README.md b/plugins/org-react/README.md index 10afde4e65..134a26d03c 100644 --- a/plugins/org-react/README.md +++ b/plugins/org-react/README.md @@ -12,10 +12,13 @@ To use the `GroupListPicker` component you'll need to import it and add it to yo ```diff + import { GroupListPicker } from '@backstage/plugin-org-react'; ++ import React, { useState } from 'react'; + ++ const [group, setGroup] = useState(); -+ ++ ``` @@ -23,5 +26,6 @@ To use the `GroupListPicker` component you'll need to import it and add it to yo The `GroupListPicker` comes with three optional props: - `groupTypes`: gives the user the option which group types the component should load. If no value is provided all group types will be loaded in; -- `defaultGroup`: which group by default should be selected. For example, a group of the logged in user; +- `initialGroup`: which group by default should be selected. For example, a group of the logged in user; - `placeholder`: the placeholder that the select box in the component should display. This might be helpful in informing your users what the functionality of the component is. +- `onChange`: a prop to help the user to give access to the selected group diff --git a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx index fbac4792ae..f0d0efb454 100644 --- a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React from 'react'; +import React, { useCallback } from 'react'; import { catalogApiRef, humanizeEntityRef, @@ -36,17 +36,17 @@ import { GroupListPickerButton } from './GroupListPickerButton'; export type GroupListPickerProps = { placeholder?: string; groupTypes?: Array; - defaultGroup?: string; + initialGroup?: string | undefined; + onChange: (value: GroupEntity | undefined) => void; }; /** @public */ export const GroupListPicker = (props: GroupListPickerProps) => { const catalogApi = useApi(catalogApiRef); - const { groupTypes, defaultGroup = '', placeholder = '' } = props; + const { onChange, groupTypes, initialGroup, placeholder = '' } = props; const [anchorEl, setAnchorEl] = React.useState(null); const [inputValue, setInputValue] = React.useState(''); - const [group, setGroup] = React.useState(defaultGroup); const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); @@ -73,6 +73,13 @@ export const GroupListPicker = (props: GroupListPickerProps) => { return groupsList.items as GroupEntity[]; }, [catalogApi, groupTypes]); + const handleChange = useCallback( + (_, v: GroupEntity | null) => { + onChange(v ?? undefined); + }, + [onChange], + ); + if (error) { return ; } @@ -98,15 +105,7 @@ export const GroupListPicker = (props: GroupListPickerProps) => { } inputValue={inputValue} onInputChange={(_, value) => setInputValue(value)} - onChange={(_, newValue) => { - if (newValue) { - setGroup( - newValue.spec.profile?.displayName ?? - getHumanEntityRef(newValue), - ); - } - setInputValue(''); - }} + onChange={handleChange} style={{ width: '300px' }} renderInput={params => ( { )} /> - + ); }; diff --git a/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx index 9e022bdf57..63fc9a983e 100644 --- a/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx @@ -47,7 +47,7 @@ const useStyles = makeStyles((theme: BackstageTheme) => ({ type GroupListPickerButtonProps = { handleClick: (event: React.MouseEvent) => void; - group: string; + group: string | undefined; }; /** @public */ diff --git a/plugins/org-react/src/plugin.ts b/plugins/org-react/src/plugin.ts index 0158ff1b06..8be5c11a4f 100644 --- a/plugins/org-react/src/plugin.ts +++ b/plugins/org-react/src/plugin.ts @@ -14,8 +14,8 @@ * limitations under the License. */ import { + createComponentExtension, createPlugin, - createRoutableExtension, } from '@backstage/core-plugin-api'; import { rootRouteRef } from './routes'; @@ -29,10 +29,11 @@ export const orgReactPlugin = createPlugin({ /** @public */ export const GroupListPicker = orgReactPlugin.provide( - createRoutableExtension({ + createComponentExtension({ name: 'GroupListPicker', - component: () => - import('./components/GroupListPicker').then(m => m.GroupListPicker), - mountPoint: rootRouteRef, + component: { + lazy: () => + import('./components/GroupListPicker').then(m => m.GroupListPicker), + }, }), ); From c71676c97e90291d598e501ce095f3cdae00fde2 Mon Sep 17 00:00:00 2001 From: djamaile Date: Wed, 19 Oct 2022 13:16:42 +0200 Subject: [PATCH 038/434] chore: clean up Signed-off-by: djamaile --- plugins/org-react/api-report.md | 5 ++++- .../src/components/GroupListPicker/GroupListPicker.test.tsx | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/org-react/api-report.md b/plugins/org-react/api-report.md index da164ec053..587f5595aa 100644 --- a/plugins/org-react/api-report.md +++ b/plugins/org-react/api-report.md @@ -5,6 +5,8 @@ ```ts /// +import { GroupEntity } from '@backstage/catalog-model'; + // @public (undocumented) export const GroupListPicker: (props: GroupListPickerProps) => JSX.Element; @@ -12,7 +14,8 @@ export const GroupListPicker: (props: GroupListPickerProps) => JSX.Element; export type GroupListPickerProps = { placeholder?: string; groupTypes?: Array; - defaultGroup?: string; + initialGroup?: string | undefined; + onChange: (value: GroupEntity | undefined) => void; }; // (No @packageDocumentation comment for this package) diff --git a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx index 5d8599528c..06d06d3b85 100644 --- a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx @@ -69,7 +69,8 @@ describe('', () => { {}} /> , ); @@ -83,6 +84,8 @@ describe('', () => { {}} /> , ); From eee9b5ac8947f4918b7818fb0402f9f31dade4e6 Mon Sep 17 00:00:00 2001 From: djamaile Date: Thu, 20 Oct 2022 10:18:44 +0200 Subject: [PATCH 039/434] chore: drop initialGroup prop Signed-off-by: djamaile --- plugins/org-react/README.md | 3 +- .../GroupListPicker/GroupListPicker.test.tsx | 16 -------- .../GroupListPicker/GroupListPicker.tsx | 5 +-- plugins/org-react/src/index.ts | 2 +- plugins/org-react/src/plugin.test.ts | 22 ----------- plugins/org-react/src/plugin.ts | 39 ------------------- 6 files changed, 4 insertions(+), 83 deletions(-) delete mode 100644 plugins/org-react/src/plugin.test.ts delete mode 100644 plugins/org-react/src/plugin.ts diff --git a/plugins/org-react/README.md b/plugins/org-react/README.md index 134a26d03c..832e41bddd 100644 --- a/plugins/org-react/README.md +++ b/plugins/org-react/README.md @@ -18,7 +18,7 @@ To use the `GroupListPicker` component you'll need to import it and add it to yo -+ ++ ``` @@ -26,6 +26,5 @@ To use the `GroupListPicker` component you'll need to import it and add it to yo The `GroupListPicker` comes with three optional props: - `groupTypes`: gives the user the option which group types the component should load. If no value is provided all group types will be loaded in; -- `initialGroup`: which group by default should be selected. For example, a group of the logged in user; - `placeholder`: the placeholder that the select box in the component should display. This might be helpful in informing your users what the functionality of the component is. - `onChange`: a prop to help the user to give access to the selected group diff --git a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx index 06d06d3b85..a011e35333 100644 --- a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx @@ -63,28 +63,12 @@ const mockCatalogApi = { const apis = TestApiRegistry.from([catalogApiRef, mockCatalogApi]); describe('', () => { - it('renders group list picker', () => { - const { queryByText } = render( - - {}} - /> - , - ); - - expect(queryByText('test')).toBeInTheDocument(); - }); - it('can choose a group', async () => { const { getByText, queryByText, getByTestId } = render( {}} /> , diff --git a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx index f0d0efb454..f08565fbfa 100644 --- a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx @@ -36,7 +36,6 @@ import { GroupListPickerButton } from './GroupListPickerButton'; export type GroupListPickerProps = { placeholder?: string; groupTypes?: Array; - initialGroup?: string | undefined; onChange: (value: GroupEntity | undefined) => void; }; @@ -44,7 +43,7 @@ export type GroupListPickerProps = { export const GroupListPicker = (props: GroupListPickerProps) => { const catalogApi = useApi(catalogApiRef); - const { onChange, groupTypes, initialGroup, placeholder = '' } = props; + const { onChange, groupTypes, placeholder = '' } = props; const [anchorEl, setAnchorEl] = React.useState(null); const [inputValue, setInputValue] = React.useState(''); @@ -116,7 +115,7 @@ export const GroupListPicker = (props: GroupListPickerProps) => { )} /> - + ); }; diff --git a/plugins/org-react/src/index.ts b/plugins/org-react/src/index.ts index 731702c80c..c3393bee48 100644 --- a/plugins/org-react/src/index.ts +++ b/plugins/org-react/src/index.ts @@ -13,5 +13,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { GroupListPicker } from './plugin'; +export { GroupListPicker } from './components/GroupListPicker'; export type { GroupListPickerProps } from './components/GroupListPicker'; diff --git a/plugins/org-react/src/plugin.test.ts b/plugins/org-react/src/plugin.test.ts deleted file mode 100644 index 4a9d976a89..0000000000 --- a/plugins/org-react/src/plugin.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { orgReactPlugin } from './plugin'; - -describe('org-react', () => { - it('should export plugin', () => { - expect(orgReactPlugin).toBeDefined(); - }); -}); diff --git a/plugins/org-react/src/plugin.ts b/plugins/org-react/src/plugin.ts deleted file mode 100644 index 8be5c11a4f..0000000000 --- a/plugins/org-react/src/plugin.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { - createComponentExtension, - createPlugin, -} from '@backstage/core-plugin-api'; - -import { rootRouteRef } from './routes'; - -export const orgReactPlugin = createPlugin({ - id: 'org-react', - routes: { - root: rootRouteRef, - }, -}); - -/** @public */ -export const GroupListPicker = orgReactPlugin.provide( - createComponentExtension({ - name: 'GroupListPicker', - component: { - lazy: () => - import('./components/GroupListPicker').then(m => m.GroupListPicker), - }, - }), -); From 1709bd952e4eaefeb7f841be6a6b811df15a3216 Mon Sep 17 00:00:00 2001 From: djamaile Date: Thu, 20 Oct 2022 10:21:17 +0200 Subject: [PATCH 040/434] chore: run api report command Signed-off-by: djamaile --- plugins/org-react/api-report.md | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/org-react/api-report.md b/plugins/org-react/api-report.md index 587f5595aa..60cd6944d0 100644 --- a/plugins/org-react/api-report.md +++ b/plugins/org-react/api-report.md @@ -14,7 +14,6 @@ export const GroupListPicker: (props: GroupListPickerProps) => JSX.Element; export type GroupListPickerProps = { placeholder?: string; groupTypes?: Array; - initialGroup?: string | undefined; onChange: (value: GroupEntity | undefined) => void; }; From c7b582195b047b5daff2249ca37def975a7bdf8a Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Thu, 20 Oct 2022 17:52:56 -0500 Subject: [PATCH 041/434] docs: Add component design guidelines Signed-off-by: Carlos Esteban Lopez --- docs/dls/component-design-guidelines.md | 100 ++++++++++++++++++++++++ microsite/sidebars.json | 1 + mkdocs.yml | 1 + 3 files changed, 102 insertions(+) create mode 100644 docs/dls/component-design-guidelines.md diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md new file mode 100644 index 0000000000..3d907d7dec --- /dev/null +++ b/docs/dls/component-design-guidelines.md @@ -0,0 +1,100 @@ +--- +id: design +title: Design +description: Documentation on Design +--- + +Be it a new component contribution, or plugin specific components, you'll want +to follow these guidelines, we'll cover the 3 main subjects that define the +general look and feel of your components, all of which build on top of the MUI +theme features: + +- Layout +- Color palette +- Typography + +## 🏗️ Layout + +Layout refers to how you organize or stack content, whenever possible we want +to use Backstage's components (check the [Storybook][1] for a list and demo) +or MUI components (check the [MUI docs][2]). + +If none of these fit your layout needs, then you can build one, however using +HTML+CSS directly is not recommended, it's better to use MUI layout components +to make your layout theme aware, meaning if someone changes the theme, your +layout would react to those changes without requiring updates to your code. + +Specifically you want to look at these components that make use of the +`theme.spacing()` function for margins, paddings and positions, as well as +color palette and typography: + +- [Container][3] mostly at page level +- [Box][4] like a div that can be customized a lot +- [Grid][5] & [Grid V2][6] (preferable V2) for flexible grid layouts +- [Stack][7] for vertical layouts (single column) +- [Paper][8] The base of a card, like it's background & padding on the borders +- [Card][9] Card with support for title, description, buttons, images... + +## Color palette + +Any component that needs a color to put in the styles should be using the +theme's color palette, most Backstage components and all MUI components should +use the theme's color palette by default, so unless you need explicit control +on the color of a component (say when the component was design to use the +primay color but you want to use the secondary), then the easiest way to access +the color palette is with [useTheme hook](https://mui.com/material-ui/customization/theming/#accessing-the-theme-in-a-component). + +It's not a very common use case to override a theme color in a MUI component +but let's say you have a Paper component that highlights it's content with a +different color for a side menu or something (usually you use the elevation, +but maybe the designer wanted a colorful app), you can use the theme like this: + +```tsx +import { useTheme } from '@mui/material/styles'; + +export function Sidebar() { + const theme = useTheme(); + return ( + + Some children here + + ); +} +``` + +Here is a link to the [Default Palette values][10] you can use, the tokens will be the same, what changes are the colors associated with those depending on +your app theme color palette. + +## Typography + +Most of the time the components from MUI will use the `` component +which will use the theme's typography properties like font family, size, weight +and appropriate color from the palette for the context of that component, like +buttons that use white font color for contained buttons, or the respective color +passed on via props when not outlined for proper contrast (buttons in dark +theme adapt properly by using a dark font instead of white). + +However for those cases where the parent component of the content doesn't handle +the text, like when the parent component is a layout one, you use typography +component instead of the HTML counterparts, usually used for titles and +paragraphs but it is valid for any type of text. + +Check the [Typography docs][11] for information on how to install, use, +customize semantic elements and specially the recommendations about +accessibility. + +[1]: http://backstage.io/storybook +[2]: https://mui.com/material-ui/getting-started/overview/ +[3]: https://mui.com/material-ui/react-container/ +[4]: https://mui.com/material-ui/react-box/ +[5]: https://mui.com/material-ui/react-grid/ +[6]: https://mui.com/material-ui/react-grid2/ +[7]: https://mui.com/material-ui/react-stack/ +[8]: https://mui.com/material-ui/react-paper/ +[9]: https://mui.com/material-ui/react-card/ +[10]: https://mui.com/material-ui/customization/palette/#default-values +[11]: https://mui.com/material-ui/react-typography diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 0826541071..dadcd6c3db 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -314,6 +314,7 @@ ], "Designing for Backstage": [ "dls/design", + "dls/component-design-guidelines", "dls/contributing-to-storybook", "dls/figma" ], diff --git a/mkdocs.yml b/mkdocs.yml index 36ff1c6348..7372e46a06 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -176,6 +176,7 @@ nav: - Heroku: 'deployment/heroku.md' - Designing for Backstage: - Design: 'dls/design.md' + - Component Design Guidelines: 'dls/component-design-guidelines.md' - Contributing to Storybook: 'dls/contributing-to-storybook.md' - Figma: 'dls/figma.md' - API Reference: From b4399355d569f78257224002269e22691e9d8ca3 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Fri, 21 Oct 2022 13:22:34 -0500 Subject: [PATCH 042/434] Update docs/dls/component-design-guidelines.md Co-authored-by: Phil Kuang Signed-off-by: Carlos Esteban Lopez Jaramillo --- docs/dls/component-design-guidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index 3d907d7dec..7c0f3e224b 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -40,7 +40,7 @@ color palette and typography: Any component that needs a color to put in the styles should be using the theme's color palette, most Backstage components and all MUI components should use the theme's color palette by default, so unless you need explicit control -on the color of a component (say when the component was design to use the +on the color of a component (say when the component was designed to use the primay color but you want to use the secondary), then the easiest way to access the color palette is with [useTheme hook](https://mui.com/material-ui/customization/theming/#accessing-the-theme-in-a-component). From 1c8c0a2cc7153a3b610927cfcb1583f7f4fb4fee Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Fri, 21 Oct 2022 13:29:10 -0500 Subject: [PATCH 043/434] docs: Address PR comments Signed-off-by: Carlos Esteban Lopez --- .github/vale/Vocab/Backstage/accept.txt | 4 ++++ docs/dls/component-design-guidelines.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index 603d5fd9af..9ba2abbc78 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -219,6 +219,10 @@ onboarding Onboarding OpenShift orgs +padding +Padding +paddings +Paddings pagerduty pageview parallelization diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index 7c0f3e224b..6b96e82ca0 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -42,7 +42,7 @@ theme's color palette, most Backstage components and all MUI components should use the theme's color palette by default, so unless you need explicit control on the color of a component (say when the component was designed to use the primay color but you want to use the secondary), then the easiest way to access -the color palette is with [useTheme hook](https://mui.com/material-ui/customization/theming/#accessing-the-theme-in-a-component). +the color palette is with [`useTheme` hook](https://mui.com/material-ui/customization/theming/#accessing-the-theme-in-a-component). It's not a very common use case to override a theme color in a MUI component but let's say you have a Paper component that highlights it's content with a From 56a74adc56338e198aa3e298b14383ddaa18d54d Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Fri, 21 Oct 2022 13:33:04 -0500 Subject: [PATCH 044/434] docs: Fix spelling issue Signed-off-by: Carlos Esteban Lopez --- docs/dls/component-design-guidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index 6b96e82ca0..3622d8f2ba 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -41,7 +41,7 @@ Any component that needs a color to put in the styles should be using the theme's color palette, most Backstage components and all MUI components should use the theme's color palette by default, so unless you need explicit control on the color of a component (say when the component was designed to use the -primay color but you want to use the secondary), then the easiest way to access +primary color but you want to use the secondary), then the easiest way to access the color palette is with [`useTheme` hook](https://mui.com/material-ui/customization/theming/#accessing-the-theme-in-a-component). It's not a very common use case to override a theme color in a MUI component From dff521fd91b90cb8171968db55f27bb26b282b85 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Fri, 21 Oct 2022 17:59:28 -0500 Subject: [PATCH 045/434] docs: Fix document ID & title Signed-off-by: Carlos Esteban Lopez --- docs/dls/component-design-guidelines.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index 3622d8f2ba..f03fbea1fb 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -1,6 +1,6 @@ --- -id: design -title: Design +id: component-design-guidelines +title: Component Design Guidelines description: Documentation on Design --- From 69f4c35c28e3466679c0dac7ceaffe1e3128be02 Mon Sep 17 00:00:00 2001 From: Axel Hecht Date: Mon, 24 Oct 2022 18:01:15 +0200 Subject: [PATCH 046/434] Add reference to RFC Signed-off-by: Axel Hecht --- contrib/scaffolder/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/scaffolder/README.md b/contrib/scaffolder/README.md index 55ffea290a..088ad9c5d1 100644 --- a/contrib/scaffolder/README.md +++ b/contrib/scaffolder/README.md @@ -4,6 +4,8 @@ Scaffolder templates support anything that backstage.io and custom actions can do, so testing them is hard without actually running the instance of Backstage that they're designed for. +Please leave [feedback on the RFC](https://github.com/backstage/backstage/issues/14280) on your experience with this approach. + The [command line script](template-testing-dry-run.md) might offer a way for you to do so using the dry-run API used for the Template Editor. Run it against a running instance, either locally or remote, and use it like ```sh From 4c74b20a6aaaf21e0e8e20c71bbc94ff6f717850 Mon Sep 17 00:00:00 2001 From: djamaile Date: Tue, 25 Oct 2022 01:29:46 +0200 Subject: [PATCH 047/434] chore: respond to comments Signed-off-by: djamaile --- plugins/org-react/README.md | 2 +- .../GroupListPicker/GroupListPicker.test.tsx | 6 ++-- .../GroupListPicker/GroupListPicker.tsx | 3 +- .../GroupListPicker/GroupListPickerButton.tsx | 35 +++++++------------ plugins/org-react/src/routes.ts | 20 ----------- 5 files changed, 18 insertions(+), 48 deletions(-) delete mode 100644 plugins/org-react/src/routes.ts diff --git a/plugins/org-react/README.md b/plugins/org-react/README.md index 832e41bddd..91c7ebf48a 100644 --- a/plugins/org-react/README.md +++ b/plugins/org-react/README.md @@ -23,7 +23,7 @@ To use the `GroupListPicker` component you'll need to import it and add it to yo ``` -The `GroupListPicker` comes with three optional props: +The `GroupListPicker` comes with three props: - `groupTypes`: gives the user the option which group types the component should load. If no value is provided all group types will be loaded in; - `placeholder`: the placeholder that the select box in the component should display. This might be helpful in informing your users what the functionality of the component is. diff --git a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx index a011e35333..b8a499b8fe 100644 --- a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx @@ -64,7 +64,7 @@ const apis = TestApiRegistry.from([catalogApiRef, mockCatalogApi]); describe('', () => { it('can choose a group', async () => { - const { getByText, queryByText, getByTestId } = render( + const { getByText, getByTestId } = render( ', () => { const input = getByTestId('group-list-picker-input').querySelector('input'); fireEvent.change(input as HTMLElement, { target: { value: 'GR' } }); - await waitFor(() => { - expect(queryByText('Group A')).toBeInTheDocument(); + await waitFor(async () => { + expect(getByText('Group A')).toBeInTheDocument(); fireEvent.click(getByText('Group A')); expect(getByText('Group A')).toBeInTheDocument(); }); diff --git a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx index f08565fbfa..1296c520c3 100644 --- a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx @@ -83,8 +83,7 @@ export const GroupListPicker = (props: GroupListPickerProps) => { return ; } - const getHumanEntityRef = (entity: Entity) => - humanizeEntityRef(entity, { defaultNamespace: false }); + const getHumanEntityRef = (entity: Entity) => humanizeEntityRef(entity); return ( <> diff --git a/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx index 63fc9a983e..149bf778b1 100644 --- a/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx @@ -16,18 +16,17 @@ import React from 'react'; import { BackstageTheme } from '@backstage/theme'; -import { Box, makeStyles, Typography } from '@material-ui/core'; +import { makeStyles, Typography, Button } from '@material-ui/core'; import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown'; import PeopleIcon from '@material-ui/icons/People'; const useStyles = makeStyles((theme: BackstageTheme) => ({ btn: { - backgroundColor: 'transparent', - border: 'none', margin: 0, - padding: 0, + padding: 10, width: '100%', cursor: 'pointer', + justifyContent: 'space-between', }, title: { fontSize: '1.5rem', @@ -36,12 +35,10 @@ const useStyles = makeStyles((theme: BackstageTheme) => ({ letterSpacing: '-0.25px', lineHeight: '32px', marginBottom: 0, + textTransform: 'none', }, - peopleIcon: { - marginRight: theme.spacing(1), - }, - arrowDownIcon: { - marginLeft: 'auto', + icon: { + transform: 'scale(1.5)', }, })); @@ -56,22 +53,16 @@ export const GroupListPickerButton = (props: GroupListPickerButtonProps) => { const classes = useStyles(); return ( - + {group} + ); }; diff --git a/plugins/org-react/src/routes.ts b/plugins/org-react/src/routes.ts deleted file mode 100644 index 80acc0eb48..0000000000 --- a/plugins/org-react/src/routes.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { createRouteRef } from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ - id: 'org-react', -}); From 761a8aed663d51c4c842810b3f1392bb663f7e4b Mon Sep 17 00:00:00 2001 From: Josh Maxwell Date: Mon, 24 Oct 2022 22:53:49 -0600 Subject: [PATCH 048/434] Adding optional string array of topics to publish gitlab action Signed-off-by: Josh Maxwell --- .../src/scaffolder/actions/builtin/publish/gitlab.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts index 9fc95b1b5e..376667fffc 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts @@ -44,6 +44,7 @@ export function createPublishGitlabAction(options: { gitAuthorName?: string; gitAuthorEmail?: string; setUserAsOwner?: boolean; + topics?: string[]; }>({ id: 'publish:gitlab', description: @@ -99,6 +100,14 @@ export function createPublishGitlabAction(options: { description: 'Set the token user as owner of the newly created repository. Requires a token authorized to do the edit in the integration configuration for the matching host', }, + topics: { + title: 'Topic labels', + description: 'Topic labels to apply on the repository.', + type: 'array', + items: { + type: 'string', + }, + }, }, }, output: { @@ -128,6 +137,7 @@ export function createPublishGitlabAction(options: { gitAuthorName, gitAuthorEmail, setUserAsOwner = false, + topics = [], } = ctx.input; const { owner, repo, host } = parseRepoUrl(repoUrl, integrations); @@ -175,6 +185,8 @@ export function createPublishGitlabAction(options: { visibility: repoVisibility, }); + await client.Projects.edit(projectId, {topics}); + // When setUserAsOwner is true the input token is expected to come from an unprivileged user GitLab // OAuth flow. In this case GitLab works in a way that allows the unprivileged user to // create the repository, but not to push the default protected branch (e.g. master). From 840ff77576e577c6ea2b22913530084827d22c9f Mon Sep 17 00:00:00 2001 From: Josh Maxwell Date: Mon, 24 Oct 2022 23:03:35 -0600 Subject: [PATCH 049/434] Checking for topics before trying to add them to Project Signed-off-by: Josh Maxwell --- .../src/scaffolder/actions/builtin/publish/gitlab.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts index 376667fffc..e4f1b759a8 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts @@ -185,7 +185,9 @@ export function createPublishGitlabAction(options: { visibility: repoVisibility, }); - await client.Projects.edit(projectId, {topics}); + if (topics.length) { + await client.Projects.edit(projectId, {topics}); + } // When setUserAsOwner is true the input token is expected to come from an unprivileged user GitLab // OAuth flow. In this case GitLab works in a way that allows the unprivileged user to From 5025d2e8b6d5e1eee8f7c00a96f90884d0968bc4 Mon Sep 17 00:00:00 2001 From: Josh Maxwell Date: Mon, 24 Oct 2022 23:09:57 -0600 Subject: [PATCH 050/434] Adding changeset Signed-off-by: Josh Maxwell --- .changeset/large-spies-doubt.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/large-spies-doubt.md diff --git a/.changeset/large-spies-doubt.md b/.changeset/large-spies-doubt.md new file mode 100644 index 0000000000..620d8cf53e --- /dev/null +++ b/.changeset/large-spies-doubt.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Adds the ability to pass (an optional) array of strings that will be applied to the newly scaffolded repository as topic labels. From 8a77c639a113231955933dbb0f00c32d2e2284c1 Mon Sep 17 00:00:00 2001 From: Josh Maxwell Date: Mon, 24 Oct 2022 23:15:08 -0600 Subject: [PATCH 051/434] Prettier -w Signed-off-by: Josh Maxwell --- .../src/scaffolder/actions/builtin/publish/gitlab.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts index e4f1b759a8..c7a811a4d2 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts @@ -186,7 +186,7 @@ export function createPublishGitlabAction(options: { }); if (topics.length) { - await client.Projects.edit(projectId, {topics}); + await client.Projects.edit(projectId, { topics }); } // When setUserAsOwner is true the input token is expected to come from an unprivileged user GitLab From 69a6e87b07352a9a3e00fcaea4be899c964686bc Mon Sep 17 00:00:00 2001 From: Josh Maxwell Date: Mon, 24 Oct 2022 23:29:20 -0600 Subject: [PATCH 052/434] Adding API Report Signed-off-by: Josh Maxwell --- plugins/scaffolder-backend/api-report.md | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 846fa59b08..f32cd42c6b 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -422,6 +422,7 @@ export function createPublishGitlabAction(options: { gitAuthorName?: string | undefined; gitAuthorEmail?: string | undefined; setUserAsOwner?: boolean | undefined; + topics?: string[] | undefined; }>; // @public From 9ff4ff3745a8073cfdc25db6347e4f0742d90035 Mon Sep 17 00:00:00 2001 From: Tomas Baltusis Date: Tue, 25 Oct 2022 15:50:07 +0300 Subject: [PATCH 053/434] Implement "Branch protection rules" support for "publish:github" action Signed-off-by: Tomas Baltusis --- .changeset/ten-hats-tickle.md | 5 ++++ plugins/scaffolder-backend/api-report.md | 21 +++++++++++++ .../builtin/github/githubRepoCreate.ts | 6 ++++ .../actions/builtin/github/githubRepoPush.ts | 10 +++++++ .../actions/builtin/github/helpers.ts | 8 +++++ .../actions/builtin/github/inputProperties.ts | 30 +++++++++++++++++++ .../src/scaffolder/actions/builtin/helpers.ts | 7 +++++ .../actions/builtin/publish/github.ts | 11 +++++++ 8 files changed, 98 insertions(+) create mode 100644 .changeset/ten-hats-tickle.md diff --git a/.changeset/ten-hats-tickle.md b/.changeset/ten-hats-tickle.md new file mode 100644 index 0000000000..5545dfa7ba --- /dev/null +++ b/.changeset/ten-hats-tickle.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Implement "Branch protection rules" support for "publish:github" action diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 846fa59b08..a48f256c45 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -198,6 +198,13 @@ export function createGithubRepoCreateAction(options: { allowMergeCommit?: boolean | undefined; allowAutoMerge?: boolean | undefined; requireCodeOwnerReviews?: boolean | undefined; + bypassPullRequestAllowances?: + | { + users?: string[] | undefined; + teams?: string[] | undefined; + apps?: string[] | undefined; + } + | undefined; requiredStatusCheckContexts?: string[] | undefined; requireBranchesToBeUpToDate?: boolean | undefined; repoVisibility?: 'internal' | 'private' | 'public' | undefined; @@ -236,6 +243,13 @@ export function createGithubRepoPushAction(options: { gitAuthorName?: string | undefined; gitAuthorEmail?: string | undefined; requireCodeOwnerReviews?: boolean | undefined; + bypassPullRequestAllowances?: + | { + users?: string[]; + teams?: string[]; + apps?: string[]; + } + | undefined; requiredStatusCheckContexts?: string[] | undefined; requireBranchesToBeUpToDate?: boolean | undefined; sourcePath?: string | undefined; @@ -366,6 +380,13 @@ export function createPublishGithubAction(options: { allowMergeCommit?: boolean | undefined; allowAutoMerge?: boolean | undefined; sourcePath?: string | undefined; + bypassPullRequestAllowances?: + | { + users?: string[]; + teams?: string[]; + apps?: string[]; + } + | undefined; requireCodeOwnerReviews?: boolean | undefined; requiredStatusCheckContexts?: string[] | undefined; requireBranchesToBeUpToDate?: boolean | undefined; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.ts index 9348526b20..760f42eade 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.ts @@ -52,6 +52,11 @@ export function createGithubRepoCreateAction(options: { allowMergeCommit?: boolean; allowAutoMerge?: boolean; requireCodeOwnerReviews?: boolean; + bypassPullRequestAllowances?: { + users?: string[]; + teams?: string[]; + apps?: string[]; + }; requiredStatusCheckContexts?: string[]; requireBranchesToBeUpToDate?: boolean; repoVisibility?: 'private' | 'internal' | 'public'; @@ -85,6 +90,7 @@ export function createGithubRepoCreateAction(options: { homepage: inputProps.homepage, access: inputProps.access, requireCodeOwnerReviews: inputProps.requireCodeOwnerReviews, + bypassPullRequestAllowances: inputProps.bypassPullRequestAllowances, requiredStatusCheckContexts: inputProps.requiredStatusCheckContexts, requireBranchesToBeUpToDate: inputProps.requireBranchesToBeUpToDate, repoVisibility: inputProps.repoVisibility, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.ts index b02a475698..1694e37710 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.ts @@ -49,6 +49,13 @@ export function createGithubRepoPushAction(options: { gitAuthorName?: string; gitAuthorEmail?: string; requireCodeOwnerReviews?: boolean; + bypassPullRequestAllowances?: + | { + users?: string[]; + teams?: string[]; + apps?: string[]; + } + | undefined; requiredStatusCheckContexts?: string[]; requireBranchesToBeUpToDate?: boolean; sourcePath?: string; @@ -65,6 +72,7 @@ export function createGithubRepoPushAction(options: { repoUrl: inputProps.repoUrl, requireCodeOwnerReviews: inputProps.requireCodeOwnerReviews, requiredStatusCheckContexts: inputProps.requiredStatusCheckContexts, + bypassPullRequestAllowances: inputProps.bypassPullRequestAllowances, requireBranchesToBeUpToDate: inputProps.requireBranchesToBeUpToDate, defaultBranch: inputProps.defaultBranch, protectDefaultBranch: inputProps.protectDefaultBranch, @@ -94,6 +102,7 @@ export function createGithubRepoPushAction(options: { gitAuthorName, gitAuthorEmail, requireCodeOwnerReviews = false, + bypassPullRequestAllowances, requiredStatusCheckContexts = [], requireBranchesToBeUpToDate = true, token: providedToken, @@ -131,6 +140,7 @@ export function createGithubRepoPushAction(options: { client, repo, requireCodeOwnerReviews, + bypassPullRequestAllowances, requiredStatusCheckContexts, requireBranchesToBeUpToDate, config, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts index 2264da1dac..2891ea51cf 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts @@ -247,6 +247,13 @@ export async function initRepoPushAndProtect( client: Octokit, repo: string, requireCodeOwnerReviews: boolean, + bypassPullRequestAllowances: + | { + users?: string[]; + teams?: string[]; + apps?: string[]; + } + | undefined, requiredStatusCheckContexts: string[], requireBranchesToBeUpToDate: boolean, config: Config, @@ -289,6 +296,7 @@ export async function initRepoPushAndProtect( repoName: repo, logger, defaultBranch, + bypassPullRequestAllowances, requireCodeOwnerReviews, requiredStatusCheckContexts, requireBranchesToBeUpToDate, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/inputProperties.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/inputProperties.ts index b00d5fa132..e832c3dbfa 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/inputProperties.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/inputProperties.ts @@ -147,6 +147,35 @@ const protectEnforceAdmins = { type: 'boolean', description: `Enforce admins to adhere to default branch protection. The default value is 'true'`, }; + +const bypassPullRequestAllowances = { + title: 'Bypass pull request requirements', + description: + 'Allow specific users, teams, or apps to bypass pull request requirements.', + type: 'object', + additionalProperties: false, + properties: { + apps: { + type: 'array', + items: { + type: 'string', + }, + }, + users: { + type: 'array', + items: { + type: 'string', + }, + }, + teams: { + type: 'array', + items: { + type: 'string', + }, + }, + }, +}; + const gitCommitMessage = { title: 'Git Commit Message', type: 'string', @@ -174,6 +203,7 @@ export { gitCommitMessage }; export { homepage }; export { protectDefaultBranch }; export { protectEnforceAdmins }; +export { bypassPullRequestAllowances }; export { repoUrl }; export { repoVisibility }; export { requireCodeOwnerReviews }; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.ts index be77d27a9a..5afe51cc35 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.ts @@ -185,6 +185,11 @@ type BranchProtectionOptions = { logger: Logger; requireCodeOwnerReviews: boolean; requiredStatusCheckContexts?: string[]; + bypassPullRequestAllowances?: { + users?: string[]; + teams?: string[]; + apps?: string[]; + }; requireBranchesToBeUpToDate?: boolean; defaultBranch?: string; enforceAdmins?: boolean; @@ -196,6 +201,7 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({ owner, logger, requireCodeOwnerReviews, + bypassPullRequestAllowances, requiredStatusCheckContexts = [], requireBranchesToBeUpToDate = true, defaultBranch = 'master', @@ -226,6 +232,7 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({ required_pull_request_reviews: { required_approving_review_count: 1, require_code_owner_reviews: requireCodeOwnerReviews, + bypass_pull_request_allowances: bypassPullRequestAllowances, }, }); } catch (e) { diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts index c1f8e8b5b6..be4cbb1dad 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts @@ -29,6 +29,7 @@ import { import * as inputProps from '../github/inputProperties'; import * as outputProps from '../github/outputProperties'; import { parseRepoUrl } from './util'; + /** * Creates a new action that initializes a git repository of the content in the workspace * and publishes it to GitHub. @@ -59,6 +60,13 @@ export function createPublishGithubAction(options: { allowMergeCommit?: boolean; allowAutoMerge?: boolean; sourcePath?: string; + bypassPullRequestAllowances?: + | { + users?: string[]; + teams?: string[]; + apps?: string[]; + } + | undefined; requireCodeOwnerReviews?: boolean; requiredStatusCheckContexts?: string[]; requireBranchesToBeUpToDate?: boolean; @@ -93,6 +101,7 @@ export function createPublishGithubAction(options: { description: inputProps.description, homepage: inputProps.homepage, access: inputProps.access, + bypassPullRequestAllowances: inputProps.bypassPullRequestAllowances, requireCodeOwnerReviews: inputProps.requireCodeOwnerReviews, requiredStatusCheckContexts: inputProps.requiredStatusCheckContexts, requireBranchesToBeUpToDate: inputProps.requireBranchesToBeUpToDate, @@ -129,6 +138,7 @@ export function createPublishGithubAction(options: { homepage, access, requireCodeOwnerReviews = false, + bypassPullRequestAllowances, requiredStatusCheckContexts = [], requireBranchesToBeUpToDate = true, repoVisibility = 'private', @@ -195,6 +205,7 @@ export function createPublishGithubAction(options: { client, repo, requireCodeOwnerReviews, + bypassPullRequestAllowances, requiredStatusCheckContexts, requireBranchesToBeUpToDate, config, From fcab2579a01bdc4c16f264f88f1dac1341aa2e98 Mon Sep 17 00:00:00 2001 From: Maxwell Elliott Date: Mon, 24 Oct 2022 12:56:08 -0400 Subject: [PATCH 054/434] Update instructions for coverage plugin Adds more steps to help setup users when using the code-coverage plugin Signed-off-by: Maxwell Elliott --- .changeset/pink-snails-hammer.md | 6 +++ plugins/code-coverage-backend/README.md | 62 +++++++++++++++++++++++++ plugins/code-coverage/README.md | 25 ++++++++++ 3 files changed, 93 insertions(+) create mode 100644 .changeset/pink-snails-hammer.md diff --git a/.changeset/pink-snails-hammer.md b/.changeset/pink-snails-hammer.md new file mode 100644 index 0000000000..fbcadfb1d9 --- /dev/null +++ b/.changeset/pink-snails-hammer.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-code-coverage': patch +'@backstage/plugin-code-coverage-backend': patch +--- + +Adds installation instructions diff --git a/plugins/code-coverage-backend/README.md b/plugins/code-coverage-backend/README.md index 4cfc187a3d..ae6021b07c 100644 --- a/plugins/code-coverage-backend/README.md +++ b/plugins/code-coverage-backend/README.md @@ -2,6 +2,68 @@ This is the backend part of the `code-coverage` plugin. It takes care of processing various coverage formats and standardizing them into a single json format, used by the frontend. +## Installation + +`yarn workspace backend add @backstage/plugin-code-coverage-backend` + +First create a `codecoverage.ts` file here: `packages/backend/src/plugins`. Now add the following as its content: + +```diff +diff --git a/packages/backend/src/plugins/codecoverage.ts b/packages/backend/src/plugins/codecoverage.ts +--- /dev/null ++++ b/packages/backend/src/plugins/codecoverage.ts +@@ -0,0 +1,15 @@ ++import { createRouter } from '@backstage/plugin-code-coverage-backend'; ++import { Router } from 'express'; ++import { PluginEnvironment } from '../types'; ++ ++export default async function createPlugin( ++ env: PluginEnvironment, ++): Promise { ++ return await createRouter({ ++ config: env.config, ++ discovery: env.discovery, ++ database: env.database, ++ urlReader: env.reader, ++ logger: env.logger, ++ }); ++} + +``` + +Finally we need to load the plugin in `packages/backend/src/index.ts`, make the following edits: + +```diff +diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts +--- a/packages/backend/src/index.ts ++++ b/packages/backend/src/index.ts +@@ -28,6 +28,7 @@ import scaffolder from './plugins/scaffolder'; + import proxy from './plugins/proxy'; + import techdocs from './plugins/techdocs'; + import search from './plugins/search'; ++import codeCoverage from './plugins/codecoverage'; + import { PluginEnvironment } from './types'; + import { ServerPermissionClient } from '@backstage/plugin-permission-node'; + import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; +@@ -85,6 +86,9 @@ async function main() { + const techdocsEnv = useHotMemoize(module, () => createEnv('techdocs')); + const searchEnv = useHotMemoize(module, () => createEnv('search')); + const appEnv = useHotMemoize(module, () => createEnv('app')); ++ const codeCoverageEnv = useHotMemoize(module, () => ++ createEnv('code-coverage'), ++ ); + + const apiRouter = Router(); + apiRouter.use('/catalog', await catalog(catalogEnv)); +@@ -93,6 +97,7 @@ async function main() { + apiRouter.use('/techdocs', await techdocs(techdocsEnv)); + apiRouter.use('/proxy', await proxy(proxyEnv)); + apiRouter.use('/search', await search(searchEnv)); ++ apiRouter.use('/code-coverage', await codeCoverage(codeCoverageEnv)); + + apiRouter.use(notFoundHandler()); +``` + ## Configuring your entity In order to use this plugin, you must set the `backstage.io/code-coverage` annotation. diff --git a/plugins/code-coverage/README.md b/plugins/code-coverage/README.md index 8903668507..ce793a78d3 100644 --- a/plugins/code-coverage/README.md +++ b/plugins/code-coverage/README.md @@ -2,6 +2,31 @@ This is the frontend part of the code-coverage plugin. It displays code coverage summaries for your entities. +## Installation + +`yarn workspace app add @backstage/plugin-code-coverage` + +Finally you need to import and render the code coverage entity, in `packages/app/src/components/catalog/EntityPage.tsx` add the following: + +```diff +@@ -70,6 +70,7 @@ import { + + import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; + import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib'; ++import { EntityCodeCoverageContent } from '@backstage/plugin-code-coverage'; + +@@ -226,6 +227,10 @@ const defaultEntityPage = ( + + {techdocsContent} + ++ ++ ++ ++ + + ); +``` + ## Configuring your entity In order to use this plugin, you must set the `backstage.io/code-coverage` annotation on entities for which coverage ingestion has been enabled. From 0ea0d474f4d273b04912f66073ec9fbce585119b Mon Sep 17 00:00:00 2001 From: Josh Maxwell Date: Tue, 25 Oct 2022 08:16:44 -0600 Subject: [PATCH 055/434] Moving topics into initial project creation rather than a secondary call Signed-off-by: Josh Maxwell --- .../src/scaffolder/actions/builtin/publish/gitlab.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts index c7a811a4d2..53669efd0b 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts @@ -183,12 +183,9 @@ export function createPublishGitlabAction(options: { namespace_id: targetNamespace, name: repo, visibility: repoVisibility, + ...(topics.length ? { topics } : {}), }); - if (topics.length) { - await client.Projects.edit(projectId, { topics }); - } - // When setUserAsOwner is true the input token is expected to come from an unprivileged user GitLab // OAuth flow. In this case GitLab works in a way that allows the unprivileged user to // create the repository, but not to push the default protected branch (e.g. master). From e8528d3befa8ca9927c9475bc4e3fb04815ab203 Mon Sep 17 00:00:00 2001 From: Josh Maxwell Date: Tue, 25 Oct 2022 08:17:24 -0600 Subject: [PATCH 056/434] updating changeset type from patch -> minor Signed-off-by: Josh Maxwell --- .changeset/large-spies-doubt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/large-spies-doubt.md b/.changeset/large-spies-doubt.md index 620d8cf53e..d81b31df28 100644 --- a/.changeset/large-spies-doubt.md +++ b/.changeset/large-spies-doubt.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-scaffolder-backend': patch +'@backstage/plugin-scaffolder-backend': minor --- Adds the ability to pass (an optional) array of strings that will be applied to the newly scaffolded repository as topic labels. From 1203493c97926f69e2b7c79ac8f456b400b850fe Mon Sep 17 00:00:00 2001 From: hillmandj Date: Tue, 25 Oct 2022 11:02:55 -0400 Subject: [PATCH 057/434] Additional Authenticate API Doc Updates Signed-off-by: hillmandj --- contrib/docs/tutorials/authenticate-api-requests.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/contrib/docs/tutorials/authenticate-api-requests.md b/contrib/docs/tutorials/authenticate-api-requests.md index c8f4083a0c..45f0c3302f 100644 --- a/contrib/docs/tutorials/authenticate-api-requests.md +++ b/contrib/docs/tutorials/authenticate-api-requests.md @@ -4,7 +4,7 @@ The Backstage backend APIs are by default available without authentication. To a API requests from frontend plugins include an authorization header with a Backstage identity token acquired when the user logs in. By adding a middleware that verifies said token to be valid and signed by Backstage, non-authenticated requests can be blocked with a 401 Unauthorized response. -**NOTE**: Enabling this means that Backstage will stop working for guests, as no token is issued for them. +**NOTE**: Enabling this means that Backstage will stop working for guests, as no token is issued for them. If you have not done so already, you will also need to implement [service-to-service auth](https://backstage.io/docs/auth/service-to-service-auth). As techdocs HTML pages load assets without an Authorization header the code below also sets a token cookie when the user logs in (and when the token is about to expire). @@ -61,7 +61,7 @@ export const createAuthMiddleware = async ( try { const token = getBearerTokenFromAuthorizationHeader(req.headers.authorization) || - (req.cookies.token as string | undefined); + (req.cookies?.token as string | undefined); if (!token) { res.status(401).send('Unauthorized'); return; @@ -180,7 +180,12 @@ export async function setTokenCookie(url: string, identityApi: IdentityApi) { ``` ```typescript -// packages/app/src/App.tsx from a create-app deployment +// required types and packages for example below + +import type { IdentityApi } from '@backstage/core-plugin-api'; +import { discoveryApiRef, useApi } from '@backstage/core-plugin-api'; + +// additional packages/app/src/App.tsx from a create-app deployment import { setTokenCookie } from './cookieAuth'; From 1baf5d5e7f897e796d4474a54ae7237c7691332f Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Wed, 26 Oct 2022 15:37:47 -0400 Subject: [PATCH 058/434] complete azure outbound access Adds the other host that must be reachable and puts all this advice in its own section. Signed-off-by: Jamie Klassen --- docs/auth/microsoft/provider.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/auth/microsoft/provider.md b/docs/auth/microsoft/provider.md index cbd24867b7..787b95f2f3 100644 --- a/docs/auth/microsoft/provider.md +++ b/docs/auth/microsoft/provider.md @@ -46,11 +46,19 @@ The Microsoft provider is a structure with three configuration keys: - `clientSecret`: Secret, found on App Registration > Certificates & secrets - `tenantId`: Directory (tenant) ID, found on App Registration > Overview -In order to finish signing a user in from Azure, the Backstage backend must -fetch their information from graph.microsoft.com (as seen in [this source -code](https://github.com/seanfisher/passport-microsoft/blob/0456aa9bce05579c18e77f51330176eb26373658/lib/strategy.js#L93-L95)), -so ensure that your Backstage backend has connectivity to this host. -Otherwise users may see an `Authentication failed, failed to fetch user profile` error when they attempt to log in. +## Outbound Network Access + +If your environment has restrictions on outgoing access (e.g. through +firewall rules), make sure your Backstage backend has access to the following +hosts: + +- `login.microsoftonline.com`, to get and exchange authorization codes and access + tokens +- `graph.microsoft.com`, to fetch user profile information (as seen + in [this source + code](https://github.com/seanfisher/passport-microsoft/blob/0456aa9bce05579c18e77f51330176eb26373658/lib/strategy.js#L93-L95)). + If this host is unreachable, users may see an `Authentication failed, failed to fetch user profile` error when they attempt to log in. + ## Adding the provider to the Backstage frontend From 9a2088fb8c5ec3d2b1e7cc37d8d7ca3e009fcd45 Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Wed, 26 Oct 2022 21:39:19 +0200 Subject: [PATCH 059/434] refactor: position Signed-off-by: Matteo Pietro Dazzi --- .../TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx index 8c548f0f96..572251008e 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx @@ -134,14 +134,14 @@ export const TechDocsReaderPageHeader = ( value={ - + - + Source From f5ab2bc24c8745258446a939df2f945db13a4c2e Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Wed, 26 Oct 2022 21:44:48 +0200 Subject: [PATCH 060/434] fix: capitalize Signed-off-by: Matteo Pietro Dazzi --- ...82af-Linux-5.10.124-linuxkit-en.properties | 235 ++++++++++++++++++ .../TechDocsReaderPageHeader.tsx | 4 +- 2 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 plugins/techdocs-backend/examples/documented-component/?/.java/fonts/11.0.16/fcinfo-1-a58239d182af-Linux-5.10.124-linuxkit-en.properties diff --git a/plugins/techdocs-backend/examples/documented-component/?/.java/fonts/11.0.16/fcinfo-1-a58239d182af-Linux-5.10.124-linuxkit-en.properties b/plugins/techdocs-backend/examples/documented-component/?/.java/fonts/11.0.16/fcinfo-1-a58239d182af-Linux-5.10.124-linuxkit-en.properties new file mode 100644 index 0000000000..34ad192560 --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component/?/.java/fonts/11.0.16/fcinfo-1-a58239d182af-Linux-5.10.124-linuxkit-en.properties @@ -0,0 +1,235 @@ +#JDK Font Configuration Generated File: *Do Not Edit* +#Wed Oct 26 19:41:31 GMT 2022 +sansserif.3.5.family=DejaVu LGC Serif +serif.1.7.family=DejaVu LGC Sans +monospaced.2.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf +serif.1.5.family=DejaVu Sans Mono +sansserif.3.7.family=DejaVu LGC Serif +sansserif.2.5.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf +serif.3.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf +serif.1.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Italic.ttf +sansserif.3.3.family=DejaVu Sans +serif.1.9.family=DejaVu Math TeX Gyre +serif.1.3.family=DejaVu Serif +serif.1.1.family=DejaVu Serif +serif.0.4.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf +monospaced.1.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Bold.ttf +monospaced.3.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf +monospaced.0.1.family=DejaVu Math TeX Gyre +monospaced.0.3.family=DejaVu Serif +sansserif.0.5.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf +serif.2.4.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans-Oblique.ttf +monospaced.3.10.family=DejaVu Math TeX Gyre +monospaced.0.length=5 +sansserif.3.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf +serif.0.6.family=DejaVu LGC Sans +sansserif.1.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-Bold.ttf +version=1 +monospaced.1.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-Bold.ttf +monospaced.3.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-BoldOblique.ttf +sansserif.2.4.family=DejaVu Serif +sansserif.2.6.family=DejaVu LGC Sans Mono +serif.1.5.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-Bold.ttf +serif.3.5.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-BoldOblique.ttf +sansserif.2.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf +monospaced.2.length=9 +monospaced.0.1.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf +sansserif.0.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf +sansserif.3.8.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf +serif.3.length=11 +serif.0.6.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans.ttf +sansserif.3.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf +serif.0.0.family=DejaVu Serif +serif.0.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf +monospaced.1.2.family=DejaVu Serif +monospaced.1.6.family=DejaVu LGC Sans +sansserif.2.0.family=DejaVu Sans +serif.3.5.family=DejaVu Sans Mono +serif.0.4.family=DejaVu Math TeX Gyre +sansserif.1.5.family=DejaVu LGC Serif +serif.1.7.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans.ttf +serif.3.1.family=DejaVu Serif +serif.1.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf +monospaced.3.9.family=DejaVu Sans +serif.2.0.family=DejaVu Serif +sansserif.2.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf +sansserif.2.7.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf +serif.2.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf +monospaced.2.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Italic.ttf +sansserif.1.6.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSansMono.ttf +monospaced.2.7.family=DejaVu Math TeX Gyre +serif.2.8.family=DejaVu Math TeX Gyre +sansserif.3.1.family=DejaVu Sans +monospaced.2.3.family=DejaVu Serif +serif.2.4.family=DejaVu LGC Sans +sansserif.1.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf +monospaced.3.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf +monospaced.1.7.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf +sansserif.2.length=8 +monospaced.3.2.family=DejaVu Sans Mono +serif.3.8.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf +serif.3.10.family=DejaVu Sans +monospaced.2.6.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf +monospaced.1.6.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans.ttf +monospaced.3.5.family=DejaVu LGC Serif +serif.3.10.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf +monospaced.3.4.family=DejaVu Serif +monospaced.3.7.family=DejaVu Sans +serif.3.9.family=DejaVu Math TeX Gyre +sansserif.1.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf +sansserif.1.1.family=DejaVu Sans +serif.3.7.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans-Oblique.ttf +serif.2.10.family=DejaVu Sans +monospaced.3.8.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-Bold.ttf +monospaced.1.8.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf +monospaced.2.6.family=DejaVu Sans +sansserif.2.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf +monospaced.2.4.family=DejaVu Serif +sansserif.0.1.family=DejaVu Sans +sansserif.0.3.family=DejaVu Sans +serif.2.9.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf +serif.1.6.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSansMono.ttf +serif.1.length=10 +sansserif.1.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf +monospaced.1.8.family=DejaVu Math TeX Gyre +serif.1.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Bold.ttf +monospaced.1.3.family=DejaVu LGC Sans +sansserif.2.2.family=DejaVu Sans +monospaced.1.0.family=DejaVu Sans Mono +serif.3.4.family=DejaVu LGC Sans Mono +monospaced.3.9.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf +serif.0.2.family=DejaVu Serif +monospaced.3.3.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-BoldItalic.ttf +sansserif.1.7.family=DejaVu Serif +sansserif.1.4.family=DejaVu Sans Mono +serif.3.7.family=DejaVu LGC Sans +sansserif.1.8.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf +serif.3.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Italic.ttf +sansserif.0.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf +monospaced.2.1.family=DejaVu Sans Mono +monospaced.0.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf +serif.0.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Italic.ttf +serif.0.7.family=DejaVu Sans +monospaced.2.5.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf +sansserif.2.5.family=DejaVu Serif +serif.2.6.family=DejaVu Sans +monospaced.1.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf +sansserif.0.6.family=DejaVu Math TeX Gyre +sansserif.3.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf +serif.1.6.family=DejaVu LGC Sans Mono +monospaced.3.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-Bold.ttf +serif.1.8.family=DejaVu Sans +sansserif.3.8.family=DejaVu Math TeX Gyre +sansserif.3.6.family=DejaVu LGC Sans Mono +sansserif.3.5.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-Italic.ttf +sansserif.1.5.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-Bold.ttf +serif.0.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf +sansserif.3.4.family=DejaVu Serif +sansserif.3.2.family=DejaVu Sans +serif.2.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Bold.ttf +serif.1.2.family=DejaVu Serif +serif.1.4.family=DejaVu Sans +monospaced.0.2.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans.ttf +serif.1.0.family=DejaVu Serif +serif.1.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf +monospaced.2.2.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-Italic.ttf +monospaced.0.4.family=DejaVu Sans +monospaced.0.2.family=DejaVu LGC Sans +monospaced.0.0.family=DejaVu Sans Mono +serif.3.4.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSansMono-BoldOblique.ttf +serif.2.1.family=DejaVu Serif +monospaced.1.3.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans-Bold.ttf +serif.1.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf +sansserif.1.7.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf +sansserif.3.7.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-Bold.ttf +cachedir.0=/var/cache/fontconfig +serif.2.9.family=DejaVu Sans Mono +cachedir.2=/tmp/.fontconfig +sansserif.2.6.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSansMono-Oblique.ttf +cachedir.1=/tmp/.cache/fontconfig +serif.3.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Bold.ttf +sansserif.0.6.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf +fcversion=21400 +sansserif.3.0.family=DejaVu Sans +serif.2.5.family=DejaVu LGC Sans Mono +serif.2.3.family=DejaVu Serif +serif.2.7.family=DejaVu LGC Sans +monospaced.0.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf +serif.3.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf +serif.2.length=11 +monospaced.2.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf +serif.3.6.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf +sansserif.0.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf +serif.0.1.family=DejaVu Serif +monospaced.1.1.family=DejaVu Sans Mono +monospaced.1.5.family=DejaVu LGC Serif +serif.0.5.family=DejaVu Sans Mono +serif.3.2.family=DejaVu Serif +serif.3.6.family=DejaVu Sans +serif.0.7.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf +sansserif.1.6.family=DejaVu LGC Sans Mono +serif.0.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Bold.ttf +sansserif.1.2.family=DejaVu Sans +monospaced.3.11.family=DejaVu Sans +monospaced.1.length=9 +monospaced.2.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-Oblique.ttf +sansserif.2.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Italic.ttf +sansserif.2.7.family=DejaVu Math TeX Gyre +sansserif.2.3.family=DejaVu Sans +serif.2.5.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSansMono-Oblique.ttf +sansserif.0.0.family=DejaVu Sans +sansserif.1.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf +sansserif.0.4.family=DejaVu Sans Mono +serif.3.9.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf +sansserif.0.5.family=DejaVu Serif +serif.1.9.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf +monospaced.2.7.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf +monospaced.3.10.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf +monospaced.3.7.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf +sansserif.1.length=9 +sansserif.3.length=9 +serif.2.8.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf +monospaced.3.11.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf +monospaced.3.6.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf +monospaced.3.6.family=DejaVu Sans +sansserif.0.length=7 +monospaced.3.0.family=DejaVu Sans Mono +monospaced.3.3.family=DejaVu LGC Serif +monospaced.3.1.family=DejaVu Sans Mono +monospaced.3.8.family=DejaVu LGC Serif +sansserif.1.3.family=DejaVu Sans +monospaced.2.0.family=DejaVu Sans Mono +monospaced.2.2.family=DejaVu LGC Serif +sansserif.3.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf +monospaced.3.5.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-Italic.ttf +serif.1.8.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf +monospaced.1.5.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif.ttf +monospaced.2.8.family=DejaVu Sans +sansserif.0.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf +monospaced.1.4.family=DejaVu Sans +serif.2.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Italic.ttf +serif.2.6.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf +serif.0.length=8 +monospaced.1.7.family=DejaVu Sans +sansserif.2.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf +sansserif.2.1.family=DejaVu Sans +serif.3.3.family=DejaVu Serif +serif.0.3.family=DejaVu Serif +sansserif.1.8.family=DejaVu Math TeX Gyre +serif.2.7.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans-BoldOblique.ttf +serif.3.8.family=DejaVu Sans +serif.3.0.family=DejaVu Serif +serif.2.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf +sansserif.0.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf +sansserif.1.0.family=DejaVu Sans +serif.2.10.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf +serif.2.2.family=DejaVu Serif +monospaced.2.8.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf +monospaced.0.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf +serif.0.5.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf +sansserif.3.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf +sansserif.3.6.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSansMono-BoldOblique.ttf +monospaced.3.length=12 +monospaced.2.5.family=DejaVu Sans +monospaced.1.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf +sansserif.0.2.family=DejaVu Sans diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx index 572251008e..f3928ae25d 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx @@ -37,6 +37,8 @@ import { RELATION_OWNED_BY, CompoundEntityRef } from '@backstage/catalog-model'; import { Header, HeaderLabel } from '@backstage/core-components'; import { useRouteRef, configApiRef, useApi } from '@backstage/core-plugin-api'; +import { capitalize } from 'lodash'; + import { rootRouteRef } from '../../../routes'; const skeleton = ; @@ -103,7 +105,7 @@ export const TechDocsReaderPageHeader = ( const labels = ( <> Date: Wed, 26 Oct 2022 21:52:36 +0200 Subject: [PATCH 061/434] fix: removed unused file Signed-off-by: Matteo Pietro Dazzi --- ...82af-Linux-5.10.124-linuxkit-en.properties | 235 ------------------ 1 file changed, 235 deletions(-) delete mode 100644 plugins/techdocs-backend/examples/documented-component/?/.java/fonts/11.0.16/fcinfo-1-a58239d182af-Linux-5.10.124-linuxkit-en.properties diff --git a/plugins/techdocs-backend/examples/documented-component/?/.java/fonts/11.0.16/fcinfo-1-a58239d182af-Linux-5.10.124-linuxkit-en.properties b/plugins/techdocs-backend/examples/documented-component/?/.java/fonts/11.0.16/fcinfo-1-a58239d182af-Linux-5.10.124-linuxkit-en.properties deleted file mode 100644 index 34ad192560..0000000000 --- a/plugins/techdocs-backend/examples/documented-component/?/.java/fonts/11.0.16/fcinfo-1-a58239d182af-Linux-5.10.124-linuxkit-en.properties +++ /dev/null @@ -1,235 +0,0 @@ -#JDK Font Configuration Generated File: *Do Not Edit* -#Wed Oct 26 19:41:31 GMT 2022 -sansserif.3.5.family=DejaVu LGC Serif -serif.1.7.family=DejaVu LGC Sans -monospaced.2.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf -serif.1.5.family=DejaVu Sans Mono -sansserif.3.7.family=DejaVu LGC Serif -sansserif.2.5.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf -serif.3.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf -serif.1.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Italic.ttf -sansserif.3.3.family=DejaVu Sans -serif.1.9.family=DejaVu Math TeX Gyre -serif.1.3.family=DejaVu Serif -serif.1.1.family=DejaVu Serif -serif.0.4.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf -monospaced.1.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Bold.ttf -monospaced.3.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf -monospaced.0.1.family=DejaVu Math TeX Gyre -monospaced.0.3.family=DejaVu Serif -sansserif.0.5.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf -serif.2.4.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans-Oblique.ttf -monospaced.3.10.family=DejaVu Math TeX Gyre -monospaced.0.length=5 -sansserif.3.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf -serif.0.6.family=DejaVu LGC Sans -sansserif.1.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-Bold.ttf -version=1 -monospaced.1.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-Bold.ttf -monospaced.3.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-BoldOblique.ttf -sansserif.2.4.family=DejaVu Serif -sansserif.2.6.family=DejaVu LGC Sans Mono -serif.1.5.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-Bold.ttf -serif.3.5.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-BoldOblique.ttf -sansserif.2.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf -monospaced.2.length=9 -monospaced.0.1.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf -sansserif.0.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf -sansserif.3.8.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf -serif.3.length=11 -serif.0.6.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans.ttf -sansserif.3.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf -serif.0.0.family=DejaVu Serif -serif.0.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf -monospaced.1.2.family=DejaVu Serif -monospaced.1.6.family=DejaVu LGC Sans -sansserif.2.0.family=DejaVu Sans -serif.3.5.family=DejaVu Sans Mono -serif.0.4.family=DejaVu Math TeX Gyre -sansserif.1.5.family=DejaVu LGC Serif -serif.1.7.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans.ttf -serif.3.1.family=DejaVu Serif -serif.1.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf -monospaced.3.9.family=DejaVu Sans -serif.2.0.family=DejaVu Serif -sansserif.2.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf -sansserif.2.7.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf -serif.2.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf -monospaced.2.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Italic.ttf -sansserif.1.6.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSansMono.ttf -monospaced.2.7.family=DejaVu Math TeX Gyre -serif.2.8.family=DejaVu Math TeX Gyre -sansserif.3.1.family=DejaVu Sans -monospaced.2.3.family=DejaVu Serif -serif.2.4.family=DejaVu LGC Sans -sansserif.1.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf -monospaced.3.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf -monospaced.1.7.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf -sansserif.2.length=8 -monospaced.3.2.family=DejaVu Sans Mono -serif.3.8.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf -serif.3.10.family=DejaVu Sans -monospaced.2.6.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf -monospaced.1.6.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans.ttf -monospaced.3.5.family=DejaVu LGC Serif -serif.3.10.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf -monospaced.3.4.family=DejaVu Serif -monospaced.3.7.family=DejaVu Sans -serif.3.9.family=DejaVu Math TeX Gyre -sansserif.1.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf -sansserif.1.1.family=DejaVu Sans -serif.3.7.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans-Oblique.ttf -serif.2.10.family=DejaVu Sans -monospaced.3.8.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-Bold.ttf -monospaced.1.8.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf -monospaced.2.6.family=DejaVu Sans -sansserif.2.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf -monospaced.2.4.family=DejaVu Serif -sansserif.0.1.family=DejaVu Sans -sansserif.0.3.family=DejaVu Sans -serif.2.9.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf -serif.1.6.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSansMono.ttf -serif.1.length=10 -sansserif.1.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf -monospaced.1.8.family=DejaVu Math TeX Gyre -serif.1.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Bold.ttf -monospaced.1.3.family=DejaVu LGC Sans -sansserif.2.2.family=DejaVu Sans -monospaced.1.0.family=DejaVu Sans Mono -serif.3.4.family=DejaVu LGC Sans Mono -monospaced.3.9.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf -serif.0.2.family=DejaVu Serif -monospaced.3.3.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-BoldItalic.ttf -sansserif.1.7.family=DejaVu Serif -sansserif.1.4.family=DejaVu Sans Mono -serif.3.7.family=DejaVu LGC Sans -sansserif.1.8.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf -serif.3.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Italic.ttf -sansserif.0.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf -monospaced.2.1.family=DejaVu Sans Mono -monospaced.0.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf -serif.0.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Italic.ttf -serif.0.7.family=DejaVu Sans -monospaced.2.5.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf -sansserif.2.5.family=DejaVu Serif -serif.2.6.family=DejaVu Sans -monospaced.1.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf -sansserif.0.6.family=DejaVu Math TeX Gyre -sansserif.3.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf -serif.1.6.family=DejaVu LGC Sans Mono -monospaced.3.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-Bold.ttf -serif.1.8.family=DejaVu Sans -sansserif.3.8.family=DejaVu Math TeX Gyre -sansserif.3.6.family=DejaVu LGC Sans Mono -sansserif.3.5.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-Italic.ttf -sansserif.1.5.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-Bold.ttf -serif.0.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf -sansserif.3.4.family=DejaVu Serif -sansserif.3.2.family=DejaVu Sans -serif.2.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Bold.ttf -serif.1.2.family=DejaVu Serif -serif.1.4.family=DejaVu Sans -monospaced.0.2.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans.ttf -serif.1.0.family=DejaVu Serif -serif.1.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf -monospaced.2.2.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-Italic.ttf -monospaced.0.4.family=DejaVu Sans -monospaced.0.2.family=DejaVu LGC Sans -monospaced.0.0.family=DejaVu Sans Mono -serif.3.4.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSansMono-BoldOblique.ttf -serif.2.1.family=DejaVu Serif -monospaced.1.3.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans-Bold.ttf -serif.1.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf -sansserif.1.7.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif.ttf -sansserif.3.7.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-Bold.ttf -cachedir.0=/var/cache/fontconfig -serif.2.9.family=DejaVu Sans Mono -cachedir.2=/tmp/.fontconfig -sansserif.2.6.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSansMono-Oblique.ttf -cachedir.1=/tmp/.cache/fontconfig -serif.3.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Bold.ttf -sansserif.0.6.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf -fcversion=21400 -sansserif.3.0.family=DejaVu Sans -serif.2.5.family=DejaVu LGC Sans Mono -serif.2.3.family=DejaVu Serif -serif.2.7.family=DejaVu LGC Sans -monospaced.0.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf -serif.3.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf -serif.2.length=11 -monospaced.2.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf -serif.3.6.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf -sansserif.0.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf -serif.0.1.family=DejaVu Serif -monospaced.1.1.family=DejaVu Sans Mono -monospaced.1.5.family=DejaVu LGC Serif -serif.0.5.family=DejaVu Sans Mono -serif.3.2.family=DejaVu Serif -serif.3.6.family=DejaVu Sans -serif.0.7.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf -sansserif.1.6.family=DejaVu LGC Sans Mono -serif.0.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Bold.ttf -sansserif.1.2.family=DejaVu Sans -monospaced.3.11.family=DejaVu Sans -monospaced.1.length=9 -monospaced.2.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono-Oblique.ttf -sansserif.2.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Italic.ttf -sansserif.2.7.family=DejaVu Math TeX Gyre -sansserif.2.3.family=DejaVu Sans -serif.2.5.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSansMono-Oblique.ttf -sansserif.0.0.family=DejaVu Sans -sansserif.1.3.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf -sansserif.0.4.family=DejaVu Sans Mono -serif.3.9.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf -sansserif.0.5.family=DejaVu Serif -serif.1.9.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf -monospaced.2.7.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf -monospaced.3.10.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf -monospaced.3.7.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf -sansserif.1.length=9 -sansserif.3.length=9 -serif.2.8.file=/usr/share/fonts/ttf-dejavu/DejaVuMathTeXGyre.ttf -monospaced.3.11.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf -monospaced.3.6.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf -monospaced.3.6.family=DejaVu Sans -sansserif.0.length=7 -monospaced.3.0.family=DejaVu Sans Mono -monospaced.3.3.family=DejaVu LGC Serif -monospaced.3.1.family=DejaVu Sans Mono -monospaced.3.8.family=DejaVu LGC Serif -sansserif.1.3.family=DejaVu Sans -monospaced.2.0.family=DejaVu Sans Mono -monospaced.2.2.family=DejaVu LGC Serif -sansserif.3.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf -monospaced.3.5.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif-Italic.ttf -serif.1.8.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf -monospaced.1.5.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSerif.ttf -monospaced.2.8.family=DejaVu Sans -sansserif.0.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf -monospaced.1.4.family=DejaVu Sans -serif.2.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-Italic.ttf -serif.2.6.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Oblique.ttf -serif.0.length=8 -monospaced.1.7.family=DejaVu Sans -sansserif.2.2.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf -sansserif.2.1.family=DejaVu Sans -serif.3.3.family=DejaVu Serif -serif.0.3.family=DejaVu Serif -sansserif.1.8.family=DejaVu Math TeX Gyre -serif.2.7.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSans-BoldOblique.ttf -serif.3.8.family=DejaVu Sans -serif.3.0.family=DejaVu Serif -serif.2.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSerif-BoldItalic.ttf -sansserif.0.1.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf -sansserif.1.0.family=DejaVu Sans -serif.2.10.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf -serif.2.2.family=DejaVu Serif -monospaced.2.8.file=/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf -monospaced.0.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf -serif.0.5.file=/usr/share/fonts/ttf-dejavu/DejaVuSansMono.ttf -sansserif.3.0.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-BoldOblique.ttf -sansserif.3.6.file=/usr/share/fonts/ttf-dejavu/DejaVuLGCSansMono-BoldOblique.ttf -monospaced.3.length=12 -monospaced.2.5.family=DejaVu Sans -monospaced.1.4.file=/usr/share/fonts/ttf-dejavu/DejaVuSans-Bold.ttf -sansserif.0.2.family=DejaVu Sans From 8813b8e063c27cd3c83ae9e27a001ebd46c1f5ea Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Wed, 26 Oct 2022 22:14:41 +0200 Subject: [PATCH 062/434] fix: updated yarn file Signed-off-by: Matteo Pietro Dazzi --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2332db24c1..c42aac2eec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3314,7 +3314,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-model@npm:^1.1.1, @backstage/catalog-model@npm:^1.1.2": +"@backstage/catalog-model@npm:^1.1.2": version: 1.1.2 resolution: "@backstage/catalog-model@npm:1.1.2" dependencies: @@ -3599,7 +3599,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@npm:^0.11.1, @backstage/core-components@npm:^0.11.2": +"@backstage/core-components@npm:^0.11.2": version: 0.11.2 resolution: "@backstage/core-components@npm:0.11.2" dependencies: @@ -3722,7 +3722,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-plugin-api@npm:^1.0.6, @backstage/core-plugin-api@npm:^1.0.7": +"@backstage/core-plugin-api@npm:^1.0.7": version: 1.0.7 resolution: "@backstage/core-plugin-api@npm:1.0.7" dependencies: @@ -5066,7 +5066,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@npm:^1.1.4, @backstage/plugin-catalog-react@npm:^1.2.0": +"@backstage/plugin-catalog-react@npm:^1.2.0": version: 1.2.0 resolution: "@backstage/plugin-catalog-react@npm:1.2.0" dependencies: From ed438a3ba5d89467f4dc8c5ce974b042a65d0812 Mon Sep 17 00:00:00 2001 From: Brian Fletcher Date: Thu, 27 Oct 2022 11:18:12 +0100 Subject: [PATCH 063/434] add more specific error handling for github actions Previously the errorApi would post a message to the page. However it was unclear which plugin was causing the error. Instead this renders a panel with the full error. Signed-off-by: Brian Fletcher --- .changeset/calm-clouds-smoke.md | 5 +++++ .../src/components/Cards/RecentWorkflowRunsCard.tsx | 6 ++++++ plugins/github-actions/src/components/useWorkflowRuns.ts | 4 +++- yarn.lock | 8 ++++---- 4 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 .changeset/calm-clouds-smoke.md diff --git a/.changeset/calm-clouds-smoke.md b/.changeset/calm-clouds-smoke.md new file mode 100644 index 0000000000..1209c6e071 --- /dev/null +++ b/.changeset/calm-clouds-smoke.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-github-actions': patch +--- + +Add error panel when the plugin fails. diff --git a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx index 89fd40da33..59d64af9c9 100644 --- a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx +++ b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx @@ -29,6 +29,7 @@ import { useRouteRef, } from '@backstage/core-plugin-api'; import { + ErrorPanel, InfoCard, InfoCardVariants, Link, @@ -76,6 +77,11 @@ export const RecentWorkflowRunsCard = (props: { const githubHost = hostname || 'github.com'; const routeLink = useRouteRef(buildRouteRef); + + if (error) { + return ; + } + return ( Date: Wed, 12 Oct 2022 11:04:58 +0200 Subject: [PATCH 064/434] Update API request auth contrib doc for 1.6, use identity from app environment. Signed-off-by: Axel Hecht --- contrib/docs/tutorials/authenticate-api-requests.md | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/contrib/docs/tutorials/authenticate-api-requests.md b/contrib/docs/tutorials/authenticate-api-requests.md index 6c5fabd709..27628d141a 100644 --- a/contrib/docs/tutorials/authenticate-api-requests.md +++ b/contrib/docs/tutorials/authenticate-api-requests.md @@ -11,12 +11,8 @@ As techdocs HTML pages load assets without an Authorization header the code belo Create `packages/backend/src/authMiddleware.ts`: ```typescript -import { SingleHostDiscovery } from '@backstage/backend-common'; import type { Config } from '@backstage/config'; -import { - getBearerTokenFromAuthorizationHeader, - IdentityClient, -} from '@backstage/plugin-auth-node'; +import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; import { NextFunction, Request, Response, RequestHandler } from 'express'; import { decodeJwt } from 'jose'; import { URL } from 'url'; @@ -45,11 +41,6 @@ export const createAuthMiddleware = async ( config: Config, appEnv: PluginEnvironment, ) => { - const discovery = SingleHostDiscovery.fromConfig(config); - const identity = IdentityClient.create({ - discovery, - issuer: await discovery.getExternalBaseUrl('auth'), - }); const baseUrl = config.getString('backend.baseUrl'); const secure = baseUrl.startsWith('https://'); const cookieDomain = new URL(baseUrl).hostname; @@ -67,7 +58,7 @@ export const createAuthMiddleware = async ( return; } try { - req.user = await identity.authenticate(token); + req.user = await appEnv.identity.getIdentity({ request: req }); } catch { await appEnv.tokenManager.authenticate(token); } From a46a72ac23c1a28437e4eb8f30cd3a6948a396c5 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 27 Oct 2022 09:09:49 -0500 Subject: [PATCH 065/434] Update docs/dls/component-design-guidelines.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Carlos Esteban Lopez Jaramillo --- docs/dls/component-design-guidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index f03fbea1fb..520283ed84 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -5,7 +5,7 @@ description: Documentation on Design --- Be it a new component contribution, or plugin specific components, you'll want -to follow these guidelines, we'll cover the 3 main subjects that define the +to follow these guidelines. We'll cover the three main subjects that define the general look and feel of your components, all of which build on top of the MUI theme features: From 9dddc98de561bfce78b3bb19e1a002805f1fb0c5 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 27 Oct 2022 09:10:09 -0500 Subject: [PATCH 066/434] Update docs/dls/component-design-guidelines.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Carlos Esteban Lopez Jaramillo --- docs/dls/component-design-guidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index 520283ed84..257e32925c 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -6,7 +6,7 @@ description: Documentation on Design Be it a new component contribution, or plugin specific components, you'll want to follow these guidelines. We'll cover the three main subjects that define the -general look and feel of your components, all of which build on top of the MUI +general look and feel of your components, all of which build on top of the Material-UI theme features: - Layout From e47357dedc82ac1016b769ad53e0fa66fbb0ee5b Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 27 Oct 2022 09:10:18 -0500 Subject: [PATCH 067/434] Update docs/dls/component-design-guidelines.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Carlos Esteban Lopez Jaramillo --- docs/dls/component-design-guidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index 257e32925c..8cc7624b11 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -15,7 +15,7 @@ theme features: ## 🏗️ Layout -Layout refers to how you organize or stack content, whenever possible we want +Layout refers to how you organize or stack content. Whenever possible, we want to use Backstage's components (check the [Storybook][1] for a list and demo) or MUI components (check the [MUI docs][2]). From 33ee80aba6dc95a2cf4f1e173147f7527213369e Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 27 Oct 2022 09:10:28 -0500 Subject: [PATCH 068/434] Update docs/dls/component-design-guidelines.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Carlos Esteban Lopez Jaramillo --- docs/dls/component-design-guidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index 8cc7624b11..654f6fbbd2 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -17,7 +17,7 @@ theme features: Layout refers to how you organize or stack content. Whenever possible, we want to use Backstage's components (check the [Storybook][1] for a list and demo) -or MUI components (check the [MUI docs][2]). +first, and otherwise fall back to Material-UI components (check the [MUI docs][2]). If none of these fit your layout needs, then you can build one, however using HTML+CSS directly is not recommended, it's better to use MUI layout components From 5c49a73041ea1133b4108482706a1eab02fa238c Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 27 Oct 2022 09:10:39 -0500 Subject: [PATCH 069/434] Update docs/dls/component-design-guidelines.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Carlos Esteban Lopez Jaramillo --- docs/dls/component-design-guidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index 654f6fbbd2..a396642c0b 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -45,7 +45,7 @@ primary color but you want to use the secondary), then the easiest way to access the color palette is with [`useTheme` hook](https://mui.com/material-ui/customization/theming/#accessing-the-theme-in-a-component). It's not a very common use case to override a theme color in a MUI component -but let's say you have a Paper component that highlights it's content with a +but let's say you have a Paper component that highlights its content with a different color for a side menu or something (usually you use the elevation, but maybe the designer wanted a colorful app), you can use the theme like this: From d4e4e45437e5c9e1d39aa3a363fa572166a0f3cd Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 27 Oct 2022 09:10:48 -0500 Subject: [PATCH 070/434] Update docs/dls/component-design-guidelines.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Carlos Esteban Lopez Jaramillo --- docs/dls/component-design-guidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index a396642c0b..52f078ea12 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -47,7 +47,7 @@ the color palette is with [`useTheme` hook](https://mui.com/material-ui/customiz It's not a very common use case to override a theme color in a MUI component but let's say you have a Paper component that highlights its content with a different color for a side menu or something (usually you use the elevation, -but maybe the designer wanted a colorful app), you can use the theme like this: +but maybe the designer wanted a colorful app). You can use the theme like this: ```tsx import { useTheme } from '@mui/material/styles'; From 8c46fedd36dcde5922e1b46c4304caf15eba60e6 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 27 Oct 2022 09:11:53 -0500 Subject: [PATCH 071/434] Update docs/dls/component-design-guidelines.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Carlos Esteban Lopez Jaramillo --- docs/dls/component-design-guidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index 52f078ea12..b474ee79d1 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -73,7 +73,7 @@ your app theme color palette. Most of the time the components from MUI will use the `` component which will use the theme's typography properties like font family, size, weight -and appropriate color from the palette for the context of that component, like +and appropriate color from the palette for the context of that component. This applies for example to buttons that use white font color for contained buttons, or the respective color passed on via props when not outlined for proper contrast (buttons in dark theme adapt properly by using a dark font instead of white). From 606d4f5247ef5854ce4a3fe28774a9cfa3050d31 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 27 Oct 2022 09:12:17 -0500 Subject: [PATCH 072/434] Update docs/dls/component-design-guidelines.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Carlos Esteban Lopez Jaramillo --- docs/dls/component-design-guidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index b474ee79d1..0ebe0caada 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -19,7 +19,7 @@ Layout refers to how you organize or stack content. Whenever possible, we want to use Backstage's components (check the [Storybook][1] for a list and demo) first, and otherwise fall back to Material-UI components (check the [MUI docs][2]). -If none of these fit your layout needs, then you can build one, however using +If none of these fit your layout needs, then you can build your own components. However, using HTML+CSS directly is not recommended, it's better to use MUI layout components to make your layout theme aware, meaning if someone changes the theme, your layout would react to those changes without requiring updates to your code. From 842b8a7b800c8d8d4c83384b05e336c856e06935 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 27 Oct 2022 09:12:58 -0500 Subject: [PATCH 073/434] Update docs/dls/component-design-guidelines.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Carlos Esteban Lopez Jaramillo --- docs/dls/component-design-guidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index 0ebe0caada..07f8b8f9a1 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -38,7 +38,7 @@ color palette and typography: ## Color palette Any component that needs a color to put in the styles should be using the -theme's color palette, most Backstage components and all MUI components should +theme's color palette. Most Backstage components and all MUI components should use the theme's color palette by default, so unless you need explicit control on the color of a component (say when the component was designed to use the primary color but you want to use the secondary), then the easiest way to access From d217290e1d1e886027521727211a9a3bf7eb2a1c Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Thu, 27 Oct 2022 09:29:39 -0500 Subject: [PATCH 074/434] fix: Remove unnecessary capitalized duplicates in vocab whitelist Signed-off-by: Carlos Esteban Lopez --- .github/vale/Vocab/Backstage/accept.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index 9ba2abbc78..5c0a7bdc8d 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -220,9 +220,7 @@ Onboarding OpenShift orgs padding -Padding paddings -Paddings pagerduty pageview parallelization From c7a6c96d0bf6ed93ac9cf24441badebda5ad1363 Mon Sep 17 00:00:00 2001 From: Johannes Grumboeck Date: Fri, 28 Oct 2022 01:08:07 +0200 Subject: [PATCH 075/434] chore: fix wrong github callback url documentation Signed-off-by: Johannes Grumboeck --- docs/auth/github/provider.md | 2 +- plugins/auth-backend/README.md | 2 +- plugins/github-actions/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/auth/github/provider.md b/docs/auth/github/provider.md index a8c6020cae..353b8ebe08 100644 --- a/docs/auth/github/provider.md +++ b/docs/auth/github/provider.md @@ -24,7 +24,7 @@ Settings for local development: - Application name: Backstage (or your custom app name) - Homepage URL: `http://localhost:3000` -- Authorization callback URL: `http://localhost:7007/api/auth/github` +- Authorization callback URL: `http://localhost:7007/api/auth/github/handler/frame` ## Configuration diff --git a/plugins/auth-backend/README.md b/plugins/auth-backend/README.md index d13a5e5a20..d389d4e97a 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:7007/api/auth/github` for local development. + 1. Set this to `http://localhost:7007/api/auth/github/handler/frame` for local development. 1. Set this to `http://{APP_FQDN}:{APP_BACKEND_PORT}/api/auth/github` for non-local deployments. ```bash diff --git a/plugins/github-actions/README.md b/plugins/github-actions/README.md index 792d13280f..cb6867193c 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/) in the GitHub organization with the callback URL set to `http://localhost:7007/api/auth/github`. + 1. [Create an OAuth App](https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app/) in the GitHub organization with the callback URL set to `http://localhost:7007/api/auth/github/handler/frame`. 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: From abaed9770ef62e4aa36ea30df6e60d6c9edea3ce Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Fri, 28 Oct 2022 11:58:34 +0200 Subject: [PATCH 076/434] chore(auth): improve logging Make the logging more clear as "provider" is ambiguous. Signed-off-by: Patrick Jungermann --- .changeset/silly-meals-teach.md | 5 +++++ plugins/auth-backend/src/service/router.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/silly-meals-teach.md diff --git a/.changeset/silly-meals-teach.md b/.changeset/silly-meals-teach.md new file mode 100644 index 0000000000..ffd80463a3 --- /dev/null +++ b/.changeset/silly-meals-teach.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Improve logging diff --git a/plugins/auth-backend/src/service/router.ts b/plugins/auth-backend/src/service/router.ts index 8fd758f1b4..7240ba1bcb 100644 --- a/plugins/auth-backend/src/service/router.ts +++ b/plugins/auth-backend/src/service/router.ts @@ -114,7 +114,7 @@ export async function createRouter( allProviderFactories, )) { if (configuredProviders.includes(providerId)) { - logger.info(`Configuring provider, ${providerId}`); + logger.info(`Configuring auth provider: ${providerId}`); try { const provider = providerFactory({ providerId, From 0d6837ca4ec66448816b6b094ed5c866c03dfb8e Mon Sep 17 00:00:00 2001 From: Johannes Grumboeck Date: Fri, 28 Oct 2022 15:42:40 +0200 Subject: [PATCH 077/434] chore: add changeset Signed-off-by: Johannes Grumboeck --- .changeset/cool-suns-add.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/cool-suns-add.md diff --git a/.changeset/cool-suns-add.md b/.changeset/cool-suns-add.md new file mode 100644 index 0000000000..c66de2e2ad --- /dev/null +++ b/.changeset/cool-suns-add.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-auth-backend': patch +'@backstage/plugin-github-actions': patch +--- + +Fix wrong GitHub callback URL documentation From 3fa1bf966ec650af42b6019f20af5aff6675867f Mon Sep 17 00:00:00 2001 From: "Augusto B. Hoffmann" Date: Fri, 28 Oct 2022 15:53:07 -0300 Subject: [PATCH 078/434] Update ADOPTERS.md Signed-off-by: Augusto B. Hoffmann --- ADOPTERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ADOPTERS.md b/ADOPTERS.md index 2dffec64dc..da56d592b3 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -216,4 +216,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Inter&Co](https://bancointer.com.br) | [Arnaud Lanna](https://github.com/arnaudlanna), [Adriano Silva](https://github.com/adrianovss), [Bruno Grossi](https://github.com/begrossi) | We're using Backstage as our internal Developer Portal to catalog and collect repositories and microservices pieces of information like ownership, deployment time, and documentation. | | [StatusNeo](https://statusneo.com/) | [Karan Nangru](mailto:nangru@statusneo.com), [@NishkarshRaj](https://github.com/NishkarshRaj), and [Gaurav Sarien](mailto:gaurav.sarien@statusneo.com) | Harnessing the power of central catalog inventory and self-serving software templates | | [Alaska Airlines](https://alaskaair.com) | [@swerdick](https://github.com/swerdick) | Backstage is the developer portal for our 'software delivery platform'. Consolidating developer tools to one place, and providing automation to make it easy for developers to create and deploy applications to Kubernetes -| [Loft](https://loft.com.br) | [Augusto Hoffmann](mailto:augusto.hoffmann@loft.com.br) | We're using Backstage to give visibility and promote ownership of all our applications, resources and tools. Now moving to use it as a Developer Portal to create applications, AWS resources etc. | +| [Loft](https://loft.com.br) | [Squad DevTools](mailto:squad_devtools@loft.com.br) | We're using Backstage to give visibility and promote ownership of all our applications, resources and tools. Now moving to use it as a Developer Portal to create applications, AWS resources etc. | From a24ae1e7a930921477c4a9549a6a5a660a373e6c Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Fri, 28 Oct 2022 18:20:00 -0500 Subject: [PATCH 079/434] docs: Improve guidelines docs & update links to MUI V4 Signed-off-by: Carlos Esteban Lopez --- docs/dls/component-design-guidelines.md | 91 +++++++++++++------------ 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index 07f8b8f9a1..877c224446 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -6,8 +6,8 @@ description: Documentation on Design Be it a new component contribution, or plugin specific components, you'll want to follow these guidelines. We'll cover the three main subjects that define the -general look and feel of your components, all of which build on top of the Material-UI -theme features: +general look and feel of your components, all of which build on top of the +Material-UI theme features: - Layout - Color palette @@ -19,10 +19,11 @@ Layout refers to how you organize or stack content. Whenever possible, we want to use Backstage's components (check the [Storybook][1] for a list and demo) first, and otherwise fall back to Material-UI components (check the [MUI docs][2]). -If none of these fit your layout needs, then you can build your own components. However, using -HTML+CSS directly is not recommended, it's better to use MUI layout components -to make your layout theme aware, meaning if someone changes the theme, your -layout would react to those changes without requiring updates to your code. +If none of these fit your layout needs, then you can build your own components. +However, using HTML+CSS directly is not recommended, it's better to use MUI +layout components to make your layout theme aware, meaning if someone changes +the theme, your layout would react to those changes without requiring updates +to your code. Specifically you want to look at these components that make use of the `theme.spacing()` function for margins, paddings and positions, as well as @@ -30,19 +31,23 @@ color palette and typography: - [Container][3] mostly at page level - [Box][4] like a div that can be customized a lot -- [Grid][5] & [Grid V2][6] (preferable V2) for flexible grid layouts -- [Stack][7] for vertical layouts (single column) -- [Paper][8] The base of a card, like it's background & padding on the borders -- [Card][9] Card with support for title, description, buttons, images... +- [Grid][5] for flexible grid layouts +- [Paper][6] The base of a card, like it's background & padding on the borders +- [Card][7] Card with support for title, description, buttons, images... ## Color palette -Any component that needs a color to put in the styles should be using the -theme's color palette. Most Backstage components and all MUI components should -use the theme's color palette by default, so unless you need explicit control -on the color of a component (say when the component was designed to use the -primary color but you want to use the secondary), then the easiest way to access -the color palette is with [`useTheme` hook](https://mui.com/material-ui/customization/theming/#accessing-the-theme-in-a-component). +If you're using an existing component and want to tweak the colors it uses in +general in the whole application, you can use a [Custom Theme][10] to override +specific styles for that component, that includes paddings, margins and colors. + +However when making a component from scratch you'll need to reference the theme +as much as possible, make sure to use the theme's color palette. Most Backstage +components and all MUI components should use the theme's color palette by default, +so unless you need explicit control on the color of a component (say when the +component was designed to use the primary color but you want to use the +secondary color instead), then the easiest way to access the color palette is +to [Override the Component Styles][11] as suggested by Backstage. It's not a very common use case to override a theme color in a MUI component but let's say you have a Paper component that highlights its content with a @@ -50,30 +55,31 @@ different color for a side menu or something (usually you use the elevation, but maybe the designer wanted a colorful app). You can use the theme like this: ```tsx -import { useTheme } from '@mui/material/styles'; +import { makeStyles, Paper } from '@material-ui/core'; -export function Sidebar() { - const theme = useTheme(); - return ( - - Some children here - - ); +const useStyles = makeStyles((theme: Theme) => ({ + sidebarPaper: { + backgroundColor: theme.palette.primary.main, + color: theme.palette.primary.contrastText, + }, +})); + +export function Sidebar({ children }) { + const { sidebarPaper } = useStyles(); + return {children}; } ``` -Here is a link to the [Default Palette values][10] you can use, the tokens will be the same, what changes are the colors associated with those depending on -your app theme color palette. +Here is a link to the [Default Palette values][8] you can use, the tokens will +be the same, what changes are the colors associated with those depending on your +app theme color palette, there's also a [Default Theme Explorer][12] to look +which tokens you can use as reference from the compiled theme. ## Typography Most of the time the components from MUI will use the `` component which will use the theme's typography properties like font family, size, weight -and appropriate color from the palette for the context of that component. This applies for example to +and appropriate color from the palette for the context of that component. This applies for example to buttons that use white font color for contained buttons, or the respective color passed on via props when not outlined for proper contrast (buttons in dark theme adapt properly by using a dark font instead of white). @@ -83,18 +89,19 @@ the text, like when the parent component is a layout one, you use typography component instead of the HTML counterparts, usually used for titles and paragraphs but it is valid for any type of text. -Check the [Typography docs][11] for information on how to install, use, +Check the [Typography docs][9] for information on how to install, use, customize semantic elements and specially the recommendations about accessibility. [1]: http://backstage.io/storybook -[2]: https://mui.com/material-ui/getting-started/overview/ -[3]: https://mui.com/material-ui/react-container/ -[4]: https://mui.com/material-ui/react-box/ -[5]: https://mui.com/material-ui/react-grid/ -[6]: https://mui.com/material-ui/react-grid2/ -[7]: https://mui.com/material-ui/react-stack/ -[8]: https://mui.com/material-ui/react-paper/ -[9]: https://mui.com/material-ui/react-card/ -[10]: https://mui.com/material-ui/customization/palette/#default-values -[11]: https://mui.com/material-ui/react-typography +[2]: https://v4.mui.com/getting-started/supported-components/ +[3]: https://v4.mui.com/components/container/ +[4]: https://v4.mui.com/components/box/ +[5]: https://v4.mui.com/components/grid/ +[6]: https://v4.mui.com/components/paper/ +[7]: https://v4.mui.com/components/cards/ +[8]: https://v4.mui.com/customization/palette/#default-values +[9]: https://v4.mui.com/customization/typography/ +[10]: https://backstage.io/docs/getting-started/app-custom-theme +[11]: https://backstage.io/docs/getting-started/app-custom-theme#overriding-backstage-and-material-ui-components-styles +[12]: https://v4.mui.com/customization/default-theme/#explore From 6b2ad43a902d1b7eda529fdeaeba9d3c0a1cd5e5 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Fri, 28 Oct 2022 18:39:03 -0500 Subject: [PATCH 080/434] docs: Additional explanation & punctuation Signed-off-by: Carlos Esteban Lopez --- docs/dls/component-design-guidelines.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index 877c224446..65eef4c057 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -20,7 +20,7 @@ to use Backstage's components (check the [Storybook][1] for a list and demo) first, and otherwise fall back to Material-UI components (check the [MUI docs][2]). If none of these fit your layout needs, then you can build your own components. -However, using HTML+CSS directly is not recommended, it's better to use MUI +However, using HTML+CSS directly is not recommended; it's better to use MUI layout components to make your layout theme aware, meaning if someone changes the theme, your layout would react to those changes without requiring updates to your code. @@ -50,9 +50,10 @@ secondary color instead), then the easiest way to access the color palette is to [Override the Component Styles][11] as suggested by Backstage. It's not a very common use case to override a theme color in a MUI component -but let's say you have a Paper component that highlights its content with a -different color for a side menu or something (usually you use the elevation, -but maybe the designer wanted a colorful app). You can use the theme like this: +but let's say you have a custom Sidebar component with a Paper component that +highlights its content with a different color for a side menu or something +(usually you use the elevation, but maybe the designer wanted a colorful app). +You can use the theme like this: ```tsx import { makeStyles, Paper } from '@material-ui/core'; From 135314fdc2ede0cfcc42d62a40fd9edee934a531 Mon Sep 17 00:00:00 2001 From: Gabriel Dantas Date: Thu, 27 Oct 2022 09:46:28 -0300 Subject: [PATCH 081/434] docs: scaffolder inputs examples Signed-off-by: Gabriel Dantas --- .../software-templates/inputs-examples.md | 198 ++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 199 insertions(+) create mode 100644 docs/features/software-templates/inputs-examples.md diff --git a/docs/features/software-templates/inputs-examples.md b/docs/features/software-templates/inputs-examples.md new file mode 100644 index 0000000000..dbaab6b144 --- /dev/null +++ b/docs/features/software-templates/inputs-examples.md @@ -0,0 +1,198 @@ +--- +id: inputs-examples +title: Built-in examples inputs +description: Some examples to use in your template +--- + +All the examples on this page you can test using _create/edit_ from your Backstage installation. + +It is important to remember that all examples are based on [react-jsonschema-form](https://rjsf-team.github.io/react-jsonschema-form/). + +# Simple text input + +## Simple input with basic validations + +```yaml +parameters: + - title: Fill in some steps + properties: + name: + title: Simple text input + type: string + description: Description about input + maxLength: 8 + pattern: '^([a-zA-Z][a-zA-Z0-9]*)(-[a-zA-Z0-9]+)*$' + ui:autofocus: true + ui:help: "Hint: additional description..." +``` + +## Simple secret input + +```yaml +parameters: + - title: Fill in some steps + properties: + secretInput: + title: Input secret + type: string + description: Super secret description hint + minLength: 6 + ui:widget: "password" +``` + +## Multi line text input + +```yaml +parameters: + - title: Fill in some steps + properties: + multiline: + title: Text area input + type: string + description: Insira o valor do input que gostraia + ui:widget: "textarea" + ui:options: + rows: 10 + ui:help: "Hint: Make it strong!" + ui:placeholder: | + apiVersion: backstage.io/v1alpha1 + kind: Component + metadata: + name: backstage + spec: + type: library + owner: CNCF + lifecycle: experimental +``` + +# Arrays options + +## Enum with custom titles + +```yaml +parameters: + - title: Fill in some steps + properties: + volume_type: + title: Volume Type + type: string + description: The volume type to be used. + enum: ['gp2', 'gp3', 'io1', 'io2', 'sc1', 'st1', 'standard'] + default: 'gp2' + enumNames: + [ + 'General Purpose SSD (gp2)', + 'General Purpose SSD (gp3)', + 'Provisioned IOPS (io1)', + 'Provisioned IOPS (io2)', + 'Cold HDD (sc1)', + 'Throughput Optimized HDD (st1)', + 'Magnetic (standard)', + ] +``` + +## A multiple choices list + +```yaml +parameters: + - title: Fill in some steps + properties: + name: + title: Select environments + type: array + items: + type: string + enum: ["production", "staging", "development"] + uniqueItems: true + ui:widget: checkboxes +``` + +## Array with another types + +```yaml +parameters: + - title: Fill in some steps + properties: + arrayObjects: + title: Array with custom objects + type: array + ui:options: + addable: false + orderable: false + removable: false + items: + type: object + properties: + array: + title: Array string with default value + type: string + default: value3 + enum: + - value1 + - value2 + - value3 + flag: + title: Boolean flag + type: boolean + ui:widget: radio + someInput: + title: Simple text input + type: string +``` + +# Boolean options + +## Boolean + +```yaml +parameters: + - title: Fill in some steps + properties: + name: + title: Checkbox boolean + type: boolean +``` + +## Boolean Yes or No options + +```yaml +parameters: + - title: Fill in some steps + properties: + name: + title: Yes or No options + type: boolean + ui:widget: radio +``` + +## Boolean multiple options + +```yaml +parameters: + - title: Fill in some steps + properties: + name: + title: Select features + type: array + items: + type: boolean + enum: ["Enable scraping", "Enable HPA", "Enable cache"] + uniqueItems: true + ui:widget: checkboxes +``` + +## Use parameters as condition in steps + +```yaml +- name: Only development environments + if: ${{ parameters.environment === "staging" and parameters.environment === "development" }} + action: debug:log + input: + message: "development step" + +- name: Only production environments + if: ${{ parameters.environment === "prod" or parameters.environment === "production" }} + action: debug:log + input: + message: "production step" +``` diff --git a/mkdocs.yml b/mkdocs.yml index 43efc32f8e..d7f303649c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -61,6 +61,7 @@ nav: - Overview: 'features/software-templates/index.md' - Configuration: 'features/software-templates/configuration.md' - Adding your own Templates: 'features/software-templates/adding-templates.md' + - Inputs examples: 'features/software-templates/inputs-examples.md' - Writing Templates: 'features/software-templates/writing-templates.md' - Builtin Actions: 'features/software-templates/builtin-actions.md' - Writing Custom Actions: 'features/software-templates/writing-custom-actions.md' From 8b0d1e72dcf61f2bb793f5460531ae87931ec45b Mon Sep 17 00:00:00 2001 From: Gabriel Dantas Date: Thu, 27 Oct 2022 09:59:19 -0300 Subject: [PATCH 082/434] fix docs quality error Signed-off-by: Gabriel Dantas --- docs/features/software-templates/inputs-examples.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-templates/inputs-examples.md b/docs/features/software-templates/inputs-examples.md index dbaab6b144..b6cccb6053 100644 --- a/docs/features/software-templates/inputs-examples.md +++ b/docs/features/software-templates/inputs-examples.md @@ -67,7 +67,7 @@ parameters: # Arrays options -## Enum with custom titles +## Array with custom titles ```yaml parameters: From 0913ace69a9f1278d1fbe0a835b411db360548db Mon Sep 17 00:00:00 2001 From: Gabriel Dantas Date: Thu, 27 Oct 2022 10:31:32 -0300 Subject: [PATCH 083/434] style: fix markdown errors Signed-off-by: Gabriel Dantas --- .../software-templates/inputs-examples.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/features/software-templates/inputs-examples.md b/docs/features/software-templates/inputs-examples.md index b6cccb6053..13bd383215 100644 --- a/docs/features/software-templates/inputs-examples.md +++ b/docs/features/software-templates/inputs-examples.md @@ -8,9 +8,9 @@ All the examples on this page you can test using _create/edit_ from your Backsta It is important to remember that all examples are based on [react-jsonschema-form](https://rjsf-team.github.io/react-jsonschema-form/). -# Simple text input +## Simple text input -## Simple input with basic validations +### Simple input with basic validations ```yaml parameters: @@ -26,7 +26,7 @@ parameters: ui:help: "Hint: additional description..." ``` -## Simple secret input +### Simple secret input ```yaml parameters: @@ -40,7 +40,7 @@ parameters: ui:widget: "password" ``` -## Multi line text input +### Multi line text input ```yaml parameters: @@ -65,9 +65,9 @@ parameters: lifecycle: experimental ``` -# Arrays options +## Arrays options -## Array with custom titles +### Array with custom titles ```yaml parameters: @@ -91,7 +91,7 @@ parameters: ] ``` -## A multiple choices list +### A multiple choices list ```yaml parameters: @@ -107,7 +107,7 @@ parameters: ui:widget: checkboxes ``` -## Array with another types +### Array with another types ```yaml parameters: @@ -140,9 +140,9 @@ parameters: type: string ``` -# Boolean options +## Boolean options -## Boolean +### Boolean ```yaml parameters: @@ -153,7 +153,7 @@ parameters: type: boolean ``` -## Boolean Yes or No options +### Boolean Yes or No options ```yaml parameters: @@ -165,7 +165,7 @@ parameters: ui:widget: radio ``` -## Boolean multiple options +### Boolean multiple options ```yaml parameters: From 2815e378951e7799ccf39c3845dedca2b4f1a6f4 Mon Sep 17 00:00:00 2001 From: Gabriel Dantas Date: Thu, 27 Oct 2022 11:47:28 -0300 Subject: [PATCH 084/434] fix: run prettier -w Signed-off-by: Gabriel Dantas --- .../software-templates/inputs-examples.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/features/software-templates/inputs-examples.md b/docs/features/software-templates/inputs-examples.md index 13bd383215..3e39c21d63 100644 --- a/docs/features/software-templates/inputs-examples.md +++ b/docs/features/software-templates/inputs-examples.md @@ -23,7 +23,7 @@ parameters: maxLength: 8 pattern: '^([a-zA-Z][a-zA-Z0-9]*)(-[a-zA-Z0-9]+)*$' ui:autofocus: true - ui:help: "Hint: additional description..." + ui:help: 'Hint: additional description...' ``` ### Simple secret input @@ -37,7 +37,7 @@ parameters: type: string description: Super secret description hint minLength: 6 - ui:widget: "password" + ui:widget: 'password' ``` ### Multi line text input @@ -50,10 +50,10 @@ parameters: title: Text area input type: string description: Insira o valor do input que gostraia - ui:widget: "textarea" - ui:options: + ui:widget: 'textarea' + ui:options: rows: 10 - ui:help: "Hint: Make it strong!" + ui:help: 'Hint: Make it strong!' ui:placeholder: | apiVersion: backstage.io/v1alpha1 kind: Component @@ -102,7 +102,7 @@ parameters: type: array items: type: string - enum: ["production", "staging", "development"] + enum: ['production', 'staging', 'development'] uniqueItems: true ui:widget: checkboxes ``` @@ -176,7 +176,7 @@ parameters: type: array items: type: boolean - enum: ["Enable scraping", "Enable HPA", "Enable cache"] + enum: ['Enable scraping', 'Enable HPA', 'Enable cache'] uniqueItems: true ui:widget: checkboxes ``` @@ -188,11 +188,11 @@ parameters: if: ${{ parameters.environment === "staging" and parameters.environment === "development" }} action: debug:log input: - message: "development step" + message: 'development step' - name: Only production environments if: ${{ parameters.environment === "prod" or parameters.environment === "production" }} action: debug:log input: - message: "production step" + message: 'production step' ``` From 87f1b7e515879178e9f30df8e99c467a22d8475e Mon Sep 17 00:00:00 2001 From: Gabriel Dantas Date: Fri, 28 Oct 2022 15:37:43 -0300 Subject: [PATCH 085/434] fix: review comments Signed-off-by: Gabriel Dantas --- .../{inputs-examples.md => input-examples.md} | 35 ++++++++++++------- mkdocs.yml | 2 +- 2 files changed, 24 insertions(+), 13 deletions(-) rename docs/features/software-templates/{inputs-examples.md => input-examples.md} (86%) diff --git a/docs/features/software-templates/inputs-examples.md b/docs/features/software-templates/input-examples.md similarity index 86% rename from docs/features/software-templates/inputs-examples.md rename to docs/features/software-templates/input-examples.md index 3e39c21d63..68a6fefc0e 100644 --- a/docs/features/software-templates/inputs-examples.md +++ b/docs/features/software-templates/input-examples.md @@ -77,18 +77,23 @@ parameters: title: Volume Type type: string description: The volume type to be used. - enum: ['gp2', 'gp3', 'io1', 'io2', 'sc1', 'st1', 'standard'] default: 'gp2' + enum: + - 'gp2' + - 'gp3' + - 'io1' + - 'io2' + - 'sc1' + - 'st1' + - 'standard' enumNames: - [ - 'General Purpose SSD (gp2)', - 'General Purpose SSD (gp3)', - 'Provisioned IOPS (io1)', - 'Provisioned IOPS (io2)', - 'Cold HDD (sc1)', - 'Throughput Optimized HDD (st1)', - 'Magnetic (standard)', - ] + - 'General Purpose SSD (gp2)' + - 'General Purpose SSD (gp3)' + - 'Provisioned IOPS (io1)' + - 'Provisioned IOPS (io2)' + - 'Cold HDD (sc1)' + - 'Throughput Optimized HDD (st1)' + - 'Magnetic (standard)' ``` ### A multiple choices list @@ -102,7 +107,10 @@ parameters: type: array items: type: string - enum: ['production', 'staging', 'development'] + enum: + - 'production' + - 'staging' + - 'development' uniqueItems: true ui:widget: checkboxes ``` @@ -176,7 +184,10 @@ parameters: type: array items: type: boolean - enum: ['Enable scraping', 'Enable HPA', 'Enable cache'] + enum: + - 'Enable scraping' + - 'Enable HPA' + - 'Enable cache' uniqueItems: true ui:widget: checkboxes ``` diff --git a/mkdocs.yml b/mkdocs.yml index d7f303649c..06906fe3f0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -61,7 +61,7 @@ nav: - Overview: 'features/software-templates/index.md' - Configuration: 'features/software-templates/configuration.md' - Adding your own Templates: 'features/software-templates/adding-templates.md' - - Inputs examples: 'features/software-templates/inputs-examples.md' + - Input examples: 'features/software-templates/inputs-examples.md' - Writing Templates: 'features/software-templates/writing-templates.md' - Builtin Actions: 'features/software-templates/builtin-actions.md' - Writing Custom Actions: 'features/software-templates/writing-custom-actions.md' From d7d8e00a5274bc37ecd6c8f6305d864d599bd89a Mon Sep 17 00:00:00 2001 From: Gabriel Dantas Date: Fri, 28 Oct 2022 16:36:27 -0300 Subject: [PATCH 086/434] fix: prettier Signed-off-by: Gabriel Dantas --- .../software-templates/input-examples.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/features/software-templates/input-examples.md b/docs/features/software-templates/input-examples.md index 68a6fefc0e..3d76f3e0ab 100644 --- a/docs/features/software-templates/input-examples.md +++ b/docs/features/software-templates/input-examples.md @@ -1,5 +1,5 @@ --- -id: inputs-examples +id: input-examples title: Built-in examples inputs description: Some examples to use in your template --- @@ -78,13 +78,13 @@ parameters: type: string description: The volume type to be used. default: 'gp2' - enum: + enum: - 'gp2' - - 'gp3' - - 'io1' - - 'io2' - - 'sc1' - - 'st1' + - 'gp3' + - 'io1' + - 'io2' + - 'sc1' + - 'st1' - 'standard' enumNames: - 'General Purpose SSD (gp2)' @@ -107,10 +107,10 @@ parameters: type: array items: type: string - enum: - - 'production' - - 'staging' - - 'development' + enum: + - 'production' + - 'staging' + - 'development' uniqueItems: true ui:widget: checkboxes ``` @@ -184,7 +184,7 @@ parameters: type: array items: type: boolean - enum: + enum: - 'Enable scraping' - 'Enable HPA' - 'Enable cache' From 014fbef35703d7689f1f95264eea4074bc091873 Mon Sep 17 00:00:00 2001 From: Gabriel Dantas Gomes Date: Sun, 30 Oct 2022 23:52:37 -0300 Subject: [PATCH 087/434] Update mkdocs.yml Co-authored-by: Ben Lambert Signed-off-by: Gabriel Dantas Gomes Signed-off-by: Gabriel Dantas --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 06906fe3f0..38070252f5 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -61,7 +61,7 @@ nav: - Overview: 'features/software-templates/index.md' - Configuration: 'features/software-templates/configuration.md' - Adding your own Templates: 'features/software-templates/adding-templates.md' - - Input examples: 'features/software-templates/inputs-examples.md' + - Input Examples: 'features/software-templates/input-examples.md' - Writing Templates: 'features/software-templates/writing-templates.md' - Builtin Actions: 'features/software-templates/builtin-actions.md' - Writing Custom Actions: 'features/software-templates/writing-custom-actions.md' From 75cbec788aba951d37ea4225f3596b2cffa2a2d3 Mon Sep 17 00:00:00 2001 From: Gabriel Dantas Gomes Date: Mon, 31 Oct 2022 01:22:05 -0300 Subject: [PATCH 088/434] fix quotes Signed-off-by: Gabriel Dantas --- .../software-templates/input-examples.md | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/features/software-templates/input-examples.md b/docs/features/software-templates/input-examples.md index 3d76f3e0ab..cd0a55aa0e 100644 --- a/docs/features/software-templates/input-examples.md +++ b/docs/features/software-templates/input-examples.md @@ -37,7 +37,7 @@ parameters: type: string description: Super secret description hint minLength: 6 - ui:widget: 'password' + ui:widget: password ``` ### Multi line text input @@ -49,8 +49,8 @@ parameters: multiline: title: Text area input type: string - description: Insira o valor do input que gostraia - ui:widget: 'textarea' + description: Insert your multi line string + ui:widget: textarea ui:options: rows: 10 ui:help: 'Hint: Make it strong!' @@ -76,16 +76,16 @@ parameters: volume_type: title: Volume Type type: string - description: The volume type to be used. - default: 'gp2' + description: The volume type to be used + default: gp2 enum: - - 'gp2' - - 'gp3' - - 'io1' - - 'io2' - - 'sc1' - - 'st1' - - 'standard' + - gp2 + - gp3 + - io1 + - io2 + - sc1 + - st1 + - standard enumNames: - 'General Purpose SSD (gp2)' - 'General Purpose SSD (gp3)' @@ -108,9 +108,9 @@ parameters: items: type: string enum: - - 'production' - - 'staging' - - 'development' + - production + - staging + - development uniqueItems: true ui:widget: checkboxes ``` From 9881c47b3125adbf3b809a9ad6493e18f449061d Mon Sep 17 00:00:00 2001 From: blakeromano-il Date: Mon, 31 Oct 2022 10:48:02 -0400 Subject: [PATCH 089/434] Add Info about 404s on Tech Insights Readme Signed-off-by: blakeromano-il --- plugins/tech-insights-backend/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/tech-insights-backend/README.md b/plugins/tech-insights-backend/README.md index 26dac78db5..95fa3ccda9 100644 --- a/plugins/tech-insights-backend/README.md +++ b/plugins/tech-insights-backend/README.md @@ -213,6 +213,8 @@ and modify the `techInsights.ts` file to contain a reference to the FactChecker }); ``` +NOTE: You need a Fact Checker Factory to get access to the backend routes that will allow the facts to be checked. If you don't have a Fact Checker Factory you will see 404s and potentially other errors. + To be able to run checks, you need to additionally add individual checks into your FactChecker implementation. For examples how to add these, you can check the documentation of the individual implementation of the FactChecker #### Modifying check persistence From f12e9e5b8c353da30f1a5076db47271b49c30122 Mon Sep 17 00:00:00 2001 From: blakeromano-il Date: Mon, 31 Oct 2022 10:49:07 -0400 Subject: [PATCH 090/434] Add changeset Signed-off-by: blakeromano-il --- .changeset/stale-dots-love.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/stale-dots-love.md diff --git a/.changeset/stale-dots-love.md b/.changeset/stale-dots-love.md new file mode 100644 index 0000000000..46327937f0 --- /dev/null +++ b/.changeset/stale-dots-love.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-tech-insights-backend': patch +--- + +Add Documentation on 404 Errors From 1083a2c47e7da4dfaf87e471783a12882dcb4147 Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Mon, 31 Oct 2022 12:53:15 +0100 Subject: [PATCH 091/434] Used Layout pattern in SettingsPage, analogous to Explore Plugin Signed-off-by: Nikita Karpukhin --- packages/app/src/App.tsx | 26 ++++-- .../DefaultSettingsPage.test.tsx} | 11 ++- .../DefaultSettingsPage.tsx | 47 +++++++++++ .../components/DefaultSettingsPage/index.ts | 17 ++++ .../SettingsLayout/SettingsLayout.tsx | 79 +++++++++++++++++++ .../src/components/SettingsLayout/index.ts | 18 +++++ .../src/components/SettingsPage.tsx | 58 ++------------ plugins/user-settings/src/components/index.ts | 1 + 8 files changed, 190 insertions(+), 67 deletions(-) rename plugins/user-settings/src/components/{SettingsPage.test.tsx => DefaultSettingsPage/DefaultSettingsPage.test.tsx} (89%) create mode 100644 plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.tsx create mode 100644 plugins/user-settings/src/components/DefaultSettingsPage/index.ts create mode 100644 plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx create mode 100644 plugins/user-settings/src/components/SettingsLayout/index.ts diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 2526f6740f..a21fe2ce9d 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -60,18 +60,18 @@ import { HomepageCompositionRoot } from '@backstage/plugin-home'; import { LighthousePage } from '@backstage/plugin-lighthouse'; import { NewRelicPage } from '@backstage/plugin-newrelic'; import { - ScaffolderFieldExtensions, - ScaffolderPage, NextScaffolderPage, - scaffolderPlugin, + ScaffolderFieldExtensions, ScaffolderLayouts, + ScaffolderPage, + scaffolderPlugin, } from '@backstage/plugin-scaffolder'; import { SearchPage } from '@backstage/plugin-search'; import { TechRadarPage } from '@backstage/plugin-tech-radar'; import { TechDocsIndexPage, - TechDocsReaderPage, techdocsPlugin, + TechDocsReaderPage, } from '@backstage/plugin-techdocs'; import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; import { @@ -80,8 +80,10 @@ import { TextSize, } from '@backstage/plugin-techdocs-module-addons-contrib'; import { + SettingsLayout, + UserSettingsFeatureFlags, + UserSettingsGeneral, UserSettingsPage, - UserSettingsTab, } from '@backstage/plugin-user-settings'; import { AdvancedSettings } from './components/advancedSettings'; import AlarmIcon from '@material-ui/icons/Alarm'; @@ -267,9 +269,17 @@ const routes = ( element={} /> }> - - - + + + + + + + + + + + } /> } /> diff --git a/plugins/user-settings/src/components/SettingsPage.test.tsx b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx similarity index 89% rename from plugins/user-settings/src/components/SettingsPage.test.tsx rename to plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx index 01810bcc8e..24810a149e 100644 --- a/plugins/user-settings/src/components/SettingsPage.test.tsx +++ b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx @@ -16,16 +16,15 @@ import React from 'react'; import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils'; -import { SettingsPage } from './SettingsPage'; -import { UserSettingsTab } from './UserSettingsTab'; +import { DefaultSettingsPage } from './DefaultSettingsPage'; +import { UserSettingsTab } from '../UserSettingsTab'; +import { useOutlet } from 'react-router'; jest.mock('react-router', () => ({ ...jest.requireActual('react-router'), useOutlet: jest.fn().mockReturnValue(undefined), })); -import { useOutlet } from 'react-router'; - describe('', () => { beforeEach(() => { (useOutlet as jest.Mock).mockReset(); @@ -33,7 +32,7 @@ describe('', () => { it('should render the settings page with 3 tabs', async () => { const { container } = await renderWithEffects( - wrapInTestApp(), + wrapInTestApp(), ); const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); @@ -48,7 +47,7 @@ describe('', () => { ); (useOutlet as jest.Mock).mockReturnValue(advancedTabRoute); const { container } = await renderWithEffects( - wrapInTestApp(), + wrapInTestApp(), ); const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); diff --git a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.tsx b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.tsx new file mode 100644 index 0000000000..4b65a26e5e --- /dev/null +++ b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.tsx @@ -0,0 +1,47 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { UserSettingsAuthProviders } from '../AuthProviders'; +import { UserSettingsFeatureFlags } from '../FeatureFlags'; +import { UserSettingsGeneral } from '../General'; +import { SettingsLayout } from '../SettingsLayout'; + +/** + * @public + */ +export const DefaultSettingsPage = (props: { + providerSettings?: JSX.Element; +}) => { + const { providerSettings } = props; + + return ( + + + + + + + + + + + + ); +}; diff --git a/plugins/user-settings/src/components/DefaultSettingsPage/index.ts b/plugins/user-settings/src/components/DefaultSettingsPage/index.ts new file mode 100644 index 0000000000..34dcb9340d --- /dev/null +++ b/plugins/user-settings/src/components/DefaultSettingsPage/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { DefaultSettingsPage } from './DefaultSettingsPage'; diff --git a/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx b/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx new file mode 100644 index 0000000000..cba2b2bf1f --- /dev/null +++ b/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx @@ -0,0 +1,79 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { TabProps } from '@material-ui/core'; +import { + Header, + Page, + RoutedTabs, + useSidebarPinState, +} from '@backstage/core-components'; +import { + attachComponentData, + useElementFilter, +} from '@backstage/core-plugin-api'; + +/** @public */ +export type SubRoute = { + path: string; + title: string; + children: JSX.Element; + tabProps?: TabProps; +}; + +const dataKey = 'plugin.explore.settingsLayoutRoute'; + +const Route: (props: SubRoute) => null = () => null; +attachComponentData(Route, dataKey, true); + +// This causes all mount points that are discovered within this route to use the path of the route itself +attachComponentData(Route, 'core.gatherMountPoints', true); + +/** @public */ +export type SettingsLayoutProps = { + title?: string; + subtitle?: string; + children?: React.ReactNode; +}; + +/** + * @public + */ +export const SettingsLayout = (props: SettingsLayoutProps) => { + const { title, children } = props; + const { isMobile } = useSidebarPinState(); + + const routes = useElementFilter(children, elements => + elements + .selectByComponentData({ + key: dataKey, + withStrictError: + 'Child of SettingsLayout must be an SettingsLayout.Route', + }) + .getElements() + .map(child => child.props), + ); + + return ( + + {!isMobile &&
} + + + ); +}; + +SettingsLayout.Route = Route; diff --git a/plugins/user-settings/src/components/SettingsLayout/index.ts b/plugins/user-settings/src/components/SettingsLayout/index.ts new file mode 100644 index 0000000000..36a5633c94 --- /dev/null +++ b/plugins/user-settings/src/components/SettingsLayout/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export type { SettingsLayoutProps, SubRoute } from './SettingsLayout'; +export { SettingsLayout } from './SettingsLayout'; diff --git a/plugins/user-settings/src/components/SettingsPage.tsx b/plugins/user-settings/src/components/SettingsPage.tsx index 9803bf4761..3fa1057881 100644 --- a/plugins/user-settings/src/components/SettingsPage.tsx +++ b/plugins/user-settings/src/components/SettingsPage.tsx @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * Copyright 2022 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,60 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -import { - Header, - Page, - TabbedLayout, - useSidebarPinState, -} from '@backstage/core-components'; -import React from 'react'; import { useOutlet } from 'react-router'; -import { useElementFilter } from '@backstage/core-plugin-api'; -import { UserSettingsAuthProviders } from './AuthProviders'; -import { UserSettingsFeatureFlags } from './FeatureFlags'; -import { UserSettingsGeneral } from './General'; -import { USER_SETTINGS_TAB_KEY, UserSettingsTabProps } from './UserSettingsTab'; +import React from 'react'; +import { DefaultSettingsPage } from './DefaultSettingsPage'; -/** - * @public - */ -export const SettingsPage = (props: { providerSettings?: JSX.Element }) => { - const { providerSettings } = props; - const { isMobile } = useSidebarPinState(); +export const SettingsPage = () => { const outlet = useOutlet(); - const tabs = useElementFilter(outlet, elements => - elements - .selectByComponentData({ - key: USER_SETTINGS_TAB_KEY, - }) - .getElements(), - ); - - return ( - - {!isMobile &&
} - - - - - - - - - - - - {tabs.map((child, i) => ( - - {child} - - ))} - - - ); + return <>{outlet || }; }; diff --git a/plugins/user-settings/src/components/index.ts b/plugins/user-settings/src/components/index.ts index 8dc76ee7f1..8eb43a7a10 100644 --- a/plugins/user-settings/src/components/index.ts +++ b/plugins/user-settings/src/components/index.ts @@ -21,3 +21,4 @@ export * from './General'; export * from './FeatureFlags'; export { useUserProfile } from './useUserProfileInfo'; export * from './UserSettingsTab'; +export * from './SettingsLayout'; From 408027734d9d3f65a3e88238960731774fe45df6 Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Mon, 31 Oct 2022 15:15:45 +0100 Subject: [PATCH 092/434] Added check for UserSettingsTab, so that the existing code doesn't break Signed-off-by: Nikita Karpukhin --- packages/app/src/App.tsx | 18 ++------ .../DefaultSettingsPage.tsx | 9 +++- .../SettingsLayout/SettingsLayout.tsx | 2 +- .../components/SettingsPage/SettingsPage.tsx | 43 +++++++++++++++++++ .../index.ts} | 10 +---- 5 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 plugins/user-settings/src/components/SettingsPage/SettingsPage.tsx rename plugins/user-settings/src/components/{SettingsPage.tsx => SettingsPage/index.ts} (70%) diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index a21fe2ce9d..0f60012759 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -80,10 +80,8 @@ import { TextSize, } from '@backstage/plugin-techdocs-module-addons-contrib'; import { - SettingsLayout, - UserSettingsFeatureFlags, - UserSettingsGeneral, UserSettingsPage, + UserSettingsTab, } from '@backstage/plugin-user-settings'; import { AdvancedSettings } from './components/advancedSettings'; import AlarmIcon from '@material-ui/icons/Alarm'; @@ -269,17 +267,9 @@ const routes = ( element={} /> }> - - - - - - - - - - - + + + } /> } /> diff --git a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.tsx b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.tsx index 4b65a26e5e..6348845763 100644 --- a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.tsx +++ b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.tsx @@ -19,14 +19,16 @@ import { UserSettingsAuthProviders } from '../AuthProviders'; import { UserSettingsFeatureFlags } from '../FeatureFlags'; import { UserSettingsGeneral } from '../General'; import { SettingsLayout } from '../SettingsLayout'; +import { UserSettingsTabProps } from '../UserSettingsTab'; /** * @public */ export const DefaultSettingsPage = (props: { + tabs?: React.ReactElement[]; providerSettings?: JSX.Element; }) => { - const { providerSettings } = props; + const { providerSettings, tabs } = props; return ( @@ -42,6 +44,11 @@ export const DefaultSettingsPage = (props: { + {tabs?.map((child, i) => ( + + {child} + + ))} ); }; diff --git a/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx b/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx index cba2b2bf1f..23394819d6 100644 --- a/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx +++ b/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx @@ -35,7 +35,7 @@ export type SubRoute = { tabProps?: TabProps; }; -const dataKey = 'plugin.explore.settingsLayoutRoute'; +const dataKey = 'plugin.user-settings.settingsLayoutRoute'; const Route: (props: SubRoute) => null = () => null; attachComponentData(Route, dataKey, true); diff --git a/plugins/user-settings/src/components/SettingsPage/SettingsPage.tsx b/plugins/user-settings/src/components/SettingsPage/SettingsPage.tsx new file mode 100644 index 0000000000..3d1f93aaef --- /dev/null +++ b/plugins/user-settings/src/components/SettingsPage/SettingsPage.tsx @@ -0,0 +1,43 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { useOutlet } from 'react-router'; +import React from 'react'; +import { DefaultSettingsPage } from '../DefaultSettingsPage'; +import { useElementFilter } from '@backstage/core-plugin-api'; +import { + USER_SETTINGS_TAB_KEY, + UserSettingsTabProps, +} from '../UserSettingsTab'; + +export const SettingsPage = (props: { providerSettings?: JSX.Element }) => { + const { providerSettings } = props; + const outlet = useOutlet(); + const tabs = useElementFilter(outlet, elements => + elements + .selectByComponentData({ + key: USER_SETTINGS_TAB_KEY, + }) + .getElements(), + ); + + return ( + <> + {(tabs.length === 0 && outlet) || ( + + )} + + ); +}; diff --git a/plugins/user-settings/src/components/SettingsPage.tsx b/plugins/user-settings/src/components/SettingsPage/index.ts similarity index 70% rename from plugins/user-settings/src/components/SettingsPage.tsx rename to plugins/user-settings/src/components/SettingsPage/index.ts index 3fa1057881..e957a1bf09 100644 --- a/plugins/user-settings/src/components/SettingsPage.tsx +++ b/plugins/user-settings/src/components/SettingsPage/index.ts @@ -13,12 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useOutlet } from 'react-router'; -import React from 'react'; -import { DefaultSettingsPage } from './DefaultSettingsPage'; - -export const SettingsPage = () => { - const outlet = useOutlet(); - - return <>{outlet || }; -}; +export { SettingsPage } from './SettingsPage'; From a27892953bf20070fe3474adaf0a20a54fa7c323 Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Mon, 31 Oct 2022 15:15:51 +0100 Subject: [PATCH 093/434] Added tests for both for UserSettingsTab and SettingsLayout setups Signed-off-by: Nikita Karpukhin --- .../DefaultSettingsPage.test.tsx | 5 +- .../SettingsPage/SettingsPage.test.tsx | 80 +++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx diff --git a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx index 24810a149e..d7bedbd5ca 100644 --- a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx +++ b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx @@ -25,7 +25,7 @@ jest.mock('react-router', () => ({ useOutlet: jest.fn().mockReturnValue(undefined), })); -describe('', () => { +describe('', () => { beforeEach(() => { (useOutlet as jest.Mock).mockReset(); }); @@ -45,9 +45,8 @@ describe('', () => {
Advanced settings
); - (useOutlet as jest.Mock).mockReturnValue(advancedTabRoute); const { container } = await renderWithEffects( - wrapInTestApp(), + wrapInTestApp(), ); const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); diff --git a/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx b/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx new file mode 100644 index 0000000000..883358de5e --- /dev/null +++ b/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx @@ -0,0 +1,80 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils'; +import { SettingsPage } from './SettingsPage'; +import { UserSettingsTab } from '../UserSettingsTab'; +import { useOutlet } from 'react-router'; +import { SettingsLayout } from '../SettingsLayout'; + +jest.mock('react-router', () => ({ + ...jest.requireActual('react-router'), + useOutlet: jest.fn().mockReturnValue(undefined), +})); + +describe('', () => { + beforeEach(() => { + (useOutlet as jest.Mock).mockReset(); + }); + + it('should render the default settings page with 3 tabs', async () => { + const { container } = await renderWithEffects( + wrapInTestApp(), + ); + + const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + expect(tabs).toHaveLength(3); + }); + + it('should render the default settings page with 4 tabs when extra tabs are provided', async () => { + const advancedTabRoute = ( + +
Advanced settings
+
+ ); + (useOutlet as jest.Mock).mockReturnValue(advancedTabRoute); + const { container } = await renderWithEffects( + wrapInTestApp(), + ); + + const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + expect(tabs).toHaveLength(4); + expect(tabs[3].textContent).toEqual('Advanced'); + }); + + it('should render the custom settings page when custom layout is provided', async () => { + const customLayout = ( + + +
User settings
+
+ +
Advanced settings
+
+
+ ); + (useOutlet as jest.Mock).mockReturnValue(customLayout); + const { container } = await renderWithEffects( + wrapInTestApp(), + ); + + const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + expect(tabs).toHaveLength(2); + expect(tabs[0].textContent).toEqual('General'); + expect(tabs[1].textContent).toEqual('Advanced'); + }); +}); From a350001484316370f2fbef97d10251d29046c90d Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Mon, 31 Oct 2022 15:29:37 +0100 Subject: [PATCH 094/434] Updated README.md Signed-off-by: Nikita Karpukhin --- plugins/user-settings/README.md | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/plugins/user-settings/README.md b/plugins/user-settings/README.md index ce07d76257..0912e34b0a 100644 --- a/plugins/user-settings/README.md +++ b/plugins/user-settings/README.md @@ -93,3 +93,43 @@ make sure you use a similar component structure as the other tabs. You can take a look at [the example extra tab](https://github.com/backstage/backstage/blob/master/packages/app/src/components/advancedSettings/AdvancedSettings.tsx) we have created in Backstage's demo app. + +To change the layout altogether, create a custom page in `packages/app/src/components/user-settings/SettingsPage.tsx`: +```typescript jsx +import React from 'react'; +import { + SettingsLayout, + UserSettingsGeneral, +} from '@backstage/plugin-user-settings'; +import { AdvancedSettings } from './advancedSettings'; + +export const SettingsPage = () => { + return ( + + + + + + + + + ); +}; + +export const settingsPage = ; +``` + +Now register the new settings page in `packages/app/src/App.tsx`: + +```typescript jsx ++ import { settingsPage } from './components/settings/settingsPage'; + +const routes = ( + +- } /> ++ }> ++ {settingsPage} ++ + +); +``` From 38064a945bc82de1db5184e5a918ca18918f9a31 Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Mon, 31 Oct 2022 16:41:14 +0100 Subject: [PATCH 095/434] Added changeset Signed-off-by: Nikita Karpukhin --- .changeset/nice-phones-sin.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/nice-phones-sin.md diff --git a/.changeset/nice-phones-sin.md b/.changeset/nice-phones-sin.md new file mode 100644 index 0000000000..ade5c2de8b --- /dev/null +++ b/.changeset/nice-phones-sin.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-user-settings': patch +--- + +Added the ability to fully customize settings page From 1695ff8c82a10772c1de41363f489671e9bd3918 Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Mon, 31 Oct 2022 16:45:05 +0100 Subject: [PATCH 096/434] Revert App.tsx changes Signed-off-by: Nikita Karpukhin --- packages/app/src/App.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 0f60012759..2526f6740f 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -60,18 +60,18 @@ import { HomepageCompositionRoot } from '@backstage/plugin-home'; import { LighthousePage } from '@backstage/plugin-lighthouse'; import { NewRelicPage } from '@backstage/plugin-newrelic'; import { - NextScaffolderPage, ScaffolderFieldExtensions, - ScaffolderLayouts, ScaffolderPage, + NextScaffolderPage, scaffolderPlugin, + ScaffolderLayouts, } from '@backstage/plugin-scaffolder'; import { SearchPage } from '@backstage/plugin-search'; import { TechRadarPage } from '@backstage/plugin-tech-radar'; import { TechDocsIndexPage, - techdocsPlugin, TechDocsReaderPage, + techdocsPlugin, } from '@backstage/plugin-techdocs'; import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; import { From bec063868f4eacb0c565f2d430aa9b24c0e41604 Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Mon, 31 Oct 2022 17:12:30 +0100 Subject: [PATCH 097/434] Ran Prettier on the README.md Signed-off-by: Nikita Karpukhin --- plugins/user-settings/README.md | 92 ++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/plugins/user-settings/README.md b/plugins/user-settings/README.md index 0912e34b0a..3d500fbcc3 100644 --- a/plugins/user-settings/README.md +++ b/plugins/user-settings/README.md @@ -4,12 +4,14 @@ Welcome to the user-settings plugin! ## About the plugin -This plugin provides two components, `` is intended to be used within the [``](https://backstage.io/storybook/?path=/story/sidebar--sample-sidebar) and displays the signed-in users profile picture and name. The second component is a settings page where the user can control different settings across the App. +This plugin provides two components, `` is intended to be used within +the [``](https://backstage.io/storybook/?path=/story/sidebar--sample-sidebar) and displays the signed-in users +profile picture and name. The second component is a settings page where the user can control different settings across +the App. -It also provides a `UserSettingsStorage` implementation of the `StorageApi`, to -be used in the frontend as a persistent alternative to the builtin `WebStorage`. -Please see [the backend -README](https://github.com/backstage/backstage/tree/master/plugins/user-settings-backend) +It also provides a `UserSettingsStorage` implementation of the `StorageApi`, to be used in the frontend as a persistent +alternative to the builtin `WebStorage`. Please +see [the backend README](https://github.com/backstage/backstage/tree/master/plugins/user-settings-backend) for installation instructions. ## Components Usage @@ -17,51 +19,60 @@ for installation instructions. Add the item to the Sidebar: ```ts -import { Settings as SidebarSettings } from '@backstage/plugin-user-settings'; +import {Settings as SidebarSettings} from '@backstage/plugin-user-settings'; - - -; + + +< /SidebarPage>; ``` Add the page to the App routing: ```ts -import { UserSettingsPage } from '@backstage/plugin-user-settings'; +import {UserSettingsPage} from '@backstage/plugin-user-settings'; const AppRoutes = () => ( - } /> - -); + +} +/> +< /Routes> +) +; ``` ### Props **Auth Providers** -By default, the plugin provides a list of configured authentication providers fetched from `app-config.yaml` and displayed in the "Authentication Providers" tab. +By default, the plugin provides a list of configured authentication providers fetched from `app-config.yaml` and +displayed in the "Authentication Providers" tab. If you want to supply your own custom list of Authentication Providers, use the `providerSettings` prop: ```ts const MyAuthProviders = () => ( - - {someAction} - + + {someAction} < /ListItemSecondaryAction> + < /ListItem> ); const AppRoutes = () => ( } />} - /> - -); + path = "/settings" +element = { < SettingsRouter +providerSettings = { < MyAuthProviders / > +} +/>} +/> +< /Routes> +) +; ``` > **Note that the list of providers expects to be rendered within a MUI [``](https://material-ui.com/components/lists/)** @@ -70,10 +81,9 @@ const AppRoutes = () => ( By default, the plugin renders 3 tabs of settings; GENERAL, AUTHENTICATION PROVIDERS, and FEATURE FLAGS. -If you want to add more options for your users, -just pass the extra tabs using `UserSettingsTab` components as children of the `UserSettingsPage` route. -The path is in this case a child of the settings path, -in the example below it would be `/settings/advanced` so that you can easily link to it. +If you want to add more options for your users, just pass the extra tabs using `UserSettingsTab` components as children +of the `UserSettingsPage` route. The path is in this case a child of the settings path, in the example below it would +be `/settings/advanced` so that you can easily link to it. ```tsx import { @@ -81,55 +91,55 @@ import { UserSettingsTab, } from '@backstage/plugin-user-settings'; -}> +}> - + ; ``` -To standardize the UI of all setting tabs, -make sure you use a similar component structure as the other tabs. -You can take a look at +To standardize the UI of all setting tabs, make sure you use a similar component structure as the other tabs. You can +take a look at [the example extra tab](https://github.com/backstage/backstage/blob/master/packages/app/src/components/advancedSettings/AdvancedSettings.tsx) we have created in Backstage's demo app. To change the layout altogether, create a custom page in `packages/app/src/components/user-settings/SettingsPage.tsx`: + ```typescript jsx import React from 'react'; import { SettingsLayout, UserSettingsGeneral, } from '@backstage/plugin-user-settings'; -import { AdvancedSettings } from './advancedSettings'; +import {AdvancedSettings} from './advancedSettings'; export const SettingsPage = () => { return ( - + - + ); }; -export const settingsPage = ; +export const settingsPage = ; ``` Now register the new settings page in `packages/app/src/App.tsx`: -```typescript jsx -+ import { settingsPage } from './components/settings/settingsPage'; +```diff ++ import {settingsPage} from './components/settings/settingsPage'; const routes = ( -- } /> -+ }> -+ {settingsPage} -+ + - }/> + + }> + + {settingsPage} + + ); ``` From 8bc63687340e99352ed82ef86a0edcf008df8b6f Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Mon, 31 Oct 2022 17:36:59 +0100 Subject: [PATCH 098/434] Ran Prettier on the README.md externally Signed-off-by: Nikita Karpukhin --- plugins/user-settings/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/user-settings/README.md b/plugins/user-settings/README.md index 3d500fbcc3..ce435ee3ce 100644 --- a/plugins/user-settings/README.md +++ b/plugins/user-settings/README.md @@ -91,9 +91,9 @@ import { UserSettingsTab, } from '@backstage/plugin-user-settings'; -}> +}> - + ; ``` @@ -111,22 +111,22 @@ import { SettingsLayout, UserSettingsGeneral, } from '@backstage/plugin-user-settings'; -import {AdvancedSettings} from './advancedSettings'; +import { AdvancedSettings } from './advancedSettings'; export const SettingsPage = () => { return ( - + - + ); }; -export const settingsPage = ; +export const settingsPage = ; ``` Now register the new settings page in `packages/app/src/App.tsx`: From 5d7b14027fad0b241eaaa6eafa48283a1854e675 Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Mon, 31 Oct 2022 18:13:22 +0100 Subject: [PATCH 099/434] Updated api-report.md Signed-off-by: Nikita Karpukhin --- plugins/user-settings/api-report.md | 28 +++++++++++++++++++ .../components/SettingsPage/SettingsPage.tsx | 1 + 2 files changed, 29 insertions(+) diff --git a/plugins/user-settings/api-report.md b/plugins/user-settings/api-report.md index c51d4f992a..1323bb8d7f 100644 --- a/plugins/user-settings/api-report.md +++ b/plugins/user-settings/api-report.md @@ -18,10 +18,12 @@ import { Observable } from '@backstage/types'; import { ProfileInfo } from '@backstage/core-plugin-api'; import { ProfileInfoApi } from '@backstage/core-plugin-api'; import { PropsWithChildren } from 'react'; +import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; import { SessionApi } from '@backstage/core-plugin-api'; import { StorageApi } from '@backstage/core-plugin-api'; import { StorageValueSnapshot } from '@backstage/core-plugin-api'; +import { TabProps } from '@material-ui/core'; // @public (undocumented) export const DefaultProviderSettings: (props: { @@ -42,6 +44,32 @@ export const Router: (props: { providerSettings?: JSX.Element }) => JSX.Element; // @public (undocumented) export const Settings: (props: { icon?: IconComponent }) => JSX.Element; +// @public (undocumented) +export const SettingsLayout: { + (props: SettingsLayoutProps): JSX.Element; + Route: (props: SubRoute) => null; +}; + +// @public (undocumented) +export type SettingsLayoutProps = { + title?: string; + subtitle?: string; + children?: React_2.ReactNode; +}; + +// @public (undocumented) +export type SubRoute = { + path: string; + title: string; + children: JSX.Element; + tabProps?: TabProps< + React_2.ElementType, + { + component?: React_2.ElementType; + } + >; +}; + // @public (undocumented) export const USER_SETTINGS_TAB_KEY = 'user-settings.tab'; diff --git a/plugins/user-settings/src/components/SettingsPage/SettingsPage.tsx b/plugins/user-settings/src/components/SettingsPage/SettingsPage.tsx index 3d1f93aaef..8559bcd8c8 100644 --- a/plugins/user-settings/src/components/SettingsPage/SettingsPage.tsx +++ b/plugins/user-settings/src/components/SettingsPage/SettingsPage.tsx @@ -22,6 +22,7 @@ import { UserSettingsTabProps, } from '../UserSettingsTab'; +/** @public */ export const SettingsPage = (props: { providerSettings?: JSX.Element }) => { const { providerSettings } = props; const outlet = useOutlet(); From e63b1d973eccb80d66cf8c9b51e06a22e7d7789e Mon Sep 17 00:00:00 2001 From: Joe Patterson Date: Wed, 2 Nov 2022 09:59:03 +1000 Subject: [PATCH 100/434] fix missing icon Signed-off-by: Joe Patterson --- plugins/org/src/components/Cards/Meta/LinksGroup.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/plugins/org/src/components/Cards/Meta/LinksGroup.tsx b/plugins/org/src/components/Cards/Meta/LinksGroup.tsx index e826c1cf9c..91843f1582 100644 --- a/plugins/org/src/components/Cards/Meta/LinksGroup.tsx +++ b/plugins/org/src/components/Cards/Meta/LinksGroup.tsx @@ -41,11 +41,8 @@ const WebLink = ({ export const LinksGroup = ({ links }: { links?: EntityLink[] }) => { const app = useApp(); - const iconResolver = useCallback( - (key?: string): IconComponent => - key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon, - [app], - ); + const iconResolver = (key?: string): IconComponent => + key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon; if (links === undefined) { return null; From 49fc8ae6b453c8be159a4cae452de174000e3d2b Mon Sep 17 00:00:00 2001 From: Joe Patterson Date: Wed, 2 Nov 2022 10:11:00 +1000 Subject: [PATCH 101/434] fix type error in LinksGroup Signed-off-by: Joe Patterson --- plugins/org/src/components/Cards/Meta/LinksGroup.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org/src/components/Cards/Meta/LinksGroup.tsx b/plugins/org/src/components/Cards/Meta/LinksGroup.tsx index 91843f1582..eeade18411 100644 --- a/plugins/org/src/components/Cards/Meta/LinksGroup.tsx +++ b/plugins/org/src/components/Cards/Meta/LinksGroup.tsx @@ -22,7 +22,7 @@ import { ListItemText, Divider, } from '@material-ui/core'; -import React, { useCallback } from 'react'; +import React from 'react'; const WebLink = ({ href, From b4fb5c8ecc9923e3b31c13ebef362269816c25e6 Mon Sep 17 00:00:00 2001 From: Jasper Herzberg Date: Tue, 25 Oct 2022 17:55:24 +0200 Subject: [PATCH 102/434] Add multi-annotation capability to missing annotation feedback Signed-off-by: Jasper Herzberg --- .changeset/little-plums-look.md | 5 ++ .../EmptyState/EmptyState.stories.tsx | 4 +- .../MissingAnnotationEmptyState.tsx | 55 +++++++++++++++---- 3 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 .changeset/little-plums-look.md diff --git a/.changeset/little-plums-look.md b/.changeset/little-plums-look.md new file mode 100644 index 0000000000..45b3c0f341 --- /dev/null +++ b/.changeset/little-plums-look.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': minor +--- + +MissingAnnotationEmptyState now accepts either a string or an array of strings to support multiple missing annotations. diff --git a/packages/core-components/src/components/EmptyState/EmptyState.stories.tsx b/packages/core-components/src/components/EmptyState/EmptyState.stories.tsx index 65e9641dd0..f87d0a82ce 100644 --- a/packages/core-components/src/components/EmptyState/EmptyState.stories.tsx +++ b/packages/core-components/src/components/EmptyState/EmptyState.stories.tsx @@ -28,7 +28,9 @@ const containerStyle = { width: '100%', height: '100vh' }; export const MissingAnnotation = () => (
- +
); diff --git a/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx b/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx index 8d8416a241..59596e6d2b 100644 --- a/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx +++ b/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx @@ -23,7 +23,7 @@ import { Link } from '../Link'; import { EmptyState } from './EmptyState'; import { CodeSnippet } from '../CodeSnippet'; -const COMPONENT_YAML = `apiVersion: backstage.io/v1alpha1 +const COMPONENT_YAML_TEMPLATE = `apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: example @@ -35,8 +35,14 @@ spec: lifecycle: production owner: user:guest`; +const ANNOTATION_REGEXP = /^.*ANNOTATION.*$/m; +const ANNOTATION_YAML = COMPONENT_YAML_TEMPLATE.match(ANNOTATION_REGEXP)![0]; +const ANNOTATION_LINE = COMPONENT_YAML_TEMPLATE.split('\n').findIndex(line => + ANNOTATION_REGEXP.test(line), +); + type Props = { - annotation: string; + annotation: string | string[]; readMoreUrl?: string; }; @@ -53,23 +59,50 @@ const useStyles = makeStyles( { name: 'BackstageMissingAnnotationEmptyState' }, ); +function generateLineNumbers(lineCount: number) { + return Array.from(Array(lineCount + 1).keys(), i => i + ANNOTATION_LINE); +} + +function generateComponentYaml(annotations: string[]) { + const annotationYaml = annotations + .map(ann => ANNOTATION_YAML.replace('ANNOTATION', ann)) + .join('\n'); + + return COMPONENT_YAML_TEMPLATE.replace(ANNOTATION_YAML, annotationYaml); +} + +function generateDescription(annotations: string[]) { + const isSingular = annotations.length <= 1; + return ( + <> + The {isSingular ? 'annotation' : 'annotations'}{' '} + {annotations + .map(ann => {ann}) + .reduce((prev, curr) => ( + <> + {prev}, {curr} + + ))}{' '} + {isSingular ? 'is' : 'are'} missing. You need to add the{' '} + {isSingular ? 'annotation' : 'annotations'} to your component if you want + to enable this tool. + + ); +} + export function MissingAnnotationEmptyState(props: Props) { const { annotation, readMoreUrl } = props; + const annotations = Array.isArray(annotation) ? annotation : [annotation]; const url = readMoreUrl || 'https://backstage.io/docs/features/software-catalog/well-known-annotations'; const classes = useStyles(); - const description = ( - <> - The {annotation} annotation is missing. You need to add the - annotation to your component if you want to enable this tool. - - ); + return ( @@ -78,10 +111,10 @@ export function MissingAnnotationEmptyState(props: Props) {
From 786117e98a86e68c7dde7d1fa4708f2e1f0a9a23 Mon Sep 17 00:00:00 2001 From: manusant Date: Wed, 2 Nov 2022 11:27:16 +0000 Subject: [PATCH 103/434] sonarqube improvements Signed-off-by: manusant --- .changeset/unlucky-pigs-end.md | 5 + plugins/sonarqube/api-report.md | 24 +++++ .../SonarQubeContentPage.test.tsx | 91 +++++++++++++++++++ .../SonarQubeContentPage.tsx | 57 ++++++++++++ .../components/SonarQubeContentPage/index.ts | 16 ++++ plugins/sonarqube/src/components/index.ts | 6 +- .../src/components/useProjectKey.test.ts | 32 +++++++ .../sonarqube/src/components/useProjectKey.ts | 16 +++- plugins/sonarqube/src/index.ts | 1 + plugins/sonarqube/src/plugin.ts | 13 +++ 10 files changed, 255 insertions(+), 6 deletions(-) create mode 100644 .changeset/unlucky-pigs-end.md create mode 100644 plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.test.tsx create mode 100644 plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx create mode 100644 plugins/sonarqube/src/components/SonarQubeContentPage/index.ts diff --git a/.changeset/unlucky-pigs-end.md b/.changeset/unlucky-pigs-end.md new file mode 100644 index 0000000000..9a33827087 --- /dev/null +++ b/.changeset/unlucky-pigs-end.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-sonarqube': minor +--- + +Fix sonarqube annotation parsing. Add content page for Sonarqube. diff --git a/plugins/sonarqube/api-report.md b/plugins/sonarqube/api-report.md index e0a51479a4..3248dbbbed 100644 --- a/plugins/sonarqube/api-report.md +++ b/plugins/sonarqube/api-report.md @@ -8,6 +8,7 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { InfoCardVariants } from '@backstage/core-components'; +import { default as React_2 } from 'react'; // @public (undocumented) export type DuplicationRating = { @@ -21,15 +22,38 @@ export const EntitySonarQubeCard: (props: { duplicationRatings?: DuplicationRating[] | undefined; }) => JSX.Element; +// @public (undocumented) +export const EntitySonarQubeContentPage: ({ + title, + supportTitle, + ...otherProps +}: SonarQubeContentPageProps) => JSX.Element; + // @public (undocumented) export const isSonarQubeAvailable: (entity: Entity) => boolean; +// @public (undocumented) +export const SONARQUBE_PROJECT_KEY_ANNOTATION = 'sonarqube.org/project-key'; + // @public (undocumented) export const SonarQubeCard: (props: { variant?: InfoCardVariants; duplicationRatings?: DuplicationRating[]; }) => JSX.Element; +// @public (undocumented) +export const SonarQubeContentPage: ({ + title, + supportTitle, + ...otherProps +}: SonarQubeContentPageProps) => JSX.Element; + +// @public (undocumented) +export type SonarQubeContentPageProps = { + title?: string; + supportTitle?: string; +} & React_2.ComponentPropsWithoutRef<'div'>; + // @public (undocumented) const sonarQubePlugin: BackstagePlugin<{}, {}, {}>; export { sonarQubePlugin as plugin }; diff --git a/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.test.tsx b/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.test.tsx new file mode 100644 index 0000000000..8e847d7c31 --- /dev/null +++ b/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.test.tsx @@ -0,0 +1,91 @@ +/* + * Copyright 2020 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 { EntityProvider } from '@backstage/plugin-catalog-react'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { lightTheme } from '@backstage/theme'; +import { ThemeProvider } from '@material-ui/core'; +import React from 'react'; +import { + isSonarQubeAvailable, + SONARQUBE_PROJECT_KEY_ANNOTATION, +} from '../useProjectKey'; +import { SonarQubeApi, sonarQubeApiRef } from '../../api'; + +const Providers = ({ + annotation, + children, +}: { annotation: string } & React.PropsWithChildren): JSX.Element => ( + + + {children} + + +); + +describe('', () => { + beforeAll(() => { + jest.mock('@backstage/plugin-sonarqube', () => ({ + __esModule: true, + isSonarQubeAvailable, + EntitySonarQubeCard: () => { + return
; + }, + })); + }); + + it('renders EntitySonarQubeCard', async () => { + const { SonarQubeContentPage } = require('./SonarQubeContentPage'); + + const rendered = await renderInTestApp( + + + , + ); + expect(rendered.getByText('SonarQube Dashboard')).toBeInTheDocument(); + expect(rendered.getByText('No information to display')).toBeInTheDocument(); + expect( + rendered.getByText("There is no SonarQube project with key 'bar'."), + ).toBeInTheDocument(); + }, 15000); + + it('renders MissingAnnotationEmptyState if sonar annotation is missing', async () => { + const { SonarQubeContentPage } = require('./SonarQubeContentPage'); + + const rendered = await renderInTestApp( + + + , + ); + expect(rendered.getByText('Missing Annotation')).toBeInTheDocument(); + expect( + rendered.getAllByText(SONARQUBE_PROJECT_KEY_ANNOTATION, { exact: false }) + .length, + ).toBe(2); + }, 15000); +}); diff --git a/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx b/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx new file mode 100644 index 0000000000..124906bb12 --- /dev/null +++ b/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx @@ -0,0 +1,57 @@ +/* + * Copyright 2020 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 { + Content, + ContentHeader, + SupportButton, +} from '@backstage/core-components'; +import { MissingAnnotationEmptyState } from '@backstage/core-components'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import React from 'react'; +import { + isSonarQubeAvailable, + SONARQUBE_PROJECT_KEY_ANNOTATION, +} from '../useProjectKey'; +import { SonarQubeCard } from '../SonarQubeCard'; + +/** @public */ +export type SonarQubeContentPageProps = { + title?: string; + supportTitle?: string; +} & React.ComponentPropsWithoutRef<'div'>; + +/** @public */ +export const SonarQubeContentPage = ({ + title = 'SonarQube Dashboard', + supportTitle, + ...otherProps +}: SonarQubeContentPageProps) => { + const { entity } = useEntity(); + + return isSonarQubeAvailable(entity) ? ( + + + {supportTitle && {supportTitle}} + + + + ) : ( + + ); +}; diff --git a/plugins/sonarqube/src/components/SonarQubeContentPage/index.ts b/plugins/sonarqube/src/components/SonarQubeContentPage/index.ts new file mode 100644 index 0000000000..27c0c59365 --- /dev/null +++ b/plugins/sonarqube/src/components/SonarQubeContentPage/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './SonarQubeContentPage'; diff --git a/plugins/sonarqube/src/components/index.ts b/plugins/sonarqube/src/components/index.ts index 7e58100efa..3edce60f37 100644 --- a/plugins/sonarqube/src/components/index.ts +++ b/plugins/sonarqube/src/components/index.ts @@ -15,4 +15,8 @@ */ export * from './SonarQubeCard'; -export { isSonarQubeAvailable } from './useProjectKey'; +export * from './SonarQubeContentPage'; +export { + isSonarQubeAvailable, + SONARQUBE_PROJECT_KEY_ANNOTATION, +} from './useProjectKey'; diff --git a/plugins/sonarqube/src/components/useProjectKey.test.ts b/plugins/sonarqube/src/components/useProjectKey.test.ts index 921e9455c0..8686ac82de 100644 --- a/plugins/sonarqube/src/components/useProjectKey.test.ts +++ b/plugins/sonarqube/src/components/useProjectKey.test.ts @@ -39,10 +39,12 @@ describe('isSonarQubeAvailable', () => { const entity = createDummyEntity('dummy'); expect(isSonarQubeAvailable(entity)).toBe(true); }); + it('returns false if sonarqube annotation empty', () => { const entity = createDummyEntity(''); expect(isSonarQubeAvailable(entity)).toBe(false); }); + it('returns false if sonarqube annotation not defined', () => { const entity = { apiVersion: '', @@ -59,6 +61,7 @@ describe('isSonarQubeAvailable', () => { describe('useProjectInfo', () => { const DUMMY_INSTANCE = 'dummyInstance'; const DUMMY_KEY = 'dummyKey'; + it('parse annotation with key and instance', () => { const entity = createDummyEntity( DUMMY_INSTANCE + SONARQUBE_PROJECT_INSTANCE_SEPARATOR + DUMMY_KEY, @@ -68,6 +71,33 @@ describe('useProjectInfo', () => { projectKey: DUMMY_KEY, }); }); + + it('parse annotation with instance, tenant/project-key', () => { + const DUMMY_KEY_WITH_TENANT = 'dummy-tenant/dummyKey'; + const entity = createDummyEntity( + DUMMY_INSTANCE + + SONARQUBE_PROJECT_INSTANCE_SEPARATOR + + DUMMY_KEY_WITH_TENANT, + ); + expect(useProjectInfo(entity)).toEqual({ + projectInstance: DUMMY_INSTANCE, + projectKey: DUMMY_KEY_WITH_TENANT, + }); + }); + + it('parse annotation with instance, tenant:project-key', () => { + const DUMMY_KEY_WITH_TENANT = 'dummy-tenant:dummyKey'; + const entity = createDummyEntity( + DUMMY_INSTANCE + + SONARQUBE_PROJECT_INSTANCE_SEPARATOR + + DUMMY_KEY_WITH_TENANT, + ); + expect(useProjectInfo(entity)).toEqual({ + projectInstance: DUMMY_INSTANCE, + projectKey: DUMMY_KEY_WITH_TENANT, + }); + }); + // compatibility with previous mono-instance sonarqube config it('parse annotation with only key', () => { const entity = createDummyEntity(DUMMY_KEY); @@ -76,6 +106,7 @@ describe('useProjectInfo', () => { projectKey: DUMMY_KEY, }); }); + it('handle empty annotation', () => { const entity = createDummyEntity(''); expect(useProjectInfo(entity)).toEqual({ @@ -83,6 +114,7 @@ describe('useProjectInfo', () => { projectKey: undefined, }); }); + it('handle non-existent annotation', () => { const entity = { apiVersion: '', diff --git a/plugins/sonarqube/src/components/useProjectKey.ts b/plugins/sonarqube/src/components/useProjectKey.ts index 59a572a6c4..20f7f03bb3 100644 --- a/plugins/sonarqube/src/components/useProjectKey.ts +++ b/plugins/sonarqube/src/components/useProjectKey.ts @@ -16,6 +16,7 @@ import { Entity } from '@backstage/catalog-model'; +/** @public */ export const SONARQUBE_PROJECT_KEY_ANNOTATION = 'sonarqube.org/project-key'; export const SONARQUBE_PROJECT_INSTANCE_SEPARATOR = '/'; @@ -42,11 +43,16 @@ export const useProjectInfo = ( const annotation = entity?.metadata.annotations?.[SONARQUBE_PROJECT_KEY_ANNOTATION]; if (annotation) { - if (annotation.indexOf(SONARQUBE_PROJECT_INSTANCE_SEPARATOR) > -1) { - [projectInstance, projectKey] = annotation.split( - SONARQUBE_PROJECT_INSTANCE_SEPARATOR, - 2, - ); + const instanceSeparatorIndex = annotation.indexOf( + SONARQUBE_PROJECT_INSTANCE_SEPARATOR, + ); + if (instanceSeparatorIndex > -1) { + // Examples: + // instanceA/projectA -> projectInstance = "instanceA" & projectKey = "projectA" + // instanceA/tenantA:projectA -> projectInstance = "instanceA" & projectKey = "tenantA:projectA" + // instanceA/tenantA/projectA -> projectInstance = "instanceA" & projectKey = "tenantA/projectA" + projectInstance = annotation.substring(0, instanceSeparatorIndex); + projectKey = annotation.substring(instanceSeparatorIndex + 1); } else { projectKey = annotation; } diff --git a/plugins/sonarqube/src/index.ts b/plugins/sonarqube/src/index.ts index 1e6f83aa49..8b2a4b86b8 100644 --- a/plugins/sonarqube/src/index.ts +++ b/plugins/sonarqube/src/index.ts @@ -26,4 +26,5 @@ export { sonarQubePlugin, sonarQubePlugin as plugin, EntitySonarQubeCard, + EntitySonarQubeContentPage, } from './plugin'; diff --git a/plugins/sonarqube/src/plugin.ts b/plugins/sonarqube/src/plugin.ts index 0ea62de492..5eb5ea82f3 100644 --- a/plugins/sonarqube/src/plugin.ts +++ b/plugins/sonarqube/src/plugin.ts @@ -52,3 +52,16 @@ export const EntitySonarQubeCard = sonarQubePlugin.provide( }, }), ); + +/** @public */ +export const EntitySonarQubeContentPage = sonarQubePlugin.provide( + createComponentExtension({ + name: 'EntitySonarQubeContentPage', + component: { + lazy: () => + import('./components/SonarQubeContentPage').then( + m => m.SonarQubeContentPage, + ), + }, + }), +); From 77df9eef6f68289f9a9355808b56fd7c4f3d5fcb Mon Sep 17 00:00:00 2001 From: Diego Morales Date: Wed, 2 Nov 2022 08:31:11 -0300 Subject: [PATCH 104/434] Fix typo on architecture-overview.md Signed-off-by: Diego Morales --- docs/overview/architecture-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/overview/architecture-overview.md b/docs/overview/architecture-overview.md index 3c9417268b..45f3190a5d 100644 --- a/docs/overview/architecture-overview.md +++ b/docs/overview/architecture-overview.md @@ -249,7 +249,7 @@ however likely to change in the future. The common packages are the packages effectively depended on by all other pages. This is a much smaller set of packages but they are also very pervasive. Because the common packages are isomorphic and must execute both in the frontend and -backend, they are never allowed to depend on any of the frontend of backend +backend, they are never allowed to depend on any of the frontend or backend packages. The Backstage CLI is in a category of its own and is depended on by virtually From db1cc43cb3ec73c44dc2f38d05911ee76bd420d6 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 2 Nov 2022 13:04:48 +0100 Subject: [PATCH 105/434] scripts: add script for creating a patch release from a PR Signed-off-by: Patrik Oldsberg --- scripts/patch-release-for-pr.js | 156 ++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100755 scripts/patch-release-for-pr.js diff --git a/scripts/patch-release-for-pr.js b/scripts/patch-release-for-pr.js new file mode 100755 index 0000000000..fcfef0c6a7 --- /dev/null +++ b/scripts/patch-release-for-pr.js @@ -0,0 +1,156 @@ +#!/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. + */ + +const fs = require('fs-extra'); +const path = require('path'); +const semver = require('semver'); +const { Octokit } = require('@octokit/rest'); +const { execFile: execFileCb } = require('child_process'); +const { promisify } = require('util'); + +const execFile = promisify(execFileCb); + +const owner = 'backstage'; +const repo = 'backstage'; +const rootDir = path.resolve(__dirname, '..'); + +const octokit = new Octokit({ + auth: process.env.GITHUB_TOKEN, +}); + +async function run(command, ...args) { + const { stdout, stderr } = await execFile(command, args, { + cwd: rootDir, + }); + + if (stderr) { + console.error(stderr); + } + + return stdout.trim(); +} + +/** + * Finds the current stable release version of the repo, looking at + * the current commit and backwards, finding the first commit were a + * stable version is present. + */ +async function findCurrentReleaseVersion() { + const rootPkgPath = path.resolve(rootDir, 'package.json'); + const pkg = await fs.readJson(rootPkgPath); + + if (!semver.prerelease(pkg.version)) { + return pkg.version; + } + + const { stdout: revListStr } = await execFile('git', [ + 'rev-list', + 'HEAD', + '--', + 'package.json', + ]); + const revList = revListStr.trim().split(/\r?\n/); + + for (const rev of revList) { + const { stdout: pkgJsonStr } = await execFile('git', [ + 'show', + `${rev}:package.json`, + ]); + if (pkgJsonStr) { + const pkgJson = JSON.parse(pkgJsonStr); + if (!semver.prerelease(pkgJson.version)) { + return pkgJson.version; + } + } + } + + throw new Error('No stable release found'); +} + +async function main(prNumberStr) { + const prNumber = parseInt(prNumberStr, 10); + if (!Number.isInteger(prNumber)) { + throw new Error('Must provide a PR number as the first argument'); + } + console.log(`PR number: ${prNumber}`); + + if (await run('git', 'status', '--porcelain')) { + throw new Error('Cannot run with a dirty working tree'); + } + + const release = await findCurrentReleaseVersion(); + console.log(`Patching release ${release}`); + + await run('git', 'fetch'); + + const patchBranch = `patch/v${release}`; + try { + await run('git', 'checkout', `origin/${patchBranch}`); + } catch { + await run('git', 'checkout', '-b', patchBranch, `v${release}`); + await run('git', 'push', 'origin', '-u', patchBranch); + } + + const { data } = await octokit.pulls.get({ + owner, + repo, + pull_number: prNumber, + }); + + const headSha = data.head.sha; + if (!headSha) { + throw new Error('head sha not available'); + } + const baseSha = data.base.sha; + if (!baseSha) { + throw new Error('base sha not available'); + } + const mergeBaseSha = await run('git', 'merge-base', headSha, baseSha); + + // Create new branch, apply changes from all commits on PR branch, commit, push + const branchName = `patch-release-pr-${prNumber}`; + await run('git', 'checkout', '-b', branchName); + + const logLines = await run( + 'git', + 'log', + `${mergeBaseSha}...${headSha}`, + '--reverse', + '--pretty=%H', + ); + for (const logSha of logLines.split(/\r?\n/)) { + await run('git', 'cherry-pick', '-n', logSha); + } + await run('git', 'commit', '--signoff', '-m', `Patch from PR #${prNumber}`); + + console.log('Running "yarn release" ...'); + await run('yarn', 'release'); + + await run('git', 'add', '.'); + await run('git', 'commit', '--signoff', '-m', 'Generate Release'); + + await run('git', 'push', 'origin', '-u', branchName); + + console.log( + `https://github.com/backstage/backstage/compare/${patchBranch}...${branchName}?expand=1&body=This%20release%20fixes%20an%20issue%20where&title=Patch%20release%20of%20%23${prNumber}`, + ); +} + +main(process.argv.slice(2)).catch(error => { + console.error(error.stack || error); + process.exit(1); +}); From 405eab555f35dc8dfc2d4dc8fba20c1c7282bd48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Grumb=C3=B6ck?= Date: Wed, 2 Nov 2022 13:39:12 +0100 Subject: [PATCH 106/434] Fix: missing another occurrence of GH auth callback URL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Johannes Grumböck --- plugins/auth-backend/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth-backend/README.md b/plugins/auth-backend/README.md index d389d4e97a..ba0042c6f9 100644 --- a/plugins/auth-backend/README.md +++ b/plugins/auth-backend/README.md @@ -35,7 +35,7 @@ Follow this link, [Create new OAuth App](https://github.com/settings/application 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:7007/api/auth/github/handler/frame` for local development. - 1. Set this to `http://{APP_FQDN}:{APP_BACKEND_PORT}/api/auth/github` for non-local deployments. + 1. Set this to `http://{APP_FQDN}:{APP_BACKEND_PORT}/api/auth/github/handler/frame` for non-local deployments. ```bash export AUTH_GITHUB_CLIENT_ID=x From f97835ff7b7aec6f598defdecd50273b765f4412 Mon Sep 17 00:00:00 2001 From: manusant Date: Wed, 2 Nov 2022 13:15:15 +0000 Subject: [PATCH 107/434] add missing type dependency Signed-off-by: manusant --- plugins/sonarqube/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index b46cb5c0b1..5d91577fd8 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -59,7 +59,8 @@ "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", - "msw": "^0.47.0" + "msw": "^0.47.0", + "@types/react": "^16.13.1 || ^17.0.0" }, "files": [ "dist", From 84f076bcfd5ff8db5e89615fcf30673130cfb35e Mon Sep 17 00:00:00 2001 From: Mark Anderson-Trocme Date: Wed, 2 Nov 2022 09:18:38 -0400 Subject: [PATCH 108/434] Typo in documentation Signed-off-by: Mark Anderson-Trocme --- docs/auth/identity-resolver.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/auth/identity-resolver.md b/docs/auth/identity-resolver.md index d96c9fc45a..a65f3d7899 100644 --- a/docs/auth/identity-resolver.md +++ b/docs/auth/identity-resolver.md @@ -49,7 +49,7 @@ A user identity within Backstage is built up from two pieces of information, a user [entity reference](../features/software-catalog/references.md), and a set of ownership entity references. When a user signs in, a Backstage token is generated with these two pieces of information, -which is then used to identity the user within the Backstage ecosystem. +which is then used to identify the user within the Backstage ecosystem. The user entity reference should uniquely identify the logged in user in Backstage. It is encouraged that a matching user entity also exists within the Software Catalog, From f267548451366066598596e432ce5e48f21d328e Mon Sep 17 00:00:00 2001 From: manusant Date: Wed, 2 Nov 2022 13:29:42 +0000 Subject: [PATCH 109/434] update yarn lock Signed-off-by: manusant --- plugins/sonarqube/package.json | 4 ++-- yarn.lock | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 5d91577fd8..99f059a016 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -59,8 +59,8 @@ "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", - "msw": "^0.47.0", - "@types/react": "^16.13.1 || ^17.0.0" + "@types/react": "^16.13.1 || ^17.0.0", + "msw": "^0.47.0" }, "files": [ "dist", diff --git a/yarn.lock b/yarn.lock index c42aac2eec..6ab3c2300a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7261,6 +7261,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 + "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 rc-progress: 3.4.0 From bfb59673619fc275d1d04c348ceccb3a38bc7c05 Mon Sep 17 00:00:00 2001 From: Pascal Lukanek Date: Wed, 2 Nov 2022 19:09:28 +0100 Subject: [PATCH 110/434] [OwnershipCard] Add type as subtitle + adjust query params Signed-off-by: Pascal Lukanek --- .../components/Cards/OwnershipCard/ComponentsGrid.tsx | 4 ++++ .../Cards/OwnershipCard/OwnershipCard.test.tsx | 10 ++++++++-- .../components/Cards/OwnershipCard/useGetEntities.ts | 5 ++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx b/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx index 6f7680849c..c1522c1fd1 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx +++ b/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx @@ -56,11 +56,13 @@ const useStyles = makeStyles((theme: BackstageTheme) => const EntityCountTile = ({ counter, type, + kind, name, url, }: { counter: number; type: string; + kind: string; name: string; url: string; }) => { @@ -80,6 +82,7 @@ const EntityCountTile = ({ {pluralize(name, counter)} + {kind != type && {kind}} ); @@ -116,6 +119,7 @@ export const ComponentsGrid = ({ { expect( queryByText(getByText('SYSTEM').parentElement!, '1'), ).toBeInTheDocument(); + expect( + queryByText(getByText('SYSTEM').parentElement!, 'System'), + ).not.toBeInTheDocument(); expect(getByText('OPENAPI')).toBeInTheDocument(); expect( queryByText(getByText('OPENAPI').parentElement!, '1'), ).toBeInTheDocument(); + expect( + queryByText(getByText('OPENAPI').parentElement!, 'API'), + ).toBeInTheDocument(); expect(() => getByText('LIBRARY')).toThrow(); }); @@ -246,7 +252,7 @@ describe('OwnershipCard', () => { expect(getByText('OPENAPI').closest('a')).toHaveAttribute( 'href', - '/create/?filters%5Bkind%5D=API&filters%5Btype%5D=openapi&filters%5Bowners%5D=my-team&filters%5Buser%5D=all', + '/create/?filters%5Bkind%5D=api&filters%5Btype%5D=openapi&filters%5Bowners%5D=my-team&filters%5Buser%5D=all', ); }); @@ -292,7 +298,7 @@ describe('OwnershipCard', () => { expect(getByText('OPENAPI').closest('a')).toHaveAttribute( 'href', - '/create/?filters%5Bkind%5D=API&filters%5Btype%5D=openapi&filters%5Bowners%5D=user%3Athe-user&filters%5Bowners%5D=my-team&filters%5Bowners%5D=custom%2Fsome-team&filters%5Buser%5D=all', + '/create/?filters%5Bkind%5D=api&filters%5Btype%5D=openapi&filters%5Bowners%5D=user%3Athe-user&filters%5Bowners%5D=my-team&filters%5Bowners%5D=custom%2Fsome-team&filters%5Buser%5D=all', ); }); diff --git a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts index 7c0bb76e2e..77d5164830 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts +++ b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts @@ -49,7 +49,7 @@ const getQueryParams = ( humanizeEntityRef(parseEntityRef(owner), { defaultKind: 'group' }), ); const filters = { - kind, + kind: kind.toLowerCase(), type, owners, user: 'all', @@ -135,6 +135,7 @@ export function useGetEntities( | { counter: number; type: string; + kind: string; name: string; queryParams: string; }[] @@ -197,11 +198,13 @@ export function useGetEntities( return topN.map(topOwnedEntity => ({ counter: topOwnedEntity.count, type: topOwnedEntity.type, + kind: topOwnedEntity.kind, name: topOwnedEntity.type.toLocaleUpperCase('en-US'), queryParams: getQueryParams(owners, topOwnedEntity), })) as Array<{ counter: number; type: string; + kind: string; name: string; queryParams: string; }>; From 38dd29ea95aa1f70710f36b5f1b5ee9d15673bcc Mon Sep 17 00:00:00 2001 From: Pascal Lukanek Date: Wed, 2 Nov 2022 19:17:08 +0100 Subject: [PATCH 111/434] Add changeset Signed-off-by: Pascal Lukanek --- .changeset/stale-tools-yawn.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/stale-tools-yawn.md diff --git a/.changeset/stale-tools-yawn.md b/.changeset/stale-tools-yawn.md new file mode 100644 index 0000000000..b053d83acd --- /dev/null +++ b/.changeset/stale-tools-yawn.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-org': patch +--- + +Add entity type to the Ownership Cards. +Fix the query params for the links of the Ownership Cards so that the catalog page actually selects the right entity kind. From 53b5069b022c21fecf211fcfa6c077c3f21361b6 Mon Sep 17 00:00:00 2001 From: Axel Hecht Date: Wed, 2 Nov 2022 19:38:53 +0100 Subject: [PATCH 112/434] Remove backend token, add ora spinner to some steps Signed-off-by: Axel Hecht --- contrib/scaffolder/README.md | 5 +--- .../scaffolder/template-testing-dry-run.md | 26 +++---------------- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/contrib/scaffolder/README.md b/contrib/scaffolder/README.md index 088ad9c5d1..e22c4b391f 100644 --- a/contrib/scaffolder/README.md +++ b/contrib/scaffolder/README.md @@ -12,7 +12,4 @@ The [command line script](template-testing-dry-run.md) might offer a way for you scaffolder-dry http://localhost:7007/ template-directory values.yml output-directory ``` -If you're using backend-to-backend authentication, either - -- pass a front-end auth token from a current browser session via `--token $FRONTEND_TOKEN`, -- have the tool create a b2b token for a given base64 encoded backend secret via `--backend-secret $BACKEND_SECRET`. +If you're using backend permissions, pass a front-end auth token from a current browser session via `--token $FRONTEND_TOKEN`. diff --git a/contrib/scaffolder/template-testing-dry-run.md b/contrib/scaffolder/template-testing-dry-run.md index 89b92e22ef..70e0c572ab 100644 --- a/contrib/scaffolder/template-testing-dry-run.md +++ b/contrib/scaffolder/template-testing-dry-run.md @@ -26,17 +26,15 @@ import { readFile, writeFile } from 'node:fs/promises'; import { gzipSync } from 'node:zlib'; import { ensureDir } from 'fs-extra'; import { program } from 'commander'; -import { base64url, exportJWK, generateSecret, jwtVerify, SignJWT } from 'jose'; import fetch from 'node-fetch'; +import ora from 'ora'; import readdir from 'recursive-readdir'; import { parse } from 'yaml'; import { version } from '../../../package.json'; import type { ScaffolderDryRunResponse } from '@backstage/plugin-scaffolder'; -const TOKEN_ALG = 'HS256'; -const TOKEN_SUB = 'backstage-server'; - const loadDirectoryContents = async (template_path: string) => { + const spinner = ora('Loading template').start(); const files = await await readdir(template_path, ['.git']); const contents = await Promise.all( files.map(async p => { @@ -46,6 +44,7 @@ const loadDirectoryContents = async (template_path: string) => { }; }), ); + spinner.succeed(); return contents; }; @@ -66,15 +65,6 @@ const writeResultContents = async ( ); }; -const getToken = async (backendSecret: string) => { - const signingKey = base64url.decode(backendSecret); - return await new SignJWT({}) - .setProtectedHeader({ alg: TOKEN_ALG }) - .setSubject(TOKEN_SUB) - .setExpirationTime('10min') - .sign(signingKey); -}; - const api = async ( bodyObj: Record, { baseURL, token }: { baseURL: string; token: string | false }, @@ -96,10 +86,7 @@ const handle = async ( template_path: string, data: string, target: string, - { - token, - backendSecret, - }: { token: string | false; backendSecret: string | false }, + { token }: { token: string | false }, ) => { const directoryContents = await loadDirectoryContents(template_path); const values = parse(await readFile(data, 'utf-8')); @@ -107,10 +94,6 @@ const handle = async ( const template = parse( await readFile(`${template_path}/template.yaml`, 'utf-8'), ); - if (backendSecret) { - // eslint-disable-next-line no-param-reassign - token = await getToken(backendSecret); - } const response = await api( { directoryContents, @@ -148,7 +131,6 @@ const main = async (argv: string[]) => { .version(version) .description('Creates a dry-run output of a given template') .option('-t, --token ', 'JWT to use for auth') - .option('-b, --backend-secret ', 'Base64 encoded backend secret') .argument('url', 'URL of your Backstage instance') .argument('template-path', 'Source directory of template') .argument('data-path', 'YAML file with input to render') From 08152905d2d34061b28c3187a9ae0f2e91ec45f8 Mon Sep 17 00:00:00 2001 From: Pascal Lukanek Date: Wed, 2 Nov 2022 20:42:33 +0100 Subject: [PATCH 113/434] Linting Signed-off-by: Pascal Lukanek --- .changeset/stale-tools-yawn.md | 3 +-- .../org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx | 2 +- .../org/src/components/Cards/OwnershipCard/useGetEntities.ts | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.changeset/stale-tools-yawn.md b/.changeset/stale-tools-yawn.md index b053d83acd..ca933d70f4 100644 --- a/.changeset/stale-tools-yawn.md +++ b/.changeset/stale-tools-yawn.md @@ -2,5 +2,4 @@ '@backstage/plugin-org': patch --- -Add entity type to the Ownership Cards. -Fix the query params for the links of the Ownership Cards so that the catalog page actually selects the right entity kind. +Add entity kind to the Ownership Cards. Fix the query params for the links of the Ownership Cards so that the catalog page actually selects the right entity kind. diff --git a/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx b/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx index c1522c1fd1..ba037f791c 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx +++ b/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx @@ -82,7 +82,7 @@ const EntityCountTile = ({ {pluralize(name, counter)} - {kind != type && {kind}} + {kind !== type && {kind}} ); diff --git a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts index 77d5164830..3756e6827e 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts +++ b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts @@ -49,7 +49,7 @@ const getQueryParams = ( humanizeEntityRef(parseEntityRef(owner), { defaultKind: 'group' }), ); const filters = { - kind: kind.toLowerCase(), + kind: kind.toLocaleLowerCase('en-US'), type, owners, user: 'all', From 12ee4453faa883b6bf5d3913a4e1811750795b2d Mon Sep 17 00:00:00 2001 From: Pascal Lukanek Date: Wed, 2 Nov 2022 20:54:57 +0100 Subject: [PATCH 114/434] Spelling Signed-off-by: Pascal Lukanek --- .changeset/stale-tools-yawn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/stale-tools-yawn.md b/.changeset/stale-tools-yawn.md index ca933d70f4..f0173c7dd7 100644 --- a/.changeset/stale-tools-yawn.md +++ b/.changeset/stale-tools-yawn.md @@ -2,4 +2,4 @@ '@backstage/plugin-org': patch --- -Add entity kind to the Ownership Cards. Fix the query params for the links of the Ownership Cards so that the catalog page actually selects the right entity kind. +Add entity kind to the Ownership Cards. Fix the query parameters for the links of the Ownership Cards so that the catalog page actually selects the right entity kind. From a392bd38abc16bfb62a67728f8589d9c7e463e65 Mon Sep 17 00:00:00 2001 From: hram_wh Date: Thu, 3 Nov 2022 10:53:53 +0530 Subject: [PATCH 115/434] readme section for tools content customization Signed-off-by: hram_wh --- plugins/explore/README.md | 24 +++++++++++++++++++ plugins/explore/api-report.md | 6 +---- .../DefaultExplorePage/DefaultExplorePage.tsx | 7 ++---- .../components/ExplorePage/ExplorePage.tsx | 7 ++---- .../ToolExplorerContent.tsx | 15 ++++-------- 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/plugins/explore/README.md b/plugins/explore/README.md index 8e1cbaed02..b28fd8ceb6 100644 --- a/plugins/explore/README.md +++ b/plugins/explore/README.md @@ -79,3 +79,27 @@ const routes = ( ); ``` + +## ToolExplorer Content Customization + +Override the `exploreToolsConfigRef` API in `/packages/app/src/apis.ts`. + +```tsx +import { exploreToolsConfigRef } from '@backstage/plugin-explore-react'; + +export const apis: AnyApiFactory[] = [ + ... + + createApiFactory({ + api: exploreToolsConfigRef, + deps: {}, + factory: () => ({ + /* pass the tools array */ + }), + }), + + .... + +]; + +``` diff --git a/plugins/explore/api-report.md b/plugins/explore/api-report.md index 7816c1c60f..9653c0fb63 100644 --- a/plugins/explore/api-report.md +++ b/plugins/explore/api-report.md @@ -8,7 +8,6 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { default as default_2 } from 'react'; import { DomainEntity } from '@backstage/catalog-model'; -import { ExploreTool } from '@backstage/plugin-explore-react'; import { ExternalRouteRef } from '@backstage/core-plugin-api'; import { RouteRef } from '@backstage/core-plugin-api'; import { TabProps } from '@material-ui/core'; @@ -45,9 +44,7 @@ export type ExploreLayoutProps = { }; // @public (undocumented) -export const ExplorePage: (props: { - exploreTools?: ExploreTool[] | undefined; -}) => JSX.Element; +export const ExplorePage: () => JSX.Element; // @public (undocumented) const explorePlugin: BackstagePlugin< @@ -93,6 +90,5 @@ export type SubRoute = { // @public (undocumented) export const ToolExplorerContent: (props: { title?: string | undefined; - exploreTools?: ExploreTool[] | undefined; }) => JSX.Element; ``` diff --git a/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.tsx b/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.tsx index 193034ea87..54beb59619 100644 --- a/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.tsx +++ b/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.tsx @@ -20,11 +20,8 @@ import { ExploreLayout } from '../ExploreLayout'; import { GroupsExplorerContent } from '../GroupsExplorerContent'; import { ToolExplorerContent } from '../ToolExplorerContent'; import { configApiRef, useApi } from '@backstage/core-plugin-api'; -import { ExploreTool } from '@backstage/plugin-explore-react'; -export const DefaultExplorePage = (props: { - exploreTools?: Array; -}) => { +export const DefaultExplorePage = () => { const configApi = useApi(configApiRef); const organizationName = configApi.getOptionalString('organization.name') ?? 'Backstage'; @@ -41,7 +38,7 @@ export const DefaultExplorePage = (props: { - + ); diff --git a/plugins/explore/src/components/ExplorePage/ExplorePage.tsx b/plugins/explore/src/components/ExplorePage/ExplorePage.tsx index 266c816f74..80fe3febec 100644 --- a/plugins/explore/src/components/ExplorePage/ExplorePage.tsx +++ b/plugins/explore/src/components/ExplorePage/ExplorePage.tsx @@ -17,12 +17,9 @@ import React from 'react'; import { useOutlet } from 'react-router'; import { DefaultExplorePage } from '../DefaultExplorePage'; -import { ExploreTool } from '@backstage/plugin-explore-react'; -export const ExplorePage = (props: { exploreTools?: Array }) => { +export const ExplorePage = () => { const outlet = useOutlet(); - return ( - <>{outlet || } - ); + return <>{outlet || }; }; diff --git a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx index 79d8fda6fe..92ba9b7b16 100644 --- a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx +++ b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx @@ -14,10 +14,7 @@ * limitations under the License. */ -import { - ExploreTool, - exploreToolsConfigRef, -} from '@backstage/plugin-explore-react'; +import { exploreToolsConfigRef } from '@backstage/plugin-explore-react'; import React from 'react'; import useAsync from 'react-use/lib/useAsync'; import { ToolCard } from '../ToolCard'; @@ -32,14 +29,13 @@ import { } from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; -const Body = (props: { exploreTools?: Array }) => { +const Body = () => { const exploreToolsConfigApi = useApi(exploreToolsConfigRef); const { value: tools, loading, error, } = useAsync(async () => { - if (props?.exploreTools) return props?.exploreTools; return await exploreToolsConfigApi.getTools(); }, [exploreToolsConfigApi]); @@ -70,14 +66,11 @@ const Body = (props: { exploreTools?: Array }) => { ); }; -export const ToolExplorerContent = (props: { - title?: string; - exploreTools?: Array; -}) => ( +export const ToolExplorerContent = (props: { title?: string }) => ( Discover the tools in your ecosystem. - + ); From 4befb8d6386469f65a941d06356af304e2a98889 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 3 Nov 2022 11:07:58 +0100 Subject: [PATCH 116/434] docs: update node versioning policy to be less optimistic Signed-off-by: Patrik Oldsberg --- docs/overview/versioning-policy.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/overview/versioning-policy.md b/docs/overview/versioning-policy.md index 885a599ed8..a989f104b5 100644 --- a/docs/overview/versioning-policy.md +++ b/docs/overview/versioning-policy.md @@ -144,9 +144,10 @@ following schedule for determining the [Node.js releases](https://nodejs.org/en/ - At any given point in time we support exactly two adjacent even-numbered releases of Node.js, for example v12 and v14. -- Three months before a Node.js release becomes _Active LTS_ we switch support - to that release and the previous one. This is halfway through the _Current LTS_ - cycle for that release and occurs at the end of July every year. +- Once a new Node.js release becomes _Active LTS_ we switch to support that + release and the previous one. The switch is not immediate but done as soon + as possible. You can find the Node.js version supported by each release + in the `engines` field in the root `package.json` of a new app. When we say _Supporting_ a Node.js release, that means the following: From 551d57244743d62b827ed09e199e440cfc07f130 Mon Sep 17 00:00:00 2001 From: hram_wh Date: Thu, 3 Nov 2022 16:01:07 +0530 Subject: [PATCH 117/434] minor changes Signed-off-by: hram_wh --- .changeset/bright-pillows-build.md | 2 +- plugins/explore/README.md | 12 +++++++++++- .../ToolExplorerContent/ToolExplorerContent.tsx | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.changeset/bright-pillows-build.md b/.changeset/bright-pillows-build.md index 65517a6595..9939fddf42 100644 --- a/.changeset/bright-pillows-build.md +++ b/.changeset/bright-pillows-build.md @@ -2,4 +2,4 @@ '@backstage/plugin-explore': patch --- -Added ability to customize the explore plugin tools tab content +Added a section to explore plugin README that describes the customization of explore tools content. diff --git a/plugins/explore/README.md b/plugins/explore/README.md index b28fd8ceb6..7fa088ab9a 100644 --- a/plugins/explore/README.md +++ b/plugins/explore/README.md @@ -94,7 +94,17 @@ export const apis: AnyApiFactory[] = [ api: exploreToolsConfigRef, deps: {}, factory: () => ({ - /* pass the tools array */ + /* pass the tools array + i.e. tools = [ + { + title: 'New Relic', + description:'new relic plugin, + url: '/newrelic', + image: 'https://i.imgur.com/L37ikrX.jpg', + tags: ['newrelic', 'proxy', 'nerdGraph'], + }, + ] + */ }), }), diff --git a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx index 92ba9b7b16..5404c67393 100644 --- a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx +++ b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx @@ -59,7 +59,7 @@ const Body = () => { return ( - {tools?.map((tool, index) => ( + {tools.map((tool, index) => ( ))} From b8ec39aba5379d235d7c6452cbc73edb94e24cdd Mon Sep 17 00:00:00 2001 From: hram_wh Date: Thu, 3 Nov 2022 16:11:46 +0530 Subject: [PATCH 118/434] prettier fix Signed-off-by: hram_wh --- plugins/explore/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/explore/README.md b/plugins/explore/README.md index 7fa088ab9a..5038f3e5f0 100644 --- a/plugins/explore/README.md +++ b/plugins/explore/README.md @@ -94,7 +94,7 @@ export const apis: AnyApiFactory[] = [ api: exploreToolsConfigRef, deps: {}, factory: () => ({ - /* pass the tools array + /* pass the tools array i.e. tools = [ { title: 'New Relic', From 9b6854f2df1f49d1168a7cfeb687452fac958383 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Oct 2022 14:14:27 +0000 Subject: [PATCH 119/434] Update dependency @types/node to v16.18.1 Signed-off-by: Renovate Bot --- yarn.lock | 160 +++++++++++++++++++++++++++--------------------------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/yarn.lock b/yarn.lock index c42aac2eec..b6816e6c16 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3108,7 +3108,7 @@ __metadata: "@material-ui/icons": ^4.9.1 "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/react": ^16.13.1 || ^17.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -3400,7 +3400,7 @@ __metadata: "@types/jest": ^29.0.0 "@types/minimatch": ^5.0.0 "@types/mock-fs": ^4.13.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/npm-packlist": ^3.0.0 "@types/recursive-readdir": ^2.2.0 "@types/rollup-plugin-peer-deps-external": ^2.2.0 @@ -3503,7 +3503,7 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/cli-common": "workspace:^" "@types/jscodeshift": ^0.11.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 chalk: ^4.0.0 commander: ^9.1.0 jscodeshift: ^0.13.0 @@ -3526,7 +3526,7 @@ __metadata: "@types/json-schema": ^7.0.6 "@types/json-schema-merge-allof": ^0.6.0 "@types/mock-fs": ^4.10.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/yup": ^0.29.13 ajv: ^8.10.0 chokidar: ^3.5.2 @@ -3579,7 +3579,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/prop-types": ^15.7.3 "@types/zen-observable": ^0.8.0 cross-fetch: ^3.1.5 @@ -3678,7 +3678,7 @@ __metadata: "@types/d3-zoom": ^3.0.1 "@types/dagre": ^0.7.44 "@types/google-protobuf": ^3.7.2 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/react-helmet": ^6.1.0 "@types/react-sparklines": ^1.7.0 "@types/react-syntax-highlighter": ^15.0.0 @@ -3754,7 +3754,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/prop-types": ^15.7.3 "@types/zen-observable": ^0.8.0 cross-fetch: ^3.1.5 @@ -3778,7 +3778,7 @@ __metadata: "@types/command-exists": ^1.2.0 "@types/fs-extra": ^9.0.1 "@types/inquirer": ^8.1.3 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/recursive-readdir": ^2.2.0 chalk: ^4.0.0 commander: ^9.1.0 @@ -3885,7 +3885,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -3990,7 +3990,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/git-url-parse": ^9.0.0 - "@types/node": "*" + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 git-url-parse: ^13.0.0 msw: ^0.47.0 @@ -4043,7 +4043,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/object-hash": ^2.2.1 cross-fetch: ^3.1.5 msw: ^0.47.0 @@ -4074,7 +4074,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -4102,7 +4102,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 react-ga: ^3.3.0 @@ -4128,7 +4128,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 qs: ^6.10.1 @@ -4172,7 +4172,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/swagger-ui-react": ^4.1.1 cross-fetch: ^3.1.5 graphiql: ^1.8.8 @@ -4208,7 +4208,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": "*" + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -4385,7 +4385,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 humanize-duration: ^3.27.0 luxon: ^3.0.0 @@ -4447,7 +4447,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -4499,7 +4499,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -4589,7 +4589,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/recharts": ^1.8.15 cross-fetch: ^3.1.5 lodash: ^4.17.21 @@ -5246,7 +5246,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/humanize-duration": ^3.25.1 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 circleci-api: ^4.0.0 cross-fetch: ^3.1.5 humanize-duration: ^3.27.0 @@ -5280,7 +5280,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -5313,7 +5313,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/humanize-duration": ^3.27.1 "@types/luxon": ^3.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 humanize-duration: ^3.27.1 luxon: ^3.0.0 @@ -5375,7 +5375,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/highlightjs": ^10.1.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/recharts": ^1.8.15 cross-fetch: ^3.1.5 highlight.js: ^10.6.0 @@ -5409,7 +5409,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": "*" + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 rc-progress: 3.4.0 @@ -5440,7 +5440,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 jsonschema: ^1.2.6 msw: ^0.47.0 @@ -5480,7 +5480,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/pluralize": ^0.0.29 "@types/recharts": ^1.8.14 "@types/regression": ^2.0.0 @@ -5522,7 +5522,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": "*" + "@types/node": ^16.0.0 express: ^4.18.1 msw: ^0.47.0 react-use: ^17.2.4 @@ -5543,7 +5543,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 languageName: unknown @@ -5570,7 +5570,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 classnames: ^2.2.6 cross-fetch: ^3.1.5 msw: ^0.47.0 @@ -5601,7 +5601,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -5631,7 +5631,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -5663,7 +5663,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/dompurify": ^2.3.3 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/sanitize-html": ^2.6.2 classnames: ^2.3.1 cross-fetch: ^3.1.5 @@ -5696,7 +5696,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 peerDependencies: @@ -5725,7 +5725,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/recharts": ^1.8.15 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -5761,7 +5761,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -5796,7 +5796,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -5828,7 +5828,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": "*" + "@types/node": ^16.0.0 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -5860,7 +5860,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -5890,7 +5890,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -5922,7 +5922,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/lodash": ^4.14.173 "@types/luxon": ^3.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 lodash: ^4.17.21 luxon: ^3.0.0 @@ -5952,7 +5952,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/codemirror": ^5.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 graphiql: ^1.5.12 graphql: ^16.0.0 @@ -6036,7 +6036,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 lodash: ^4.17.21 msw: ^0.47.0 @@ -6070,7 +6070,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 humanize-duration: ^3.26.0 luxon: ^3.0.0 @@ -6139,7 +6139,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/testing-library__jest-dom": ^5.9.1 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -6195,7 +6195,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 jest-when: ^3.1.0 msw: ^0.47.0 @@ -6276,7 +6276,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/react": ^16.13.1 || ^17.0.0 cronstrue: ^2.2.0 cross-fetch: ^3.1.5 @@ -6312,7 +6312,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 @@ -6363,7 +6363,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -6392,7 +6392,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 p-limit: ^3.1.0 @@ -6426,7 +6426,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 classnames: ^2.2.6 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -6479,7 +6479,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/luxon": ^3.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -6672,7 +6672,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": "*" + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 lodash: ^4.17.21 msw: ^0.47.0 @@ -6759,7 +6759,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 lodash: ^4.17.21 @@ -6810,7 +6810,7 @@ __metadata: "@types/command-exists": ^1.2.0 "@types/fs-extra": ^9.0.1 "@types/mock-fs": ^4.13.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 command-exists: ^1.2.9 fs-extra: ^10.0.1 jest-when: ^3.1.0 @@ -6950,7 +6950,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/humanize-duration": ^3.18.1 "@types/json-schema": ^7.0.9 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@uiw/react-codemirror": ^4.9.3 classnames: ^2.2.6 cross-fetch: ^3.1.5 @@ -7140,7 +7140,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 qs: ^6.9.4 @@ -7174,7 +7174,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/luxon": ^3.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -7205,7 +7205,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/zen-observable": ^0.8.2 cross-fetch: ^3.1.5 msw: ^0.47.0 @@ -7260,7 +7260,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 rc-progress: 3.4.0 @@ -7290,7 +7290,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/luxon": ^3.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 classnames: ^2.2.6 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -7358,7 +7358,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 lodash: ^4.17.21 msw: ^0.47.0 @@ -7470,7 +7470,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 qs: ^6.9.4 @@ -7501,7 +7501,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/color": ^3.0.1 "@types/d3-force": ^3.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/react": ^16.13.1 || ^17.0.0 color: ^4.0.1 cross-fetch: ^3.1.5 @@ -7536,7 +7536,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -7604,7 +7604,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 git-url-parse: ^13.0.0 @@ -7711,7 +7711,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/dompurify": ^2.2.2 "@types/event-source-polyfill": ^1.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 canvas: ^2.6.1 cross-fetch: ^3.1.5 dompurify: ^2.2.9 @@ -7774,7 +7774,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -7825,7 +7825,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 @@ -7884,7 +7884,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": "*" + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -7912,7 +7912,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/luxon": ^3.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 lodash: ^4.17.21 luxon: ^3.0.0 @@ -7953,7 +7953,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 zen-observable: ^0.8.15 @@ -9697,7 +9697,7 @@ __metadata: "@backstage/dev-utils": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/test-utils": "workspace:^" - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 languageName: unknown @@ -9720,7 +9720,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 msw: ^0.47.0 react-use: ^17.2.4 peerDependencies: @@ -13059,7 +13059,7 @@ __metadata: "@types/dockerode": ^3.3.0 "@types/fs-extra": ^9.0.6 "@types/http-proxy": ^1.17.4 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/serve-handler": ^6.1.0 "@types/webpack-env": ^1.15.3 commander: ^9.1.0 @@ -14380,7 +14380,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^16.0.0, @types/node@npm:^16.11.26, @types/node@npm:^16.9.2": +"@types/node@npm:^16.0.0, @types/node@npm:^16.9.2": version: 16.11.56 resolution: "@types/node@npm:16.11.56" checksum: b4efade16eb08a39810921c54a1637e69c8f3184a20d87e8fe74d557d9bda73f0829ac318e2a30a32b1903e4b099812defd1dfe438be70b98dbfbea5b0d99a53 @@ -20789,7 +20789,7 @@ __metadata: "@backstage/cli-common": "workspace:^" "@backstage/errors": "workspace:^" "@types/fs-extra": ^9.0.1 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/puppeteer": ^5.4.4 chalk: ^4.0.0 commander: ^9.1.0 @@ -22323,7 +22323,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/jquery": ^3.3.34 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/react": "*" "@types/react-dom": "*" "@types/zen-observable": ^0.8.0 @@ -35357,7 +35357,7 @@ __metadata: "@octokit/rest": ^19.0.3 "@spotify/prettier-config": ^14.0.0 "@techdocs/cli": "workspace:*" - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/webpack": ^5.28.0 command-exists: ^1.2.9 concurrently: ^7.0.0 @@ -37513,7 +37513,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.11.26 + "@types/node": ^16.0.0 "@types/react-dom": "*" cross-env: ^7.0.0 cypress: ^10.0.0 From 66f82000be9c37b65ec4546285124d5d55037edf Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 3 Nov 2022 12:38:00 +0100 Subject: [PATCH 120/434] yarn.lock: fix Signed-off-by: Patrik Oldsberg --- yarn.lock | 193 ++++++++++++++++++++++++++---------------------------- 1 file changed, 93 insertions(+), 100 deletions(-) diff --git a/yarn.lock b/yarn.lock index b6816e6c16..0e86d9ed64 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3108,7 +3108,7 @@ __metadata: "@material-ui/icons": ^4.9.1 "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -3400,7 +3400,7 @@ __metadata: "@types/jest": ^29.0.0 "@types/minimatch": ^5.0.0 "@types/mock-fs": ^4.13.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/npm-packlist": ^3.0.0 "@types/recursive-readdir": ^2.2.0 "@types/rollup-plugin-peer-deps-external": ^2.2.0 @@ -3503,7 +3503,7 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/cli-common": "workspace:^" "@types/jscodeshift": ^0.11.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 chalk: ^4.0.0 commander: ^9.1.0 jscodeshift: ^0.13.0 @@ -3526,7 +3526,7 @@ __metadata: "@types/json-schema": ^7.0.6 "@types/json-schema-merge-allof": ^0.6.0 "@types/mock-fs": ^4.10.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/yup": ^0.29.13 ajv: ^8.10.0 chokidar: ^3.5.2 @@ -3579,7 +3579,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/prop-types": ^15.7.3 "@types/zen-observable": ^0.8.0 cross-fetch: ^3.1.5 @@ -3678,7 +3678,7 @@ __metadata: "@types/d3-zoom": ^3.0.1 "@types/dagre": ^0.7.44 "@types/google-protobuf": ^3.7.2 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/react-helmet": ^6.1.0 "@types/react-sparklines": ^1.7.0 "@types/react-syntax-highlighter": ^15.0.0 @@ -3754,7 +3754,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/prop-types": ^15.7.3 "@types/zen-observable": ^0.8.0 cross-fetch: ^3.1.5 @@ -3778,7 +3778,7 @@ __metadata: "@types/command-exists": ^1.2.0 "@types/fs-extra": ^9.0.1 "@types/inquirer": ^8.1.3 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/recursive-readdir": ^2.2.0 chalk: ^4.0.0 commander: ^9.1.0 @@ -3885,7 +3885,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -3990,7 +3990,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/git-url-parse": ^9.0.0 - "@types/node": ^16.0.0 + "@types/node": "*" cross-fetch: ^3.1.5 git-url-parse: ^13.0.0 msw: ^0.47.0 @@ -4043,7 +4043,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/object-hash": ^2.2.1 cross-fetch: ^3.1.5 msw: ^0.47.0 @@ -4074,7 +4074,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -4102,7 +4102,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 react-ga: ^3.3.0 @@ -4128,7 +4128,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 qs: ^6.10.1 @@ -4172,7 +4172,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/swagger-ui-react": ^4.1.1 cross-fetch: ^3.1.5 graphiql: ^1.8.8 @@ -4208,7 +4208,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": "*" cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -4385,7 +4385,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 humanize-duration: ^3.27.0 luxon: ^3.0.0 @@ -4447,7 +4447,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -4499,7 +4499,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -4589,7 +4589,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/recharts": ^1.8.15 cross-fetch: ^3.1.5 lodash: ^4.17.21 @@ -5246,7 +5246,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/humanize-duration": ^3.25.1 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 circleci-api: ^4.0.0 cross-fetch: ^3.1.5 humanize-duration: ^3.27.0 @@ -5280,7 +5280,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -5313,7 +5313,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/humanize-duration": ^3.27.1 "@types/luxon": ^3.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 humanize-duration: ^3.27.1 luxon: ^3.0.0 @@ -5375,7 +5375,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/highlightjs": ^10.1.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/recharts": ^1.8.15 cross-fetch: ^3.1.5 highlight.js: ^10.6.0 @@ -5409,7 +5409,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": "*" cross-fetch: ^3.1.5 msw: ^0.47.0 rc-progress: 3.4.0 @@ -5440,7 +5440,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 jsonschema: ^1.2.6 msw: ^0.47.0 @@ -5480,7 +5480,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/pluralize": ^0.0.29 "@types/recharts": ^1.8.14 "@types/regression": ^2.0.0 @@ -5522,7 +5522,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": "*" express: ^4.18.1 msw: ^0.47.0 react-use: ^17.2.4 @@ -5543,7 +5543,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 languageName: unknown @@ -5570,7 +5570,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 classnames: ^2.2.6 cross-fetch: ^3.1.5 msw: ^0.47.0 @@ -5601,7 +5601,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -5631,7 +5631,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -5663,7 +5663,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/dompurify": ^2.3.3 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/sanitize-html": ^2.6.2 classnames: ^2.3.1 cross-fetch: ^3.1.5 @@ -5696,7 +5696,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 peerDependencies: @@ -5725,7 +5725,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/recharts": ^1.8.15 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -5761,7 +5761,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -5796,7 +5796,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -5828,7 +5828,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": "*" "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -5860,7 +5860,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -5890,7 +5890,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -5922,7 +5922,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/lodash": ^4.14.173 "@types/luxon": ^3.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 lodash: ^4.17.21 luxon: ^3.0.0 @@ -5952,7 +5952,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/codemirror": ^5.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 graphiql: ^1.5.12 graphql: ^16.0.0 @@ -6036,7 +6036,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 lodash: ^4.17.21 msw: ^0.47.0 @@ -6070,7 +6070,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 humanize-duration: ^3.26.0 luxon: ^3.0.0 @@ -6139,7 +6139,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/testing-library__jest-dom": ^5.9.1 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -6195,7 +6195,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 jest-when: ^3.1.0 msw: ^0.47.0 @@ -6276,7 +6276,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 cronstrue: ^2.2.0 cross-fetch: ^3.1.5 @@ -6312,7 +6312,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 @@ -6363,7 +6363,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -6392,7 +6392,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 p-limit: ^3.1.0 @@ -6426,7 +6426,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 classnames: ^2.2.6 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -6479,7 +6479,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/luxon": ^3.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -6672,7 +6672,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": "*" cross-fetch: ^3.1.5 lodash: ^4.17.21 msw: ^0.47.0 @@ -6759,7 +6759,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 lodash: ^4.17.21 @@ -6810,7 +6810,7 @@ __metadata: "@types/command-exists": ^1.2.0 "@types/fs-extra": ^9.0.1 "@types/mock-fs": ^4.13.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 command-exists: ^1.2.9 fs-extra: ^10.0.1 jest-when: ^3.1.0 @@ -6950,7 +6950,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/humanize-duration": ^3.18.1 "@types/json-schema": ^7.0.9 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@uiw/react-codemirror": ^4.9.3 classnames: ^2.2.6 cross-fetch: ^3.1.5 @@ -7140,7 +7140,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 qs: ^6.9.4 @@ -7174,7 +7174,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/luxon": ^3.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -7205,7 +7205,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/zen-observable": ^0.8.2 cross-fetch: ^3.1.5 msw: ^0.47.0 @@ -7260,7 +7260,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 rc-progress: 3.4.0 @@ -7290,7 +7290,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/luxon": ^3.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 classnames: ^2.2.6 cross-fetch: ^3.1.5 luxon: ^3.0.0 @@ -7358,7 +7358,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 lodash: ^4.17.21 msw: ^0.47.0 @@ -7470,7 +7470,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 qs: ^6.9.4 @@ -7501,7 +7501,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/color": ^3.0.1 "@types/d3-force": ^3.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 color: ^4.0.1 cross-fetch: ^3.1.5 @@ -7536,7 +7536,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -7604,7 +7604,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 git-url-parse: ^13.0.0 @@ -7711,7 +7711,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/dompurify": ^2.2.2 "@types/event-source-polyfill": ^1.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 canvas: ^2.6.1 cross-fetch: ^3.1.5 dompurify: ^2.2.9 @@ -7774,7 +7774,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -7825,7 +7825,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 @@ -7884,7 +7884,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": "*" cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -7912,7 +7912,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/luxon": ^3.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 lodash: ^4.17.21 luxon: ^3.0.0 @@ -7953,7 +7953,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 zen-observable: ^0.8.15 @@ -9697,7 +9697,7 @@ __metadata: "@backstage/dev-utils": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/test-utils": "workspace:^" - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 languageName: unknown @@ -9720,7 +9720,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 msw: ^0.47.0 react-use: ^17.2.4 peerDependencies: @@ -13059,7 +13059,7 @@ __metadata: "@types/dockerode": ^3.3.0 "@types/fs-extra": ^9.0.6 "@types/http-proxy": ^1.17.4 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/serve-handler": ^6.1.0 "@types/webpack-env": ^1.15.3 commander: ^9.1.0 @@ -14331,10 +14331,10 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0": - version: 17.0.25 - resolution: "@types/node@npm:17.0.25" - checksum: 6a820bd624e69ea772f52a6cdb326484eff5829443dc981939373929ade109f58c21698b9f0a831bd6ceea799e722a75dc49c5fa7a6bc32a81e1cbdfc6507b64 +"@types/node@npm:*, @types/node@npm:>= 8, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0": + version: 18.11.9 + resolution: "@types/node@npm:18.11.9" + checksum: cc0aae109e9b7adefc32eecb838d6fad931663bb06484b5e9cbbbf74865c721b03d16fd8d74ad90e31dbe093d956a7c2c306ba5429ba0c00f3f7505103d7a496 languageName: node linkType: hard @@ -14345,13 +14345,6 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:>= 8": - version: 18.7.4 - resolution: "@types/node@npm:18.7.4" - checksum: 051d2147e4d8129fceb63ee9384259b2f224dbc4e4b0c46d96a6b61cbaad4e3fe4060950e7f4fc3d5692b1e6ea47e68ad03b61155754bfa169593747cfe3f8f4 - languageName: node - linkType: hard - "@types/node@npm:^10.1.0, @types/node@npm:^10.12.0": version: 10.17.60 resolution: "@types/node@npm:10.17.60" @@ -14360,16 +14353,16 @@ __metadata: linkType: hard "@types/node@npm:^12.7.1": - version: 12.20.48 - resolution: "@types/node@npm:12.20.48" - checksum: 48bd705bda1af2332c50fb24819bba7b0eac791b07c24c098c39b10940170a53bd3c4755aedc3409c7114c539f1f86ea657aa6838d164fd135e3b89b9f9aa772 + version: 12.20.55 + resolution: "@types/node@npm:12.20.55" + checksum: e4f86785f4092706e0d3b0edff8dca5a13b45627e4b36700acd8dfe6ad53db71928c8dee914d4276c7fd3b6ccd829aa919811c9eb708a2c8e4c6eb3701178c37 languageName: node linkType: hard "@types/node@npm:^14.14.31": - version: 14.18.16 - resolution: "@types/node@npm:14.18.16" - checksum: 1999799309dc8620a2adf9a5d5e48416af87321bae4c950b4aa8018fcef2c3b6c1fcf98c39eae06f6492c03a643a5a44e2bb3750cd2574d9cf7eac33bac50e24 + version: 14.18.33 + resolution: "@types/node@npm:14.18.33" + checksum: 4e23f95186d8ae1d38c999bc6b46fe94e790da88744b0a3bfeedcbd0d9ffe2cb0ff39e85f43014f6739e5270292c1a1f6f97a1fc606fd573a0c17fda9a1d42de languageName: node linkType: hard @@ -14380,10 +14373,10 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^16.0.0, @types/node@npm:^16.9.2": - version: 16.11.56 - resolution: "@types/node@npm:16.11.56" - checksum: b4efade16eb08a39810921c54a1637e69c8f3184a20d87e8fe74d557d9bda73f0829ac318e2a30a32b1903e4b099812defd1dfe438be70b98dbfbea5b0d99a53 +"@types/node@npm:^16.0.0, @types/node@npm:^16.11.26, @types/node@npm:^16.9.2": + version: 16.18.3 + resolution: "@types/node@npm:16.18.3" + checksum: 6b8ba2ea5d842f7986e366cb9184c54d273d492784dc62e08fd5afeae938d9b61aec6e4222d2541cd18f9b1412ba361bbcb3f4204fb003608af80a2a6af959f9 languageName: node linkType: hard @@ -20789,7 +20782,7 @@ __metadata: "@backstage/cli-common": "workspace:^" "@backstage/errors": "workspace:^" "@types/fs-extra": ^9.0.1 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/puppeteer": ^5.4.4 chalk: ^4.0.0 commander: ^9.1.0 @@ -22323,7 +22316,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/jquery": ^3.3.34 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/react": "*" "@types/react-dom": "*" "@types/zen-observable": ^0.8.0 @@ -35357,7 +35350,7 @@ __metadata: "@octokit/rest": ^19.0.3 "@spotify/prettier-config": ^14.0.0 "@techdocs/cli": "workspace:*" - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/webpack": ^5.28.0 command-exists: ^1.2.9 concurrently: ^7.0.0 @@ -37513,7 +37506,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 - "@types/node": ^16.0.0 + "@types/node": ^16.11.26 "@types/react-dom": "*" cross-env: ^7.0.0 cypress: ^10.0.0 From 39ef7c5ae494c40e94ed17e2edfccb768f989713 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 11:44:32 +0000 Subject: [PATCH 121/434] Update dependency @octokit/graphql to v5.0.4 Signed-off-by: Renovate Bot --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index c42aac2eec..84bd3270b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11570,13 +11570,13 @@ __metadata: linkType: hard "@octokit/graphql@npm:^5.0.0": - version: 5.0.1 - resolution: "@octokit/graphql@npm:5.0.1" + version: 5.0.4 + resolution: "@octokit/graphql@npm:5.0.4" dependencies: "@octokit/request": ^6.0.0 - "@octokit/types": ^7.0.0 + "@octokit/types": ^8.0.0 universal-user-agent: ^6.0.0 - checksum: 310549c2d7966adb46428e943cd99cb766519819bd4945d8349d3ec0642e4ee39d9194e1b0a87a5404951c04c247fafb4a8456ed4c839c64bfb4042aa4a6812c + checksum: 8cf65cf7e6608cf3cbc96a2fa902172b4d5dc30e88ee0bae3711bf467a25b828b10cce1aaabb7f82a7580bfbcf7028b91d1dd1a894940945e38ca2deb6509754 languageName: node linkType: hard From 13547e4df28440a98c5fe10decd99a9ab3c472d3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 11:46:46 +0000 Subject: [PATCH 122/434] Update dependency @swc/core to v1.3.14 Signed-off-by: Renovate Bot --- storybook/yarn.lock | 142 ++++++++++++++------------------------------ yarn.lock | 142 ++++++++++++++------------------------------ 2 files changed, 86 insertions(+), 198 deletions(-) diff --git a/storybook/yarn.lock b/storybook/yarn.lock index be9a98e42a..c864d817ab 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -3107,137 +3107,95 @@ __metadata: languageName: node linkType: hard -"@swc/core-android-arm-eabi@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-android-arm-eabi@npm:1.3.9" - dependencies: - "@swc/wasm": 1.2.122 - conditions: os=android & cpu=arm - languageName: node - linkType: hard - -"@swc/core-android-arm64@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-android-arm64@npm:1.3.9" - dependencies: - "@swc/wasm": 1.2.130 - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@swc/core-darwin-arm64@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-darwin-arm64@npm:1.3.9" +"@swc/core-darwin-arm64@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-darwin-arm64@npm:1.3.14" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-darwin-x64@npm:1.3.9" +"@swc/core-darwin-x64@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-darwin-x64@npm:1.3.14" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-freebsd-x64@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-freebsd-x64@npm:1.3.9" - dependencies: - "@swc/wasm": 1.2.130 - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@swc/core-linux-arm-gnueabihf@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.9" - dependencies: - "@swc/wasm": 1.2.130 +"@swc/core-linux-arm-gnueabihf@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.14" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.9" +"@swc/core-linux-arm64-gnu@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.14" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.9" +"@swc/core-linux-arm64-musl@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.14" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.9" +"@swc/core-linux-x64-gnu@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.14" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-linux-x64-musl@npm:1.3.9" +"@swc/core-linux-x64-musl@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-linux-x64-musl@npm:1.3.14" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.9" - dependencies: - "@swc/wasm": 1.2.130 +"@swc/core-win32-arm64-msvc@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.14" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.9" - dependencies: - "@swc/wasm": 1.2.130 +"@swc/core-win32-ia32-msvc@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.14" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.9" +"@swc/core-win32-x64-msvc@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.14" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.9": - version: 1.3.9 - resolution: "@swc/core@npm:1.3.9" + version: 1.3.14 + resolution: "@swc/core@npm:1.3.14" dependencies: - "@swc/core-android-arm-eabi": 1.3.9 - "@swc/core-android-arm64": 1.3.9 - "@swc/core-darwin-arm64": 1.3.9 - "@swc/core-darwin-x64": 1.3.9 - "@swc/core-freebsd-x64": 1.3.9 - "@swc/core-linux-arm-gnueabihf": 1.3.9 - "@swc/core-linux-arm64-gnu": 1.3.9 - "@swc/core-linux-arm64-musl": 1.3.9 - "@swc/core-linux-x64-gnu": 1.3.9 - "@swc/core-linux-x64-musl": 1.3.9 - "@swc/core-win32-arm64-msvc": 1.3.9 - "@swc/core-win32-ia32-msvc": 1.3.9 - "@swc/core-win32-x64-msvc": 1.3.9 + "@swc/core-darwin-arm64": 1.3.14 + "@swc/core-darwin-x64": 1.3.14 + "@swc/core-linux-arm-gnueabihf": 1.3.14 + "@swc/core-linux-arm64-gnu": 1.3.14 + "@swc/core-linux-arm64-musl": 1.3.14 + "@swc/core-linux-x64-gnu": 1.3.14 + "@swc/core-linux-x64-musl": 1.3.14 + "@swc/core-win32-arm64-msvc": 1.3.14 + "@swc/core-win32-ia32-msvc": 1.3.14 + "@swc/core-win32-x64-msvc": 1.3.14 dependenciesMeta: - "@swc/core-android-arm-eabi": - optional: true - "@swc/core-android-arm64": - optional: true "@swc/core-darwin-arm64": optional: true "@swc/core-darwin-x64": optional: true - "@swc/core-freebsd-x64": - optional: true "@swc/core-linux-arm-gnueabihf": optional: true "@swc/core-linux-arm64-gnu": @@ -3256,21 +3214,7 @@ __metadata: optional: true bin: swcx: run_swcx.js - checksum: 761918f1bca5d494eaaafd49720717e3b3071df5bc6ef8b298a778ba4e4d20bc5a78c939a0b1c98623f9fe23e535a16a359179b72390cd1f5cbc891ea53c22fa - languageName: node - linkType: hard - -"@swc/wasm@npm:1.2.122": - version: 1.2.122 - resolution: "@swc/wasm@npm:1.2.122" - checksum: 563345370c5ad18373d3b403590ab880fe52dcd8fc8c8601be263fcd9886520b28a7f4e46236cf49ca2b136c79d4ef50c960bc34b7cdc2068118b0d84dfca1f4 - languageName: node - linkType: hard - -"@swc/wasm@npm:1.2.130": - version: 1.2.130 - resolution: "@swc/wasm@npm:1.2.130" - checksum: 02203bfef3e382c64cbbd63c138c8fdf61865e74d923b317e9d9e9f33f5a3f0a9533b5fdbc9505e76d78e864be04a82fc847eb987a1e47ccac5850146c858292 + checksum: 79e9857ee3d5af22d9a6e644d7608594fa8ccd9102dbc088addc0f6ee9e1e8e3fc8835545730707395aa47197ab119fa323aedf4184cf51892379b307aedddc0 languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index c42aac2eec..37aa84c7ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12822,137 +12822,95 @@ __metadata: languageName: node linkType: hard -"@swc/core-android-arm-eabi@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-android-arm-eabi@npm:1.3.9" - dependencies: - "@swc/wasm": 1.2.122 - conditions: os=android & cpu=arm - languageName: node - linkType: hard - -"@swc/core-android-arm64@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-android-arm64@npm:1.3.9" - dependencies: - "@swc/wasm": 1.2.130 - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@swc/core-darwin-arm64@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-darwin-arm64@npm:1.3.9" +"@swc/core-darwin-arm64@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-darwin-arm64@npm:1.3.14" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-darwin-x64@npm:1.3.9" +"@swc/core-darwin-x64@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-darwin-x64@npm:1.3.14" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-freebsd-x64@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-freebsd-x64@npm:1.3.9" - dependencies: - "@swc/wasm": 1.2.130 - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@swc/core-linux-arm-gnueabihf@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.9" - dependencies: - "@swc/wasm": 1.2.130 +"@swc/core-linux-arm-gnueabihf@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.14" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.9" +"@swc/core-linux-arm64-gnu@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.14" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.9" +"@swc/core-linux-arm64-musl@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.14" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.9" +"@swc/core-linux-x64-gnu@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.14" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-linux-x64-musl@npm:1.3.9" +"@swc/core-linux-x64-musl@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-linux-x64-musl@npm:1.3.14" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.9" - dependencies: - "@swc/wasm": 1.2.130 +"@swc/core-win32-arm64-msvc@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.14" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.9" - dependencies: - "@swc/wasm": 1.2.130 +"@swc/core-win32-ia32-msvc@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.14" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.9": - version: 1.3.9 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.9" +"@swc/core-win32-x64-msvc@npm:1.3.14": + version: 1.3.14 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.14" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.9": - version: 1.3.9 - resolution: "@swc/core@npm:1.3.9" + version: 1.3.14 + resolution: "@swc/core@npm:1.3.14" dependencies: - "@swc/core-android-arm-eabi": 1.3.9 - "@swc/core-android-arm64": 1.3.9 - "@swc/core-darwin-arm64": 1.3.9 - "@swc/core-darwin-x64": 1.3.9 - "@swc/core-freebsd-x64": 1.3.9 - "@swc/core-linux-arm-gnueabihf": 1.3.9 - "@swc/core-linux-arm64-gnu": 1.3.9 - "@swc/core-linux-arm64-musl": 1.3.9 - "@swc/core-linux-x64-gnu": 1.3.9 - "@swc/core-linux-x64-musl": 1.3.9 - "@swc/core-win32-arm64-msvc": 1.3.9 - "@swc/core-win32-ia32-msvc": 1.3.9 - "@swc/core-win32-x64-msvc": 1.3.9 + "@swc/core-darwin-arm64": 1.3.14 + "@swc/core-darwin-x64": 1.3.14 + "@swc/core-linux-arm-gnueabihf": 1.3.14 + "@swc/core-linux-arm64-gnu": 1.3.14 + "@swc/core-linux-arm64-musl": 1.3.14 + "@swc/core-linux-x64-gnu": 1.3.14 + "@swc/core-linux-x64-musl": 1.3.14 + "@swc/core-win32-arm64-msvc": 1.3.14 + "@swc/core-win32-ia32-msvc": 1.3.14 + "@swc/core-win32-x64-msvc": 1.3.14 dependenciesMeta: - "@swc/core-android-arm-eabi": - optional: true - "@swc/core-android-arm64": - optional: true "@swc/core-darwin-arm64": optional: true "@swc/core-darwin-x64": optional: true - "@swc/core-freebsd-x64": - optional: true "@swc/core-linux-arm-gnueabihf": optional: true "@swc/core-linux-arm64-gnu": @@ -12971,7 +12929,7 @@ __metadata: optional: true bin: swcx: run_swcx.js - checksum: 761918f1bca5d494eaaafd49720717e3b3071df5bc6ef8b298a778ba4e4d20bc5a78c939a0b1c98623f9fe23e535a16a359179b72390cd1f5cbc891ea53c22fa + checksum: 79e9857ee3d5af22d9a6e644d7608594fa8ccd9102dbc088addc0f6ee9e1e8e3fc8835545730707395aa47197ab119fa323aedf4184cf51892379b307aedddc0 languageName: node linkType: hard @@ -12996,20 +12954,6 @@ __metadata: languageName: node linkType: hard -"@swc/wasm@npm:1.2.122": - version: 1.2.122 - resolution: "@swc/wasm@npm:1.2.122" - checksum: 563345370c5ad18373d3b403590ab880fe52dcd8fc8c8601be263fcd9886520b28a7f4e46236cf49ca2b136c79d4ef50c960bc34b7cdc2068118b0d84dfca1f4 - languageName: node - linkType: hard - -"@swc/wasm@npm:1.2.130": - version: 1.2.130 - resolution: "@swc/wasm@npm:1.2.130" - checksum: 02203bfef3e382c64cbbd63c138c8fdf61865e74d923b317e9d9e9f33f5a3f0a9533b5fdbc9505e76d78e864be04a82fc847eb987a1e47ccac5850146c858292 - languageName: node - linkType: hard - "@szmarczak/http-timer@npm:^4.0.5": version: 4.0.5 resolution: "@szmarczak/http-timer@npm:4.0.5" From d617c6d372ce2347d316e0d81f3ebbe7ea9782ff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 11:48:36 +0000 Subject: [PATCH 123/434] Update dependency @google-cloud/storage to v6.6.0 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c42aac2eec..b09a691fbc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8697,8 +8697,8 @@ __metadata: linkType: hard "@google-cloud/storage@npm:^6.0.0": - version: 6.5.3 - resolution: "@google-cloud/storage@npm:6.5.3" + version: 6.6.0 + resolution: "@google-cloud/storage@npm:6.6.0" dependencies: "@google-cloud/paginator": ^3.0.7 "@google-cloud/projectify": ^3.0.0 @@ -8717,7 +8717,7 @@ __metadata: retry-request: ^5.0.0 teeny-request: ^8.0.0 uuid: ^8.0.0 - checksum: 9b88a5bff4e8401dbd18223fe570882df632cbb0e515e7f3eca33dbea16568168b2c0397b02ad8030e6d114b6d73109283d17a49762f1833f077424bf90a676d + checksum: fef529fc83be01fc421e2ee8c8cd6a78dc5b0d50b1f0912e358285b2e4650a3111229feaef5b517fc90b718e7424251dadc59e12ab782303d57aa3e59dc019ab languageName: node linkType: hard From b3b5f682645b52c93b1409fffd0a240e4fe61a96 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 11:58:36 +0000 Subject: [PATCH 124/434] Update dependency @changesets/cli to v2.25.2 Signed-off-by: Renovate Bot --- yarn.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/yarn.lock b/yarn.lock index c42aac2eec..fe63063d7b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8028,9 +8028,9 @@ __metadata: languageName: node linkType: hard -"@changesets/apply-release-plan@npm:^6.1.1": - version: 6.1.1 - resolution: "@changesets/apply-release-plan@npm:6.1.1" +"@changesets/apply-release-plan@npm:^6.1.2": + version: 6.1.2 + resolution: "@changesets/apply-release-plan@npm:6.1.2" dependencies: "@babel/runtime": ^7.10.4 "@changesets/config": ^2.2.0 @@ -8045,7 +8045,7 @@ __metadata: prettier: ^2.7.1 resolve-from: ^5.0.0 semver: ^5.4.1 - checksum: 34da2d52eced00bc5f51c8e8ce16c0e487743219f057da2b3e6c6597bb2d50498f3996c779e4fc29b19d357c9b700d82310d723395ba09350b9a139c9e0e0d23 + checksum: efe2cdc493cb2182140b73ff76e34ee7c90887bfa2f42b4ec07db0107ec94b9c0e95519912dafcf9eb530ad2414487fbd61ca6e6d5f853fe383db93856d0d362 languageName: node linkType: hard @@ -8073,11 +8073,11 @@ __metadata: linkType: hard "@changesets/cli@npm:^2.14.0": - version: 2.25.0 - resolution: "@changesets/cli@npm:2.25.0" + version: 2.25.2 + resolution: "@changesets/cli@npm:2.25.2" dependencies: "@babel/runtime": ^7.10.4 - "@changesets/apply-release-plan": ^6.1.1 + "@changesets/apply-release-plan": ^6.1.2 "@changesets/assemble-release-plan": ^5.2.2 "@changesets/changelog-git": ^0.1.13 "@changesets/config": ^2.2.0 @@ -8089,7 +8089,7 @@ __metadata: "@changesets/pre": ^1.0.13 "@changesets/read": ^0.5.8 "@changesets/types": ^5.2.0 - "@changesets/write": ^0.2.1 + "@changesets/write": ^0.2.2 "@manypkg/get-packages": ^1.1.3 "@types/is-ci": ^3.0.0 "@types/semver": ^6.0.0 @@ -8111,7 +8111,7 @@ __metadata: tty-table: ^4.1.5 bin: changeset: bin.js - checksum: 54439bdfa7ca115964482f6323e9475b5917d68c2e0752a272ed133b863fce51eeba86366d8740a275dc0b891af8e272602da69d04144f40e4bf3531f48fe8fb + checksum: 815c69cb6cee75ede88361582581d94a860d96335e7bab179481cd5e2bb1e60cc39662dccd2b2b87818e9c63a84ff9eb469ed27f13b6adf4401a699e49beb79c languageName: node linkType: hard @@ -8250,16 +8250,16 @@ __metadata: languageName: node linkType: hard -"@changesets/write@npm:^0.2.1": - version: 0.2.1 - resolution: "@changesets/write@npm:0.2.1" +"@changesets/write@npm:^0.2.2": + version: 0.2.2 + resolution: "@changesets/write@npm:0.2.2" dependencies: "@babel/runtime": ^7.10.4 "@changesets/types": ^5.2.0 fs-extra: ^7.0.1 human-id: ^1.0.2 prettier: ^2.7.1 - checksum: 98b4d9c12fe13177860407557979d475361076a596103895440f52b2724f7004d6c98af39105fda0eaa52ceca8c0dc0ec9c8ab10eec7a0cb9bf83301f2ca48b3 + checksum: e23fb4a88e12af32db59d2f1866380ec4a50e7fa55cb55d860619f0735c5078ed170f832125672bb007b7a0cced67d9304a1b81260a7224af6afe0e3957dc999 languageName: node linkType: hard From b1d28d05ecd183b5e22a06cf2c56073b95846915 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Oct 2022 00:16:59 +0000 Subject: [PATCH 125/434] Update dependency @types/react to v17.0.51 Signed-off-by: Renovate Bot --- yarn.lock | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/yarn.lock b/yarn.lock index 37aa84c7ab..4ce35bbf9d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3109,7 +3109,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@types/node": ^16.11.26 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 peerDependencies: react: ^16.13.1 || ^17.0.0 react-dom: ^16.13.1 || ^17.0.0 @@ -4144,7 +4144,7 @@ __metadata: dependencies: "@backstage/cli": "workspace:^" "@testing-library/jest-dom": ^5.16.4 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 grpc-docs: ^1.1.2 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -5214,7 +5214,7 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.57 "@material-ui/pickers": ^3.3.10 "@types/luxon": ^3.0.0 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 already: ^3.2.0 humanize-duration: ^3.27.0 lodash: ^4.17.21 @@ -5829,7 +5829,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/node": "*" - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -5861,7 +5861,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -6277,7 +6277,7 @@ __metadata: "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 cronstrue: ^2.2.0 cross-fetch: ^3.1.5 js-yaml: ^4.0.0 @@ -6313,7 +6313,7 @@ __metadata: "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -6338,7 +6338,7 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.57 "@testing-library/jest-dom": ^5.10.1 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 cross-fetch: ^3.1.5 react-use: ^17.2.4 peerDependencies: @@ -6760,7 +6760,7 @@ __metadata: "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 cross-fetch: ^3.1.5 lodash: ^4.17.21 msw: ^0.47.0 @@ -7175,7 +7175,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/luxon": ^3.0.0 "@types/node": ^16.11.26 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -7502,7 +7502,7 @@ __metadata: "@types/color": ^3.0.1 "@types/d3-force": ^3.0.0 "@types/node": ^16.11.26 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 color: ^4.0.1 cross-fetch: ^3.1.5 d3-force: ^3.0.0 @@ -7605,7 +7605,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 cross-fetch: ^3.1.5 git-url-parse: ^13.0.0 msw: ^0.47.0 @@ -7826,7 +7826,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -9660,7 +9660,7 @@ __metadata: dependencies: "@backstage/plugin-catalog": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^17 peerDependencies: react: ^16.13.1 || ^17.0.0 languageName: unknown @@ -22268,7 +22268,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/jquery": ^3.3.34 "@types/node": ^16.11.26 - "@types/react": "*" + "@types/react": ^17 "@types/react-dom": "*" "@types/zen-observable": ^0.8.0 cross-env: ^7.0.0 From e424f6e58a0356165dde91ff09cff11cd39be21d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 3 Nov 2022 12:39:14 +0100 Subject: [PATCH 126/434] yarn.lock: fix Signed-off-by: Patrik Oldsberg --- yarn.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4ce35bbf9d..2591cc8971 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3109,7 +3109,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@types/node": ^16.11.26 - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 react-dom: ^16.13.1 || ^17.0.0 @@ -4144,7 +4144,7 @@ __metadata: dependencies: "@backstage/cli": "workspace:^" "@testing-library/jest-dom": ^5.16.4 - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 grpc-docs: ^1.1.2 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -5214,7 +5214,7 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.57 "@material-ui/pickers": ^3.3.10 "@types/luxon": ^3.0.0 - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 already: ^3.2.0 humanize-duration: ^3.27.0 lodash: ^4.17.21 @@ -5829,7 +5829,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/node": "*" - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -5861,7 +5861,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -6277,7 +6277,7 @@ __metadata: "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 cronstrue: ^2.2.0 cross-fetch: ^3.1.5 js-yaml: ^4.0.0 @@ -6313,7 +6313,7 @@ __metadata: "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -6338,7 +6338,7 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.57 "@testing-library/jest-dom": ^5.10.1 - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 react-use: ^17.2.4 peerDependencies: @@ -6760,7 +6760,7 @@ __metadata: "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 lodash: ^4.17.21 msw: ^0.47.0 @@ -7175,7 +7175,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/luxon": ^3.0.0 "@types/node": ^16.11.26 - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 msw: ^0.47.0 @@ -7502,7 +7502,7 @@ __metadata: "@types/color": ^3.0.1 "@types/d3-force": ^3.0.0 "@types/node": ^16.11.26 - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 color: ^4.0.1 cross-fetch: ^3.1.5 d3-force: ^3.0.0 @@ -7605,7 +7605,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 git-url-parse: ^13.0.0 msw: ^0.47.0 @@ -7826,7 +7826,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 react-use: ^17.2.4 @@ -9660,7 +9660,7 @@ __metadata: dependencies: "@backstage/plugin-catalog": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" - "@types/react": ^17 + "@types/react": ^16.13.1 || ^17.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 languageName: unknown @@ -14605,13 +14605,13 @@ __metadata: linkType: hard "@types/react@npm:^17": - version: 17.0.45 - resolution: "@types/react@npm:17.0.45" + version: 17.0.52 + resolution: "@types/react@npm:17.0.52" dependencies: "@types/prop-types": "*" "@types/scheduler": "*" csstype: ^3.0.2 - checksum: 3cc13a02824c13f6fa4807a83abd065ac1d9943359e76bd995cc7cd2b4148c1176ebd54a30a9f4eb8a0f141ff359d712876f256c4fee707e4290607ef8410b3e + checksum: a51b98dd87838d161278fdf9dd78e6a4ff8c018f406d6647f77963e144fb52a8beee40c89fd0e7e840eaeaa8bd9fe2f34519410540b1a52d43a6f8b4d2fbce33 languageName: node linkType: hard @@ -22268,7 +22268,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/jquery": ^3.3.34 "@types/node": ^16.11.26 - "@types/react": ^17 + "@types/react": "*" "@types/react-dom": "*" "@types/zen-observable": ^0.8.0 cross-env: ^7.0.0 From bbebe92e9e454a20c05a3652971cf49fa32abb48 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 12:31:36 +0000 Subject: [PATCH 127/434] Update dependency @graphql-tools/schema to v9.0.8 Signed-off-by: Renovate Bot --- yarn.lock | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/yarn.lock b/yarn.lock index 37aa84c7ab..c4912669b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9244,15 +9244,15 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/merge@npm:8.3.6": - version: 8.3.6 - resolution: "@graphql-tools/merge@npm:8.3.6" +"@graphql-tools/merge@npm:8.3.10": + version: 8.3.10 + resolution: "@graphql-tools/merge@npm:8.3.10" dependencies: - "@graphql-tools/utils": 8.12.0 + "@graphql-tools/utils": 9.0.1 tslib: ^2.4.0 peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: 3e45ebff0dce9524e72c4af1d2b9799c16515c1236290e07cd68fb2226c4e54734e2444d89a64b387b7ba991d15c6f948fdfc20c77a74b1d24babddd865ff32a + checksum: dbe2c6faee8034339c5708a43157b185b8523c131dde1b37bb511d96ac527da51f5be9501d9ffe0a8c424e419d64bb8415ec96e8443d3d0a5a6582a37b0aafa2 languageName: node linkType: hard @@ -9366,16 +9366,16 @@ __metadata: linkType: hard "@graphql-tools/schema@npm:^9.0.0": - version: 9.0.4 - resolution: "@graphql-tools/schema@npm:9.0.4" + version: 9.0.8 + resolution: "@graphql-tools/schema@npm:9.0.8" dependencies: - "@graphql-tools/merge": 8.3.6 - "@graphql-tools/utils": 8.12.0 + "@graphql-tools/merge": 8.3.10 + "@graphql-tools/utils": 9.0.1 tslib: ^2.4.0 value-or-promise: 1.0.11 peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: 0644ba225ff7fb03c6fb7f026b6a77a4ac5dd14fd10bb562ea0072bfe0258620fd4789b851b0b97007db8754d0b7d88a1061bb98bacc679b22e2eb7706e79e0e + checksum: fb29c29269622f2636ecccac868fa44a585622e16be74286a4cd97b259ba2d2dad5ec67e77b00117f70e500a9262e0edc58a35a83cea0618618993e5e1d809fb languageName: node linkType: hard @@ -9429,17 +9429,6 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/utils@npm:8.12.0": - version: 8.12.0 - resolution: "@graphql-tools/utils@npm:8.12.0" - dependencies: - tslib: ^2.4.0 - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: 24edc6ba3bcfa9a4c1d1d37117c3f96d847beed9638325083c32c6ec9674729dc89fc8cc389d317ae5d9dba22e91443bd9788f1dc8de91a1b6f1e592112bd48f - languageName: node - linkType: hard - "@graphql-tools/utils@npm:8.6.9": version: 8.6.9 resolution: "@graphql-tools/utils@npm:8.6.9" @@ -9473,6 +9462,17 @@ __metadata: languageName: node linkType: hard +"@graphql-tools/utils@npm:9.0.1": + version: 9.0.1 + resolution: "@graphql-tools/utils@npm:9.0.1" + dependencies: + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: a41221d8568bfaafa76526eaa89550d67965c43e0cd1ff94979f61c117d0caf880938799b351c4b637ce26309ba5d2ef8c4a657298f5d46702f43759b89bfa05 + languageName: node + linkType: hard + "@graphql-tools/wrap@npm:8.5.0": version: 8.5.0 resolution: "@graphql-tools/wrap@npm:8.5.0" From 52057107b49b4411be972d541492df1624bb8b11 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 12:52:33 +0000 Subject: [PATCH 128/434] Update dependency @types/dockerode to v3.3.12 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9cf0c5fd2b..b93da55efc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13643,12 +13643,12 @@ __metadata: linkType: hard "@types/dockerode@npm:^3.3.0": - version: 3.3.10 - resolution: "@types/dockerode@npm:3.3.10" + version: 3.3.12 + resolution: "@types/dockerode@npm:3.3.12" dependencies: "@types/docker-modem": "*" "@types/node": "*" - checksum: ef2231adebbdc1876a00fd16a51963ed2ea05a2305031467420c753f77a27a6f2a47617e2f4a42702be84c88046a5a5f6dfd471e3579f11f21166f539a3d2373 + checksum: 65f16894dca4d359395ed9619ed10d5297917a63b9d86660578e38b97380f5f871188556ab1a5003852e9535a5001ecd7d6c03a1da4391e7c31b30762de55e69 languageName: node linkType: hard From 762d4559c492300b7cd2fdd493318649cf838643 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 13:03:00 +0000 Subject: [PATCH 129/434] Update dependency @types/ldapjs to v2.2.5 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9cf0c5fd2b..e41a3d94e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14087,11 +14087,11 @@ __metadata: linkType: hard "@types/ldapjs@npm:^2.2.0": - version: 2.2.4 - resolution: "@types/ldapjs@npm:2.2.4" + version: 2.2.5 + resolution: "@types/ldapjs@npm:2.2.5" dependencies: "@types/node": "*" - checksum: 3f240809927e1292380e5977579d7edffb6e5e41b35510c7091b51da19e7387d4ebff0f254c0b145f3cf5d5485b6bb39c77335d857d092e6f4e9ce5a6682a872 + checksum: 779e462f118f8a6643b7f49d35646e4dae339ff1c6290198950327a736a79bc03beca882e1356ede4c8d54f6dc19bf544f0d23b09279558d69222a93bacd459c languageName: node linkType: hard From d7ffce99843ad045a322122c55af9b8b120e163f Mon Sep 17 00:00:00 2001 From: hram_wh Date: Thu, 3 Nov 2022 19:39:11 +0530 Subject: [PATCH 130/434] changes Signed-off-by: hram_wh --- plugins/explore/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/explore/README.md b/plugins/explore/README.md index 5038f3e5f0..94ab0984a0 100644 --- a/plugins/explore/README.md +++ b/plugins/explore/README.md @@ -94,8 +94,10 @@ export const apis: AnyApiFactory[] = [ api: exploreToolsConfigRef, deps: {}, factory: () => ({ - /* pass the tools array - i.e. tools = [ + async getTools() { + return tools; + }, + /* e.g. tools = [ { title: 'New Relic', description:'new relic plugin, @@ -104,7 +106,7 @@ export const apis: AnyApiFactory[] = [ tags: ['newrelic', 'proxy', 'nerdGraph'], }, ] - */ + */ }), }), From fa5b7547c9d6ae4a5d99731832b79fba8c728aed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 14:21:24 +0000 Subject: [PATCH 131/434] Update dependency canvas to v2.10.2 Signed-off-by: Renovate Bot --- yarn.lock | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6657305c84..e2ed925e4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17865,14 +17865,14 @@ __metadata: linkType: hard "canvas@npm:^2.6.1": - version: 2.10.1 - resolution: "canvas@npm:2.10.1" + version: 2.10.2 + resolution: "canvas@npm:2.10.2" dependencies: "@mapbox/node-pre-gyp": ^1.0.0 - nan: ^2.15.0 + nan: ^2.17.0 node-gyp: latest simple-get: ^3.0.3 - checksum: 29b162a59df8c63e5591cae62711ab3cc3b0a078f260b39b4594b51c5bcb9baa597eff40b52f25bd788aceb81756a41097c2dd0c01cbc17ae4a15e873da44cdf + checksum: b2e3eb4c3635fa2f67857619621c3d314f935a9e51904536dadf4908ab580dff4f5bcbaafe6eb0255247fa027ca494d5cd97c33376a49a0f994997263fa9944b languageName: node linkType: hard @@ -30248,6 +30248,15 @@ __metadata: languageName: node linkType: hard +"nan@npm:^2.17.0": + version: 2.17.0 + resolution: "nan@npm:2.17.0" + dependencies: + node-gyp: latest + checksum: ec609aeaf7e68b76592a3ba96b372aa7f5df5b056c1e37410b0f1deefbab5a57a922061e2c5b369bae9c7c6b5e6eecf4ad2dac8833a1a7d3a751e0a7c7f849ed + languageName: node + linkType: hard + "nano-css@npm:^5.3.1": version: 5.3.1 resolution: "nano-css@npm:5.3.1" From af951b40aa731f4a39dd7692d72403e49676bfef Mon Sep 17 00:00:00 2001 From: manusant Date: Thu, 3 Nov 2022 14:39:17 +0000 Subject: [PATCH 132/434] move type dependency Signed-off-by: manusant --- plugins/sonarqube/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 99f059a016..89cbb0c049 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -45,7 +45,8 @@ "@material-ui/styles": "^4.10.0", "cross-fetch": "^3.1.5", "rc-progress": "3.4.0", - "react-use": "^17.2.4" + "react-use": "^17.2.4", + "@types/react": "^16.13.1 || ^17.0.0" }, "peerDependencies": { "react": "^16.13.1 || ^17.0.0" @@ -59,7 +60,6 @@ "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", - "@types/react": "^16.13.1 || ^17.0.0", "msw": "^0.47.0" }, "files": [ From 0a0acc71236160401b6d45f73bd20e6c09d856d3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 14:54:17 +0000 Subject: [PATCH 133/434] Update dependency dompurify to v2.4.0 Signed-off-by: Renovate Bot --- yarn.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6657305c84..85fbc5edc9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7714,7 +7714,7 @@ __metadata: "@types/node": ^16.11.26 canvas: ^2.6.1 cross-fetch: ^3.1.5 - dompurify: ^2.2.9 + dompurify: ^2.3.6 event-source-polyfill: 1.0.25 git-url-parse: ^13.0.0 jss: ~10.8.2 @@ -20643,7 +20643,7 @@ __metadata: languageName: node linkType: hard -"dompurify@npm:=2.3.10, dompurify@npm:^2.2.7, dompurify@npm:^2.2.9, dompurify@npm:^2.3.6": +"dompurify@npm:=2.3.10, dompurify@npm:^2.2.7, dompurify@npm:^2.3.6": version: 2.3.10 resolution: "dompurify@npm:2.3.10" checksum: ee343876b4c065e82d194818c66af76a6d2290264c7db583ad71761c11781fd626f0245f9f4670175d5707c4b8fcfb89adae80bed0418a9426a47ee7f36b0ffc From 22ac86271192a49e1ec356b90ae8eac170565e57 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 3 Nov 2022 15:59:14 +0100 Subject: [PATCH 134/434] yarn.lock: fix Signed-off-by: Patrik Oldsberg --- yarn.lock | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index 85fbc5edc9..398b23bf40 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7714,7 +7714,7 @@ __metadata: "@types/node": ^16.11.26 canvas: ^2.6.1 cross-fetch: ^3.1.5 - dompurify: ^2.3.6 + dompurify: ^2.2.9 event-source-polyfill: 1.0.25 git-url-parse: ^13.0.0 jss: ~10.8.2 @@ -20643,13 +20643,20 @@ __metadata: languageName: node linkType: hard -"dompurify@npm:=2.3.10, dompurify@npm:^2.2.7, dompurify@npm:^2.3.6": +"dompurify@npm:=2.3.10": version: 2.3.10 resolution: "dompurify@npm:2.3.10" checksum: ee343876b4c065e82d194818c66af76a6d2290264c7db583ad71761c11781fd626f0245f9f4670175d5707c4b8fcfb89adae80bed0418a9426a47ee7f36b0ffc languageName: node linkType: hard +"dompurify@npm:^2.2.7, dompurify@npm:^2.2.9, dompurify@npm:^2.3.6": + version: 2.4.0 + resolution: "dompurify@npm:2.4.0" + checksum: c93ea73cf8e3ba044588450198563e56ce6902e36d0e16e3699df2fa59e82c4fdd11d4ad04ef5024569ce96a35b46f29d0bbea522516add33cd39a7f56a8a675 + languageName: node + linkType: hard + "domutils@npm:^2.5.2, domutils@npm:^2.6.0": version: 2.8.0 resolution: "domutils@npm:2.8.0" From eec8acf54e23d8f81d5c15ffddf697fce275d100 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 3 Nov 2022 16:03:06 +0100 Subject: [PATCH 135/434] Update .changeset/little-plums-look.md Signed-off-by: Patrik Oldsberg --- .changeset/little-plums-look.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/little-plums-look.md b/.changeset/little-plums-look.md index 45b3c0f341..4fd40ad32a 100644 --- a/.changeset/little-plums-look.md +++ b/.changeset/little-plums-look.md @@ -1,5 +1,5 @@ --- -'@backstage/core-components': minor +'@backstage/core-components': patch --- MissingAnnotationEmptyState now accepts either a string or an array of strings to support multiple missing annotations. From c4dc45d7818e46cc90b5b2b63b639f976701d317 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 15:03:34 +0000 Subject: [PATCH 136/434] Update dependency react-window to v1.8.8 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6657305c84..77ef27964c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34114,15 +34114,15 @@ __metadata: linkType: hard "react-window@npm:^1.8.6": - version: 1.8.7 - resolution: "react-window@npm:1.8.7" + version: 1.8.8 + resolution: "react-window@npm:1.8.8" dependencies: "@babel/runtime": ^7.0.0 memoize-one: ">=3.1.1 <6" peerDependencies: react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 - checksum: 1e122c29224781e70359978287a2e850ccdf509cd71ba16b16ea258725687a62f5c16ab69f52f732b4ed20df583196dbe2a04804f3e4a176bb3e62f3fc910452 + checksum: a19f43b9015fb84e16db983617dac618a8b298881d2ca96ffc2fb00534afd958ee57a00fd0017733b56f8c34dd84e5be59337877aed3c66329ed3b84e8d018ba languageName: node linkType: hard From 26f9b90dd11474500d6722c853fb44e215b522f7 Mon Sep 17 00:00:00 2001 From: Gabriel Dantas Date: Thu, 3 Nov 2022 12:24:48 -0300 Subject: [PATCH 137/434] update sidebars.json Signed-off-by: Gabriel Dantas --- microsite/sidebars.json | 1 + 1 file changed, 1 insertion(+) diff --git a/microsite/sidebars.json b/microsite/sidebars.json index e758fe9100..f9fdb9ee9a 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -95,6 +95,7 @@ "features/software-templates/configuration", "features/software-templates/adding-templates", "features/software-templates/writing-templates", + "features/software-templates/input-examples", "features/software-templates/builtin-actions", "features/software-templates/writing-custom-actions", "features/software-templates/writing-custom-field-extensions", From 9eb73906a374224a712f647a2954669a4d427b22 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 16:55:26 +0000 Subject: [PATCH 138/434] Update dependency serve-handler to v6.1.5 Signed-off-by: Renovate Bot --- yarn.lock | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/yarn.lock b/yarn.lock index ceffbb8c53..4d6ac55849 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29800,12 +29800,12 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:3.0.4": - version: 3.0.4 - resolution: "minimatch@npm:3.0.4" +"minimatch@npm:3.1.2, minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" dependencies: brace-expansion: ^1.1.7 - checksum: 66ac295f8a7b59788000ea3749938b0970344c841750abd96694f80269b926ebcafad3deeb3f1da2522978b119e6ae3a5869b63b13a7859a456b3408bd18a078 + checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a languageName: node linkType: hard @@ -29827,15 +29827,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": - version: 3.1.2 - resolution: "minimatch@npm:3.1.2" - dependencies: - brace-expansion: ^1.1.7 - checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a - languageName: node - linkType: hard - "minimist-options@npm:^4.0.2": version: 4.1.0 resolution: "minimist-options@npm:4.1.0" @@ -35709,18 +35700,18 @@ __metadata: linkType: hard "serve-handler@npm:^6.1.3": - version: 6.1.3 - resolution: "serve-handler@npm:6.1.3" + version: 6.1.5 + resolution: "serve-handler@npm:6.1.5" dependencies: bytes: 3.0.0 content-disposition: 0.5.2 fast-url-parser: 1.1.3 mime-types: 2.1.18 - minimatch: 3.0.4 + minimatch: 3.1.2 path-is-inside: 1.0.2 path-to-regexp: 2.2.1 range-parser: 1.2.0 - checksum: 384c1bc10add07a554207f918acaa75af47fcfd8fb89e070faa3468ab45ec5bbc9f976e62d659b6b63404edcf5c54efb7e0a48f3f55946eec83b62b283b9837e + checksum: 7a98ca9cbf8692583b6cde4deb3941cff900fa38bf16adbfccccd8430209bab781e21d9a1f61c9c03e226f9f67689893bbce25941368f3ddaf985fc3858b49dc languageName: node linkType: hard From 54ba1c13fc184f6b82be7cbc38a878ba185fac41 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 17:49:28 +0000 Subject: [PATCH 139/434] Update dependency @rjsf/utils to v5.0.0-beta.12 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4d6ac55849..78f63c59a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12240,8 +12240,8 @@ __metadata: linkType: hard "@rjsf/utils@npm:^5.0.0-beta.10": - version: 5.0.0-beta.11 - resolution: "@rjsf/utils@npm:5.0.0-beta.11" + version: 5.0.0-beta.12 + resolution: "@rjsf/utils@npm:5.0.0-beta.12" dependencies: json-schema-merge-allof: ^0.8.1 jsonpointer: ^5.0.1 @@ -12250,7 +12250,7 @@ __metadata: react-is: ^18.2.0 peerDependencies: react: ^16.14.0 || >=17 - checksum: 4e77616023b5cf193e1631a4d5fb8d54122d9f48e30ce2fcb1b22f057e2dcf37aae174f25f1afddb664b0114e461f9d738fa282995b07e9e3eb30f7469d77145 + checksum: b9698a2238dd5d3c79c13b84d92587825005938cd449680204903463b6fc6f63165fb715ea1e50a94e6764aa405be2b2ac2e6aad8bc68cd50623f065fd6f979a languageName: node linkType: hard From 95557641e505b240d5e0a0dfc974cecfdd322477 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 18:36:31 +0000 Subject: [PATCH 140/434] Update dependency tar to v6.1.12 Signed-off-by: Renovate Bot --- yarn.lock | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 78f63c59a7..3469951abe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -37399,7 +37399,7 @@ __metadata: languageName: node linkType: hard -"tar@npm:^6.0.2, tar@npm:^6.1.0, tar@npm:^6.1.11, tar@npm:^6.1.2": +"tar@npm:^6.0.2, tar@npm:^6.1.0, tar@npm:^6.1.11": version: 6.1.11 resolution: "tar@npm:6.1.11" dependencies: @@ -37413,6 +37413,20 @@ __metadata: languageName: node linkType: hard +"tar@npm:^6.1.2": + version: 6.1.12 + resolution: "tar@npm:6.1.12" + dependencies: + chownr: ^2.0.0 + fs-minipass: ^2.0.0 + minipass: ^3.0.0 + minizlib: ^2.1.1 + mkdirp: ^1.0.3 + yallist: ^4.0.0 + checksum: 49d72e4420944e7ede2782d6b0826a6ede6cdab23c7de63470917e7a78166bc4d5b1a96279d3d79a85f1ba5a17cd37c0acbb3cbff19a07447691445b8b051c55 + languageName: node + linkType: hard + "tarn@npm:^3.0.2": version: 3.0.2 resolution: "tarn@npm:3.0.2" From f13cf292ec5307d2840aac41c0da5fa377ec976e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 18:37:38 +0000 Subject: [PATCH 141/434] Update graphqlcodegenerator monorepo Signed-off-by: Renovate Bot --- yarn.lock | 175 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 112 insertions(+), 63 deletions(-) diff --git a/yarn.lock b/yarn.lock index 78f63c59a7..e606b0317a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8755,21 +8755,21 @@ __metadata: linkType: hard "@graphql-codegen/cli@npm:^2.3.1": - version: 2.13.7 - resolution: "@graphql-codegen/cli@npm:2.13.7" + version: 2.13.11 + resolution: "@graphql-codegen/cli@npm:2.13.11" dependencies: "@babel/generator": ^7.18.13 "@babel/template": ^7.18.10 "@babel/types": ^7.18.13 - "@graphql-codegen/core": 2.6.2 - "@graphql-codegen/plugin-helpers": ^2.6.2 + "@graphql-codegen/core": 2.6.5 + "@graphql-codegen/plugin-helpers": ^2.7.2 "@graphql-tools/apollo-engine-loader": ^7.3.6 "@graphql-tools/code-file-loader": ^7.3.1 "@graphql-tools/git-loader": ^7.2.1 "@graphql-tools/github-loader": ^7.3.6 "@graphql-tools/graphql-file-loader": ^7.5.0 "@graphql-tools/json-file-loader": ^7.4.1 - "@graphql-tools/load": ^7.7.1 + "@graphql-tools/load": 7.8.0 "@graphql-tools/prisma-loader": ^7.2.7 "@graphql-tools/url-loader": ^7.13.2 "@graphql-tools/utils": ^8.9.0 @@ -8801,37 +8801,37 @@ __metadata: graphql-code-generator: cjs/bin.js graphql-codegen: cjs/bin.js graphql-codegen-esm: esm/bin.js - checksum: c025e311c072c1d992451f27625c863eef1236e5f01e2aeb6f00e67a60e99c7812a13481481a8fc6ea2967fffd77433d582f10365244d677608fdc7aa13bbe29 + checksum: 8d5d6f848f245b2091b85785466805cced26d788a66c3e03fbcfd6dc8b5bac4215b6b687d746ad0ee05685c700eecc93b502fd73c3383e5ac4a19cc1b4198ac1 languageName: node linkType: hard -"@graphql-codegen/core@npm:2.6.2": - version: 2.6.2 - resolution: "@graphql-codegen/core@npm:2.6.2" +"@graphql-codegen/core@npm:2.6.5": + version: 2.6.5 + resolution: "@graphql-codegen/core@npm:2.6.5" dependencies: - "@graphql-codegen/plugin-helpers": ^2.6.2 + "@graphql-codegen/plugin-helpers": ^2.7.2 "@graphql-tools/schema": ^9.0.0 - "@graphql-tools/utils": ^8.8.0 + "@graphql-tools/utils": 9.0.0 tslib: ~2.4.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 3d078e9caa11baf7ceaa4d67b29a6be32f50a183c1fa6f228a3ade62902b9b91cdea2c94d99adbadf10ec38a7f2df9f16cd366dc7b4febf95336e3b4a7eb9160 + checksum: 22a30285af6adf5acd8ed2f45363c77b718a1789f024094a4fcc62fc164440f0fed595b5eecfa216e3568a81ba07dd8f2e6111cb49f2ce46160b14167a330c41 languageName: node linkType: hard "@graphql-codegen/graphql-modules-preset@npm:^2.3.2": - version: 2.5.4 - resolution: "@graphql-codegen/graphql-modules-preset@npm:2.5.4" + version: 2.5.5 + resolution: "@graphql-codegen/graphql-modules-preset@npm:2.5.5" dependencies: - "@graphql-codegen/plugin-helpers": ^2.6.2 - "@graphql-codegen/visitor-plugin-common": 2.13.0 + "@graphql-codegen/plugin-helpers": ^2.7.2 + "@graphql-codegen/visitor-plugin-common": 2.13.1 "@graphql-tools/utils": ^8.8.0 change-case-all: 1.0.14 parse-filepath: ^1.0.2 tslib: ~2.4.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: d3e9b90c475c1a093149038b0dea448ebbb25bf9cf853d1947427bed741d739f140daca8f3861da63bfee6f6958c25f1b1081ce4365c7db1efe6527bb9b9c1dc + checksum: d499001af49d0a829c6adcbc211d252e8d5a42ba1635c32265ad99d187666425150c99815d48e591ca66e811a2b09860a5f59ba02484a3a3f0dcf4dcba8a6fb8 languageName: node linkType: hard @@ -8851,6 +8851,22 @@ __metadata: languageName: node linkType: hard +"@graphql-codegen/plugin-helpers@npm:^2.7.2": + version: 2.7.2 + resolution: "@graphql-codegen/plugin-helpers@npm:2.7.2" + dependencies: + "@graphql-tools/utils": ^8.8.0 + change-case-all: 1.0.14 + common-tags: 1.8.2 + import-from: 4.0.0 + lodash: ~4.17.0 + tslib: ~2.4.0 + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 66e0d507ad5db60b67092ebf7632d464d56ab446ac8fd87c293e00d9016944912d8cf9199e3e026b0a9247a50f50c4118a44f49e13675db64211652cd6259b05 + languageName: node + linkType: hard + "@graphql-codegen/schema-ast@npm:^2.5.1": version: 2.5.1 resolution: "@graphql-codegen/schema-ast@npm:2.5.1" @@ -8865,56 +8881,41 @@ __metadata: linkType: hard "@graphql-codegen/typescript-resolvers@npm:^2.4.3": - version: 2.7.5 - resolution: "@graphql-codegen/typescript-resolvers@npm:2.7.5" + version: 2.7.6 + resolution: "@graphql-codegen/typescript-resolvers@npm:2.7.6" dependencies: - "@graphql-codegen/plugin-helpers": ^2.6.2 - "@graphql-codegen/typescript": ^2.7.5 - "@graphql-codegen/visitor-plugin-common": 2.13.0 + "@graphql-codegen/plugin-helpers": ^2.7.2 + "@graphql-codegen/typescript": ^2.8.1 + "@graphql-codegen/visitor-plugin-common": 2.13.1 "@graphql-tools/utils": ^8.8.0 auto-bind: ~4.0.0 tslib: ~2.4.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 7384bbb42bdf43157b6133812c2e84bb162ab5b52add05bed86a4f3c149bf3ab1f178bb5a7d51c661ba354296b2fa9e4983ee42b373c3815fdc6ee391a9e5307 + checksum: f552f74aa264c0f9024834d6d1c126f9f1a69dccf7278525c7609ad1820daf87607447f30351506fe3728a855690928ba7775edbbbff0fee610a2ce02913a98e languageName: node linkType: hard -"@graphql-codegen/typescript@npm:^2.4.2": - version: 2.8.0 - resolution: "@graphql-codegen/typescript@npm:2.8.0" +"@graphql-codegen/typescript@npm:^2.4.2, @graphql-codegen/typescript@npm:^2.8.1": + version: 2.8.1 + resolution: "@graphql-codegen/typescript@npm:2.8.1" dependencies: - "@graphql-codegen/plugin-helpers": ^2.6.2 + "@graphql-codegen/plugin-helpers": ^2.7.2 "@graphql-codegen/schema-ast": ^2.5.1 - "@graphql-codegen/visitor-plugin-common": 2.13.0 + "@graphql-codegen/visitor-plugin-common": 2.13.1 auto-bind: ~4.0.0 tslib: ~2.4.0 peerDependencies: graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 45550613384c930d046f1ca8bfd73c25e1219fc45315b1885017e08577a517547d5af86908162f61eee0670689df5c926b5e394b318d5c3d94ee5eef5ac1bc52 + checksum: 2b5466190e385c557eed6210b861fb9e632fb61b90bd0f97ff983f359c0ad8106228667c9ff2201842100417a07cfaffa91794ef03058a151df256d733363fa2 languageName: node linkType: hard -"@graphql-codegen/typescript@npm:^2.7.5": - version: 2.7.5 - resolution: "@graphql-codegen/typescript@npm:2.7.5" +"@graphql-codegen/visitor-plugin-common@npm:2.13.1": + version: 2.13.1 + resolution: "@graphql-codegen/visitor-plugin-common@npm:2.13.1" dependencies: - "@graphql-codegen/plugin-helpers": ^2.6.2 - "@graphql-codegen/schema-ast": ^2.5.1 - "@graphql-codegen/visitor-plugin-common": 2.13.0 - auto-bind: ~4.0.0 - tslib: ~2.4.0 - peerDependencies: - graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 0eb51d2bb826284cfed29fdaee0fc57694932627f0146394711d3f012377bccb19592270f6c04f775ec06ec87e1a05a0c85064ca186ea0e50a306ec058674fad - languageName: node - linkType: hard - -"@graphql-codegen/visitor-plugin-common@npm:2.13.0": - version: 2.13.0 - resolution: "@graphql-codegen/visitor-plugin-common@npm:2.13.0" - dependencies: - "@graphql-codegen/plugin-helpers": ^2.6.2 + "@graphql-codegen/plugin-helpers": ^2.7.2 "@graphql-tools/optimize": ^1.3.0 "@graphql-tools/relay-operation-optimizer": ^6.5.0 "@graphql-tools/utils": ^8.8.0 @@ -8926,7 +8927,7 @@ __metadata: tslib: ~2.4.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 1d7491d626059529faca2eda5466aa8b05bf2cc9a768175043461d0ec4793b4cbda2fb762ef44e6c8d094f951960569f2adf177af74156f4a74f33c6d5ae77bf + checksum: 0c329aa6e435602f2f6c1569ec2091b7850f58cc5dca7ac763c38c82588545ec1110c1de587f5f3949b11ff96f94401d1e63e329607d78424583b276fd08f1ae languageName: node linkType: hard @@ -9180,6 +9181,20 @@ __metadata: languageName: node linkType: hard +"@graphql-tools/load@npm:7.8.0": + version: 7.8.0 + resolution: "@graphql-tools/load@npm:7.8.0" + dependencies: + "@graphql-tools/schema": 9.0.4 + "@graphql-tools/utils": 8.12.0 + p-limit: 3.1.0 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 24ade442e13429d087ceac905cef4e6a14d0961e2b231adf91180a4d674de08ac6de66e6103c3e118b6ccf24065492bb69f5c99cb336e71a579ab382c8574791 + languageName: node + linkType: hard + "@graphql-tools/load@npm:^7.5.5": version: 7.7.0 resolution: "@graphql-tools/load@npm:7.7.0" @@ -9194,20 +9209,6 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/load@npm:^7.7.1": - version: 7.7.1 - resolution: "@graphql-tools/load@npm:7.7.1" - dependencies: - "@graphql-tools/schema": 8.5.1 - "@graphql-tools/utils": 8.9.0 - p-limit: 3.1.0 - tslib: ^2.4.0 - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: 4abaab346dab9547f547fe619476e5de54698121174f579f3473f2d5678891c249482a3e56f9b748400d5062c9bd3b5d5d5e56885555e5a3422cafa2afd6022e - languageName: node - linkType: hard - "@graphql-tools/merge@npm:8.2.10": version: 8.2.10 resolution: "@graphql-tools/merge@npm:8.2.10" @@ -9256,6 +9257,18 @@ __metadata: languageName: node linkType: hard +"@graphql-tools/merge@npm:8.3.6": + version: 8.3.6 + resolution: "@graphql-tools/merge@npm:8.3.6" + dependencies: + "@graphql-tools/utils": 8.12.0 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 3e45ebff0dce9524e72c4af1d2b9799c16515c1236290e07cd68fb2226c4e54734e2444d89a64b387b7ba991d15c6f948fdfc20c77a74b1d24babddd865ff32a + languageName: node + linkType: hard + "@graphql-tools/mock@npm:^8.1.2": version: 8.6.8 resolution: "@graphql-tools/mock@npm:8.6.8" @@ -9365,6 +9378,20 @@ __metadata: languageName: node linkType: hard +"@graphql-tools/schema@npm:9.0.4": + version: 9.0.4 + resolution: "@graphql-tools/schema@npm:9.0.4" + dependencies: + "@graphql-tools/merge": 8.3.6 + "@graphql-tools/utils": 8.12.0 + tslib: ^2.4.0 + value-or-promise: 1.0.11 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 0644ba225ff7fb03c6fb7f026b6a77a4ac5dd14fd10bb562ea0072bfe0258620fd4789b851b0b97007db8754d0b7d88a1061bb98bacc679b22e2eb7706e79e0e + languageName: node + linkType: hard + "@graphql-tools/schema@npm:^9.0.0": version: 9.0.8 resolution: "@graphql-tools/schema@npm:9.0.8" @@ -9429,6 +9456,17 @@ __metadata: languageName: node linkType: hard +"@graphql-tools/utils@npm:8.12.0": + version: 8.12.0 + resolution: "@graphql-tools/utils@npm:8.12.0" + dependencies: + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 24edc6ba3bcfa9a4c1d1d37117c3f96d847beed9638325083c32c6ec9674729dc89fc8cc389d317ae5d9dba22e91443bd9788f1dc8de91a1b6f1e592112bd48f + languageName: node + linkType: hard + "@graphql-tools/utils@npm:8.6.9": version: 8.6.9 resolution: "@graphql-tools/utils@npm:8.6.9" @@ -9462,6 +9500,17 @@ __metadata: languageName: node linkType: hard +"@graphql-tools/utils@npm:9.0.0": + version: 9.0.0 + resolution: "@graphql-tools/utils@npm:9.0.0" + dependencies: + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 8da22b13e0cfceac20f2ee08c45f360d0bd1390fa0edd8496ea75a0ca7d10ab3bbafca6b4b0dbc3f233a05cd53096e3063b9208f727c72db00e461751164afbd + languageName: node + linkType: hard + "@graphql-tools/utils@npm:9.0.1": version: 9.0.1 resolution: "@graphql-tools/utils@npm:9.0.1" From dc780745322aaa664f355573c3360c839f8df573 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 19:31:06 +0000 Subject: [PATCH 142/434] Update Apollo GraphQL packages to v3.11.1 Signed-off-by: Renovate Bot --- yarn.lock | 53 +++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/yarn.lock b/yarn.lock index e606b0317a..4d20815e73 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16099,9 +16099,9 @@ __metadata: languageName: node linkType: hard -"apollo-server-core@npm:^3.10.3": - version: 3.10.3 - resolution: "apollo-server-core@npm:3.10.3" +"apollo-server-core@npm:^3.11.1": + version: 3.11.1 + resolution: "apollo-server-core@npm:3.11.1" dependencies: "@apollo/utils.keyvaluecache": ^1.0.1 "@apollo/utils.logger": ^1.0.0 @@ -16115,19 +16115,20 @@ __metadata: apollo-reporting-protobuf: ^3.3.3 apollo-server-env: ^4.2.1 apollo-server-errors: ^3.3.1 - apollo-server-plugin-base: ^3.6.3 - apollo-server-types: ^3.6.3 + apollo-server-plugin-base: ^3.7.1 + apollo-server-types: ^3.7.1 async-retry: ^1.2.1 fast-json-stable-stringify: ^2.1.0 graphql-tag: ^2.11.0 loglevel: ^1.6.8 lru-cache: ^6.0.0 + node-abort-controller: ^3.0.1 sha.js: ^2.4.11 uuid: ^9.0.0 whatwg-mimetype: ^3.0.0 peerDependencies: graphql: ^15.3.0 || ^16.0.0 - checksum: 1a9c3ca29c1e664970737e83d76999d43ceb938e39026a329682fcc80fa17a564a69cb7b38110b1928d3d512ae77eeeb8ed6e160043521052c0360b0b00f0ada + checksum: a5cb7cff331680c2a926c64e88f744425b724bcfae46aeb02ae636d0b6f57a605e561eb284e765618bd0b2b5f8c556c92183f69852f2e4f5889368fee6aa38dc languageName: node linkType: hard @@ -16149,9 +16150,9 @@ __metadata: languageName: node linkType: hard -"apollo-server-express@npm:^3.0.0, apollo-server-express@npm:^3.10.3": - version: 3.10.3 - resolution: "apollo-server-express@npm:3.10.3" +"apollo-server-express@npm:^3.0.0, apollo-server-express@npm:^3.11.1": + version: 3.11.1 + resolution: "apollo-server-express@npm:3.11.1" dependencies: "@types/accepts": ^1.3.5 "@types/body-parser": 1.19.2 @@ -16159,32 +16160,32 @@ __metadata: "@types/express": 4.17.14 "@types/express-serve-static-core": 4.17.31 accepts: ^1.3.5 - apollo-server-core: ^3.10.3 - apollo-server-types: ^3.6.3 + apollo-server-core: ^3.11.1 + apollo-server-types: ^3.7.1 body-parser: ^1.19.0 cors: ^2.8.5 parseurl: ^1.3.3 peerDependencies: express: ^4.17.1 graphql: ^15.3.0 || ^16.0.0 - checksum: c6dcfd8b61a558bd479d93d1c9cc4f436145b31e7f5e53d6c655d919c79f0b4b785788f0d16fc1d94c1929b85b034ae84a7332ce4e20603b67e0a4709e48b3a6 + checksum: 1db1a77aaa2f760c885233ded249b632e467bb4895d1c3f797df6e197a9ca7021c5b65dd8829e88fd6dbf32d925c7dcf62b48b949a518e2e31072c490302fa60 languageName: node linkType: hard -"apollo-server-plugin-base@npm:^3.6.3": - version: 3.6.3 - resolution: "apollo-server-plugin-base@npm:3.6.3" +"apollo-server-plugin-base@npm:^3.7.1": + version: 3.7.1 + resolution: "apollo-server-plugin-base@npm:3.7.1" dependencies: - apollo-server-types: ^3.6.3 + apollo-server-types: ^3.7.1 peerDependencies: graphql: ^15.3.0 || ^16.0.0 - checksum: 50e690cf4c5047957c4546676f11d82f8c0bee2c0340573322f23188af27175ac49859d463c6123ebef500b3c32a0932e3e3f9fa8671e2d1a410d2e89c8608e3 + checksum: db8c5f658da8c51c067bd6659b31ec2436d4961437b6f6f6b1b2a109d26764bc52a4dbe1bdafcb3c712b0e2f13ca10ed787e90423505685d2043a77363bdfc0b languageName: node linkType: hard -"apollo-server-types@npm:^3.6.3": - version: 3.6.3 - resolution: "apollo-server-types@npm:3.6.3" +"apollo-server-types@npm:^3.7.1": + version: 3.7.1 + resolution: "apollo-server-types@npm:3.7.1" dependencies: "@apollo/utils.keyvaluecache": ^1.0.1 "@apollo/utils.logger": ^1.0.0 @@ -16192,21 +16193,21 @@ __metadata: apollo-server-env: ^4.2.1 peerDependencies: graphql: ^15.3.0 || ^16.0.0 - checksum: ebd218e6fa8b756bb2d6954b454676907d99b8f140923b439cc1bbb200251f9df7228a9d83c5c91bb571a448cc80c2d86bc0a0eae491a4ce028e86a724cde68a + checksum: fe9a0847d0b8ab70dbe407b4ba1f5e506d351ff1f728193f4b308806e73b958f50537478a71edeefdd66fcf3dbf32ec732b6ffe6542860d5b683b1d657a019a2 languageName: node linkType: hard "apollo-server@npm:^3.0.0": - version: 3.10.3 - resolution: "apollo-server@npm:3.10.3" + version: 3.11.1 + resolution: "apollo-server@npm:3.11.1" dependencies: "@types/express": 4.17.14 - apollo-server-core: ^3.10.3 - apollo-server-express: ^3.10.3 + apollo-server-core: ^3.11.1 + apollo-server-express: ^3.11.1 express: ^4.17.1 peerDependencies: graphql: ^15.3.0 || ^16.0.0 - checksum: eec2423bbd30256683c0e7873cd1e3f616ff2a3c90cf7bba241880027f5e1374d20d13bf7ce4b09543b16753d0d7a4627f77d64de77b5b241c410f0f246bdbd7 + checksum: 6d4e981682e3b60313dddfe999c408c683f7e4cdeed5c14b6d6245b708808b94cb14df67ebe1b9df38df6b5193a9291089c41e287d014f2a9f94b2f3ecc9b376 languageName: node linkType: hard From c49fe0daadba86881253180673f65a180f12b31b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 19:32:04 +0000 Subject: [PATCH 143/434] Update dependency @google-cloud/storage to v6.7.0 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e606b0317a..b536287976 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8697,8 +8697,8 @@ __metadata: linkType: hard "@google-cloud/storage@npm:^6.0.0": - version: 6.6.0 - resolution: "@google-cloud/storage@npm:6.6.0" + version: 6.7.0 + resolution: "@google-cloud/storage@npm:6.7.0" dependencies: "@google-cloud/paginator": ^3.0.7 "@google-cloud/projectify": ^3.0.0 @@ -8717,7 +8717,7 @@ __metadata: retry-request: ^5.0.0 teeny-request: ^8.0.0 uuid: ^8.0.0 - checksum: fef529fc83be01fc421e2ee8c8cd6a78dc5b0d50b1f0912e358285b2e4650a3111229feaef5b517fc90b718e7424251dadc59e12ab782303d57aa3e59dc019ab + checksum: 269224b965eb6a4c0c47b5df7cc21a6110ded2596c649ea94737ad622410b10a91fc0a1b765667c7bb64e44a98dad35abc5d342173b13b10f174ab0ce211f434 languageName: node linkType: hard From ac4272629523cd85f7b0410f5c6161fe6dafa088 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Thu, 3 Nov 2022 14:36:51 -0500 Subject: [PATCH 144/434] feat: Enable theme overrides for components in catalog-graph plugin Signed-off-by: Carlos Esteban Lopez --- .../CatalogGraphCard/CatalogGraphCard.tsx | 25 ++--- .../CatalogGraphPage/CatalogGraphPage.tsx | 95 ++++++++++--------- .../CatalogGraphPage/MaxDepthFilter.tsx | 13 ++- .../CatalogGraphPage/SelectedKindsFilter.tsx | 11 ++- .../SelectedRelationsFilter.tsx | 11 ++- .../CatalogGraphPage/SwitchFilter.tsx | 13 ++- .../EntityRelationsGraph/CustomLabel.tsx | 19 ++-- .../EntityRelationsGraph/CustomNode.tsx | 55 ++++++----- .../EntityRelationsGraph.tsx | 57 +++++------ 9 files changed, 163 insertions(+), 136 deletions(-) diff --git a/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.tsx b/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.tsx index ae1ca9c22d..47b29b7c56 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.tsx @@ -39,18 +39,21 @@ import { RelationPairs, } from '../EntityRelationsGraph'; -const useStyles = makeStyles({ - card: ({ height }) => ({ - display: 'flex', - flexDirection: 'column', - maxHeight: height, - minHeight: height, - }), - graph: { - flex: 1, - minHeight: 0, +const useStyles = makeStyles( + { + card: ({ height }) => ({ + display: 'flex', + flexDirection: 'column', + maxHeight: height, + minHeight: height, + }), + graph: { + flex: 1, + minHeight: 0, + }, }, -}); + { name: 'PluginCatalogGraphCatalogGraphCard' }, +); export const CatalogGraphCard = (props: { variant?: InfoCardVariants; diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.tsx index a6a6c2a711..4a36d516e2 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.tsx @@ -48,57 +48,60 @@ import { SelectedRelationsFilter } from './SelectedRelationsFilter'; import { SwitchFilter } from './SwitchFilter'; import { useCatalogGraphPage } from './useCatalogGraphPage'; -const useStyles = makeStyles(theme => ({ - content: { - minHeight: 0, - }, - container: { - height: '100%', - maxHeight: '100%', - minHeight: 0, - }, - fullHeight: { - maxHeight: '100%', - display: 'flex', - minHeight: 0, - }, - graphWrapper: { - position: 'relative', - flex: 1, - minHeight: 0, - display: 'flex', - }, - graph: { - flex: 1, - minHeight: 0, - }, - legend: { - position: 'absolute', - bottom: 0, - right: 0, - padding: theme.spacing(1), - '& .icon': { - verticalAlign: 'bottom', +const useStyles = makeStyles( + theme => ({ + content: { + minHeight: 0, }, - }, - filters: { - display: 'grid', - gridGap: theme.spacing(1), - gridAutoRows: 'auto', - [theme.breakpoints.up('lg')]: { - display: 'block', + container: { + height: '100%', + maxHeight: '100%', + minHeight: 0, }, - [theme.breakpoints.only('md')]: { - gridTemplateColumns: 'repeat(3, 1fr)', + fullHeight: { + maxHeight: '100%', + display: 'flex', + minHeight: 0, }, - [theme.breakpoints.only('sm')]: { - gridTemplateColumns: 'repeat(2, 1fr)', + graphWrapper: { + position: 'relative', + flex: 1, + minHeight: 0, + display: 'flex', }, - [theme.breakpoints.down('xs')]: { - gridTemplateColumns: 'repeat(1, 1fr)', + graph: { + flex: 1, + minHeight: 0, }, - }, -})); + legend: { + position: 'absolute', + bottom: 0, + right: 0, + padding: theme.spacing(1), + '& .icon': { + verticalAlign: 'bottom', + }, + }, + filters: { + display: 'grid', + gridGap: theme.spacing(1), + gridAutoRows: 'auto', + [theme.breakpoints.up('lg')]: { + display: 'block', + }, + [theme.breakpoints.only('md')]: { + gridTemplateColumns: 'repeat(3, 1fr)', + }, + [theme.breakpoints.only('sm')]: { + gridTemplateColumns: 'repeat(2, 1fr)', + }, + [theme.breakpoints.down('xs')]: { + gridTemplateColumns: 'repeat(1, 1fr)', + }, + }, + }), + { name: 'PluginCatalogGraphCatalogGraphPage' }, +); export const CatalogGraphPage = (props: { relationPairs?: RelationPairs; diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.tsx index 7828a60fb6..b6b03d8831 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.tsx @@ -30,12 +30,15 @@ export type Props = { onChange: (value: number) => void; }; -const useStyles = makeStyles({ - formControl: { - width: '100%', - maxWidth: 300, +const useStyles = makeStyles( + { + formControl: { + width: '100%', + maxWidth: 300, + }, }, -}); + { name: 'PluginCatalogGraphMaxDepthFilter' }, +); export const MaxDepthFilter = ({ value, onChange }: Props) => { const classes = useStyles(); diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.tsx index 316f83da62..0817a01e0b 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.tsx @@ -30,11 +30,14 @@ import { Autocomplete } from '@material-ui/lab'; import React, { useCallback, useEffect, useMemo } from 'react'; import useAsync from 'react-use/lib/useAsync'; -const useStyles = makeStyles({ - formControl: { - maxWidth: 300, +const useStyles = makeStyles( + { + formControl: { + maxWidth: 300, + }, }, -}); + { name: 'PluginCatalogGraphSelectedKindsFilter' }, +); export type Props = { value: string[] | undefined; diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedRelationsFilter.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedRelationsFilter.tsx index 839bfbe425..197f65cef8 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedRelationsFilter.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedRelationsFilter.tsx @@ -28,11 +28,14 @@ import { Autocomplete } from '@material-ui/lab'; import React, { useCallback, useMemo } from 'react'; import { RelationPairs } from '../EntityRelationsGraph'; -const useStyles = makeStyles({ - formControl: { - maxWidth: 300, +const useStyles = makeStyles( + { + formControl: { + maxWidth: 300, + }, }, -}); + { name: 'PluginCatalogGraphSelectedRelationsFilter' }, +); export type Props = { relationPairs: RelationPairs; diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/SwitchFilter.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/SwitchFilter.tsx index 214080db6e..495f6b4db2 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/SwitchFilter.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/SwitchFilter.tsx @@ -22,12 +22,15 @@ export type Props = { onChange: (value: boolean) => void; }; -const useStyles = makeStyles({ - root: { - width: '100%', - maxWidth: 300, +const useStyles = makeStyles( + { + root: { + width: '100%', + maxWidth: 300, + }, }, -}); + { name: 'PluginCatalogGraphSwitchFilter' }, +); export const SwitchFilter = ({ label, value, onChange }: Props) => { const classes = useStyles(); diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/CustomLabel.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/CustomLabel.tsx index 60a858eee6..19082cfe81 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/CustomLabel.tsx +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/CustomLabel.tsx @@ -20,14 +20,17 @@ import React from 'react'; import { EntityEdgeData } from './types'; import classNames from 'classnames'; -const useStyles = makeStyles((theme: BackstageTheme) => ({ - text: { - fill: theme.palette.textContrast, - }, - secondary: { - fill: theme.palette.textSubtle, - }, -})); +const useStyles = makeStyles( + (theme: BackstageTheme) => ({ + text: { + fill: theme.palette.textContrast, + }, + secondary: { + fill: theme.palette.textSubtle, + }, + }), + { name: 'PluginCatalogGraphCustomLabel' }, +); export function CustomLabel({ edge: { relations }, diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/CustomNode.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/CustomNode.tsx index ae541fa997..edcdb97fcb 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/CustomNode.tsx +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/CustomNode.tsx @@ -22,37 +22,40 @@ import React, { useLayoutEffect, useRef, useState } from 'react'; import { EntityKindIcon } from './EntityKindIcon'; import { EntityNodeData } from './types'; -const useStyles = makeStyles((theme: BackstageTheme) => ({ - node: { - fill: theme.palette.grey[300], - stroke: theme.palette.grey[300], +const useStyles = makeStyles( + (theme: BackstageTheme) => ({ + node: { + fill: theme.palette.grey[300], + stroke: theme.palette.grey[300], - '&.primary': { - fill: theme.palette.primary.light, - stroke: theme.palette.primary.light, + '&.primary': { + fill: theme.palette.primary.light, + stroke: theme.palette.primary.light, + }, + '&.secondary': { + fill: theme.palette.secondary.light, + stroke: theme.palette.secondary.light, + }, }, - '&.secondary': { - fill: theme.palette.secondary.light, - stroke: theme.palette.secondary.light, - }, - }, - text: { - fill: theme.palette.getContrastText(theme.palette.grey[300]), + text: { + fill: theme.palette.getContrastText(theme.palette.grey[300]), - '&.primary': { - fill: theme.palette.primary.contrastText, + '&.primary': { + fill: theme.palette.primary.contrastText, + }, + '&.secondary': { + fill: theme.palette.secondary.contrastText, + }, + '&.focused': { + fontWeight: 'bold', + }, }, - '&.secondary': { - fill: theme.palette.secondary.contrastText, + clickable: { + cursor: 'pointer', }, - '&.focused': { - fontWeight: 'bold', - }, - }, - clickable: { - cursor: 'pointer', - }, -})); + }), + { name: 'PluginCatalogGraphCustomNode' }, +); export function CustomNode({ node: { diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.tsx index c0e2f610c1..72ec4b4aed 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.tsx +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.tsx @@ -32,36 +32,39 @@ import { ALL_RELATION_PAIRS, RelationPairs } from './relations'; import { Direction, EntityEdge, EntityNode } from './types'; import { useEntityRelationNodesAndEdges } from './useEntityRelationNodesAndEdges'; -const useStyles = makeStyles(theme => ({ - progress: { - position: 'absolute', - left: '50%', - top: '50%', - marginLeft: '-20px', - marginTop: '-20px', - }, - container: { - position: 'relative', - width: '100%', - display: 'flex', - flexDirection: 'column', - }, - graph: { - width: '100%', - flex: 1, - // Right now there is no good way to style edges between nodes, we have to - // fallback to these hacks: - '& path[marker-end]': { - transition: 'filter 0.1s ease-in-out', +const useStyles = makeStyles( + theme => ({ + progress: { + position: 'absolute', + left: '50%', + top: '50%', + marginLeft: '-20px', + marginTop: '-20px', }, - '& path[marker-end]:hover': { - filter: `drop-shadow(2px 2px 4px ${theme.palette.primary.dark});`, + container: { + position: 'relative', + width: '100%', + display: 'flex', + flexDirection: 'column', }, - '& g[data-testid=label]': { - transition: 'transform 0s', + graph: { + width: '100%', + flex: 1, + // Right now there is no good way to style edges between nodes, we have to + // fallback to these hacks: + '& path[marker-end]': { + transition: 'filter 0.1s ease-in-out', + }, + '& path[marker-end]:hover': { + filter: `drop-shadow(2px 2px 4px ${theme.palette.primary.dark});`, + }, + '& g[data-testid=label]': { + transition: 'transform 0s', + }, }, - }, -})); + }), + { name: 'PluginCatalogGraphEntityRelationsGraph' }, +); /** * Core building block for custom entity relations diagrams. From 21d84ef3325332133fa08ec34214237c8ca54eb3 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Thu, 3 Nov 2022 14:43:11 -0500 Subject: [PATCH 145/434] fix: Add changeset Signed-off-by: Carlos Esteban Lopez --- .changeset/lazy-nails-study.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/lazy-nails-study.md diff --git a/.changeset/lazy-nails-study.md b/.changeset/lazy-nails-study.md new file mode 100644 index 0000000000..8d365c4662 --- /dev/null +++ b/.changeset/lazy-nails-study.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-graph': patch +--- + +feat: Enable theme overrides for components in catalog-graph plugin From ee301bb405091a1c37f96e739f0e600be3e0ce0b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 20:14:33 +0000 Subject: [PATCH 146/434] Update dependency @opensearch-project/opensearch to v2.1.0 Signed-off-by: Renovate Bot --- yarn.lock | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b536287976..7f530482c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12019,14 +12019,15 @@ __metadata: linkType: hard "@opensearch-project/opensearch@npm:^2.0.0": - version: 2.0.0 - resolution: "@opensearch-project/opensearch@npm:2.0.0" + version: 2.1.0 + resolution: "@opensearch-project/opensearch@npm:2.1.0" dependencies: + aws4: ^1.11.0 debug: ^4.3.1 hpagent: ^0.1.1 ms: ^2.1.3 secure-json-parse: ^2.4.0 - checksum: 7e0e7ae6ac8b6789f7fac59d66ef8afb960cdff46a5d201d9fb447270b808a5e0fd725b75e5fc647974b1b86e5a048e1e9d79aed04b11a424e14ec30079f2e44 + checksum: 900b90f35d5b960fe60979168e21e9e5b6089a8e3dd9341b5d86c7f7aa7671cbfd937fbec311a6cfe195c113db755e699d3678ee0cbf454e9a9de1189d8cc935 languageName: node linkType: hard From 07d1a15de659649d495e629a8d25fbaecd037bcb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 20:55:06 +0000 Subject: [PATCH 147/434] Update dependency @tanstack/react-query to v4.14.1 Signed-off-by: Renovate Bot --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7f530482c2..8c492da7cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13013,18 +13013,18 @@ __metadata: languageName: node linkType: hard -"@tanstack/query-core@npm:4.13.0": - version: 4.13.0 - resolution: "@tanstack/query-core@npm:4.13.0" - checksum: 11cb95be4dc6e1ba3f0f4eb04c255eab7fa5eca3441d6e698e2c6d03c84c03efaf34d475594e259593d76f584af0c0e830c7d868a682d6dc0f61d1a439728d12 +"@tanstack/query-core@npm:4.14.1": + version: 4.14.1 + resolution: "@tanstack/query-core@npm:4.14.1" + checksum: 632528627c2d3e8899e4d26ef47c6ff96db6aa1b94683eb2882f2372b6a0e70991f5b0e9729c0ba9e27751c509256453070d78067d5a89db3d7c5dbf9617f777 languageName: node linkType: hard "@tanstack/react-query@npm:^4.1.3": - version: 4.13.0 - resolution: "@tanstack/react-query@npm:4.13.0" + version: 4.14.1 + resolution: "@tanstack/react-query@npm:4.14.1" dependencies: - "@tanstack/query-core": 4.13.0 + "@tanstack/query-core": 4.14.1 use-sync-external-store: ^1.2.0 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -13035,7 +13035,7 @@ __metadata: optional: true react-native: optional: true - checksum: e538b585e4c2b4a8ff84c17509f4ce226e18e3e862553b6a9ca90e29c200db4ec7ab4f400f19ef4846a76c51babe0db120c54779054805fbecdcd29b369caf0e + checksum: 52397fedbb30bb5299045a66877c996e4a97f858f93436100fd7accc9731adf9ad61cf5a5e54d20e2f6b60ce7fdb9a2a209f3d5875d49793d758133e88048a10 languageName: node linkType: hard From 83c77f12d6f34db8c927118759f9a704f510a591 Mon Sep 17 00:00:00 2001 From: Gabriel Dantas Gomes Date: Thu, 3 Nov 2022 19:05:04 -0300 Subject: [PATCH 148/434] Update docs/features/software-templates/input-examples.md Co-authored-by: Patrik Oldsberg Signed-off-by: Gabriel Dantas Gomes --- docs/features/software-templates/input-examples.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-templates/input-examples.md b/docs/features/software-templates/input-examples.md index cd0a55aa0e..77b29f33e3 100644 --- a/docs/features/software-templates/input-examples.md +++ b/docs/features/software-templates/input-examples.md @@ -1,6 +1,6 @@ --- id: input-examples -title: Built-in examples inputs +title: Input Examples description: Some examples to use in your template --- From a54b681d02285579308c944a6387bb5217bbe813 Mon Sep 17 00:00:00 2001 From: Johnny Huynh <27847622+johnnyhuy@users.noreply.github.com> Date: Fri, 4 Nov 2022 09:28:45 +1100 Subject: [PATCH 149/434] Rename to GithubOrgEntityProvider The other one has been deprecated! Signed-off-by: Johnny Huynh <27847622+johnnyhuy@users.noreply.github.com> --- docs/integrations/github/org.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/integrations/github/org.md b/docs/integrations/github/org.md index 5482733a58..8212c254d7 100644 --- a/docs/integrations/github/org.md +++ b/docs/integrations/github/org.md @@ -38,7 +38,7 @@ schedule it: ```diff // packages/backend/src/plugins/catalog.ts -+import { GitHubOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-github'; ++import { GithubOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-github'; export default async function createPlugin( env: PluginEnvironment, @@ -48,7 +48,7 @@ schedule it: + // The org URL below needs to match a configured integrations.github entry + // specified in your app-config. + builder.addEntityProvider( -+ GitHubOrgEntityProvider.fromConfig(env.config, { ++ GithubOrgEntityProvider.fromConfig(env.config, { + id: 'production', + orgUrl: 'https://github.com/backstage', + logger: env.logger, From d1547a654789bfca4052a9e69efb9d968def416c Mon Sep 17 00:00:00 2001 From: Gabriel Dantas Date: Thu, 3 Nov 2022 22:29:27 -0300 Subject: [PATCH 150/434] fix: change secret input and sidebar order Signed-off-by: Gabriel Dantas --- docs/features/software-templates/input-examples.md | 14 -------------- mkdocs.yml | 2 +- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/docs/features/software-templates/input-examples.md b/docs/features/software-templates/input-examples.md index 77b29f33e3..c44ee39269 100644 --- a/docs/features/software-templates/input-examples.md +++ b/docs/features/software-templates/input-examples.md @@ -26,20 +26,6 @@ parameters: ui:help: 'Hint: additional description...' ``` -### Simple secret input - -```yaml -parameters: - - title: Fill in some steps - properties: - secretInput: - title: Input secret - type: string - description: Super secret description hint - minLength: 6 - ui:widget: password -``` - ### Multi line text input ```yaml diff --git a/mkdocs.yml b/mkdocs.yml index 38070252f5..ea2031dac6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -61,8 +61,8 @@ nav: - Overview: 'features/software-templates/index.md' - Configuration: 'features/software-templates/configuration.md' - Adding your own Templates: 'features/software-templates/adding-templates.md' - - Input Examples: 'features/software-templates/input-examples.md' - Writing Templates: 'features/software-templates/writing-templates.md' + - Input Examples: 'features/software-templates/input-examples.md' - Builtin Actions: 'features/software-templates/builtin-actions.md' - Writing Custom Actions: 'features/software-templates/writing-custom-actions.md' - Writing Custom Step Layouts: 'features/software-templates/writing-custom-step-layouts.md' From 580285787daa75989931cdde320e2151c04a9c5e Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Tue, 25 Oct 2022 21:05:05 -0400 Subject: [PATCH 151/434] Add create and click analytics events to 'next' create page Signed-off-by: Eric Peterson --- .changeset/analyze-next-software-creation.md | 5 + .../TemplateWizardPage/Stepper/Stepper.tsx | 37 +++++- .../TemplateWizardPage.test.tsx | 115 ++++++++++++++++++ .../TemplateWizardPage/TemplateWizardPage.tsx | 59 ++++----- 4 files changed, 182 insertions(+), 34 deletions(-) create mode 100644 .changeset/analyze-next-software-creation.md create mode 100644 plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx diff --git a/.changeset/analyze-next-software-creation.md b/.changeset/analyze-next-software-creation.md new file mode 100644 index 0000000000..0a4ce20e9d --- /dev/null +++ b/.changeset/analyze-next-software-creation.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +The `create` and `click` analytics events are now also captured on the "next" version of the component creation page. diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx index 511b020c3c..bed2515aaf 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx @@ -13,8 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useApiHolder } from '@backstage/core-plugin-api'; -import { JsonObject, JsonValue } from '@backstage/types'; +import { + useAnalytics, + useApiHolder, + useRouteRefParams, +} from '@backstage/core-plugin-api'; +import { JsonValue } from '@backstage/types'; import { Stepper as MuiStepper, Step as MuiStep, @@ -31,6 +35,7 @@ import { createAsyncValidators } from './createAsyncValidators'; import { useTemplateSchema } from './useTemplateSchema'; import { ReviewState } from './ReviewState'; import validator from '@rjsf/validator-ajv8'; +import { selectedTemplateRouteRef } from '../../../routes'; const useStyles = makeStyles(theme => ({ backButton: { @@ -59,10 +64,12 @@ export interface StepperProps { const Form = withTheme(require('@rjsf/material-ui-v5').Theme); export const Stepper = (props: StepperProps) => { + const { templateName } = useRouteRefParams(selectedTemplateRouteRef); + const analytics = useAnalytics(); const { steps } = useTemplateSchema(props.manifest); const apiHolder = useApiHolder(); const [activeStep, setActiveStep] = useState(0); - const [formState, setFormState] = useState({}); + const [formState, setFormState] = useState>({}); const [errors, setErrors] = useState< undefined | Record >(); @@ -90,7 +97,11 @@ export const Stepper = (props: StepperProps) => { setActiveStep(prevActiveStep => prevActiveStep - 1); }; - const handleNext = async ({ formData }: { formData: JsonObject }) => { + const handleNext = async ({ + formData, + }: { + formData: Record; + }) => { // TODO(blam): What do we do about loading states, does each field extension get a chance // to display it's own loading? Or should we grey out the entire form. setErrors(undefined); @@ -105,7 +116,11 @@ export const Stepper = (props: StepperProps) => { setErrors(returnedValidation); } else { setErrors(undefined); - setActiveStep(prevActiveStep => prevActiveStep + 1); + setActiveStep(prevActiveStep => { + const stepNum = prevActiveStep + 1; + analytics.captureEvent('click', `Next Step (${stepNum})`); + return stepNum; + }); } setFormState(current => ({ ...current, ...formData })); }; @@ -160,7 +175,17 @@ export const Stepper = (props: StepperProps) => { diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx new file mode 100644 index 0000000000..f36fae9aa3 --- /dev/null +++ b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx @@ -0,0 +1,115 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ApiProvider } from '@backstage/core-app-api'; +import { analyticsApiRef } from '@backstage/core-plugin-api'; +import { + MockAnalyticsApi, + renderInTestApp, + TestApiRegistry, +} from '@backstage/test-utils'; +import { act, fireEvent } from '@testing-library/react'; +import React from 'react'; +import { scaffolderApiRef } from '../../api'; +import { nextRouteRef, rootRouteRef } from '../../routes'; +import { ScaffolderApi } from '../../types'; +import { TemplateWizardPage } from './TemplateWizardPage'; + +jest.mock('react-router-dom', () => { + return { + ...(jest.requireActual('react-router-dom') as any), + useParams: () => ({ + templateName: 'test', + }), + }; +}); + +const scaffolderApiMock: jest.Mocked = { + scaffold: jest.fn(), + getTemplateParameterSchema: jest.fn(), + getIntegrationsList: jest.fn(), + getTask: jest.fn(), + streamLogs: jest.fn(), + listActions: jest.fn(), + listTasks: jest.fn(), +}; + +const analyticsMock = new MockAnalyticsApi(); +const apis = TestApiRegistry.from( + [scaffolderApiRef, scaffolderApiMock], + [analyticsApiRef, analyticsMock], +); + +describe('TemplateWizardPage', () => { + it('captures expected analytics events', async () => { + scaffolderApiMock.scaffold.mockResolvedValue({ taskId: 'xyz' }); + scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue({ + steps: [ + { + title: 'Step 1', + schema: { + properties: { + name: { + type: 'string', + }, + }, + }, + }, + ], + title: 'React JSON Schema Form Test', + }); + + const { findByRole, getByRole } = await renderInTestApp( + + , + , + { + mountedRoutes: { + '/create': nextRouteRef, + '/create-legacy': rootRouteRef, + }, + }, + ); + + // Fill out the name field + fireEvent.change(getByRole('textbox', { name: 'name' }), { + target: { value: 'expected-name' }, + }); + + // Go to the final page + await act(async () => { + fireEvent.click(await findByRole('button', { name: 'Review' })); + }); + + // Create the software + await act(async () => { + fireEvent.click(await findByRole('button', { name: 'Create' })); + }); + + // The "Next Step" button should have fired an event + expect(analyticsMock.getEvents()[0]).toMatchObject({ + action: 'click', + subject: 'Next Step (1)', + context: { entityRef: 'template:default/test' }, + }); + + // And the "Create" button should have fired an event + expect(analyticsMock.getEvents()[1]).toMatchObject({ + action: 'create', + subject: 'expected-name', + context: { entityRef: 'template:default/test' }, + }); + }); +}); diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx index b650e4a676..28dc806214 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx @@ -26,6 +26,7 @@ import { NextFieldExtensionOptions } from '../../extensions'; import { Navigate, useNavigate } from 'react-router'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { + AnalyticsContext, errorApiRef, useApi, useRouteRef, @@ -111,34 +112,36 @@ export const TemplateWizardPage = (props: TemplateWizardPageProps) => { } return ( - -
- - {loading && } - {manifest && ( - + +
+ + {loading && } + {manifest && ( + + } + noPadding + titleTypographyProps={{ component: 'h2' }} + > + - } - noPadding - titleTypographyProps={{ component: 'h2' }} - > - - - )} - - + + )} + + + ); }; From 92a0cbb2f07be3faf9ff39c3fcb3a1ae686ea45d Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Fri, 4 Nov 2022 18:08:45 +0100 Subject: [PATCH 152/434] Fix style in README.md Signed-off-by: Nikita Karpukhin --- plugins/user-settings/README.md | 42 +++++++++++++-------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/plugins/user-settings/README.md b/plugins/user-settings/README.md index ce435ee3ce..c1b50710f4 100644 --- a/plugins/user-settings/README.md +++ b/plugins/user-settings/README.md @@ -18,30 +18,26 @@ for installation instructions. Add the item to the Sidebar: -```ts +```tsx import {Settings as SidebarSettings} from '@backstage/plugin-user-settings'; - - + + < /SidebarPage>; ``` Add the page to the App routing: -```ts -import {UserSettingsPage} from '@backstage/plugin-user-settings'; +```tsx +import { UserSettingsPage } from '@backstage/plugin-user-settings'; const AppRoutes = () => ( - -} -/> -< /Routes> -) -; + } /> + +); ``` ### Props @@ -53,26 +49,22 @@ displayed in the "Authentication Providers" tab. If you want to supply your own custom list of Authentication Providers, use the `providerSettings` prop: -```ts +```tsx const MyAuthProviders = () => ( - - {someAction} < /ListItemSecondaryAction> - < /ListItem> + + {someAction} + ); const AppRoutes = () => ( -} -/>} -/> -< /Routes> -) -; + path="/settings" + element={} />} + /> + +); ``` > **Note that the list of providers expects to be rendered within a MUI [``](https://material-ui.com/components/lists/)** From 031028c2ac225d51278b3dd5885f4255f6e8ae89 Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Fri, 4 Nov 2022 18:18:29 +0100 Subject: [PATCH 153/434] Revert changes in README.md Signed-off-by: Nikita Karpukhin --- plugins/user-settings/README.md | 37 ++++++++++++++++----------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/plugins/user-settings/README.md b/plugins/user-settings/README.md index c1b50710f4..1d15c404e5 100644 --- a/plugins/user-settings/README.md +++ b/plugins/user-settings/README.md @@ -4,14 +4,12 @@ Welcome to the user-settings plugin! ## About the plugin -This plugin provides two components, `` is intended to be used within -the [``](https://backstage.io/storybook/?path=/story/sidebar--sample-sidebar) and displays the signed-in users -profile picture and name. The second component is a settings page where the user can control different settings across -the App. +This plugin provides two components, `` is intended to be used within the [``](https://backstage.io/storybook/?path=/story/sidebar--sample-sidebar) and displays the signed-in users profile picture and name. The second component is a settings page where the user can control different settings across the App. -It also provides a `UserSettingsStorage` implementation of the `StorageApi`, to be used in the frontend as a persistent -alternative to the builtin `WebStorage`. Please -see [the backend README](https://github.com/backstage/backstage/tree/master/plugins/user-settings-backend) +It also provides a `UserSettingsStorage` implementation of the `StorageApi`, to +be used in the frontend as a persistent alternative to the builtin `WebStorage`. +Please see [the backend +README](https://github.com/backstage/backstage/tree/master/plugins/user-settings-backend) for installation instructions. ## Components Usage @@ -19,13 +17,13 @@ for installation instructions. Add the item to the Sidebar: ```tsx -import {Settings as SidebarSettings} from '@backstage/plugin-user-settings'; +import { Settings as SidebarSettings } from '@backstage/plugin-user-settings'; - + -< /SidebarPage>; +; ``` Add the page to the App routing: @@ -44,8 +42,7 @@ const AppRoutes = () => ( **Auth Providers** -By default, the plugin provides a list of configured authentication providers fetched from `app-config.yaml` and -displayed in the "Authentication Providers" tab. +By default, the plugin provides a list of configured authentication providers fetched from `app-config.yaml` and displayed in the "Authentication Providers" tab. If you want to supply your own custom list of Authentication Providers, use the `providerSettings` prop: @@ -53,7 +50,7 @@ If you want to supply your own custom list of Authentication Providers, use the const MyAuthProviders = () => ( - {someAction} + {someAction} ); @@ -73,9 +70,10 @@ const AppRoutes = () => ( By default, the plugin renders 3 tabs of settings; GENERAL, AUTHENTICATION PROVIDERS, and FEATURE FLAGS. -If you want to add more options for your users, just pass the extra tabs using `UserSettingsTab` components as children -of the `UserSettingsPage` route. The path is in this case a child of the settings path, in the example below it would -be `/settings/advanced` so that you can easily link to it. +If you want to add more options for your users, +just pass the extra tabs using `UserSettingsTab` components as children of the `UserSettingsPage` route. +The path is in this case a child of the settings path, +in the example below it would be `/settings/advanced` so that you can easily link to it. ```tsx import { @@ -90,14 +88,15 @@ import { ; ``` -To standardize the UI of all setting tabs, make sure you use a similar component structure as the other tabs. You can -take a look at +To standardize the UI of all setting tabs, +make sure you use a similar component structure as the other tabs. +You can take a look at [the example extra tab](https://github.com/backstage/backstage/blob/master/packages/app/src/components/advancedSettings/AdvancedSettings.tsx) we have created in Backstage's demo app. To change the layout altogether, create a custom page in `packages/app/src/components/user-settings/SettingsPage.tsx`: -```typescript jsx +```tsx import React from 'react'; import { SettingsLayout, From 2b35cf99f9aed5932a0e52f312892dea8cdb682c Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Fri, 4 Nov 2022 18:24:17 +0100 Subject: [PATCH 154/434] Fix diff in README.md Signed-off-by: Nikita Karpukhin --- plugins/user-settings/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/user-settings/README.md b/plugins/user-settings/README.md index 1d15c404e5..09e095a8e0 100644 --- a/plugins/user-settings/README.md +++ b/plugins/user-settings/README.md @@ -127,10 +127,10 @@ Now register the new settings page in `packages/app/src/App.tsx`: const routes = ( - - }/> - + }> - + {settingsPage} - + +- } /> ++ }> ++ {settingsPage} ++ ); ``` From c250fd8f8c74bc4b823109913d7fd2c1be604de8 Mon Sep 17 00:00:00 2001 From: aaron Date: Fri, 4 Nov 2022 14:01:16 -0500 Subject: [PATCH 155/434] Update config.d.ts replacing with "allowlist" for inclusive terminology Signed-off-by: aaron --- plugins/catalog-backend/config.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-backend/config.d.ts b/plugins/catalog-backend/config.d.ts index 950ed2f63c..f90bfa3721 100644 --- a/plugins/catalog-backend/config.d.ts +++ b/plugins/catalog-backend/config.d.ts @@ -25,7 +25,7 @@ export interface Config { * An undefined list of matchers means match all, an empty list of * matchers means match none. * - * This is commonly used to put in what amounts to a whitelist of kinds + * This is commonly used to put in what amounts to a allowlist of kinds * that regular users of Backstage are permitted to register locations * for. This can be used to stop them from registering yaml files * describing for example a Group entity called "admin" that they make From fd80613e2814b6d408f2e47b5230933320eb032f Mon Sep 17 00:00:00 2001 From: aaron Date: Fri, 4 Nov 2022 14:02:41 -0500 Subject: [PATCH 156/434] Update example-schema.json replaced with "allowlist" for more inclusive terminology Signed-off-by: aaron --- plugins/config-schema/dev/example-schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/config-schema/dev/example-schema.json b/plugins/config-schema/dev/example-schema.json index bb90595340..2a722205fc 100644 --- a/plugins/config-schema/dev/example-schema.json +++ b/plugins/config-schema/dev/example-schema.json @@ -665,7 +665,7 @@ "type": "object", "properties": { "rules": { - "description": "Rules to apply to all catalog entities, from any location.\n\nAn undefined list of matchers means match all, an empty list of\nmatchers means match none.\n\nThis is commonly used to put in what amounts to a whitelist of kinds\nthat regular users of Backstage are permitted to register locations\nfor. This can be used to stop them from registering yaml files\ndescribing for example a Group entity called \"admin\" that they make\nthemselves members of, or similar.", + "description": "Rules to apply to all catalog entities, from any location.\n\nAn undefined list of matchers means match all, an empty list of\nmatchers means match none.\n\nThis is commonly used to put in what amounts to an allowlist of kinds\nthat regular users of Backstage are permitted to register locations\nfor. This can be used to stop them from registering yaml files\ndescribing for example a Group entity called \"admin\" that they make\nthemselves members of, or similar.", "type": "array", "items": { "type": "object", From 151df9ac6e051f967153f2cecca8746ec2694baa Mon Sep 17 00:00:00 2001 From: aaron Date: Fri, 4 Nov 2022 14:03:11 -0500 Subject: [PATCH 157/434] Update config.d.ts Signed-off-by: aaron --- plugins/catalog-backend/config.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-backend/config.d.ts b/plugins/catalog-backend/config.d.ts index f90bfa3721..daa70656bc 100644 --- a/plugins/catalog-backend/config.d.ts +++ b/plugins/catalog-backend/config.d.ts @@ -25,7 +25,7 @@ export interface Config { * An undefined list of matchers means match all, an empty list of * matchers means match none. * - * This is commonly used to put in what amounts to a allowlist of kinds + * This is commonly used to put in what amounts to an allowlist of kinds * that regular users of Backstage are permitted to register locations * for. This can be used to stop them from registering yaml files * describing for example a Group entity called "admin" that they make From 8433a1aae3687855f2f26588a880ac3481d59038 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 6 Nov 2022 18:05:52 +0000 Subject: [PATCH 158/434] Update dependency @tanstack/react-query to v4.14.5 Signed-off-by: Renovate Bot --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3cd999c6aa..8e95f4d065 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13042,18 +13042,18 @@ __metadata: languageName: node linkType: hard -"@tanstack/query-core@npm:4.14.1": - version: 4.14.1 - resolution: "@tanstack/query-core@npm:4.14.1" - checksum: 632528627c2d3e8899e4d26ef47c6ff96db6aa1b94683eb2882f2372b6a0e70991f5b0e9729c0ba9e27751c509256453070d78067d5a89db3d7c5dbf9617f777 +"@tanstack/query-core@npm:4.14.5": + version: 4.14.5 + resolution: "@tanstack/query-core@npm:4.14.5" + checksum: 25af0f4999668cd66a4a54c2d2d64dd7002f4852fb901d1d1d64908da4ea43d63e53e512b536987a789039713ffc6ae4ffa2d41cfab676b01704f4937be18a04 languageName: node linkType: hard "@tanstack/react-query@npm:^4.1.3": - version: 4.14.1 - resolution: "@tanstack/react-query@npm:4.14.1" + version: 4.14.5 + resolution: "@tanstack/react-query@npm:4.14.5" dependencies: - "@tanstack/query-core": 4.14.1 + "@tanstack/query-core": 4.14.5 use-sync-external-store: ^1.2.0 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -13064,7 +13064,7 @@ __metadata: optional: true react-native: optional: true - checksum: 52397fedbb30bb5299045a66877c996e4a97f858f93436100fd7accc9731adf9ad61cf5a5e54d20e2f6b60ce7fdb9a2a209f3d5875d49793d758133e88048a10 + checksum: fe98c7900c989512c5818b7aa3c81d81ce2c1149a25e9279f8efcf462a00a156c78c398b5e01c50e5da23788709ed36f8dae4236a51fde459a427a5ece474b0f languageName: node linkType: hard From bbf989ddb4e7ae3fa7acf4a462870599c873ba93 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 6 Nov 2022 18:19:42 +0000 Subject: [PATCH 159/434] Update dependency concurrently to v7.5.0 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3cd999c6aa..6ec8878b25 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18930,8 +18930,8 @@ __metadata: linkType: hard "concurrently@npm:^7.0.0": - version: 7.4.0 - resolution: "concurrently@npm:7.4.0" + version: 7.5.0 + resolution: "concurrently@npm:7.5.0" dependencies: chalk: ^4.1.0 date-fns: ^2.29.1 @@ -18945,7 +18945,7 @@ __metadata: bin: conc: dist/bin/concurrently.js concurrently: dist/bin/concurrently.js - checksum: cc547866ad8d009d184ca3a7115d6636052a5f56f5429d123092d651286043d7233f6429257e30e50f509894cd12798ea831896ac18092d8135f67ffcc8ac3ea + checksum: 7886e1c8559d2699ae1b62be8aca5d56c226966e252a2b9dd6077b3c1fd5397e98ef537c040fffa1de50418bd2616746eb9dd589a31ffb9056d4758b850a865b languageName: node linkType: hard From 34b772ef319e7c9fc833147efe8fa0b36c93e21c Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Sun, 6 Nov 2022 19:52:56 +0100 Subject: [PATCH 160/434] feat(splunk-on-call): use routing key instead of team name for triggered incidents Use the routing key if it's available instead of team name when triggering incidents. BREAKING CHANGE: Before, the team name was used even if the routing key (with or without team) was used. Now, the routing key defined for the component will be used instead of the team name. Closes: #14453 Signed-off-by: Patrick Jungermann --- .changeset/funny-singers-serve.md | 9 +++ .../EntitySplunkOnCallCard.test.tsx | 35 ++++++++--- .../src/components/EntitySplunkOnCallCard.tsx | 30 ++++++--- .../TriggerDialog/TriggerDialog.test.tsx | 44 +++---------- .../TriggerDialog/TriggerDialog.tsx | 10 +-- .../src/components/TriggerDialog/testUtils.ts | 62 +++++++++++++++++++ 6 files changed, 129 insertions(+), 61 deletions(-) create mode 100644 .changeset/funny-singers-serve.md create mode 100644 plugins/splunk-on-call/src/components/TriggerDialog/testUtils.ts diff --git a/.changeset/funny-singers-serve.md b/.changeset/funny-singers-serve.md new file mode 100644 index 0000000000..5812bdf5e3 --- /dev/null +++ b/.changeset/funny-singers-serve.md @@ -0,0 +1,9 @@ +--- +'@backstage/plugin-splunk-on-call': minor +--- + +Use the routing key if it's available instead of team name when triggering incidents. + +BREAKING CHANGE: +Before, the team name was used even if the routing key (with or without team) was used. +Now, the routing key defined for the component will be used instead of the team name. diff --git a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx index 0688fb8237..051d9de030 100644 --- a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx +++ b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx @@ -13,11 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react'; -import { act, fireEvent, render, waitFor } from '@testing-library/react'; import { Entity } from '@backstage/catalog-model'; +import { ApiProvider, ConfigReader } from '@backstage/core-app-api'; +import { + alertApiRef, + ConfigApi, + configApiRef, +} from '@backstage/core-plugin-api'; import { EntityProvider } from '@backstage/plugin-catalog-react'; import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils'; +import { act, fireEvent, render, waitFor } from '@testing-library/react'; +import React from 'react'; import { splunkOnCallApiRef, SplunkOnCallClient, @@ -33,13 +39,7 @@ import { MOCK_TEAM_NO_INCIDENTS, } from '../api/mocks'; import { EntitySplunkOnCallCard } from './EntitySplunkOnCallCard'; - -import { - alertApiRef, - ConfigApi, - configApiRef, -} from '@backstage/core-plugin-api'; -import { ApiProvider, ConfigReader } from '@backstage/core-app-api'; +import { expectTriggeredIncident } from './TriggerDialog/testUtils'; const mockSplunkOnCallApi: Partial = { getUsers: async () => [], @@ -167,8 +167,10 @@ describe('SplunkOnCallCard', () => { mockSplunkOnCallApi.getTeams = jest .fn() .mockImplementation(async () => [MOCK_TEAM]); + const mockTriggerAlarmFn = jest.fn(); + mockSplunkOnCallApi.incidentAction = mockTriggerAlarmFn; - const { getByText, queryByTestId } = render( + const { getByRole, getByTestId, getByText, queryByTestId } = render( wrapInTestApp( @@ -179,10 +181,23 @@ describe('SplunkOnCallCard', () => { ); await waitFor(() => !queryByTestId('progress')); expect(getByText(`Team: ${MOCK_TEAM.name}`)).toBeInTheDocument(); + expect(getByText('Create Incident')).toBeInTheDocument(); await waitFor( () => expect(getByText('test-incident')).toBeInTheDocument(), { timeout: 2000 }, ); + + const createIncidentButton = await getByText('Create Incident'); + await act(async () => { + fireEvent.click(createIncidentButton); + }); + expect(getByRole('dialog')).toBeInTheDocument(); + + await expectTriggeredIncident( + 'test-routing-key', + getByTestId, + mockTriggerAlarmFn, + ); }); it('Handles custom error for missing token', async () => { diff --git a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx index d635f7328f..26521ea9ee 100644 --- a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx +++ b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx @@ -29,11 +29,11 @@ import AlarmAddIcon from '@material-ui/icons/AlarmAdd'; import WebIcon from '@material-ui/icons/Web'; import { Alert } from '@material-ui/lab'; import { splunkOnCallApiRef, UnauthorizedError } from '../api'; -import { MissingApiKeyOrApiIdError } from './Errors/MissingApiKeyOrApiIdError'; +import { MissingApiKeyOrApiIdError } from './Errors'; import { EscalationPolicy } from './Escalation'; import { Incidents } from './Incident'; import { TriggerDialog } from './TriggerDialog'; -import { Team, User } from './types'; +import { RoutingKey, Team, User } from './types'; import { configApiRef, useApi } from '@backstage/core-plugin-api'; import { @@ -143,7 +143,7 @@ export const EntitySplunkOnCallCard = (props: EntitySplunkOnCallCardProps) => { }, []); const { - value: usersAndTeams, + value: entityData, loading, error, } = useAsync(async () => { @@ -162,11 +162,15 @@ export const EntitySplunkOnCallCard = (props: EntitySplunkOnCallCardProps) => { teams.find(teamValue => teamValue.name === teamAnnotation), ].filter(team => team !== undefined); - if (!foundTeams.length && routingKeyAnnotation) { + let foundRoutingKey: RoutingKey | undefined; + if (routingKeyAnnotation) { const routingKeys = await api.getRoutingKeys(); - const foundRoutingKey = routingKeys.find( + foundRoutingKey = routingKeys.find( key => key.routingKey === routingKeyAnnotation, ); + } + + if (!foundTeams.length) { foundTeams = foundRoutingKey ? foundRoutingKey.targets .map(target => { @@ -179,7 +183,7 @@ export const EntitySplunkOnCallCard = (props: EntitySplunkOnCallCardProps) => { : []; } - return { usersHashMap, foundTeams }; + return { usersHashMap, foundTeams, foundRoutingKey }; }); if (!teamAnnotation && !routingKeyAnnotation) { @@ -206,7 +210,7 @@ export const EntitySplunkOnCallCard = (props: EntitySplunkOnCallCardProps) => { return ; } - if (!usersAndTeams?.foundTeams || !usersAndTeams?.foundTeams.length) { + if (!entityData?.foundTeams || !entityData?.foundTeams.length) { return ( { const Content = ({ team, + routingKey, usersHashMap, }: { team: Team | undefined; + routingKey: RoutingKey | undefined; usersHashMap: any; }) => { const teamName = team?.name ?? ''; @@ -235,7 +241,7 @@ export const EntitySplunkOnCallCard = (props: EntitySplunkOnCallCardProps) => { )} { icon: , }; - const teams = usersAndTeams?.foundTeams || []; + const teams = entityData?.foundTeams || []; return ( <> @@ -277,7 +283,11 @@ export const EntitySplunkOnCallCard = (props: EntitySplunkOnCallCardProps) => { /> - + ))} 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 0b64a137af..3bfbddb0e4 100644 --- a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.test.tsx +++ b/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.test.tsx @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react'; -import { render, fireEvent, act } from '@testing-library/react'; -import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils'; -import { splunkOnCallApiRef } from '../../api'; -import { TriggerDialog } from './TriggerDialog'; - import { ApiProvider } from '@backstage/core-app-api'; import { alertApiRef } from '@backstage/core-plugin-api'; +import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils'; +import { render } from '@testing-library/react'; +import React from 'react'; +import { splunkOnCallApiRef } from '../../api'; +import { TriggerDialog } from './TriggerDialog'; +import { expectTriggeredIncident } from './testUtils'; describe('TriggerDialog', () => { const mockTriggerAlarmFn = jest.fn(); @@ -38,7 +38,7 @@ describe('TriggerDialog', () => { wrapInTestApp( {}} onIncidentCreated={() => {}} @@ -53,34 +53,6 @@ describe('TriggerDialog', () => { exact: false, }), ).toBeInTheDocument(); - const incidentType = getByTestId('trigger-incident-type'); - const incidentId = getByTestId('trigger-incident-id'); - const incidentDisplayName = getByTestId('trigger-incident-displayName'); - const incidentMessage = getByTestId('trigger-incident-message'); - - await act(async () => { - fireEvent.change(incidentType, { target: { value: 'CRITICAL' } }); - fireEvent.change(incidentId, { target: { value: 'incident-id' } }); - fireEvent.change(incidentDisplayName, { - target: { value: 'incident-display-name' }, - }); - fireEvent.change(incidentMessage, { - target: { value: 'incident-message' }, - }); - }); - - // Trigger incident creation button - const triggerButton = getByTestId('trigger-button'); - await act(async () => { - fireEvent.click(triggerButton); - }); - expect(mockTriggerAlarmFn).toHaveBeenCalled(); - expect(mockTriggerAlarmFn).toHaveBeenCalledWith({ - incidentType: 'CRITICAL', - incidentId: 'incident-id', - routingKey: 'Example', - incidentDisplayName: 'incident-display-name', - incidentMessage: 'incident-message', - }); + await expectTriggeredIncident('Example', getByTestId, mockTriggerAlarmFn); }); }); diff --git a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx b/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx index 82dd2da74d..dd8f0b1909 100644 --- a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx +++ b/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx @@ -35,11 +35,11 @@ import { import useAsyncFn from 'react-use/lib/useAsyncFn'; import { splunkOnCallApiRef } from '../../api'; import { Alert } from '@material-ui/lab'; -import { TriggerAlarmRequest } from '../../api/types'; +import { TriggerAlarmRequest } from '../../api'; import { useApi, alertApiRef } from '@backstage/core-plugin-api'; type Props = { - team: string; + routingKey: string; showDialog: boolean; handleDialog: () => void; onIncidentCreated: () => void; @@ -76,7 +76,7 @@ const useStyles = makeStyles((theme: Theme) => ); export const TriggerDialog = ({ - team, + routingKey, showDialog, handleDialog, onIncidentCreated: onIncidentCreated, @@ -221,7 +221,7 @@ export const TriggerDialog = ({ id="details" multiline fullWidth - rows="2" + minRows="2" margin="normal" label="Incident message" variant="outlined" @@ -242,7 +242,7 @@ export const TriggerDialog = ({ variant="contained" onClick={() => handleTriggerAlarm({ - routingKey: team, + routingKey, incidentType, incidentDisplayName, incidentMessage, diff --git a/plugins/splunk-on-call/src/components/TriggerDialog/testUtils.ts b/plugins/splunk-on-call/src/components/TriggerDialog/testUtils.ts new file mode 100644 index 0000000000..764ac94e2c --- /dev/null +++ b/plugins/splunk-on-call/src/components/TriggerDialog/testUtils.ts @@ -0,0 +1,62 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// eslint-disable-next-line import/no-extraneous-dependencies +import { + act, + fireEvent, + Matcher, + MatcherOptions, +} from '@testing-library/react'; + +export async function expectTriggeredIncident( + routingKey: string, + getByTestId: ( + id: Matcher, + options?: MatcherOptions | undefined, + ) => HTMLElement, + mockTriggerAlarmFn: any, +): Promise { + const incidentType = getByTestId('trigger-incident-type'); + const incidentId = getByTestId('trigger-incident-id'); + const incidentDisplayName = getByTestId('trigger-incident-displayName'); + const incidentMessage = getByTestId('trigger-incident-message'); + + await act(async () => { + fireEvent.change(incidentType, { target: { value: 'CRITICAL' } }); + fireEvent.change(incidentId, { target: { value: 'incident-id' } }); + fireEvent.change(incidentDisplayName, { + target: { value: 'incident-display-name' }, + }); + fireEvent.change(incidentMessage, { + target: { value: 'incident-message' }, + }); + }); + + // Trigger incident creation button + const triggerButton = getByTestId('trigger-button'); + await act(async () => { + fireEvent.click(triggerButton); + }); + + expect(mockTriggerAlarmFn).toHaveBeenCalled(); + expect(mockTriggerAlarmFn).toHaveBeenCalledWith({ + incidentType: 'CRITICAL', + incidentId: 'incident-id', + routingKey: routingKey, + incidentDisplayName: 'incident-display-name', + incidentMessage: 'incident-message', + }); +} From b9b2dc8743538c4b1ff6d1a217286f1dab090e68 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 6 Nov 2022 19:07:34 +0000 Subject: [PATCH 161/434] Update dependency core-js to v3.26.0 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 557a3585c1..6a7634a230 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19144,9 +19144,9 @@ __metadata: linkType: hard "core-js@npm:^3.6.5": - version: 3.25.5 - resolution: "core-js@npm:3.25.5" - checksum: 208b308c49bc022f90d4349d4c99802a73c9d55053976b3c529f10014c1e37845926defad8c519f2c7f71ea0acf18d2b323ab6aaee34dc85b4c4b3ced0623f3f + version: 3.26.0 + resolution: "core-js@npm:3.26.0" + checksum: 0149eb9d3909fde9c17626af3a6e625c326e8598d0bb5e6c5b48a18e5fcd4eaf48d4964d873667d8148542ff590fb98eb3f93618da114ca54999d6bc0349734b languageName: node linkType: hard From da0bf25d1a893f1c0ecb19df0431c60f83874781 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Sun, 6 Nov 2022 20:39:12 +0100 Subject: [PATCH 162/434] feat(catalog-graph): preserve entity graph options + increment max depth Currently, all configuration options for the `CatalogGraphCard` are lost at the "View Graph" link at the bottom which opens the full graph view using the current entity as root entity. Esp. for `maxDepth` the default was Infinite / no limit. The change will preserve options used at the `CatalogGraphCard` (displayed at the entity page) and additionally, increments the `maxDepth` option by 1 to increase the scope slightly compared to the graph already seen by the users. The default for `maxDepth` at `CatalogGraphCard` is 1. Closes: #14462 Signed-off-by: Patrick Jungermann --- .changeset/hungry-kiwis-scream.md | 12 +++++++++ .../CatalogGraphCard.test.tsx | 26 ++++++++++++++++++- .../CatalogGraphCard/CatalogGraphCard.tsx | 10 ++++++- 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 .changeset/hungry-kiwis-scream.md diff --git a/.changeset/hungry-kiwis-scream.md b/.changeset/hungry-kiwis-scream.md new file mode 100644 index 0000000000..f11125b8c0 --- /dev/null +++ b/.changeset/hungry-kiwis-scream.md @@ -0,0 +1,12 @@ +--- +'@backstage/plugin-catalog-graph': patch +--- + +Preserve graph options and increment `maxDepth` by 1. + +The change will preserve options used at the `CatalogGraphCard` +(displayed at the entity page) and additionally, increments the +`maxDepth` option by 1 to increase the scope slightly compared to +the graph already seen by the users. + +The default for `maxDepth` at `CatalogGraphCard` is 1. diff --git a/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.test.tsx b/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.test.tsx index 74fcd4e501..7cd6d29bbc 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.test.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.test.tsx @@ -116,7 +116,31 @@ describe('', () => { expect(button).toBeInTheDocument(); expect(button.closest('a')).toHaveAttribute( 'href', - '/catalog-graph?rootEntityRefs%5B%5D=b%3Ad%2Fc', + '/catalog-graph?rootEntityRefs%5B%5D=b%3Ad%2Fc&maxDepth=2&unidirectional=true&mergeRelations=true&direction=LR', + ); + }); + + test('renders link to standalone viewer with custom config', async () => { + const { findByText, getByText } = await renderInTestApp( + + + + + , + { + mountedRoutes: { + '/entity/{kind}/{namespace}/{name}': entityRouteRef, + '/catalog-graph': catalogGraphRouteRef, + }, + }, + ); + + expect(await findByText('b:d/c')).toBeInTheDocument(); + const button = getByText('View graph'); + expect(button).toBeInTheDocument(); + expect(button.closest('a')).toHaveAttribute( + 'href', + '/catalog-graph?rootEntityRefs%5B%5D=b%3Ad%2Fc&maxDepth=3&unidirectional=true&mergeRelations=false&direction=LR', ); }); diff --git a/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.tsx b/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.tsx index ae1ca9c22d..5cb86db69f 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.tsx @@ -106,7 +106,15 @@ export const CatalogGraphCard = (props: { ); const catalogGraphParams = qs.stringify( - { rootEntityRefs: [stringifyEntityRef(entity)] }, + { + rootEntityRefs: [stringifyEntityRef(entity)], + maxDepth: maxDepth + 1, + unidirectional, + mergeRelations, + kinds, + relations, + direction, + }, { arrayFormat: 'brackets', addQueryPrefix: true }, ); const catalogGraphUrl = `${catalogGraphRoute()}${catalogGraphParams}`; From aa857ffa49e521da3c799fd1911b5b70ae1f365f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 6 Nov 2022 21:38:43 +0000 Subject: [PATCH 163/434] Update dependency cypress to v10.11.0 Signed-off-by: Renovate Bot --- cypress/yarn.lock | 6 +++--- yarn.lock | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cypress/yarn.lock b/cypress/yarn.lock index 3b1358156e..07249a29fc 100644 --- a/cypress/yarn.lock +++ b/cypress/yarn.lock @@ -414,8 +414,8 @@ __metadata: linkType: hard "cypress@npm:^10.0.0": - version: 10.10.0 - resolution: "cypress@npm:10.10.0" + version: 10.11.0 + resolution: "cypress@npm:10.11.0" dependencies: "@cypress/request": ^2.88.10 "@cypress/xvfb": ^1.2.4 @@ -461,7 +461,7 @@ __metadata: yauzl: ^2.10.0 bin: cypress: bin/cypress - checksum: 668a32534a527dba79754abbf98af176b80c539a12ec00058932ba2a19c794c7888323e59e738c30f726ad740c5451c31d02548a0cb7c1b1c8ad01c55a984ca2 + checksum: 938cc6a20f7eeace5c8e850d234904ee1651cbb36d94666fe600cf17ce964e73d4f7d8d944aab677491702a57364e6aceeb4fe8bcbd96147ff5e2b575a956fb2 languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index 557a3585c1..0f6b2375ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19723,8 +19723,8 @@ __metadata: linkType: hard "cypress@npm:^10.0.0": - version: 10.10.0 - resolution: "cypress@npm:10.10.0" + version: 10.11.0 + resolution: "cypress@npm:10.11.0" dependencies: "@cypress/request": ^2.88.10 "@cypress/xvfb": ^1.2.4 @@ -19770,7 +19770,7 @@ __metadata: yauzl: ^2.10.0 bin: cypress: bin/cypress - checksum: 668a32534a527dba79754abbf98af176b80c539a12ec00058932ba2a19c794c7888323e59e738c30f726ad740c5451c31d02548a0cb7c1b1c8ad01c55a984ca2 + checksum: 938cc6a20f7eeace5c8e850d234904ee1651cbb36d94666fe600cf17ce964e73d4f7d8d944aab677491702a57364e6aceeb4fe8bcbd96147ff5e2b575a956fb2 languageName: node linkType: hard From 969a8444ea34f66c06195234398b2f4e42d0d46c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 6 Nov 2022 21:39:27 +0000 Subject: [PATCH 164/434] Update dependency esbuild to ^0.15.0 Signed-off-by: Renovate Bot --- .changeset/renovate-25512c2.md | 6 + packages/cli/package.json | 2 +- plugins/scaffolder-backend/package.json | 2 +- yarn.lock | 190 +++++++++++++----------- 4 files changed, 108 insertions(+), 92 deletions(-) create mode 100644 .changeset/renovate-25512c2.md diff --git a/.changeset/renovate-25512c2.md b/.changeset/renovate-25512c2.md new file mode 100644 index 0000000000..64690469d3 --- /dev/null +++ b/.changeset/renovate-25512c2.md @@ -0,0 +1,6 @@ +--- +'@backstage/cli': patch +'@backstage/plugin-scaffolder-backend': patch +--- + +Updated dependency `esbuild` to `^0.15.0`. diff --git a/packages/cli/package.json b/packages/cli/package.json index b62d3f8691..9eb6bed3d6 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -68,7 +68,7 @@ "commander": "^9.1.0", "css-loader": "^6.5.1", "diff": "^5.0.0", - "esbuild": "^0.14.10", + "esbuild": "^0.15.0", "esbuild-loader": "^2.18.0", "eslint": "^8.6.0", "eslint-config-prettier": "^8.3.0", diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index a52adf1cf7..816704705e 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -90,7 +90,7 @@ "@types/nunjucks": "^3.1.4", "@types/supertest": "^2.0.8", "@types/zen-observable": "^0.8.0", - "esbuild": "^0.14.1", + "esbuild": "^0.15.0", "jest-when": "^3.1.0", "mock-fs": "^5.1.0", "msw": "^0.47.0", diff --git a/yarn.lock b/yarn.lock index 557a3585c1..eda7012f71 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3422,7 +3422,7 @@ __metadata: css-loader: ^6.5.1 del: ^6.0.0 diff: ^5.0.0 - esbuild: ^0.14.10 + esbuild: ^0.15.0 esbuild-loader: ^2.18.0 eslint: ^8.6.0 eslint-config-prettier: ^8.3.0 @@ -6895,7 +6895,7 @@ __metadata: command-exists: ^1.2.9 compression: ^1.7.4 cors: ^2.8.5 - esbuild: ^0.14.1 + esbuild: ^0.15.0 express: ^4.17.1 express-promise-router: ^4.1.0 fs-extra: 10.1.0 @@ -8567,6 +8567,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.15.13": + version: 0.15.13 + resolution: "@esbuild/android-arm@npm:0.15.13" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.15.8": version: 0.15.8 resolution: "@esbuild/android-arm@npm:0.15.8" @@ -8576,9 +8583,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.14.54": - version: 0.14.54 - resolution: "@esbuild/linux-loong64@npm:0.14.54" +"@esbuild/linux-loong64@npm:0.15.13": + version: 0.15.13 + resolution: "@esbuild/linux-loong64@npm:0.15.13" conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -21240,9 +21247,9 @@ __metadata: languageName: node linkType: hard -"esbuild-android-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-android-64@npm:0.14.54" +"esbuild-android-64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-android-64@npm:0.15.13" conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -21256,9 +21263,9 @@ __metadata: languageName: node linkType: hard -"esbuild-android-arm64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-android-arm64@npm:0.14.54" +"esbuild-android-arm64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-android-arm64@npm:0.15.13" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -21270,9 +21277,9 @@ __metadata: languageName: node linkType: hard -"esbuild-darwin-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-darwin-64@npm:0.14.54" +"esbuild-darwin-64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-darwin-64@npm:0.15.13" conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -21284,9 +21291,9 @@ __metadata: languageName: node linkType: hard -"esbuild-darwin-arm64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-darwin-arm64@npm:0.14.54" +"esbuild-darwin-arm64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-darwin-arm64@npm:0.15.13" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -21298,9 +21305,9 @@ __metadata: languageName: node linkType: hard -"esbuild-freebsd-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-freebsd-64@npm:0.14.54" +"esbuild-freebsd-64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-freebsd-64@npm:0.15.13" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -21312,9 +21319,9 @@ __metadata: languageName: node linkType: hard -"esbuild-freebsd-arm64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-freebsd-arm64@npm:0.14.54" +"esbuild-freebsd-arm64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-freebsd-arm64@npm:0.15.13" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -21326,9 +21333,9 @@ __metadata: languageName: node linkType: hard -"esbuild-linux-32@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-32@npm:0.14.54" +"esbuild-linux-32@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-linux-32@npm:0.15.13" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -21340,9 +21347,9 @@ __metadata: languageName: node linkType: hard -"esbuild-linux-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-64@npm:0.14.54" +"esbuild-linux-64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-linux-64@npm:0.15.13" conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -21354,9 +21361,9 @@ __metadata: languageName: node linkType: hard -"esbuild-linux-arm64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-arm64@npm:0.14.54" +"esbuild-linux-arm64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-linux-arm64@npm:0.15.13" conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -21368,9 +21375,9 @@ __metadata: languageName: node linkType: hard -"esbuild-linux-arm@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-arm@npm:0.14.54" +"esbuild-linux-arm@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-linux-arm@npm:0.15.13" conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -21382,9 +21389,9 @@ __metadata: languageName: node linkType: hard -"esbuild-linux-mips64le@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-mips64le@npm:0.14.54" +"esbuild-linux-mips64le@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-linux-mips64le@npm:0.15.13" conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -21396,9 +21403,9 @@ __metadata: languageName: node linkType: hard -"esbuild-linux-ppc64le@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-ppc64le@npm:0.14.54" +"esbuild-linux-ppc64le@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-linux-ppc64le@npm:0.15.13" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -21410,9 +21417,9 @@ __metadata: languageName: node linkType: hard -"esbuild-linux-riscv64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-riscv64@npm:0.14.54" +"esbuild-linux-riscv64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-linux-riscv64@npm:0.15.13" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -21424,9 +21431,9 @@ __metadata: languageName: node linkType: hard -"esbuild-linux-s390x@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-s390x@npm:0.14.54" +"esbuild-linux-s390x@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-linux-s390x@npm:0.15.13" conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -21454,9 +21461,9 @@ __metadata: languageName: node linkType: hard -"esbuild-netbsd-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-netbsd-64@npm:0.14.54" +"esbuild-netbsd-64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-netbsd-64@npm:0.15.13" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -21468,9 +21475,9 @@ __metadata: languageName: node linkType: hard -"esbuild-openbsd-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-openbsd-64@npm:0.14.54" +"esbuild-openbsd-64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-openbsd-64@npm:0.15.13" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -21482,9 +21489,9 @@ __metadata: languageName: node linkType: hard -"esbuild-sunos-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-sunos-64@npm:0.14.54" +"esbuild-sunos-64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-sunos-64@npm:0.15.13" conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -21505,9 +21512,9 @@ __metadata: languageName: node linkType: hard -"esbuild-windows-32@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-windows-32@npm:0.14.54" +"esbuild-windows-32@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-windows-32@npm:0.15.13" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -21519,9 +21526,9 @@ __metadata: languageName: node linkType: hard -"esbuild-windows-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-windows-64@npm:0.14.54" +"esbuild-windows-64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-windows-64@npm:0.15.13" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -21533,9 +21540,9 @@ __metadata: languageName: node linkType: hard -"esbuild-windows-arm64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-windows-arm64@npm:0.14.54" +"esbuild-windows-arm64@npm:0.15.13": + version: 0.15.13 + resolution: "esbuild-windows-arm64@npm:0.15.13" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -21547,32 +21554,35 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.14.1, esbuild@npm:^0.14.10": - version: 0.14.54 - resolution: "esbuild@npm:0.14.54" +"esbuild@npm:^0.15.0": + version: 0.15.13 + resolution: "esbuild@npm:0.15.13" dependencies: - "@esbuild/linux-loong64": 0.14.54 - esbuild-android-64: 0.14.54 - esbuild-android-arm64: 0.14.54 - esbuild-darwin-64: 0.14.54 - esbuild-darwin-arm64: 0.14.54 - esbuild-freebsd-64: 0.14.54 - esbuild-freebsd-arm64: 0.14.54 - esbuild-linux-32: 0.14.54 - esbuild-linux-64: 0.14.54 - esbuild-linux-arm: 0.14.54 - esbuild-linux-arm64: 0.14.54 - esbuild-linux-mips64le: 0.14.54 - esbuild-linux-ppc64le: 0.14.54 - esbuild-linux-riscv64: 0.14.54 - esbuild-linux-s390x: 0.14.54 - esbuild-netbsd-64: 0.14.54 - esbuild-openbsd-64: 0.14.54 - esbuild-sunos-64: 0.14.54 - esbuild-windows-32: 0.14.54 - esbuild-windows-64: 0.14.54 - esbuild-windows-arm64: 0.14.54 + "@esbuild/android-arm": 0.15.13 + "@esbuild/linux-loong64": 0.15.13 + esbuild-android-64: 0.15.13 + esbuild-android-arm64: 0.15.13 + esbuild-darwin-64: 0.15.13 + esbuild-darwin-arm64: 0.15.13 + esbuild-freebsd-64: 0.15.13 + esbuild-freebsd-arm64: 0.15.13 + esbuild-linux-32: 0.15.13 + esbuild-linux-64: 0.15.13 + esbuild-linux-arm: 0.15.13 + esbuild-linux-arm64: 0.15.13 + esbuild-linux-mips64le: 0.15.13 + esbuild-linux-ppc64le: 0.15.13 + esbuild-linux-riscv64: 0.15.13 + esbuild-linux-s390x: 0.15.13 + esbuild-netbsd-64: 0.15.13 + esbuild-openbsd-64: 0.15.13 + esbuild-sunos-64: 0.15.13 + esbuild-windows-32: 0.15.13 + esbuild-windows-64: 0.15.13 + esbuild-windows-arm64: 0.15.13 dependenciesMeta: + "@esbuild/android-arm": + optional: true "@esbuild/linux-loong64": optional: true esbuild-android-64: @@ -21617,7 +21627,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 49e360b1185c797f5ca3a7f5f0a75121494d97ddf691f65ed1796e6257d318f928342a97f559bb8eced6a90cf604dd22db4a30e0dbbf15edd9dbf22459b639af + checksum: ef5f339fae7e2abc4ec5484d4b301efdf40f580e043cbf8a66e19d6c91df82368a810abec61fd5e5db226f0c354f49c36616c9ea04c5412a142a050c10239bf7 languageName: node linkType: hard From a97bc93775276f7c37f76c9a637f875c72c8f117 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 6 Nov 2022 21:40:23 +0000 Subject: [PATCH 165/434] Update dependency eslint to v8.27.0 Signed-off-by: Renovate Bot --- yarn.lock | 72 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/yarn.lock b/yarn.lock index 557a3585c1..acb412b39e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8590,9 +8590,9 @@ __metadata: languageName: node linkType: hard -"@eslint/eslintrc@npm:^1.3.2": - version: 1.3.2 - resolution: "@eslint/eslintrc@npm:1.3.2" +"@eslint/eslintrc@npm:^1.3.3": + version: 1.3.3 + resolution: "@eslint/eslintrc@npm:1.3.3" dependencies: ajv: ^6.12.4 debug: ^4.3.2 @@ -8603,7 +8603,7 @@ __metadata: js-yaml: ^4.1.0 minimatch: ^3.1.2 strip-json-comments: ^3.1.1 - checksum: 2074dca47d7e1c5c6323ff353f690f4b25d3ab53fe7d27337e2592d37a894cf60ca0e85ca66b50ff2db0bc7e630cc1e9c7347d65bb185b61416565584c38999c + checksum: f03e9d6727efd3e0719da2051ea80c0c73d20e28c171121527dbb868cd34232ca9c1d0525a66e517a404afea26624b1e47895b6a92474678418c2f50c9566694 languageName: node linkType: hard @@ -9671,21 +9671,14 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.10.4": - version: 0.10.4 - resolution: "@humanwhocodes/config-array@npm:0.10.4" +"@humanwhocodes/config-array@npm:^0.11.6": + version: 0.11.7 + resolution: "@humanwhocodes/config-array@npm:0.11.7" dependencies: "@humanwhocodes/object-schema": ^1.2.1 debug: ^4.1.1 - minimatch: ^3.0.4 - checksum: d480e5d57e6d787565b6cff78e27c3d1b380692d4ffb0ada7d7f5957a56c9032f034da05a3e443065dbd0671ebf4d859036ced34e96b325bbc1badbae3c05300 - languageName: node - linkType: hard - -"@humanwhocodes/gitignore-to-minimatch@npm:^1.0.2": - version: 1.0.2 - resolution: "@humanwhocodes/gitignore-to-minimatch@npm:1.0.2" - checksum: aba5c40c9e3770ed73a558b0bfb53323842abfc2ce58c91d7e8b1073995598e6374456d38767be24ab6176915f0a8d8b23eaae5c85e2b488c0dccca6d795e2ad + minimatch: ^3.0.5 + checksum: cf506dc45d9488af7fbf108ea6ac2151ba1a25e6d2b94b9b4fc36d2c1e4099b89ff560296dbfa13947e44604d4ca4a90d97a4fb167370bf8dd01a6ca2b6d83ac languageName: node linkType: hard @@ -11239,6 +11232,16 @@ __metadata: languageName: node linkType: hard +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": 2.0.5 + run-parallel: ^1.1.9 + checksum: a970d595bd23c66c880e0ef1817791432dbb7acbb8d44b7e7d0e7a22f4521260d4a83f7f9fd61d44fda4610105577f8f58a60718105fb38352baed612fd79e59 + languageName: node + linkType: hard + "@nodelib/fs.stat@npm:2.0.3, @nodelib/fs.stat@npm:^2.0.2": version: 2.0.3 resolution: "@nodelib/fs.stat@npm:2.0.3" @@ -11246,6 +11249,13 @@ __metadata: languageName: node linkType: hard +"@nodelib/fs.stat@npm:2.0.5": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 + languageName: node + linkType: hard + "@nodelib/fs.walk@npm:^1.2.3": version: 1.2.4 resolution: "@nodelib/fs.walk@npm:1.2.4" @@ -11256,6 +11266,16 @@ __metadata: languageName: node linkType: hard +"@nodelib/fs.walk@npm:^1.2.8": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": 2.1.5 + fastq: ^1.6.0 + checksum: 190c643f156d8f8f277bf2a6078af1ffde1fd43f498f187c2db24d35b4b4b5785c02c7dc52e356497b9a1b65b13edc996de08de0b961c32844364da02986dc53 + languageName: node + linkType: hard + "@npmcli/arborist@npm:^4.0.4": version: 4.3.1 resolution: "@npmcli/arborist@npm:4.3.1" @@ -22033,13 +22053,13 @@ __metadata: linkType: hard "eslint@npm:^8.6.0": - version: 8.23.1 - resolution: "eslint@npm:8.23.1" + version: 8.27.0 + resolution: "eslint@npm:8.27.0" dependencies: - "@eslint/eslintrc": ^1.3.2 - "@humanwhocodes/config-array": ^0.10.4 - "@humanwhocodes/gitignore-to-minimatch": ^1.0.2 + "@eslint/eslintrc": ^1.3.3 + "@humanwhocodes/config-array": ^0.11.6 "@humanwhocodes/module-importer": ^1.0.1 + "@nodelib/fs.walk": ^1.2.8 ajv: ^6.10.0 chalk: ^4.0.0 cross-spawn: ^7.0.2 @@ -22055,14 +22075,14 @@ __metadata: fast-deep-equal: ^3.1.3 file-entry-cache: ^6.0.1 find-up: ^5.0.0 - glob-parent: ^6.0.1 + glob-parent: ^6.0.2 globals: ^13.15.0 - globby: ^11.1.0 grapheme-splitter: ^1.0.4 ignore: ^5.2.0 import-fresh: ^3.0.0 imurmurhash: ^0.1.4 is-glob: ^4.0.0 + is-path-inside: ^3.0.3 js-sdsl: ^4.1.4 js-yaml: ^4.1.0 json-stable-stringify-without-jsonify: ^1.0.1 @@ -22077,7 +22097,7 @@ __metadata: text-table: ^0.2.0 bin: eslint: bin/eslint.js - checksum: a727e15492786a03b438bcf021db49f715680679846a7b8d79b98ad34576f2a570404ffe882d3c3e26f6359bff7277ef11fae5614bfe8629adb653f20d018c71 + checksum: 153b022d309e1b647a73b1bb0fa98912add699b06e279084155f23c6f2b5fc5abd05411fc1ba81608a24bbfaf044ca079544c16fffa6fc987b8f676c9960a2c4 languageName: node linkType: hard @@ -23861,7 +23881,7 @@ __metadata: languageName: node linkType: hard -"glob-parent@npm:^6.0.1": +"glob-parent@npm:^6.0.2": version: 6.0.2 resolution: "glob-parent@npm:6.0.2" dependencies: @@ -26001,7 +26021,7 @@ __metadata: languageName: node linkType: hard -"is-path-inside@npm:^3.0.2": +"is-path-inside@npm:^3.0.2, is-path-inside@npm:^3.0.3": version: 3.0.3 resolution: "is-path-inside@npm:3.0.3" checksum: abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 From 29c6e465f63663c04ef855285c2967d36a924116 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 00:16:44 +0000 Subject: [PATCH 166/434] Update dependency @keyv/redis to v2.5.3 Signed-off-by: Renovate Bot --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index acb412b39e..338d171216 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10656,11 +10656,11 @@ __metadata: linkType: hard "@keyv/redis@npm:^2.2.3": - version: 2.5.2 - resolution: "@keyv/redis@npm:2.5.2" + version: 2.5.3 + resolution: "@keyv/redis@npm:2.5.3" dependencies: - ioredis: ^5.2.3 - checksum: 2439e5097c6d4bf14e316b7a19d532287d43c5860f0614569f125a3c0a0a8c322610ed26b86b941b9aa9243ebf1e265c1d3f99a43da42d2150d02fc8fd2d94dd + ioredis: ^5.2.4 + checksum: db6be54624320f5d03856985fee5151601fa278d63ef98feac12f89188fbf86b972e7f5ca3ece0d6137c81038b1eb3c42805beaf51c4c963cca35c2b7d68be92 languageName: node linkType: hard @@ -25518,9 +25518,9 @@ __metadata: languageName: node linkType: hard -"ioredis@npm:^5.2.3": - version: 5.2.3 - resolution: "ioredis@npm:5.2.3" +"ioredis@npm:^5.2.4": + version: 5.2.4 + resolution: "ioredis@npm:5.2.4" dependencies: "@ioredis/commands": ^1.1.1 cluster-key-slot: ^1.1.0 @@ -25531,7 +25531,7 @@ __metadata: redis-errors: ^1.2.0 redis-parser: ^3.0.0 standard-as-callback: ^2.1.0 - checksum: 2cb7f0f4217e6774accad3620af1b7114722721c1d1824be2c9f0c2a77ab9629f2e0848d18b1a7208bc37796ae1207cb3e0898fce61900cfe797da0382724ad1 + checksum: c3a7df407a41ae516bede8b6db853c568198b13fe4a4785f66be5cd541087121b9d45fb9a6b1b6a5fb668c29ce52ab4685642b994803bdfa0a35f794ea8ef7ae languageName: node linkType: hard From 3aba6baea7804a05a23d45a17fc4f5df7ffcc99c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 01:06:19 +0000 Subject: [PATCH 167/434] Update dependency eslint-plugin-jest to v27.1.4 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 338d171216..c1acd5600b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21891,8 +21891,8 @@ __metadata: linkType: hard "eslint-plugin-jest@npm:^27.0.0": - version: 27.0.4 - resolution: "eslint-plugin-jest@npm:27.0.4" + version: 27.1.4 + resolution: "eslint-plugin-jest@npm:27.1.4" dependencies: "@typescript-eslint/utils": ^5.10.0 peerDependencies: @@ -21903,7 +21903,7 @@ __metadata: optional: true jest: optional: true - checksum: 8408d8a53bae946527ac4120865c29b3468cf58d8e5ff3b9c75c5303bb5aa451ac7e04329fc004cf6302f84431e6c6c1f2ba9009b0150d1718df58ea490ed3f5 + checksum: b7e3bf0dc092d9936ac1c10a0aceda411935c411c9323def109c2429ccf8486b3faead80fb769119add578c200352729ff96523bffec083f421e1b151404f642 languageName: node linkType: hard From d12a7ac3badb4003b001db4e31c91fbfecc81ac7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 01:07:08 +0000 Subject: [PATCH 168/434] Update dependency google-auth-library to v8.6.0 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 338d171216..6cebe1dea7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24059,8 +24059,8 @@ __metadata: linkType: hard "google-auth-library@npm:^8.0.0": - version: 8.5.2 - resolution: "google-auth-library@npm:8.5.2" + version: 8.6.0 + resolution: "google-auth-library@npm:8.6.0" dependencies: arrify: ^2.0.0 base64-js: ^1.3.0 @@ -24071,7 +24071,7 @@ __metadata: gtoken: ^6.1.0 jws: ^4.0.0 lru-cache: ^6.0.0 - checksum: 5ab2904f5da3c119a7c241a1d5a11640468a7da58dfcec8a9cad181cc2723e6662b3c65997906069852d9fa066ba3e4b7f14e11cbb80d541e320b66ead6777dc + checksum: ba2eed30dc495393cbaa4159e85504944c88c751f780fdff03a98e065c72f160e0918f5ddeb2af3631867f5018d1812ea8c75067d4be051cafdbdcc7b9cc0247 languageName: node linkType: hard From fb55a7d007997e0775cee883951834ddf23cad0d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 02:34:54 +0000 Subject: [PATCH 169/434] Update dependency jose to v4.10.4 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c1acd5600b..ec493bfd00 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27121,9 +27121,9 @@ __metadata: linkType: hard "jose@npm:^4.6.0": - version: 4.9.3 - resolution: "jose@npm:4.9.3" - checksum: 95865830768dcf82774d19e92dc854c5bc9dc5d9c9626a65a2974272e3aca5d2f56678611943f85802431d2d6d6f8bff9548b7cdb7578e6fe61529bd9c82e1d3 + version: 4.10.4 + resolution: "jose@npm:4.10.4" + checksum: 0e6caaae0b0303534c0ac23711d45eadfbdbff63d9aeed80965c668b5532c254ab25b48afddc3e1ecfcfd36b4275dee41174a097c5a47a25ce04268c78f3c130 languageName: node linkType: hard From 58502ec285f10a7d5eb1b3929554b11e8e817c3d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 02:35:33 +0000 Subject: [PATCH 170/434] Update dependency jscodeshift to ^0.14.0 Signed-off-by: Renovate Bot --- .changeset/renovate-3d08223.md | 5 + packages/codemods/package.json | 2 +- yarn.lock | 764 ++------------------------------- 3 files changed, 51 insertions(+), 720 deletions(-) create mode 100644 .changeset/renovate-3d08223.md diff --git a/.changeset/renovate-3d08223.md b/.changeset/renovate-3d08223.md new file mode 100644 index 0000000000..76c89644d1 --- /dev/null +++ b/.changeset/renovate-3d08223.md @@ -0,0 +1,5 @@ +--- +'@backstage/codemods': patch +--- + +Updated dependency `jscodeshift` to `^0.14.0`. diff --git a/packages/codemods/package.json b/packages/codemods/package.json index cc3ad6e468..af8a68cb55 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -35,7 +35,7 @@ "dependencies": { "@backstage/cli-common": "workspace:^", "chalk": "^4.0.0", - "jscodeshift": "^0.13.0", + "jscodeshift": "^0.14.0", "jscodeshift-add-imports": "^1.0.10" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index c1acd5600b..bf022e44cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3506,7 +3506,7 @@ __metadata: "@types/node": ^16.11.26 chalk: ^4.0.0 commander: ^9.1.0 - jscodeshift: ^0.13.0 + jscodeshift: ^0.14.0 jscodeshift-add-imports: ^1.0.10 ts-node: ^10.0.0 bin: @@ -16397,27 +16397,6 @@ __metadata: languageName: node linkType: hard -"arr-diff@npm:^4.0.0": - version: 4.0.0 - resolution: "arr-diff@npm:4.0.0" - checksum: ea7c8834842ad3869297f7915689bef3494fd5b102ac678c13ffccab672d3d1f35802b79e90c4cfec2f424af3392e44112d1ccf65da34562ed75e049597276a0 - languageName: node - linkType: hard - -"arr-flatten@npm:^1.1.0": - version: 1.1.0 - resolution: "arr-flatten@npm:1.1.0" - checksum: 963fe12564fca2f72c055f3f6c206b9e031f7c433a0c66ca9858b484821f248c5b1e5d53c8e4989d80d764cd776cf6d9b160ad05f47bdc63022bfd63b5455e22 - languageName: node - linkType: hard - -"arr-union@npm:^3.1.0": - version: 3.1.0 - resolution: "arr-union@npm:3.1.0" - checksum: b5b0408c6eb7591143c394f3be082fee690ddd21f0fdde0a0a01106799e847f67fcae1b7e56b0a0c173290e29c6aca9562e82b300708a268bc8f88f3d6613cb9 - languageName: node - linkType: hard - "array-differ@npm:^3.0.0": version: 3.0.0 resolution: "array-differ@npm:3.0.0" @@ -16495,13 +16474,6 @@ __metadata: languageName: node linkType: hard -"array-unique@npm:^0.3.2": - version: 0.3.2 - resolution: "array-unique@npm:0.3.2" - checksum: da344b89cfa6b0a5c221f965c21638bfb76b57b45184a01135382186924f55973cd9b171d4dad6bf606c6d9d36b0d721d091afdc9791535ead97ccbe78f8a888 - languageName: node - linkType: hard - "array.prototype.flat@npm:^1.2.3": version: 1.3.0 resolution: "array.prototype.flat@npm:1.3.0" @@ -16613,13 +16585,6 @@ __metadata: languageName: node linkType: hard -"assign-symbols@npm:^1.0.0": - version: 1.0.0 - resolution: "assign-symbols@npm:1.0.0" - checksum: c0eb895911d05b6b2d245154f70461c5e42c107457972e5ebba38d48967870dee53bcdf6c7047990586daa80fab8dab3cc6300800fbd47b454247fdedd859a2c - languageName: node - linkType: hard - "ast-types-flow@npm:^0.0.7": version: 0.0.7 resolution: "ast-types-flow@npm:0.0.7" @@ -16636,6 +16601,15 @@ __metadata: languageName: node linkType: hard +"ast-types@npm:0.15.2": + version: 0.15.2 + resolution: "ast-types@npm:0.15.2" + dependencies: + tslib: ^2.0.1 + checksum: 24f0d86bf9e4c8dae16fa24b13c1776f2c2677040bcfbd4eb4f27911db49020be4876885e45e6cfcc548ed4dfea3a0742d77e3346b84fae47379cb0b89e9daa0 + languageName: node + linkType: hard + "astral-regex@npm:^2.0.0": version: 2.0.0 resolution: "astral-regex@npm:2.0.0" @@ -16680,15 +16654,6 @@ __metadata: languageName: node linkType: hard -"atob@npm:^2.1.2": - version: 2.1.2 - resolution: "atob@npm:2.1.2" - bin: - atob: bin/atob.js - checksum: dfeeeb70090c5ebea7be4b9f787f866686c645d9f39a0d184c817252d0cf08455ed25267d79c03254d3be1f03ac399992a792edcd5ffb9c91e097ab5ef42833a - languageName: node - linkType: hard - "atomic-sleep@npm:^1.0.0": version: 1.0.0 resolution: "atomic-sleep@npm:1.0.0" @@ -17150,21 +17115,6 @@ __metadata: languageName: node linkType: hard -"base@npm:^0.11.1": - version: 0.11.2 - resolution: "base@npm:0.11.2" - dependencies: - cache-base: ^1.0.1 - class-utils: ^0.3.5 - component-emitter: ^1.2.1 - define-property: ^1.0.0 - isobject: ^3.0.1 - mixin-deep: ^1.2.0 - pascalcase: ^0.1.1 - checksum: a4a146b912e27eea8f66d09cb0c9eab666f32ce27859a7dfd50f38cd069a2557b39f16dba1bc2aecb3b44bf096738dd207b7970d99b0318423285ab1b1994edd - languageName: node - linkType: hard - "basic-auth@npm:~2.0.1": version: 2.0.1 resolution: "basic-auth@npm:2.0.1" @@ -17437,24 +17387,6 @@ __metadata: languageName: node linkType: hard -"braces@npm:^2.3.1": - version: 2.3.2 - resolution: "braces@npm:2.3.2" - dependencies: - arr-flatten: ^1.1.0 - array-unique: ^0.3.2 - extend-shallow: ^2.0.1 - fill-range: ^4.0.0 - isobject: ^3.0.1 - repeat-element: ^1.1.2 - snapdragon: ^0.8.1 - snapdragon-node: ^2.0.1 - split-string: ^3.0.2 - to-regex: ^3.0.1 - checksum: e30dcb6aaf4a31c8df17d848aa283a65699782f75ad61ae93ec25c9729c66cf58e66f0000a9fec84e4add1135bb7da40f7cb9601b36bebcfa9ca58e8d5c07de0 - languageName: node - linkType: hard - "braces@npm:^3.0.2, braces@npm:~3.0.2": version: 3.0.2 resolution: "braces@npm:3.0.2" @@ -17800,23 +17732,6 @@ __metadata: languageName: node linkType: hard -"cache-base@npm:^1.0.1": - version: 1.0.1 - resolution: "cache-base@npm:1.0.1" - dependencies: - collection-visit: ^1.0.0 - component-emitter: ^1.2.1 - get-value: ^2.0.6 - has-value: ^1.0.0 - isobject: ^3.0.1 - set-value: ^2.0.0 - to-object-path: ^0.3.0 - union-value: ^1.0.0 - unset-value: ^1.0.0 - checksum: 9114b8654fe2366eedc390bad0bcf534e2f01b239a888894e2928cb58cdc1e6ea23a73c6f3450dcfd2058aa73a8a981e723cd1e7c670c047bf11afdc65880107 - languageName: node - linkType: hard - "cacheable-lookup@npm:^5.0.3": version: 5.0.3 resolution: "cacheable-lookup@npm:5.0.3" @@ -18243,18 +18158,6 @@ __metadata: languageName: node linkType: hard -"class-utils@npm:^0.3.5": - version: 0.3.6 - resolution: "class-utils@npm:0.3.6" - dependencies: - arr-union: ^3.1.0 - define-property: ^0.2.5 - isobject: ^3.0.0 - static-extend: ^0.1.1 - checksum: be108900801e639e50f96a7e4bfa8867c753a7750a7603879f3981f8b0a89cba657497a2d5f40cd4ea557ff15d535a100818bb486baf6e26fe5d7872e75f1078 - languageName: node - linkType: hard - "classnames@npm:*, classnames@npm:^2.2.5, classnames@npm:^2.2.6, classnames@npm:^2.3.1": version: 2.3.1 resolution: "classnames@npm:2.3.1" @@ -18549,16 +18452,6 @@ __metadata: languageName: node linkType: hard -"collection-visit@npm:^1.0.0": - version: 1.0.0 - resolution: "collection-visit@npm:1.0.0" - dependencies: - map-visit: ^1.0.0 - object-visit: ^1.0.0 - checksum: 15d9658fe6eb23594728346adad5433b86bb7a04fd51bbab337755158722f9313a5376ef479de5b35fbc54140764d0d39de89c339f5d25b959ed221466981da9 - languageName: node - linkType: hard - "color-convert@npm:^0.5.2": version: 0.5.3 resolution: "color-convert@npm:0.5.3" @@ -18831,7 +18724,7 @@ __metadata: languageName: node linkType: hard -"component-emitter@npm:^1.2.1, component-emitter@npm:^1.3.0, component-emitter@npm:~1.3.0": +"component-emitter@npm:^1.3.0, component-emitter@npm:~1.3.0": version: 1.3.0 resolution: "component-emitter@npm:1.3.0" checksum: b3c46de38ffd35c57d1c02488355be9f218e582aec72d72d1b8bbec95a3ac1b38c96cd6e03ff015577e68f550fbb361a3bfdbd9bb248be9390b7b3745691be6b @@ -19102,13 +18995,6 @@ __metadata: languageName: node linkType: hard -"copy-descriptor@npm:^0.1.0": - version: 0.1.1 - resolution: "copy-descriptor@npm:0.1.1" - checksum: d4b7b57b14f1d256bb9aa0b479241048afd7f5bcf22035fc7b94e8af757adeae247ea23c1a774fe44869fd5694efba4a969b88d966766c5245fdee59837fe45b - languageName: node - linkType: hard - "copy-to-clipboard@npm:^3, copy-to-clipboard@npm:^3.2.0, copy-to-clipboard@npm:^3.3.1": version: 3.3.1 resolution: "copy-to-clipboard@npm:3.3.1" @@ -20093,7 +19979,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.0, debug@npm:^2.6.9": +"debug@npm:2.6.9, debug@npm:^2.6.0, debug@npm:^2.6.9": version: 2.6.9 resolution: "debug@npm:2.6.9" dependencies: @@ -20302,34 +20188,6 @@ __metadata: languageName: node linkType: hard -"define-property@npm:^0.2.5": - version: 0.2.5 - resolution: "define-property@npm:0.2.5" - dependencies: - is-descriptor: ^0.1.0 - checksum: 85af107072b04973b13f9e4128ab74ddfda48ec7ad2e54b193c0ffb57067c4ce5b7786a7b4ae1f24bd03e87c5d18766b094571810b314d7540f86d4354dbd394 - languageName: node - linkType: hard - -"define-property@npm:^1.0.0": - version: 1.0.0 - resolution: "define-property@npm:1.0.0" - dependencies: - is-descriptor: ^1.0.0 - checksum: 5fbed11dace44dd22914035ba9ae83ad06008532ca814d7936a53a09e897838acdad5b108dd0688cc8d2a7cf0681acbe00ee4136cf36743f680d10517379350a - languageName: node - linkType: hard - -"define-property@npm:^2.0.2": - version: 2.0.2 - resolution: "define-property@npm:2.0.2" - dependencies: - is-descriptor: ^1.0.2 - isobject: ^3.0.1 - checksum: 3217ed53fc9eed06ba8da6f4d33e28c68a82e2f2a8ab4d562c4920d8169a166fe7271453675e6c69301466f36a65d7f47edf0cf7f474b9aa52a5ead9c1b13c99 - languageName: node - linkType: hard - "del@npm:^6.0.0": version: 6.1.1 resolution: "del@npm:6.1.1" @@ -22558,21 +22416,6 @@ __metadata: languageName: node linkType: hard -"expand-brackets@npm:^2.1.4": - version: 2.1.4 - resolution: "expand-brackets@npm:2.1.4" - dependencies: - debug: ^2.3.3 - define-property: ^0.2.5 - extend-shallow: ^2.0.1 - posix-character-classes: ^0.1.0 - regex-not: ^1.0.0 - snapdragon: ^0.8.1 - to-regex: ^3.0.1 - checksum: 1781d422e7edfa20009e2abda673cadb040a6037f0bd30fcd7357304f4f0c284afd420d7622722ca4a016f39b6d091841ab57b401c1f7e2e5131ac65b9f14fa1 - languageName: node - linkType: hard - "expand-template@npm:^2.0.3": version: 2.0.3 resolution: "expand-template@npm:2.0.3" @@ -22686,25 +22529,6 @@ __metadata: languageName: node linkType: hard -"extend-shallow@npm:^2.0.1": - version: 2.0.1 - resolution: "extend-shallow@npm:2.0.1" - dependencies: - is-extendable: ^0.1.0 - checksum: 8fb58d9d7a511f4baf78d383e637bd7d2e80843bd9cd0853649108ea835208fb614da502a553acc30208e1325240bb7cc4a68473021612496bb89725483656d8 - languageName: node - linkType: hard - -"extend-shallow@npm:^3.0.0, extend-shallow@npm:^3.0.2": - version: 3.0.2 - resolution: "extend-shallow@npm:3.0.2" - dependencies: - assign-symbols: ^1.0.0 - is-extendable: ^1.0.1 - checksum: a920b0cd5838a9995ace31dfd11ab5e79bf6e295aa566910ce53dff19f4b1c0fda2ef21f26b28586c7a2450ca2b42d97bd8c0f5cec9351a819222bf861e02461 - languageName: node - linkType: hard - "extend@npm:3.0.2, extend@npm:^3.0.0, extend@npm:^3.0.2, extend@npm:~3.0.2": version: 3.0.2 resolution: "extend@npm:3.0.2" @@ -22730,22 +22554,6 @@ __metadata: languageName: node linkType: hard -"extglob@npm:^2.0.4": - version: 2.0.4 - resolution: "extglob@npm:2.0.4" - dependencies: - array-unique: ^0.3.2 - define-property: ^1.0.0 - expand-brackets: ^2.1.4 - extend-shallow: ^2.0.1 - fragment-cache: ^0.2.1 - regex-not: ^1.0.0 - snapdragon: ^0.8.1 - to-regex: ^3.0.1 - checksum: a41531b8934735b684cef5e8c5a01d0f298d7d384500ceca38793a9ce098125aab04ee73e2d75d5b2901bc5dddd2b64e1b5e3bf19139ea48bac52af4a92f1d00 - languageName: node - linkType: hard - "extract-files@npm:^11.0.0": version: 11.0.0 resolution: "extract-files@npm:11.0.0" @@ -23030,18 +22838,6 @@ __metadata: languageName: node linkType: hard -"fill-range@npm:^4.0.0": - version: 4.0.0 - resolution: "fill-range@npm:4.0.0" - dependencies: - extend-shallow: ^2.0.1 - is-number: ^3.0.0 - repeat-string: ^1.6.1 - to-regex-range: ^2.1.0 - checksum: dbb5102467786ab42bc7a3ec7380ae5d6bfd1b5177b2216de89e4a541193f8ba599a6db84651bd2c58c8921db41b8cc3d699ea83b477342d3ce404020f73c298 - languageName: node - linkType: hard - "fill-range@npm:^7.0.1": version: 7.0.1 resolution: "fill-range@npm:7.0.1" @@ -23251,13 +23047,6 @@ __metadata: languageName: node linkType: hard -"for-in@npm:^1.0.2": - version: 1.0.2 - resolution: "for-in@npm:1.0.2" - checksum: 09f4ae93ce785d253ac963d94c7f3432d89398bf25ac7a24ed034ca393bf74380bdeccc40e0f2d721a895e54211b07c8fad7132e8157827f6f7f059b70b4043d - languageName: node - linkType: hard - "foreach@npm:^2.0.4, foreach@npm:^2.0.5": version: 2.0.5 resolution: "foreach@npm:2.0.5" @@ -23427,15 +23216,6 @@ __metadata: languageName: node linkType: hard -"fragment-cache@npm:^0.2.1": - version: 0.2.1 - resolution: "fragment-cache@npm:0.2.1" - dependencies: - map-cache: ^0.2.2 - checksum: 1cbbd0b0116b67d5790175de0038a11df23c1cd2e8dcdbade58ebba5594c2d641dade6b4f126d82a7b4a6ffc2ea12e3d387dbb64ea2ae97cf02847d436f60fdc - languageName: node - linkType: hard - "fresh@npm:0.5.2": version: 0.5.2 resolution: "fresh@npm:0.5.2" @@ -23814,13 +23594,6 @@ __metadata: languageName: node linkType: hard -"get-value@npm:^2.0.3, get-value@npm:^2.0.6": - version: 2.0.6 - resolution: "get-value@npm:2.0.6" - checksum: 5c3b99cb5398ea8016bf46ff17afc5d1d286874d2ad38ca5edb6e87d75c0965b0094cb9a9dddef2c59c23d250702323539a7fbdd870620db38c7e7d7ec87c1eb - languageName: node - linkType: hard - "getopts@npm:2.3.0": version: 2.3.0 resolution: "getopts@npm:2.3.0" @@ -24559,45 +24332,6 @@ __metadata: languageName: node linkType: hard -"has-value@npm:^0.3.1": - version: 0.3.1 - resolution: "has-value@npm:0.3.1" - dependencies: - get-value: ^2.0.3 - has-values: ^0.1.4 - isobject: ^2.0.0 - checksum: 29e2a1e6571dad83451b769c7ce032fce6009f65bccace07c2962d3ad4d5530b6743d8f3229e4ecf3ea8e905d23a752c5f7089100c1f3162039fa6dc3976558f - languageName: node - linkType: hard - -"has-value@npm:^1.0.0": - version: 1.0.0 - resolution: "has-value@npm:1.0.0" - dependencies: - get-value: ^2.0.6 - has-values: ^1.0.0 - isobject: ^3.0.0 - checksum: b9421d354e44f03d3272ac39fd49f804f19bc1e4fa3ceef7745df43d6b402053f828445c03226b21d7d934a21ac9cf4bc569396dc312f496ddff873197bbd847 - languageName: node - linkType: hard - -"has-values@npm:^0.1.4": - version: 0.1.4 - resolution: "has-values@npm:0.1.4" - checksum: ab1c4bcaf811ccd1856c11cfe90e62fca9e2b026ebe474233a3d282d8d67e3b59ed85b622c7673bac3db198cb98bd1da2b39300a2f98e453729b115350af49bc - languageName: node - linkType: hard - -"has-values@npm:^1.0.0": - version: 1.0.0 - resolution: "has-values@npm:1.0.0" - dependencies: - is-number: ^3.0.0 - kind-of: ^4.0.0 - checksum: 77e6693f732b5e4cf6c38dfe85fdcefad0fab011af74995c3e83863fabf5e3a836f406d83565816baa0bc0a523c9410db8b990fe977074d61aeb6d8f4fcffa11 - languageName: node - linkType: hard - "has@npm:^1.0.3": version: 1.0.3 resolution: "has@npm:1.0.3" @@ -25580,24 +25314,6 @@ __metadata: languageName: node linkType: hard -"is-accessor-descriptor@npm:^0.1.6": - version: 0.1.6 - resolution: "is-accessor-descriptor@npm:0.1.6" - dependencies: - kind-of: ^3.0.2 - checksum: 3d629a086a9585bc16a83a8e8a3416f400023301855cafb7ccc9a1d63145b7480f0ad28877dcc2cce09492c4ec1c39ef4c071996f24ee6ac626be4217b8ffc8a - languageName: node - linkType: hard - -"is-accessor-descriptor@npm:^1.0.0": - version: 1.0.0 - resolution: "is-accessor-descriptor@npm:1.0.0" - dependencies: - kind-of: ^6.0.0 - checksum: 8e475968e9b22f9849343c25854fa24492dbe8ba0dea1a818978f9f1b887339190b022c9300d08c47fe36f1b913d70ce8cbaca00369c55a56705fdb7caed37fe - languageName: node - linkType: hard - "is-alphabetical@npm:^1.0.0": version: 1.0.4 resolution: "is-alphabetical@npm:1.0.4" @@ -25681,13 +25397,6 @@ __metadata: languageName: node linkType: hard -"is-buffer@npm:^1.1.5": - version: 1.1.6 - resolution: "is-buffer@npm:1.1.6" - checksum: 4a186d995d8bbf9153b4bd9ff9fd04ae75068fe695d29025d25e592d9488911eeece84eefbd8fa41b8ddcc0711058a71d4c466dcf6f1f6e1d83830052d8ca707 - languageName: node - linkType: hard - "is-buffer@npm:^2.0.0": version: 2.0.4 resolution: "is-buffer@npm:2.0.4" @@ -25749,24 +25458,6 @@ __metadata: languageName: node linkType: hard -"is-data-descriptor@npm:^0.1.4": - version: 0.1.4 - resolution: "is-data-descriptor@npm:0.1.4" - dependencies: - kind-of: ^3.0.2 - checksum: 5c622e078ba933a78338ae398a3d1fc5c23332b395312daf4f74bab4afb10d061cea74821add726cb4db8b946ba36217ee71a24fe71dd5bca4632edb7f6aad87 - languageName: node - linkType: hard - -"is-data-descriptor@npm:^1.0.0": - version: 1.0.0 - resolution: "is-data-descriptor@npm:1.0.0" - dependencies: - kind-of: ^6.0.0 - checksum: e705e6816241c013b05a65dc452244ee378d1c3e3842bd140beabe6e12c0d700ef23c91803f971aa7b091fb0573c5da8963af34a2b573337d87bc3e1f53a4e6d - languageName: node - linkType: hard - "is-date-object@npm:^1.0.1": version: 1.0.5 resolution: "is-date-object@npm:1.0.5" @@ -25790,28 +25481,6 @@ __metadata: languageName: node linkType: hard -"is-descriptor@npm:^0.1.0": - version: 0.1.6 - resolution: "is-descriptor@npm:0.1.6" - dependencies: - is-accessor-descriptor: ^0.1.6 - is-data-descriptor: ^0.1.4 - kind-of: ^5.0.0 - checksum: 0f780c1b46b465f71d970fd7754096ffdb7b69fd8797ca1f5069c163eaedcd6a20ec4a50af669075c9ebcfb5266d2e53c8b227e485eefdb0d1fee09aa1dd8ab6 - languageName: node - linkType: hard - -"is-descriptor@npm:^1.0.0, is-descriptor@npm:^1.0.2": - version: 1.0.2 - resolution: "is-descriptor@npm:1.0.2" - dependencies: - is-accessor-descriptor: ^1.0.0 - is-data-descriptor: ^1.0.0 - kind-of: ^6.0.2 - checksum: 2ed623560bee035fb67b23e32ce885700bef8abe3fbf8c909907d86507b91a2c89a9d3a4d835a4d7334dd5db0237a0aeae9ca109c1e4ef1c0e7b577c0846ab5a - languageName: node - linkType: hard - "is-docker@npm:^2.0.0, is-docker@npm:^2.1.1": version: 2.2.1 resolution: "is-docker@npm:2.2.1" @@ -25831,22 +25500,6 @@ __metadata: languageName: node linkType: hard -"is-extendable@npm:^0.1.0, is-extendable@npm:^0.1.1": - version: 0.1.1 - resolution: "is-extendable@npm:0.1.1" - checksum: 3875571d20a7563772ecc7a5f36cb03167e9be31ad259041b4a8f73f33f885441f778cee1f1fe0085eb4bc71679b9d8c923690003a36a6a5fdf8023e6e3f0672 - languageName: node - linkType: hard - -"is-extendable@npm:^1.0.1": - version: 1.0.1 - resolution: "is-extendable@npm:1.0.1" - dependencies: - is-plain-object: ^2.0.4 - checksum: db07bc1e9de6170de70eff7001943691f05b9d1547730b11be01c0ebfe67362912ba743cf4be6fd20a5e03b4180c685dad80b7c509fe717037e3eee30ad8e84f - languageName: node - linkType: hard - "is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" @@ -25991,15 +25644,6 @@ __metadata: languageName: node linkType: hard -"is-number@npm:^3.0.0": - version: 3.0.0 - resolution: "is-number@npm:3.0.0" - dependencies: - kind-of: ^3.0.2 - checksum: 0c62bf8e9d72c4dd203a74d8cfc751c746e75513380fef420cda8237e619a988ee43e678ddb23c87ac24d91ac0fe9f22e4ffb1301a50310c697e9d73ca3994e9 - languageName: node - linkType: hard - "is-number@npm:^7.0.0": version: 7.0.0 resolution: "is-number@npm:7.0.0" @@ -26049,7 +25693,7 @@ __metadata: languageName: node linkType: hard -"is-plain-object@npm:^2.0.3, is-plain-object@npm:^2.0.4": +"is-plain-object@npm:^2.0.4": version: 2.0.4 resolution: "is-plain-object@npm:2.0.4" dependencies: @@ -26285,7 +25929,7 @@ __metadata: languageName: node linkType: hard -"is-windows@npm:^1.0.0, is-windows@npm:^1.0.1, is-windows@npm:^1.0.2": +"is-windows@npm:^1.0.0, is-windows@npm:^1.0.1": version: 1.0.2 resolution: "is-windows@npm:1.0.2" checksum: 438b7e52656fe3b9b293b180defb4e448088e7023a523ec21a91a80b9ff8cdb3377ddb5b6e60f7c7de4fa8b63ab56e121b6705fe081b3cf1b828b0a380009ad7 @@ -26308,13 +25952,6 @@ __metadata: languageName: node linkType: hard -"isarray@npm:1.0.0, isarray@npm:^1.0.0, isarray@npm:~1.0.0": - version: 1.0.0 - resolution: "isarray@npm:1.0.0" - checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab - languageName: node - linkType: hard - "isarray@npm:2.0.1": version: 2.0.1 resolution: "isarray@npm:2.0.1" @@ -26322,6 +25959,13 @@ __metadata: languageName: node linkType: hard +"isarray@npm:^1.0.0, isarray@npm:~1.0.0": + version: 1.0.0 + resolution: "isarray@npm:1.0.0" + checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab + languageName: node + linkType: hard + "isbinaryfile@npm:^4.0.10": version: 4.0.10 resolution: "isbinaryfile@npm:4.0.10" @@ -26350,16 +25994,7 @@ __metadata: languageName: node linkType: hard -"isobject@npm:^2.0.0": - version: 2.1.0 - resolution: "isobject@npm:2.1.0" - dependencies: - isarray: 1.0.0 - checksum: 811c6f5a866877d31f0606a88af4a45f282544de886bf29f6a34c46616a1ae2ed17076cc6bf34c0128f33eecf7e1fcaa2c82cf3770560d3e26810894e96ae79f - languageName: node - linkType: hard - -"isobject@npm:^3.0.0, isobject@npm:^3.0.1": +"isobject@npm:^3.0.1": version: 3.0.1 resolution: "isobject@npm:3.0.1" checksum: db85c4c970ce30693676487cca0e61da2ca34e8d4967c2e1309143ff910c207133a969f9e4ddb2dc6aba670aabce4e0e307146c310350b298e74a31f7d464703 @@ -27262,9 +26897,9 @@ __metadata: languageName: node linkType: hard -"jscodeshift@npm:^0.13.0": - version: 0.13.1 - resolution: "jscodeshift@npm:0.13.1" +"jscodeshift@npm:^0.14.0": + version: 0.14.0 + resolution: "jscodeshift@npm:0.14.0" dependencies: "@babel/core": ^7.13.16 "@babel/parser": ^7.13.16 @@ -27279,17 +26914,17 @@ __metadata: chalk: ^4.1.2 flow-parser: 0.* graceful-fs: ^4.2.4 - micromatch: ^3.1.10 + micromatch: ^4.0.4 neo-async: ^2.5.0 node-dir: ^0.1.17 - recast: ^0.20.4 + recast: ^0.21.0 temp: ^0.8.4 write-file-atomic: ^2.3.0 peerDependencies: "@babel/preset-env": ^7.1.6 bin: jscodeshift: bin/jscodeshift.js - checksum: 1c35938de5fc29cafec80e2c37d5c3411f85cd5d40e0243b52f2da0c1ab4b659daddfd62de558eca5d562303616f7838097727b651f4ad8e32b1e96f169cdd76 + checksum: 54ea6d639455883336f80b38a70648821c88b7942315dc0fbab01bc34a9ad0f0f78e3bd69304b5ab167e4262d6ed7e6284c6d32525ab01c89d9118df89b3e2a0 languageName: node linkType: hard @@ -27948,32 +27583,7 @@ __metadata: languageName: node linkType: hard -"kind-of@npm:^3.0.2, kind-of@npm:^3.0.3, kind-of@npm:^3.2.0": - version: 3.2.2 - resolution: "kind-of@npm:3.2.2" - dependencies: - is-buffer: ^1.1.5 - checksum: e898df8ca2f31038f27d24f0b8080da7be274f986bc6ed176f37c77c454d76627619e1681f6f9d2e8d2fd7557a18ecc419a6bb54e422abcbb8da8f1a75e4b386 - languageName: node - linkType: hard - -"kind-of@npm:^4.0.0": - version: 4.0.0 - resolution: "kind-of@npm:4.0.0" - dependencies: - is-buffer: ^1.1.5 - checksum: 1b9e7624a8771b5a2489026e820f3bbbcc67893e1345804a56b23a91e9069965854d2a223a7c6ee563c45be9d8c6ff1ef87f28ed5f0d1a8d00d9dcbb067c529f - languageName: node - linkType: hard - -"kind-of@npm:^5.0.0": - version: 5.1.0 - resolution: "kind-of@npm:5.1.0" - checksum: f2a0102ae0cf19c4a953397e552571bad2b588b53282874f25fca7236396e650e2db50d41f9f516bd402536e4df968dbb51b8e69e4d5d4a7173def78448f7bab - languageName: node - linkType: hard - -"kind-of@npm:^6.0.0, kind-of@npm:^6.0.2, kind-of@npm:^6.0.3": +"kind-of@npm:^6.0.2, kind-of@npm:^6.0.3": version: 6.0.3 resolution: "kind-of@npm:6.0.3" checksum: 3ab01e7b1d440b22fe4c31f23d8d38b4d9b91d9f291df683476576493d5dfd2e03848a8b05813dd0c3f0e835bc63f433007ddeceb71f05cb25c45ae1b19c6d3b @@ -28958,7 +28568,7 @@ __metadata: languageName: node linkType: hard -"map-cache@npm:^0.2.0, map-cache@npm:^0.2.2": +"map-cache@npm:^0.2.0": version: 0.2.2 resolution: "map-cache@npm:0.2.2" checksum: 3067cea54285c43848bb4539f978a15dedc63c03022abeec6ef05c8cb6829f920f13b94bcaf04142fc6a088318e564c4785704072910d120d55dbc2e0c421969 @@ -28986,15 +28596,6 @@ __metadata: languageName: node linkType: hard -"map-visit@npm:^1.0.0": - version: 1.0.0 - resolution: "map-visit@npm:1.0.0" - dependencies: - object-visit: ^1.0.0 - checksum: c27045a5021c344fc19b9132eb30313e441863b2951029f8f8b66f79d3d8c1e7e5091578075a996f74e417479506fe9ede28c44ca7bc351a61c9d8073daec36a - languageName: node - linkType: hard - "markdown-it-anchor@npm:^8.4.1": version: 8.6.4 resolution: "markdown-it-anchor@npm:8.6.4" @@ -29722,27 +29323,6 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:^3.1.10": - version: 3.1.10 - resolution: "micromatch@npm:3.1.10" - dependencies: - arr-diff: ^4.0.0 - array-unique: ^0.3.2 - braces: ^2.3.1 - define-property: ^2.0.2 - extend-shallow: ^3.0.2 - extglob: ^2.0.4 - fragment-cache: ^0.2.1 - kind-of: ^6.0.2 - nanomatch: ^1.2.9 - object.pick: ^1.3.0 - regex-not: ^1.0.0 - snapdragon: ^0.8.1 - to-regex: ^3.0.2 - checksum: ad226cba4daa95b4eaf47b2ca331c8d2e038d7b41ae7ed0697cde27f3f1d6142881ab03d4da51b65d9d315eceb5e4cdddb3fbb55f5f72cfa19cf3ea469d054dc - languageName: node - linkType: hard - "micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5": version: 4.0.5 resolution: "micromatch@npm:4.0.5" @@ -30074,16 +29654,6 @@ __metadata: languageName: node linkType: hard -"mixin-deep@npm:^1.2.0": - version: 1.3.2 - resolution: "mixin-deep@npm:1.3.2" - dependencies: - for-in: ^1.0.2 - is-extendable: ^1.0.1 - checksum: 820d5a51fcb7479f2926b97f2c3bb223546bc915e6b3a3eb5d906dda871bba569863595424a76682f2b15718252954644f3891437cb7e3f220949bed54b1750d - languageName: node - linkType: hard - "mixme@npm:^0.5.1": version: 0.5.4 resolution: "mixme@npm:0.5.4" @@ -30390,25 +29960,6 @@ __metadata: languageName: node linkType: hard -"nanomatch@npm:^1.2.9": - version: 1.2.13 - resolution: "nanomatch@npm:1.2.13" - dependencies: - arr-diff: ^4.0.0 - array-unique: ^0.3.2 - define-property: ^2.0.2 - extend-shallow: ^3.0.2 - fragment-cache: ^0.2.1 - is-windows: ^1.0.2 - kind-of: ^6.0.2 - object.pick: ^1.3.0 - regex-not: ^1.0.0 - snapdragon: ^0.8.1 - to-regex: ^3.0.1 - checksum: 54d4166d6ef08db41252eb4e96d4109ebcb8029f0374f9db873bd91a1f896c32ec780d2a2ea65c0b2d7caf1f28d5e1ea33746a470f32146ac8bba821d80d38d8 - languageName: node - linkType: hard - "napi-build-utils@npm:^1.0.1": version: 1.0.2 resolution: "napi-build-utils@npm:1.0.2" @@ -30942,17 +30493,6 @@ __metadata: languageName: node linkType: hard -"object-copy@npm:^0.1.0": - version: 0.1.0 - resolution: "object-copy@npm:0.1.0" - dependencies: - copy-descriptor: ^0.1.0 - define-property: ^0.2.5 - kind-of: ^3.0.3 - checksum: a9e35f07e3a2c882a7e979090360d1a20ab51d1fa19dfdac3aa8873b328a7c4c7683946ee97c824ae40079d848d6740a3788fa14f2185155dab7ed970a72c783 - languageName: node - linkType: hard - "object-hash@npm:3.0.0, object-hash@npm:^3.0.0": version: 3.0.0 resolution: "object-hash@npm:3.0.0" @@ -30981,15 +30521,6 @@ __metadata: languageName: node linkType: hard -"object-visit@npm:^1.0.0": - version: 1.0.1 - resolution: "object-visit@npm:1.0.1" - dependencies: - isobject: ^3.0.0 - checksum: b0ee07f5bf3bb881b881ff53b467ebbde2b37ebb38649d6944a6cd7681b32eedd99da9bd1e01c55facf81f54ed06b13af61aba6ad87f0052982995e09333f790 - languageName: node - linkType: hard - "object.assign@npm:^4.1.0": version: 4.1.2 resolution: "object.assign@npm:4.1.2" @@ -31046,15 +30577,6 @@ __metadata: languageName: node linkType: hard -"object.pick@npm:^1.3.0": - version: 1.3.0 - resolution: "object.pick@npm:1.3.0" - dependencies: - isobject: ^3.0.1 - checksum: 77fb6eed57c67adf75e9901187e37af39f052ef601cb4480386436561357eb9e459e820762f01fd02c5c1b42ece839ad393717a6d1850d848ee11fbabb3e580a - languageName: node - linkType: hard - "object.values@npm:^1.1.5": version: 1.1.5 resolution: "object.values@npm:1.1.5" @@ -31761,13 +31283,6 @@ __metadata: languageName: node linkType: hard -"pascalcase@npm:^0.1.1": - version: 0.1.1 - resolution: "pascalcase@npm:0.1.1" - checksum: f83681c3c8ff75fa473a2bb2b113289952f802ff895d435edd717e7cb898b0408cbdb247117a938edcbc5d141020909846cc2b92c47213d764e2a94d2ad2b925 - languageName: node - linkType: hard - "passport-auth0@npm:^1.4.3": version: 1.4.3 resolution: "passport-auth0@npm:1.4.3" @@ -32415,13 +31930,6 @@ __metadata: languageName: node linkType: hard -"posix-character-classes@npm:^0.1.0": - version: 0.1.1 - resolution: "posix-character-classes@npm:0.1.1" - checksum: dedb99913c60625a16050cfed2fb5c017648fc075be41ac18474e1c6c3549ef4ada201c8bd9bd006d36827e289c571b6092e1ef6e756cdbab2fd7046b25c6442 - languageName: node - linkType: hard - "postcss-calc@npm:^8.0.0": version: 8.0.0 resolution: "postcss-calc@npm:8.0.0" @@ -34381,7 +33889,7 @@ __metadata: languageName: node linkType: hard -"recast@npm:^0.20.3, recast@npm:^0.20.4": +"recast@npm:^0.20.3": version: 0.20.4 resolution: "recast@npm:0.20.4" dependencies: @@ -34393,6 +33901,18 @@ __metadata: languageName: node linkType: hard +"recast@npm:^0.21.0": + version: 0.21.5 + resolution: "recast@npm:0.21.5" + dependencies: + ast-types: 0.15.2 + esprima: ~4.0.0 + source-map: ~0.6.1 + tslib: ^2.0.1 + checksum: 03cc7f57562238ba258d468be67bf7446ce7a707bc87a087891dad15afead46c36e9aaeedf2130e2ab5a465244a9c62bfd4127849761cf8f4085abe2f3e5f485 + languageName: node + linkType: hard + "recharts-scale@npm:^0.4.4": version: 0.4.5 resolution: "recharts-scale@npm:0.4.5" @@ -34614,16 +34134,6 @@ __metadata: languageName: node linkType: hard -"regex-not@npm:^1.0.0, regex-not@npm:^1.0.2": - version: 1.0.2 - resolution: "regex-not@npm:1.0.2" - dependencies: - extend-shallow: ^3.0.2 - safe-regex: ^1.1.0 - checksum: 3081403de79559387a35ef9d033740e41818a559512668cef3d12da4e8a29ef34ee13c8ed1256b07e27ae392790172e8a15c8a06b72962fd4550476cde3d8f77 - languageName: node - linkType: hard - "regexp.prototype.flags@npm:^1.4.1, regexp.prototype.flags@npm:^1.4.3": version: 1.4.3 resolution: "regexp.prototype.flags@npm:1.4.3" @@ -34812,14 +34322,7 @@ __metadata: languageName: node linkType: hard -"repeat-element@npm:^1.1.2": - version: 1.1.3 - resolution: "repeat-element@npm:1.1.3" - checksum: 0743a136b484117016ad587577ede60a3ffe604b74e57bd5d7d0aa041fe2f1c956e6b2f3ff83c86f4db9fac022c3fa2da8e58b9d3618b8b4cb1c3d041bcc422f - languageName: node - linkType: hard - -"repeat-string@npm:^1.5.2, repeat-string@npm:^1.6.1": +"repeat-string@npm:^1.5.2": version: 1.6.1 resolution: "repeat-string@npm:1.6.1" checksum: 1b809fc6db97decdc68f5b12c4d1a671c8e3f65ec4a40c238bc5200e44e85bcc52a54f78268ab9c29fcf5fe4f1343e805420056d1f30fa9a9ee4c2d93e3cc6c0 @@ -34971,13 +34474,6 @@ __metadata: languageName: node linkType: hard -"resolve-url@npm:^0.2.1": - version: 0.2.1 - resolution: "resolve-url@npm:0.2.1" - checksum: 7b7035b9ed6e7bc7d289e90aef1eab5a43834539695dac6416ca6e91f1a94132ae4796bbd173cdacfdc2ade90b5f38a3fb6186bebc1b221cd157777a23b9ad14 - languageName: node - linkType: hard - "resolve.exports@npm:^1.1.0": version: 1.1.0 resolution: "resolve.exports@npm:1.1.0" @@ -35147,13 +34643,6 @@ __metadata: languageName: node linkType: hard -"ret@npm:~0.1.10": - version: 0.1.15 - resolution: "ret@npm:0.1.15" - checksum: d76a9159eb8c946586567bd934358dfc08a36367b3257f7a3d7255fdd7b56597235af23c6afa0d7f0254159e8051f93c918809962ebd6df24ca2a83dbe4d4151 - languageName: node - linkType: hard - "retry-request@npm:^5.0.0": version: 5.0.0 resolution: "retry-request@npm:5.0.0" @@ -35519,15 +35008,6 @@ __metadata: languageName: node linkType: hard -"safe-regex@npm:^1.1.0": - version: 1.1.0 - resolution: "safe-regex@npm:1.1.0" - dependencies: - ret: ~0.1.10 - checksum: 9a8bba57c87a841f7997b3b951e8e403b1128c1a4fd1182f40cc1a20e2d490593d7c2a21030fadfea320c8e859219019e136f678c6689ed5960b391b822f01d5 - languageName: node - linkType: hard - "safe-stable-stringify@npm:^2.2.0, safe-stable-stringify@npm:^2.3.1": version: 2.3.1 resolution: "safe-stable-stringify@npm:2.3.1" @@ -35863,18 +35343,6 @@ __metadata: languageName: node linkType: hard -"set-value@npm:^2.0.0, set-value@npm:^2.0.1": - version: 2.0.1 - resolution: "set-value@npm:2.0.1" - dependencies: - extend-shallow: ^2.0.1 - is-extendable: ^0.1.1 - is-plain-object: ^2.0.3 - split-string: ^3.0.1 - checksum: 09a4bc72c94641aeae950eb60dc2755943b863780fcc32e441eda964b64df5e3f50603d5ebdd33394ede722528bd55ed43aae26e9df469b4d32e2292b427b601 - languageName: node - linkType: hard - "set-value@npm:^4.1.0": version: 4.1.0 resolution: "set-value@npm:4.1.0" @@ -36170,42 +35638,6 @@ __metadata: languageName: node linkType: hard -"snapdragon-node@npm:^2.0.1": - version: 2.1.1 - resolution: "snapdragon-node@npm:2.1.1" - dependencies: - define-property: ^1.0.0 - isobject: ^3.0.0 - snapdragon-util: ^3.0.1 - checksum: 9bb57d759f9e2a27935dbab0e4a790137adebace832b393e350a8bf5db461ee9206bb642d4fe47568ee0b44080479c8b4a9ad0ebe3712422d77edf9992a672fd - languageName: node - linkType: hard - -"snapdragon-util@npm:^3.0.1": - version: 3.0.1 - resolution: "snapdragon-util@npm:3.0.1" - dependencies: - kind-of: ^3.2.0 - checksum: 684997dbe37ec995c03fd3f412fba2b711fc34cb4010452b7eb668be72e8811a86a12938b511e8b19baf853b325178c56d8b78d655305e5cfb0bb8b21677e7b7 - languageName: node - linkType: hard - -"snapdragon@npm:^0.8.1": - version: 0.8.2 - resolution: "snapdragon@npm:0.8.2" - dependencies: - base: ^0.11.1 - debug: ^2.2.0 - define-property: ^0.2.5 - extend-shallow: ^2.0.1 - map-cache: ^0.2.2 - source-map: ^0.5.6 - source-map-resolve: ^0.5.0 - use: ^3.1.0 - checksum: a197f242a8f48b11036563065b2487e9b7068f50a20dd81d9161eca6af422174fc158b8beeadbe59ce5ef172aa5718143312b3aebaae551c124b7824387c8312 - languageName: node - linkType: hard - "socket.io-adapter@npm:~1.1.0": version: 1.1.2 resolution: "socket.io-adapter@npm:1.1.2" @@ -36335,19 +35767,6 @@ __metadata: languageName: node linkType: hard -"source-map-resolve@npm:^0.5.0": - version: 0.5.3 - resolution: "source-map-resolve@npm:0.5.3" - dependencies: - atob: ^2.1.2 - decode-uri-component: ^0.2.0 - resolve-url: ^0.2.1 - source-map-url: ^0.4.0 - urix: ^0.1.0 - checksum: c73fa44ac00783f025f6ad9e038ab1a2e007cd6a6b86f47fe717c3d0765b4a08d264f6966f3bd7cd9dbcd69e4832783d5472e43247775b2a550d6f2155d24bae - languageName: node - linkType: hard - "source-map-support@npm:0.5.13": version: 0.5.13 resolution: "source-map-support@npm:0.5.13" @@ -36368,13 +35787,6 @@ __metadata: languageName: node linkType: hard -"source-map-url@npm:^0.4.0": - version: 0.4.0 - resolution: "source-map-url@npm:0.4.0" - checksum: 63ed54045fcd7b4ec7ca17513f48fdc23b573eef679326ecf1a31333e1aaecc0a9c085adaa7d118283b160e65b71cc72da9e1385f2de4ac5ed68294e3920d719 - languageName: node - linkType: hard - "source-map@npm:0.5.6": version: 0.5.6 resolution: "source-map@npm:0.5.6" @@ -36382,7 +35794,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.5.0, source-map@npm:^0.5.6": +"source-map@npm:^0.5.0": version: 0.5.7 resolution: "source-map@npm:0.5.7" checksum: 5dc2043b93d2f194142c7f38f74a24670cd7a0063acdaf4bf01d2964b402257ae843c2a8fa822ad5b71013b5fcafa55af7421383da919752f22ff488bc553f4d @@ -36516,15 +35928,6 @@ __metadata: languageName: node linkType: hard -"split-string@npm:^3.0.1, split-string@npm:^3.0.2": - version: 3.1.0 - resolution: "split-string@npm:3.1.0" - dependencies: - extend-shallow: ^3.0.0 - checksum: ae5af5c91bdc3633628821bde92fdf9492fa0e8a63cf6a0376ed6afde93c701422a1610916f59be61972717070119e848d10dfbbd5024b7729d6a71972d2a84c - languageName: node - linkType: hard - "split2@npm:^3.0.0": version: 3.2.2 resolution: "split2@npm:3.2.2" @@ -36734,16 +36137,6 @@ __metadata: languageName: node linkType: hard -"static-extend@npm:^0.1.1": - version: 0.1.2 - resolution: "static-extend@npm:0.1.2" - dependencies: - define-property: ^0.2.5 - object-copy: ^0.1.0 - checksum: 8657485b831f79e388a437260baf22784540417a9b29e11572c87735df24c22b84eda42107403a64b30861b2faf13df9f7fc5525d51f9d1d2303aba5cbf4e12c - languageName: node - linkType: hard - "statuses@npm:2.0.1, statuses@npm:^2.0.0": version: 2.0.1 resolution: "statuses@npm:2.0.1" @@ -37897,25 +37290,6 @@ __metadata: languageName: node linkType: hard -"to-object-path@npm:^0.3.0": - version: 0.3.0 - resolution: "to-object-path@npm:0.3.0" - dependencies: - kind-of: ^3.0.2 - checksum: 9425effee5b43e61d720940fa2b889623f77473d459c2ce3d4a580a4405df4403eec7be6b857455908070566352f9e2417304641ed158dda6f6a365fe3e66d70 - languageName: node - linkType: hard - -"to-regex-range@npm:^2.1.0": - version: 2.1.1 - resolution: "to-regex-range@npm:2.1.1" - dependencies: - is-number: ^3.0.0 - repeat-string: ^1.6.1 - checksum: 46093cc14be2da905cc931e442d280b2e544e2bfdb9a24b3cf821be8d342f804785e5736c108d5be026021a05d7b38144980a61917eee3c88de0a5e710e10320 - languageName: node - linkType: hard - "to-regex-range@npm:^5.0.1": version: 5.0.1 resolution: "to-regex-range@npm:5.0.1" @@ -37925,18 +37299,6 @@ __metadata: languageName: node linkType: hard -"to-regex@npm:^3.0.1, to-regex@npm:^3.0.2": - version: 3.0.2 - resolution: "to-regex@npm:3.0.2" - dependencies: - define-property: ^2.0.2 - extend-shallow: ^3.0.2 - regex-not: ^1.0.2 - safe-regex: ^1.1.0 - checksum: 4ed4a619059b64e204aad84e4e5f3ea82d97410988bcece7cf6cbfdbf193d11bff48cf53842d88b8bb00b1bfc0d048f61f20f0709e6f393fd8fe0122662d9db4 - languageName: node - linkType: hard - "toggle-selection@npm:^1.0.6": version: 1.0.6 resolution: "toggle-selection@npm:1.0.6" @@ -38635,18 +37997,6 @@ __metadata: languageName: node linkType: hard -"union-value@npm:^1.0.0": - version: 1.0.1 - resolution: "union-value@npm:1.0.1" - dependencies: - arr-union: ^3.1.0 - get-value: ^2.0.6 - is-extendable: ^0.1.1 - set-value: ^2.0.1 - checksum: a3464097d3f27f6aa90cf103ed9387541bccfc006517559381a10e0dffa62f465a9d9a09c9b9c3d26d0f4cbe61d4d010e2fbd710fd4bf1267a768ba8a774b0ba - languageName: node - linkType: hard - "uniq@npm:^1.0.1": version: 1.0.1 resolution: "uniq@npm:1.0.1" @@ -38800,16 +38150,6 @@ __metadata: languageName: node linkType: hard -"unset-value@npm:^1.0.0": - version: 1.0.0 - resolution: "unset-value@npm:1.0.0" - dependencies: - has-value: ^0.3.1 - isobject: ^3.0.0 - checksum: 5990ecf660672be2781fc9fb322543c4aa592b68ed9a3312fa4df0e9ba709d42e823af090fc8f95775b4cd2c9a5169f7388f0cec39238b6d0d55a69fc2ab6b29 - languageName: node - linkType: hard - "untildify@npm:^4.0.0": version: 4.0.0 resolution: "untildify@npm:4.0.0" @@ -38872,13 +38212,6 @@ __metadata: languageName: node linkType: hard -"urix@npm:^0.1.0": - version: 0.1.0 - resolution: "urix@npm:0.1.0" - checksum: 4c076ecfbf3411e888547fe844e52378ab5ada2d2f27625139011eada79925e77f7fbf0e4016d45e6a9e9adb6b7e64981bd49b22700c7c401c5fc15f423303b3 - languageName: node - linkType: hard - "url-parse@npm:^1.5.8": version: 1.5.10 resolution: "url-parse@npm:1.5.10" @@ -38968,13 +38301,6 @@ __metadata: languageName: node linkType: hard -"use@npm:^3.1.0": - version: 3.1.1 - resolution: "use@npm:3.1.1" - checksum: 08a130289f5238fcbf8f59a18951286a6e660d17acccc9d58d9b69dfa0ee19aa038e8f95721b00b432c36d1629a9e32a464bf2e7e0ae6a244c42ddb30bdd8b33 - languageName: node - linkType: hard - "utf8-byte-length@npm:^1.0.1": version: 1.0.4 resolution: "utf8-byte-length@npm:1.0.4" From aa686533a0ee331b9b35893e3ca74c20887f2d8f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 03:18:41 +0000 Subject: [PATCH 171/434] Update dependency json-schema-library to v7.3.0 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 13cfb8a90b..bb994b29b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27478,15 +27478,15 @@ __metadata: linkType: hard "json-schema-library@npm:^7.0.0": - version: 7.2.1 - resolution: "json-schema-library@npm:7.2.1" + version: 7.3.0 + resolution: "json-schema-library@npm:7.3.0" dependencies: deepmerge: ^4.2.2 fast-deep-equal: ^3.1.3 gson-pointer: ^4.1.1 gson-query: ^5.1.0 valid-url: ^1.0.9 - checksum: 65bc4014cdfe22c4f46d6cb0a0c059d94045128fb96189c4823dff653b6788c2dbab8d5d2e8475bbdc65fd47abf19cedcc3f02df608452c5413fea5d6e675003 + checksum: 3d148d4be1e59e058bd777d247c181e2cb4820f9f5b9c97f7258f88fa73e1c0ed5c8e07c3fef4e1e8e892666def02b2b5fe5366d3d8d2bed09be3752e5593319 languageName: node linkType: hard From 76acc4905e33151ac53d223653df15e3e138d18b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 09:11:56 +0000 Subject: [PATCH 172/434] Update dependency rollup-plugin-esbuild to v4.10.2 Signed-off-by: Renovate Bot --- yarn.lock | 81 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 27 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0b00cf29bd..909d52aaf6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12551,16 +12551,6 @@ __metadata: languageName: node linkType: hard -"@rollup/pluginutils@npm:^4.1.1": - version: 4.1.1 - resolution: "@rollup/pluginutils@npm:4.1.1" - dependencies: - estree-walker: ^2.0.1 - picomatch: ^2.2.2 - checksum: 405f681c7d32661980aa3caa928ff22e1c06f0e081db1550e6ab9c179dc9d3d8d63c05dcc7338fe65ab3f856a56c465696a51300b83e98171956fcb141106e39 - languageName: node - linkType: hard - "@rollup/pluginutils@npm:^4.2.1": version: 4.2.1 resolution: "@rollup/pluginutils@npm:4.2.1" @@ -12571,6 +12561,22 @@ __metadata: languageName: node linkType: hard +"@rollup/pluginutils@npm:^5.0.1": + version: 5.0.2 + resolution: "@rollup/pluginutils@npm:5.0.2" + dependencies: + "@types/estree": ^1.0.0 + estree-walker: ^2.0.2 + picomatch: ^2.3.1 + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + checksum: edea15e543bebc7dcac3b0ac8bc7b8e8e6dbd46e2864dbe5dd28072de1fbd5b0e10d545a610c0edaa178e8a7ac432e2a2a52e547ece1308471412caba47db8ce + languageName: node + linkType: hard + "@rushstack/node-core-library@npm:3.45.4": version: 3.45.4 resolution: "@rushstack/node-core-library@npm:3.45.4" @@ -13811,6 +13817,13 @@ __metadata: languageName: node linkType: hard +"@types/estree@npm:^1.0.0": + version: 1.0.0 + resolution: "@types/estree@npm:1.0.0" + checksum: 910d97fb7092c6738d30a7430ae4786a38542023c6302b95d46f49420b797f21619cdde11fa92b338366268795884111c2eb10356e4bd2c8ad5b92941e9e6443 + languageName: node + linkType: hard + "@types/event-source-polyfill@npm:^1.0.0": version: 1.0.0 resolution: "@types/event-source-polyfill@npm:1.0.0" @@ -21233,13 +21246,20 @@ __metadata: languageName: node linkType: hard -"es-module-lexer@npm:^0.9.0, es-module-lexer@npm:^0.9.3": +"es-module-lexer@npm:^0.9.0": version: 0.9.3 resolution: "es-module-lexer@npm:0.9.3" checksum: 84bbab23c396281db2c906c766af58b1ae2a1a2599844a504df10b9e8dc77ec800b3211fdaa133ff700f5703d791198807bba25d9667392d27a5e9feda344da8 languageName: node linkType: hard +"es-module-lexer@npm:^1.0.5": + version: 1.1.0 + resolution: "es-module-lexer@npm:1.1.0" + checksum: 3e9f5019b69c6b2f04eb8478c4fdb4ed72cb8b4c97511b5dd39c1f498386ed8f5083c32067c15efcfabc7e8460cb65ed4627dd32405475715a898009922f41fa + languageName: node + linkType: hard + "es-shim-unscopables@npm:^1.0.0": version: 1.0.0 resolution: "es-shim-unscopables@npm:1.0.0" @@ -22192,6 +22212,13 @@ __metadata: languageName: node linkType: hard +"estree-walker@npm:^2.0.2": + version: 2.0.2 + resolution: "estree-walker@npm:2.0.2" + checksum: 6151e6f9828abe2259e57f5fd3761335bb0d2ebd76dc1a01048ccee22fabcfef3c0859300f6d83ff0d1927849368775ec5a6d265dde2f6de5a1be1721cd94efc + languageName: node + linkType: hard + "esutils@npm:^2.0.2": version: 2.0.3 resolution: "esutils@npm:2.0.3" @@ -27144,6 +27171,13 @@ __metadata: languageName: node linkType: hard +"joycon@npm:^3.1.1": + version: 3.1.1 + resolution: "joycon@npm:3.1.1" + checksum: 8003c9c3fc79c5c7602b1c7e9f7a2df2e9916f046b0dbad862aa589be78c15734d11beb9fe846f5e06138df22cb2ad29961b6a986ba81c4920ce2b15a7f11067 + languageName: node + linkType: hard + "jpeg-js@npm:^0.3.4": version: 0.3.7 resolution: "jpeg-js@npm:0.3.7" @@ -27620,13 +27654,6 @@ __metadata: languageName: node linkType: hard -"jsonc-parser@npm:^3.0.0": - version: 3.0.0 - resolution: "jsonc-parser@npm:3.0.0" - checksum: 1df2326f1f9688de30c70ff19c5b2a83ba3b89a1036160da79821d1361090775e9db502dc57a67c11b56e1186fc1ed70b887f25c5febf9a3ec4f91435836c99d - languageName: node - linkType: hard - "jsonc-parser@npm:^3.2.0": version: 3.2.0 resolution: "jsonc-parser@npm:3.2.0" @@ -35294,18 +35321,18 @@ __metadata: linkType: hard "rollup-plugin-esbuild@npm:^4.7.2": - version: 4.10.1 - resolution: "rollup-plugin-esbuild@npm:4.10.1" + version: 4.10.2 + resolution: "rollup-plugin-esbuild@npm:4.10.2" dependencies: - "@rollup/pluginutils": ^4.1.1 - debug: ^4.3.3 - es-module-lexer: ^0.9.3 - joycon: ^3.0.1 - jsonc-parser: ^3.0.0 + "@rollup/pluginutils": ^5.0.1 + debug: ^4.3.4 + es-module-lexer: ^1.0.5 + joycon: ^3.1.1 + jsonc-parser: ^3.2.0 peerDependencies: esbuild: ">=0.10.1" - rollup: ^1.20.0 || ^2.0.0 - checksum: 8bc7c90c972e00d6757b92d6ee4c04d9b0f34b61659f4c544b3994091bc5fdfe4ffdcbf56999111da39e39e650eb93001d587843e87bc306322d9869afe4d60b + rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 + checksum: 0f8e57fe40bf3b9a575cec039bf6d6789dedcbdc3ffee868fccdfe15f5e30e7fd68d7c6550cdbe9de1db7855c700f0bda8b4f10bf3d09b9f6b7516bc48334bc4 languageName: node linkType: hard From 7605c11cdaf627a9c686c6fa03c105f7c3a84da2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 9 Jul 2022 16:32:48 +0200 Subject: [PATCH 173/434] bump Node.js to 16 & 18 Signed-off-by: Patrik Oldsberg --- .github/workflows/ci.yml | 6 +++--- .github/workflows/deploy_microsite.yml | 2 +- .github/workflows/deploy_nightly.yml | 2 +- .github/workflows/deploy_packages.yml | 4 ++-- .github/workflows/sync_snyk-github-issues.yml | 2 +- .github/workflows/verify_e2e-linux.yml | 2 +- .github/workflows/verify_e2e-techdocs.yml | 2 +- .github/workflows/verify_e2e-tugboat.yml | 2 +- .github/workflows/verify_e2e-windows.yml | 2 +- .github/workflows/verify_kubernetes.yml | 2 +- .github/workflows/verify_microsite.yml | 2 +- .github/workflows/verify_windows.yml | 2 +- contrib/docker/devops/Dockerfile | 2 +- contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild | 2 +- cypress/tsconfig.json | 4 ++-- docs/features/search/how-to-guides.md | 4 ++-- docs/getting-started/running-backstage-locally.md | 6 +++--- docs/tutorials/quickstart-app-plugin.md | 2 +- package.json | 2 +- packages/cli/config/tsconfig.json | 4 ++-- packages/create-app/templates/default-app/package.json.hbs | 2 +- plugins/scaffolder-backend/scripts/build-nunjucks.js | 2 +- 22 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 64067188bb..3ab979593c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [14.x, 16.x] + node-version: [16.x, 18.x] env: CI: true @@ -47,7 +47,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [14.x, 16.x] + node-version: [16.x, 18.x] env: CI: true @@ -121,7 +121,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [14.x, 16.x] + node-version: [16.x, 18.x] services: postgres13: diff --git a/.github/workflows/deploy_microsite.yml b/.github/workflows/deploy_microsite.yml index af6f222377..1f87c30af2 100644 --- a/.github/workflows/deploy_microsite.yml +++ b/.github/workflows/deploy_microsite.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: - node-version: [14.x] + node-version: [16.x] env: CI: true diff --git a/.github/workflows/deploy_nightly.yml b/.github/workflows/deploy_nightly.yml index 476e5dd10b..74dc60783a 100644 --- a/.github/workflows/deploy_nightly.yml +++ b/.github/workflows/deploy_nightly.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: - node-version: [14.x] + node-version: [16.x] env: CI: true diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index f3736d93a2..56ff61c75b 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - node-version: [14.x, 16.x] + node-version: [16.x, 18.x] services: postgres13: @@ -130,7 +130,7 @@ jobs: strategy: matrix: - node-version: [14.x] + node-version: [16.x] env: CI: 'true' diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml index dd35ba26f3..de05c79300 100644 --- a/.github/workflows/sync_snyk-github-issues.yml +++ b/.github/workflows/sync_snyk-github-issues.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - node-version: [14.x] + node-version: [16.x] steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index 3353a84f3b..fefdd1fdd5 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -31,7 +31,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - node-version: [14.x, 16.x] + node-version: [16.x, 18.x] env: CI: true diff --git a/.github/workflows/verify_e2e-techdocs.yml b/.github/workflows/verify_e2e-techdocs.yml index e1bb2246dc..8d59d15899 100644 --- a/.github/workflows/verify_e2e-techdocs.yml +++ b/.github/workflows/verify_e2e-techdocs.yml @@ -18,7 +18,7 @@ jobs: strategy: matrix: - node-version: [14.x, 16.x] + node-version: [16.x, 18.x] env: CI: true diff --git a/.github/workflows/verify_e2e-tugboat.yml b/.github/workflows/verify_e2e-tugboat.yml index 04d9e686e2..cb3a463a0d 100644 --- a/.github/workflows/verify_e2e-tugboat.yml +++ b/.github/workflows/verify_e2e-tugboat.yml @@ -52,7 +52,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: '14' + node-version: '16.x' - name: yarn install run: yarn --cwd cypress install diff --git a/.github/workflows/verify_e2e-windows.yml b/.github/workflows/verify_e2e-windows.yml index 4e8025f7d5..fc29c1f03b 100644 --- a/.github/workflows/verify_e2e-windows.yml +++ b/.github/workflows/verify_e2e-windows.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: os: [windows-2019] - node-version: [14.x, 16.x] + node-version: [16.x, 18.x] env: CI: true diff --git a/.github/workflows/verify_kubernetes.yml b/.github/workflows/verify_kubernetes.yml index e64ddec586..e8c248699a 100644 --- a/.github/workflows/verify_kubernetes.yml +++ b/.github/workflows/verify_kubernetes.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - node-version: [14.x, 16.x] + node-version: [16.x, 18.x] env: CI: true diff --git a/.github/workflows/verify_microsite.yml b/.github/workflows/verify_microsite.yml index 50c2116090..3a24befa84 100644 --- a/.github/workflows/verify_microsite.yml +++ b/.github/workflows/verify_microsite.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - node-version: [14.x] + node-version: [16.x] env: CI: true diff --git a/.github/workflows/verify_windows.yml b/.github/workflows/verify_windows.yml index 8bbaa645bf..75a0633cbe 100644 --- a/.github/workflows/verify_windows.yml +++ b/.github/workflows/verify_windows.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - node-version: [14.x, 16.x] + node-version: [16.x, 18.x] env: CI: true diff --git a/contrib/docker/devops/Dockerfile b/contrib/docker/devops/Dockerfile index a7c194618a..8703b2ab48 100644 --- a/contrib/docker/devops/Dockerfile +++ b/contrib/docker/devops/Dockerfile @@ -1,4 +1,4 @@ -ARG IMAGE_TAG=14-alpine +ARG IMAGE_TAG=16-alpine FROM node:${IMAGE_TAG} diff --git a/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild b/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild index 41f931544f..053b4fb492 100644 --- a/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild +++ b/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild @@ -35,7 +35,7 @@ -FROM node:14-buster AS build +FROM node:16-buster AS build RUN mkdir /app COPY . /app diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index d9b4869ecd..9c4a63b76c 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -10,7 +10,7 @@ "incremental": true, "isolatedModules": true, "jsx": "react", - "lib": ["DOM", "DOM.Iterable", "ScriptHost", "ES2020", "ESNext.Promise"], + "lib": ["DOM", "DOM.Iterable", "ScriptHost", "ES2021", "ESNext.Promise"], "module": "ESNext", "moduleResolution": "node", "noEmit": true, @@ -31,7 +31,7 @@ "strictNullChecks": true, "strictPropertyInitialization": true, "stripInternal": true, - "target": "ES2019", + "target": "ES2021", "types": ["node", "cypress"] } } diff --git a/docs/features/search/how-to-guides.md b/docs/features/search/how-to-guides.md index 01d85b8aa2..5cc2ab5f06 100644 --- a/docs/features/search/how-to-guides.md +++ b/docs/features/search/how-to-guides.md @@ -171,6 +171,6 @@ const highlightOverride = { }; ``` -[obj-mode]: https://nodejs.org/docs/latest-v14.x/api/stream.html#stream_object_mode -[read-stream]: https://nodejs.org/docs/latest-v14.x/api/stream.html#stream_readable_streams +[obj-mode]: https://nodejs.org/dist/latest-v16.x/docs/api/stream.html#stream_object_mode +[read-stream]: https://nodejs.org/dist/latest-v16.x/docs/api/stream.html#readable-streams [async-gen]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of#iterating_over_async_generators diff --git a/docs/getting-started/running-backstage-locally.md b/docs/getting-started/running-backstage-locally.md index 7cc6f6be6a..3e3e8b0727 100644 --- a/docs/getting-started/running-backstage-locally.md +++ b/docs/getting-started/running-backstage-locally.md @@ -21,12 +21,12 @@ This is made easy with a version manager such as # Installing current LTS release nvm install --lts > Installing latest LTS version. -> Downloading and installing node v14.15.1... -> Now using node v14.15.1 (npm v6.14.8) +> Downloading and installing node v16.16.0... +> Now using node v16.16.0 (npm v8.11.0) # Checking your version node --version -> v14.15.1 +> v16.16.0 ``` - Yarn diff --git a/docs/tutorials/quickstart-app-plugin.md b/docs/tutorials/quickstart-app-plugin.md index d1ca61a11f..ea0a511c93 100644 --- a/docs/tutorials/quickstart-app-plugin.md +++ b/docs/tutorials/quickstart-app-plugin.md @@ -20,7 +20,7 @@ title: Adding Custom Plugin to Existing Monorepo App > functionality, extend the Sidebar to make our life easy. Finally, we add > custom code to display GitHub repository information. > -> This document assumes you have Node.js 14 active along with Yarn and Python. +> This document assumes you have Node.js 16 active along with Yarn and Python. > Please note, that at the time of this writing, the current version is > 0.1.1-alpha.21. This guide can still be used with future versions, just, > verify as you go. If you run into issues, you can compare your setup with mine diff --git a/package.json b/package.json index 9f17e5ee36..417fd328c6 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "root", "private": true, "engines": { - "node": "14 || 16" + "node": "16 || 18" }, "scripts": { "dev": "concurrently \"yarn start\" \"yarn start-backend\"", diff --git a/packages/cli/config/tsconfig.json b/packages/cli/config/tsconfig.json index 33a8b0a9bd..5486f1900f 100644 --- a/packages/cli/config/tsconfig.json +++ b/packages/cli/config/tsconfig.json @@ -11,7 +11,7 @@ "incremental": true, "isolatedModules": true, "jsx": "react", - "lib": ["DOM", "DOM.Iterable", "ScriptHost", "ES2020"], + "lib": ["DOM", "DOM.Iterable", "ScriptHost", "ES2021"], "module": "ESNext", "moduleResolution": "node", "noEmit": false, @@ -32,7 +32,7 @@ "strictNullChecks": true, "strictPropertyInitialization": true, "stripInternal": true, - "target": "ES2019", + "target": "ES2021", "types": ["node", "jest", "webpack-env"], "useDefineForClassFields": true } diff --git a/packages/create-app/templates/default-app/package.json.hbs b/packages/create-app/templates/default-app/package.json.hbs index c5810d8880..adcd3a5774 100644 --- a/packages/create-app/templates/default-app/package.json.hbs +++ b/packages/create-app/templates/default-app/package.json.hbs @@ -3,7 +3,7 @@ "version": "1.0.0", "private": true, "engines": { - "node": "14 || 16" + "node": "16 || 18" }, "scripts": { "dev": "concurrently \"yarn start\" \"yarn start-backend\"", diff --git a/plugins/scaffolder-backend/scripts/build-nunjucks.js b/plugins/scaffolder-backend/scripts/build-nunjucks.js index b195f96159..8b98ac4305 100755 --- a/plugins/scaffolder-backend/scripts/build-nunjucks.js +++ b/plugins/scaffolder-backend/scripts/build-nunjucks.js @@ -58,7 +58,7 @@ require('esbuild') bundle: true, format: 'cjs', platform: 'node', - target: 'node14', + target: 'node16', banner: { js: NUNJUCKS_LICENSE }, external: ['fsevents'], outfile: path.resolve(__dirname, '../assets/nunjucks.js.txt'), From 384eaa230720e511706679dde5ed5769aefdfd1e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 9 Jul 2022 16:37:54 +0200 Subject: [PATCH 174/434] changests: add changesets for Node.js 18 bump Signed-off-by: Patrik Oldsberg --- .changeset/thirty-deers-float.md | 19 +++++++++++++++++++ .changeset/two-timers-pump.md | 5 +++++ 2 files changed, 24 insertions(+) create mode 100644 .changeset/thirty-deers-float.md create mode 100644 .changeset/two-timers-pump.md diff --git a/.changeset/thirty-deers-float.md b/.changeset/thirty-deers-float.md new file mode 100644 index 0000000000..198d6f909d --- /dev/null +++ b/.changeset/thirty-deers-float.md @@ -0,0 +1,19 @@ +--- +'@backstage/create-app': patch +--- + +Switched Node.js version to support version 16 & 18, rather than 14 & 16. To switch the Node.js version in your own project, apply the following change to the root `package.json`: + +```diff + "engines": { +- "node": "14 || 16" ++ "node": "16 || 18" + }, +``` + +As well as the following change to `packages/app/package.json`: + +```diff +- "@types/node": "^14.14.32", ++ "@types/node": "^16.11.26", +``` diff --git a/.changeset/two-timers-pump.md b/.changeset/two-timers-pump.md new file mode 100644 index 0000000000..e3c1ec2351 --- /dev/null +++ b/.changeset/two-timers-pump.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': minor +--- + +Switched `tsconfig.json` to target and support `ES2021`, in line with the bump to Node.js 16 & 18. From 1d43bcfa6d4090109bfabef06b49a4069120dd33 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 11 Jul 2022 13:49:25 +0200 Subject: [PATCH 175/434] auth-backend: add script for re-publishing openid-client Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .../scripts/republish-openid-client.js | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100755 plugins/auth-backend/scripts/republish-openid-client.js diff --git a/plugins/auth-backend/scripts/republish-openid-client.js b/plugins/auth-backend/scripts/republish-openid-client.js new file mode 100755 index 0000000000..9d4497e590 --- /dev/null +++ b/plugins/auth-backend/scripts/republish-openid-client.js @@ -0,0 +1,109 @@ +#!/usr/bin/env node +/* eslint-disable import/no-extraneous-dependencies */ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const fetch = require('node-fetch'); +const zlib = require('zlib'); + +// eslint-disable-next-line import/no-extraneous-dependencies +const libpub = require('libnpmpublish'); +const concatStream = require('concat-stream'); +const tar = require('tar-stream'); + +/* + +This works around an incompatibility in node versioning policies between Backstage and +the openid-client package. This script downloads a target version of the openid-client +package and re-publishes it as a new version of the openid-client-any-engine package. + +Usage: ./republish-openid-client.js + +Environment Variables: + +NPM_TOKEN: The NPM auth token to use for publishing. +NPM_OTP: The NPM OTP (2FA one time password) to use for publishing. + +*/ + +async function main(args) { + const [version] = args; + if (!version) { + throw new Error('No version provided, Usage: $0 '); + } + + const res = await fetch( + `https://registry.npmjs.org/openid-client/-/openid-client-${version}.tgz`, + ); + if (!res.ok) { + throw new Error(`Failed to fetch openid-client: ${res.status}`); + } + + const { data, manifest } = await new Promise((resolve, reject) => { + const extract = tar.extract(); + const pack = tar.pack(); + let foundPackageJson = undefined; + + res.body.pipe(zlib.createGunzip()).pipe(extract).on('error', reject); + + extract.on('entry', (header, stream, callback) => { + if (header.name === 'package/package.json') { + stream.pipe( + concatStream(fileContents => { + const packageJson = JSON.parse(fileContents.toString('utf8')); + packageJson.name = 'openid-client-any-engine'; + packageJson.description = + 'Re-publish of openid-client that allows any Node.js version above 12.19.0'; + packageJson.engines.node = '>=12.19.0'; + + foundPackageJson = packageJson; + + pack.entry( + { name: 'package/package.json' }, + JSON.stringify(packageJson, null, 2), + ); + callback(); + }), + ); + } else { + stream.pipe(pack.entry(header, callback)); + } + }); + + extract.on('finish', () => { + pack.finalize(); + }); + + pack + .pipe(zlib.createGzip()) + .pipe( + concatStream(d => { + resolve({ data: d, manifest: foundPackageJson }); + }), + ) + .on('error', reject); + }); + + await libpub.publish(manifest, data, { + token: process.env.NPM_TOKEN, + otp: process.env.NPM_OTP, + }); +} + +main(process.argv.slice(2)).catch(error => { + console.error(error); + process.exit(1); +}); From 4ca99cc3672f159f1c05a455241969190edd7e21 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 11 Jul 2022 14:01:10 +0200 Subject: [PATCH 176/434] auth-backend: use openid-client-any-engine Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- plugins/auth-backend/package.json | 2 +- yarn.lock | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 4b3d7910e5..a4033b90b0 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -60,7 +60,7 @@ "morgan": "^1.10.0", "node-cache": "^5.1.2", "node-fetch": "^2.6.7", - "openid-client": "^5.1.3", + "openid-client": "npm:openid-client-any-engine@^5.1.3", "passport": "^0.6.0", "passport-auth0": "^1.4.3", "passport-bitbucket-oauth2": "^0.1.2", diff --git a/yarn.lock b/yarn.lock index 909d52aaf6..f8130e8e31 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4296,7 +4296,7 @@ __metadata: msw: ^0.47.0 node-cache: ^5.1.2 node-fetch: ^2.6.7 - openid-client: ^5.1.3 + openid-client: "npm:openid-client-any-engine@^5.1.3" passport: ^0.6.0 passport-auth0: ^1.4.3 passport-bitbucket-oauth2: ^0.1.2 @@ -31238,18 +31238,6 @@ __metadata: languageName: node linkType: hard -"openid-client@npm:^5.1.3": - version: 5.1.10 - resolution: "openid-client@npm:5.1.10" - dependencies: - jose: ^4.1.4 - lru-cache: ^6.0.0 - object-hash: ^2.0.1 - oidc-token-hash: ^5.0.1 - checksum: 38a4bf08ea4ee4576043968307cf53f0369df224bd025c1bc348b295152df36c47d2a836dfe1505d15c6b79c05f86aadefad798bd3ea3ccbe90834be01f2245c - languageName: node - linkType: hard - "openid-client@npm:^5.1.6": version: 5.1.9 resolution: "openid-client@npm:5.1.9" @@ -31262,6 +31250,18 @@ __metadata: languageName: node linkType: hard +"openid-client@npm:openid-client-any-engine@^5.1.3": + version: 5.1.8 + resolution: "openid-client-any-engine@npm:5.1.8" + dependencies: + jose: ^4.1.4 + lru-cache: ^6.0.0 + object-hash: ^2.0.1 + oidc-token-hash: ^5.0.1 + checksum: dbd6f54a1d9ec50b82299d117556003670c796db553b35a50c4dfa57824f33721d12b2afc0d92a5dece936ef35d190f6dceab0258c65eb78d045dfb966b64831 + languageName: node + linkType: hard + "optionator@npm:^0.8.1": version: 0.8.3 resolution: "optionator@npm:0.8.3" From 009db8b28e7d7c9b892b4487afc6152758fbf1d8 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 31 Aug 2022 23:24:50 +0200 Subject: [PATCH 177/434] root: add node-gyp dep to fill missing dep of ssh2 Signed-off-by: Patrik Oldsberg --- package.json | 1 + yarn.lock | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 417fd328c6..11e92b530b 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "husky": "^8.0.0", "lint-staged": "^13.0.0", "minimist": "^1.2.5", + "node-gyp": "^9.1.0", "prettier": "^2.2.1", "semver": "^7.3.2", "shx": "^0.3.2", diff --git a/yarn.lock b/yarn.lock index f8130e8e31..6ea74fa461 100644 --- a/yarn.lock +++ b/yarn.lock @@ -30594,7 +30594,7 @@ __metadata: languageName: node linkType: hard -"node-gyp@npm:latest": +"node-gyp@npm:^9.1.0, node-gyp@npm:latest": version: 9.1.0 resolution: "node-gyp@npm:9.1.0" dependencies: @@ -35450,6 +35450,7 @@ __metadata: husky: ^8.0.0 lint-staged: ^13.0.0 minimist: ^1.2.5 + node-gyp: ^9.1.0 prettier: ^2.2.1 semver: ^7.3.2 shx: ^0.3.2 From 24b06ff92b39cf468161d4763c52b53729914a79 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 19 Aug 2022 11:26:57 +0200 Subject: [PATCH 178/434] root: work around openid-client with resolutions Signed-off-by: Patrik Oldsberg --- package.json | 1 + yarn.lock | 12 ------------ 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/package.json b/package.json index 11e92b530b..d793648768 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ ] }, "resolutions": { + "openid-client": "npm:openid-client-any-engine@^5.1.3", "@types/react": "^17", "@types/react-dom": "^17" }, diff --git a/yarn.lock b/yarn.lock index 6ea74fa461..8a6cfe1be6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -31238,18 +31238,6 @@ __metadata: languageName: node linkType: hard -"openid-client@npm:^5.1.6": - version: 5.1.9 - resolution: "openid-client@npm:5.1.9" - dependencies: - jose: ^4.1.4 - lru-cache: ^6.0.0 - object-hash: ^2.0.1 - oidc-token-hash: ^5.0.1 - checksum: 55390a7eceaafdc340a5f2ece576eb4863fcb4cd8840e4a7a1af66bbaf830623b18cf1dd0b8ce472c6f36c6313e78f92db48ca0c10eb8c681a81e5a3d607fc9f - languageName: node - linkType: hard - "openid-client@npm:openid-client-any-engine@^5.1.3": version: 5.1.8 resolution: "openid-client-any-engine@npm:5.1.8" From 6fb165fbd402c18c14ad9074f7419881c989c71f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 1 Sep 2022 00:53:53 +0200 Subject: [PATCH 179/434] scripts/check-type-dependencies: work around exports resolution Signed-off-by: Patrik Oldsberg --- scripts/check-type-dependencies.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/check-type-dependencies.js b/scripts/check-type-dependencies.js index ba362bd5ff..ebad9b6dfc 100755 --- a/scripts/check-type-dependencies.js +++ b/scripts/check-type-dependencies.js @@ -136,10 +136,21 @@ function findTypesPackage(dep, pkg) { return undefined; } catch { try { - // Finally check if it's just a .d.ts file + // Check if it's just a .d.ts file require.resolve(`${dep}.d.ts`, { paths: [pkg.dir] }); return undefined; } catch { + // And finally a naive lookup of the file directly, in case `require.resolve` fails us due to "exports" + if (fs.existsSync(resolvePath(pkg.dir, `node_modules/${dep}.d.ts`))) { + return undefined; + } + if ( + fs.existsSync( + resolvePath(pkg.dir, `../../node_modules/${dep}.d.ts`), + ) + ) { + return undefined; + } throw mkErr('MissingDepError', `No types for ${dep}`, { dep }); } } From cfb30b700c54419c32198882091043b07f5b6f24 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 22 Sep 2022 11:13:32 +0200 Subject: [PATCH 180/434] bump @kubernetes/client-node to 0.17.1 Signed-off-by: Patrik Oldsberg --- .changeset/silent-moles-chew.md | 8 ++ packages/backend-common/package.json | 2 +- plugins/kubernetes-backend/package.json | 2 +- plugins/kubernetes-common/package.json | 2 +- plugins/kubernetes/package.json | 2 +- yarn.lock | 111 +++++------------------- 6 files changed, 33 insertions(+), 94 deletions(-) create mode 100644 .changeset/silent-moles-chew.md diff --git a/.changeset/silent-moles-chew.md b/.changeset/silent-moles-chew.md new file mode 100644 index 0000000000..09d00ff81b --- /dev/null +++ b/.changeset/silent-moles-chew.md @@ -0,0 +1,8 @@ +--- +'@backstage/backend-common': patch +'@backstage/plugin-kubernetes': patch +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-kubernetes-common': patch +--- + +Bumped `@kubernetes/client-node` to `^0.17.1`. diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 94b2338ab0..7dde8e6512 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -42,7 +42,7 @@ "@backstage/types": "workspace:^", "@google-cloud/storage": "^6.0.0", "@keyv/redis": "^2.2.3", - "@kubernetes/client-node": "^0.17.0", + "@kubernetes/client-node": "^0.17.1", "@manypkg/get-packages": "^1.1.3", "@octokit/rest": "^19.0.3", "@types/cors": "^2.8.6", diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 4082bd5b3a..2cef29c4bb 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -43,7 +43,7 @@ "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-kubernetes-common": "workspace:^", "@google-cloud/container": "^4.0.0", - "@kubernetes/client-node": "^0.17.0", + "@kubernetes/client-node": "^0.17.1", "@types/express": "^4.17.6", "@types/luxon": "^3.0.0", "aws-sdk": "^2.840.0", diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index 48c04fb222..5ef960a396 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -39,7 +39,7 @@ }, "dependencies": { "@backstage/catalog-model": "workspace:^", - "@kubernetes/client-node": "^0.17.0" + "@kubernetes/client-node": "^0.17.1" }, "devDependencies": { "@backstage/cli": "workspace:^" diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index ee4da4b55f..349642f65a 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -40,7 +40,7 @@ "@backstage/plugin-catalog-react": "workspace:^", "@backstage/plugin-kubernetes-common": "workspace:^", "@backstage/theme": "workspace:^", - "@kubernetes/client-node": "^0.17.0", + "@kubernetes/client-node": "^0.17.1", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", diff --git a/yarn.lock b/yarn.lock index 8a6cfe1be6..d967f0a877 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3148,7 +3148,7 @@ __metadata: "@backstage/types": "workspace:^" "@google-cloud/storage": ^6.0.0 "@keyv/redis": ^2.2.3 - "@kubernetes/client-node": ^0.17.0 + "@kubernetes/client-node": ^0.17.1 "@manypkg/get-packages": ^1.1.3 "@octokit/rest": ^19.0.3 "@types/archiver": ^5.1.0 @@ -6220,7 +6220,7 @@ __metadata: "@backstage/plugin-auth-node": "workspace:^" "@backstage/plugin-kubernetes-common": "workspace:^" "@google-cloud/container": ^4.0.0 - "@kubernetes/client-node": ^0.17.0 + "@kubernetes/client-node": ^0.17.1 "@types/aws4": ^1.5.1 "@types/express": ^4.17.6 "@types/luxon": ^3.0.0 @@ -6249,7 +6249,7 @@ __metadata: dependencies: "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" - "@kubernetes/client-node": ^0.17.0 + "@kubernetes/client-node": ^0.17.1 languageName: unknown linkType: soft @@ -6268,7 +6268,7 @@ __metadata: "@backstage/plugin-kubernetes-common": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" - "@kubernetes/client-node": ^0.17.0 + "@kubernetes/client-node": ^0.17.1 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.57 @@ -10671,17 +10671,10 @@ __metadata: languageName: node linkType: hard -"@kubernetes/client-node@npm:^0.17.0": - version: 0.17.0 - resolution: "@kubernetes/client-node@npm:0.17.0" +"@kubernetes/client-node@npm:^0.17.1": + version: 0.17.1 + resolution: "@kubernetes/client-node@npm:0.17.1" dependencies: - "@types/js-yaml": ^4.0.1 - "@types/node": ^10.12.0 - "@types/request": ^2.47.1 - "@types/stream-buffers": ^3.0.3 - "@types/tar": ^4.0.3 - "@types/underscore": ^1.8.9 - "@types/ws": ^6.0.1 byline: ^5.0.0 execa: 5.0.0 isomorphic-ws: ^4.0.1 @@ -10697,7 +10690,10 @@ __metadata: tslib: ^1.9.3 underscore: ^1.9.1 ws: ^7.3.1 - checksum: 5a6edce96946966d8b61359ab043b42e69d1b31178133bc3bf4b5a5c9191766986e08f85d6ae814b56546ed20389817a79dca5101342543d79d750f30cba21f7 + dependenciesMeta: + openid-client: + optional: true + checksum: 834ab0ca1f8583b06c4102395ad712c115a6f99201f8dd7f0b59c1a0a5da67b006d1fe5857ad909d762b9cf82a75503665df19fdb640bf620f6123ddb36c8872 languageName: node linkType: hard @@ -13451,13 +13447,6 @@ __metadata: languageName: node linkType: hard -"@types/caseless@npm:*": - version: 0.12.2 - resolution: "@types/caseless@npm:0.12.2" - checksum: 430d15911184ad11e0a8aa21d1ec15fcc93b90b63570c37bf16ebd34457482bfc8de3f5eb6771e0ef986ce183270d4297823b0f492c346255967e78f7292388b - languageName: node - linkType: hard - "@types/classnames@npm:^2.2.9": version: 2.3.1 resolution: "@types/classnames@npm:2.3.1" @@ -14120,7 +14109,7 @@ __metadata: languageName: node linkType: hard -"@types/js-yaml@npm:^4.0.0, @types/js-yaml@npm:^4.0.1": +"@types/js-yaml@npm:^4.0.0": version: 4.0.5 resolution: "@types/js-yaml@npm:4.0.5" checksum: 7dcac8c50fec31643cc9d6444b5503239a861414cdfaa7ae9a38bc22597c4d850c4b8cec3d82d73b3fbca408348ce223b0408d598b32e094470dfffc6d486b4d @@ -14331,15 +14320,6 @@ __metadata: languageName: node linkType: hard -"@types/minipass@npm:*": - version: 3.3.5 - resolution: "@types/minipass@npm:3.3.5" - dependencies: - minipass: "*" - checksum: 160f4ae5416697c947e0c0ee1225fe25973acf73a30d01bdf202447f12bd32ba3ea33d2fc4f2517a038dc408022a5aff5f7a1d92da0157a9b04276d1b0209550 - languageName: node - linkType: hard - "@types/mock-fs@npm:^4.10.0, @types/mock-fs@npm:^4.13.0": version: 4.13.1 resolution: "@types/mock-fs@npm:4.13.1" @@ -14394,7 +14374,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:>= 8, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0": +"@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0": version: 18.11.9 resolution: "@types/node@npm:18.11.9" checksum: cc0aae109e9b7adefc32eecb838d6fad931663bb06484b5e9cbbbf74865c721b03d16fd8d74ad90e31dbe093d956a7c2c306ba5429ba0c00f3f7505103d7a496 @@ -14408,7 +14388,14 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^10.1.0, @types/node@npm:^10.12.0": +"@types/node@npm:>= 8": + version: 18.7.4 + resolution: "@types/node@npm:18.7.4" + checksum: 051d2147e4d8129fceb63ee9384259b2f224dbc4e4b0c46d96a6b61cbaad4e3fe4060950e7f4fc3d5692b1e6ea47e68ad03b61155754bfa169593747cfe3f8f4 + languageName: node + linkType: hard + +"@types/node@npm:^10.1.0": version: 10.17.60 resolution: "@types/node@npm:10.17.60" checksum: 2cdb3a77d071ba8513e5e8306fa64bf50e3c3302390feeaeff1fd325dd25c8441369715dfc8e3701011a72fed5958c7dfa94eb9239a81b3c286caa4d97db6eef @@ -14753,18 +14740,6 @@ __metadata: languageName: node linkType: hard -"@types/request@npm:^2.47.1": - version: 2.48.5 - resolution: "@types/request@npm:2.48.5" - dependencies: - "@types/caseless": "*" - "@types/node": "*" - "@types/tough-cookie": "*" - form-data: ^2.5.0 - checksum: 02572a0558b9a95ae1a2fa3912b45c4c12f587e25773b2d9bdbf5dfa6f2da5e3787d22256ee0dc4836250f39cf2dcb39fc4ded5bf554c0f948a623c8772e8bd3 - languageName: node - linkType: hard - "@types/resize-observer-browser@npm:^0.1.6": version: 0.1.7 resolution: "@types/resize-observer-browser@npm:0.1.7" @@ -14951,15 +14926,6 @@ __metadata: languageName: node linkType: hard -"@types/stream-buffers@npm:^3.0.3": - version: 3.0.3 - resolution: "@types/stream-buffers@npm:3.0.3" - dependencies: - "@types/node": "*" - checksum: c3456fa2a18f89d31c54fe169621d8288a9735fb7e92aba45786642659d93be26fa0b4caa5c1043b21f4cfaeeefc24d247fa833586a8a0f3aecedf03adb7b5ac - languageName: node - linkType: hard - "@types/styled-jsx@npm:^2.2.8": version: 2.2.8 resolution: "@types/styled-jsx@npm:2.2.8" @@ -15006,16 +14972,6 @@ __metadata: languageName: node linkType: hard -"@types/tar@npm:^4.0.3": - version: 4.0.5 - resolution: "@types/tar@npm:4.0.5" - dependencies: - "@types/minipass": "*" - "@types/node": "*" - checksum: 476d8af8f4cffcd973de026e043271be76171f9cb07bb869ba38a193ce89ee361b59ff8484e28b57216266063d91502c5208d2ab6b976e7370d9bdf4c4dadadc - languageName: node - linkType: hard - "@types/tar@npm:^6.1.1": version: 6.1.3 resolution: "@types/tar@npm:6.1.3" @@ -15085,13 +15041,6 @@ __metadata: languageName: node linkType: hard -"@types/underscore@npm:^1.8.9": - version: 1.10.23 - resolution: "@types/underscore@npm:1.10.23" - checksum: 5e9458888e8c09a0f61f93f5958d4ce57e02e317b21444319f7e4a11796445e58a78d6c743dad17365aa8fb9c31fa23d5f4d30a9047fa2df30d446ccc5e42023 - languageName: node - linkType: hard - "@types/unist@npm:*, @types/unist@npm:^2.0.0": version: 2.0.6 resolution: "@types/unist@npm:2.0.6" @@ -15141,15 +15090,6 @@ __metadata: languageName: node linkType: hard -"@types/ws@npm:^6.0.1": - version: 6.0.4 - resolution: "@types/ws@npm:6.0.4" - dependencies: - "@types/node": "*" - checksum: b2656a76bfad0c17bb1e3fc237ba7122431c1373669977ed8edef45934c82f71c75d8c71f0a576dc6d98b0954fd94cae0166c6b4ccb40f7e0ee29cc92673519c - languageName: node - linkType: hard - "@types/ws@npm:^8.0.0, @types/ws@npm:^8.5.1": version: 8.5.3 resolution: "@types/ws@npm:8.5.3" @@ -30074,15 +30014,6 @@ __metadata: languageName: node linkType: hard -"minipass@npm:*": - version: 3.3.4 - resolution: "minipass@npm:3.3.4" - dependencies: - yallist: ^4.0.0 - checksum: 5d95a7738c54852ba78d484141e850c792e062666a2d0c681a5ac1021275beb7e1acb077e59f9523ff1defb80901aea4e30fac10ded9a20a25d819a42916ef1b - languageName: node - linkType: hard - "minipass@npm:^3.0.0, minipass@npm:^3.1.0, minipass@npm:^3.1.1, minipass@npm:^3.1.3, minipass@npm:^3.1.6": version: 3.1.6 resolution: "minipass@npm:3.1.6" From 7bcb96a6683bde9521d51c23fab26e13a5b9d731 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 31 Aug 2022 23:36:43 +0200 Subject: [PATCH 181/434] workflows: work around missing node-canvas binaries for node 18 Signed-off-by: Patrik Oldsberg --- .github/workflows/ci.yml | 7 +++++++ .github/workflows/deploy_nightly.yml | 2 ++ .github/workflows/deploy_packages.yml | 8 ++++++++ .github/workflows/verify_e2e-linux.yml | 6 ++++++ .github/workflows/verify_e2e-techdocs.yml | 7 +++++++ .github/workflows/verify_e2e-windows.yml | 10 ++++++++++ .github/workflows/verify_kubernetes.yml | 6 ++++++ .github/workflows/verify_windows.yml | 9 +++++++++ 8 files changed, 55 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ab979593c..1d8040e993 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,13 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth + # Needed until there are pre-built binaries of node-canvas for Node 18 + - name: node-canvas dependencies + if: matrix.node-version == '18.x' + run: | + sudo apt update + sudo apt install -y build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev + - name: yarn install uses: backstage/actions/yarn-install@v0.5.6 with: diff --git a/.github/workflows/deploy_nightly.yml b/.github/workflows/deploy_nightly.yml index 74dc60783a..bb41481cb1 100644 --- a/.github/workflows/deploy_nightly.yml +++ b/.github/workflows/deploy_nightly.yml @@ -25,6 +25,8 @@ jobs: with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth + + # Needed until there are pre-built binaries for Node 18 - name: yarn install uses: backstage/actions/yarn-install@v0.5.6 with: diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index 56ff61c75b..6fffe4d60a 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -66,6 +66,14 @@ jobs: with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth + + # Needed until there are pre-built binaries of node-canvas for Node 18 + - name: node-canvas dependencies + if: matrix.node-version == '18.x' + run: | + sudo apt update + sudo apt install -y build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev + - name: yarn install uses: backstage/actions/yarn-install@v0.5.6 with: diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index fefdd1fdd5..db8f6662fe 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -51,6 +51,12 @@ jobs: with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth + # Needed until there are pre-built binaries of node-canvas for Node 18 + - name: node-canvas dependencies + if: matrix.node-version == '18.x' + run: | + sudo apt update + sudo apt install -y build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev - name: yarn install uses: backstage/actions/yarn-install@v0.5.6 with: diff --git a/.github/workflows/verify_e2e-techdocs.yml b/.github/workflows/verify_e2e-techdocs.yml index 8d59d15899..0d6836ad3a 100644 --- a/.github/workflows/verify_e2e-techdocs.yml +++ b/.github/workflows/verify_e2e-techdocs.yml @@ -28,6 +28,13 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v3 + # Needed until there are pre-built binaries of node-canvas for Node 18 + - name: node-canvas dependencies + if: matrix.node-version == '18.x' + run: | + sudo apt update + sudo apt install -y build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev + - name: install dependencies run: yarn install --immutable diff --git a/.github/workflows/verify_e2e-windows.yml b/.github/workflows/verify_e2e-windows.yml index fc29c1f03b..9d1ba8a154 100644 --- a/.github/workflows/verify_e2e-windows.yml +++ b/.github/workflows/verify_e2e-windows.yml @@ -52,6 +52,16 @@ jobs: uses: microsoft/setup-msbuild@v1.0.3 - name: setup chrome uses: browser-actions/setup-chrome@latest + + # Needed until there are pre-built binaries of node-canvas for Node 18 + - name: node-canvas dependencies + if: matrix.node-version == '18.x' + # From https://github.com/Automattic/node-canvas/blob/master/.github/workflows/ci.yaml + run: | + Invoke-WebRequest "https://ftp-osl.osuosl.org/pub/gnome/binaries/win64/gtk+/2.22/gtk+-bundle_2.22.1-20101229_win64.zip" -OutFile "gtk.zip" + Expand-Archive gtk.zip -DestinationPath "C:\GTK" + Invoke-WebRequest "https://downloads.sourceforge.net/project/libjpeg-turbo/2.0.4/libjpeg-turbo-2.0.4-vc64.exe" -OutFile "libjpeg.exe" -UserAgent NativeHost + .\libjpeg.exe /S - name: yarn install run: yarn install --immutable diff --git a/.github/workflows/verify_kubernetes.yml b/.github/workflows/verify_kubernetes.yml index e8c248699a..ea5e3ebe4e 100644 --- a/.github/workflows/verify_kubernetes.yml +++ b/.github/workflows/verify_kubernetes.yml @@ -27,6 +27,12 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth + # Needed until there are pre-built binaries of node-canvas for Node 18 + - name: node-canvas dependencies + if: matrix.node-version == '18.x' + run: | + sudo apt update + sudo apt install -y build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev - name: yarn install uses: backstage/actions/yarn-install@v0.5.6 with: diff --git a/.github/workflows/verify_windows.yml b/.github/workflows/verify_windows.yml index 75a0633cbe..a092c8d405 100644 --- a/.github/workflows/verify_windows.yml +++ b/.github/workflows/verify_windows.yml @@ -32,6 +32,15 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth + # Needed until there are pre-built binaries of node-canvas for Node 18 + - name: node-canvas dependencies + if: matrix.node-version == '18.x' + # From https://github.com/Automattic/node-canvas/blob/master/.github/workflows/ci.yaml + run: | + Invoke-WebRequest "https://ftp-osl.osuosl.org/pub/gnome/binaries/win64/gtk+/2.22/gtk+-bundle_2.22.1-20101229_win64.zip" -OutFile "gtk.zip" + Expand-Archive gtk.zip -DestinationPath "C:\GTK" + Invoke-WebRequest "https://downloads.sourceforge.net/project/libjpeg-turbo/2.0.4/libjpeg-turbo-2.0.4-vc64.exe" -OutFile "libjpeg.exe" -UserAgent NativeHost + .\libjpeg.exe /S # Windows file operation slowness means there's no point caching this - name: yarn install run: yarn install --immutable From 21339ea5951c9f8f2b3782e82c8d89fa458470b9 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 22 Sep 2022 14:51:07 +0200 Subject: [PATCH 182/434] backend-common: work around premature close errors Signed-off-by: Patrik Oldsberg --- .changeset/swift-suits-reply.md | 5 ++ .../src/reading/GerritUrlReader.ts | 8 +-- .../src/reading/tree/ReadableArrayResponse.ts | 10 ++- .../src/reading/tree/TarArchiveResponse.ts | 15 ++--- .../src/reading/tree/util.test.ts | 63 +++++++++++++++++++ .../backend-common/src/reading/tree/util.ts | 35 ++++++++--- 6 files changed, 109 insertions(+), 27 deletions(-) create mode 100644 .changeset/swift-suits-reply.md create mode 100644 packages/backend-common/src/reading/tree/util.test.ts diff --git a/.changeset/swift-suits-reply.md b/.changeset/swift-suits-reply.md new file mode 100644 index 0000000000..f81f39bee2 --- /dev/null +++ b/.changeset/swift-suits-reply.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Refactored internal usage of the build-in `pipeline` from `'stream'` to work around `tar` bug in Node 18. diff --git a/packages/backend-common/src/reading/GerritUrlReader.ts b/packages/backend-common/src/reading/GerritUrlReader.ts index 59b33bb2cb..9ec5e35f65 100644 --- a/packages/backend-common/src/reading/GerritUrlReader.ts +++ b/packages/backend-common/src/reading/GerritUrlReader.ts @@ -32,8 +32,7 @@ import fetch, { Response } from 'node-fetch'; import os from 'os'; import { join as joinPath } from 'path'; import tar from 'tar'; -import { pipeline as pipelineCb, Readable } from 'stream'; -import { promisify } from 'util'; +import { Readable } from 'stream'; import { ReaderFactory, ReadTreeOptions, @@ -45,8 +44,7 @@ import { UrlReader, } from './types'; import { ScmIntegrations } from '@backstage/integration'; - -const pipeline = promisify(pipelineCb); +import { pipeStream } from './tree/util'; const createTemporaryDirectory = async (workDir: string): Promise => await fs.mkdtemp(joinPath(workDir, '/gerrit-clone-')); @@ -197,7 +195,7 @@ export class GerritUrlReader implements UrlReader { }); const data = await new Promise(async resolve => { - await pipeline( + await pipeStream( tar.create({ cwd: tempDir }, ['']), concatStream(resolve), ); diff --git a/packages/backend-common/src/reading/tree/ReadableArrayResponse.ts b/packages/backend-common/src/reading/tree/ReadableArrayResponse.ts index eabaa3bc56..da145b0f4b 100644 --- a/packages/backend-common/src/reading/tree/ReadableArrayResponse.ts +++ b/packages/backend-common/src/reading/tree/ReadableArrayResponse.ts @@ -19,17 +19,15 @@ import platformPath, { basename } from 'path'; import getRawBody from 'raw-body'; import fs from 'fs-extra'; -import { promisify } from 'util'; import tar from 'tar'; -import { pipeline as pipelineCb, Readable } from 'stream'; +import { Readable } from 'stream'; import { ReadTreeResponse, ReadTreeResponseFile, ReadTreeResponseDirOptions, FromReadableArrayOptions, } from '../types'; - -const pipeline = promisify(pipelineCb); +import { pipeStream } from './util'; /** * Wraps a array of Readable objects into a tree response reader. @@ -75,7 +73,7 @@ export class ReadableArrayResponse implements ReadTreeResponse { try { const data = await new Promise(async resolve => { - await pipeline( + await pipeStream( tar.create({ cwd: tmpDir }, ['']), concatStream(resolve), ); @@ -95,7 +93,7 @@ export class ReadableArrayResponse implements ReadTreeResponse { for (let i = 0; i < this.stream.length; i++) { if (!this.stream[i].path.endsWith('/')) { - await pipeline( + await pipeStream( this.stream[i].data, fs.createWriteStream( platformPath.join(dir, basename(this.stream[i].path)), diff --git a/packages/backend-common/src/reading/tree/TarArchiveResponse.ts b/packages/backend-common/src/reading/tree/TarArchiveResponse.ts index 493e283c5f..7d0d8f42a2 100644 --- a/packages/backend-common/src/reading/tree/TarArchiveResponse.ts +++ b/packages/backend-common/src/reading/tree/TarArchiveResponse.ts @@ -17,21 +17,18 @@ import concatStream from 'concat-stream'; import fs from 'fs-extra'; import platformPath from 'path'; -import { pipeline as pipelineCb, Readable } from 'stream'; +import { Readable } from 'stream'; import tar, { Parse, ParseStream, ReadEntry } from 'tar'; -import { promisify } from 'util'; import { ReadTreeResponse, ReadTreeResponseDirOptions, ReadTreeResponseFile, } from '../types'; -import { stripFirstDirectoryFromPath } from './util'; +import { pipeStream, stripFirstDirectoryFromPath } from './util'; // Tar types for `Parse` is not a proper constructor, but it should be const TarParseStream = Parse as unknown as { new (): ParseStream }; -const pipeline = promisify(pipelineCb); - /** * Wraps a tar archive stream into a tree response reader. */ @@ -99,7 +96,7 @@ export class TarArchiveResponse implements ReadTreeResponse { } const content = new Promise(async resolve => { - await pipeline(entry, concatStream(resolve)); + await pipeStream(entry, concatStream(resolve)); }); files.push({ @@ -110,7 +107,7 @@ export class TarArchiveResponse implements ReadTreeResponse { entry.resume(); }); - await pipeline(this.stream, parser); + await pipeStream(this.stream, parser); return files; } @@ -128,7 +125,7 @@ export class TarArchiveResponse implements ReadTreeResponse { try { const data = await new Promise(async resolve => { - await pipeline( + await pipeStream( tar.create({ cwd: tmpDir }, ['']), concatStream(resolve), ); @@ -152,7 +149,7 @@ export class TarArchiveResponse implements ReadTreeResponse { let filterError: Error | undefined = undefined; - await pipeline( + await pipeStream( this.stream, tar.extract({ strip, diff --git a/packages/backend-common/src/reading/tree/util.test.ts b/packages/backend-common/src/reading/tree/util.test.ts new file mode 100644 index 0000000000..662ff3f194 --- /dev/null +++ b/packages/backend-common/src/reading/tree/util.test.ts @@ -0,0 +1,63 @@ +/* + * 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 { Readable, Writable } from 'stream'; +import { pipeStream, streamToBuffer } from './util'; + +describe('pipeStream', () => { + it('should pipe a stream', async () => { + const from = Readable.from(['hello']); + + let written = ''; + const to = new Writable({ + write(chunk, encoding, callback) { + written = `${encoding}:${chunk}`; + callback(); + }, + }); + + await pipeStream(from, to); + expect(written).toBe('buffer:hello'); + }); + + it('should forward errors', async () => { + const from = new Readable({ + read() { + throw new Error('oh no'); + }, + }); + const to = new Writable(); + + await expect(pipeStream(from, to)).rejects.toThrow('oh no'); + }); +}); + +describe('streamToBuffer', () => { + it('should read a stream', async () => { + await expect(streamToBuffer(Readable.from(['hello']))).resolves.toBe( + 'hello', + ); + }); + + it('should fail on errors', async () => { + const stream = new Readable({ + read() { + throw new Error('oh no'); + }, + }); + await expect(streamToBuffer(stream)).rejects.toThrow('oh no'); + }); +}); diff --git a/packages/backend-common/src/reading/tree/util.ts b/packages/backend-common/src/reading/tree/util.ts index 63192102f4..a4e9a6686c 100644 --- a/packages/backend-common/src/reading/tree/util.ts +++ b/packages/backend-common/src/reading/tree/util.ts @@ -14,12 +14,9 @@ * limitations under the License. */ -import { Readable, pipeline as pipelineCb } from 'stream'; -import { promisify } from 'util'; +import { Readable, finished } from 'stream'; import concatStream from 'concat-stream'; -const pipeline = promisify(pipelineCb); - // Matches a directory name + one `/` at the start of any string, // containing any character except `/` one or more times, and ending with a `/` // e.g. Will match `dirA/` in `dirA/dirB/file.ext` @@ -29,13 +26,37 @@ export function stripFirstDirectoryFromPath(path: string): string { return path.replace(directoryNameRegex, ''); } +// Custom pipeline implementation, since pipeline doesn't work well with tar on node 18 +// See https://github.com/npm/node-tar/issues/321 +export function pipeStream( + from: NodeJS.ReadableStream, + to: NodeJS.WritableStream, +): Promise { + return new Promise((resolve, reject) => { + from.pipe(to); + finished(from, fromErr => { + if (fromErr) { + reject(fromErr); + } else { + finished(to, toErr => { + if (toErr) { + reject(toErr); + } else { + resolve(); + } + }); + } + }); + }); +} + // Collect the stream into a buffer and return -export const streamToBuffer = (stream: Readable): Promise => { +export function streamToBuffer(stream: Readable): Promise { return new Promise(async (resolve, reject) => { try { - await pipeline(stream, concatStream(resolve)); + await pipeStream(stream, concatStream(resolve)); } catch (ex) { reject(ex); } }); -}; +} From 90e5b42258bbbbe5ac057ecd2d926cdb92295f0f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 22 Sep 2022 17:44:51 +0200 Subject: [PATCH 183/434] catalog-backend-module-github: work around lack of msw fetch support in Node 18 Signed-off-by: Patrik Oldsberg --- plugins/catalog-backend-module-github/src/lib/github.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/catalog-backend-module-github/src/lib/github.test.ts b/plugins/catalog-backend-module-github/src/lib/github.test.ts index 25878c2005..0002c4cef0 100644 --- a/plugins/catalog-backend-module-github/src/lib/github.test.ts +++ b/plugins/catalog-backend-module-github/src/lib/github.test.ts @@ -25,6 +25,11 @@ import { getOrganizationRepositories, QueryResponse, } from './github'; +import fetch from 'node-fetch'; + +// Workaround for Node.js 18, where native fetch is available, but not yet picked up by msw +// TODO(Rugvip): remove once https://github.com/mswjs/msw/issues/1388 is resolved +(global as any).fetch = fetch; describe('github', () => { const server = setupServer(); From 428e5d55960e694c17ce5be4104d22f08253b8a6 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 1 Nov 2022 15:29:59 +0100 Subject: [PATCH 184/434] Revert "root: work around openid-client with resolutions" This reverts commit 59bcd774351a86193eaa2fe8360cfc867a4f16da. Signed-off-by: Patrik Oldsberg --- package.json | 1 - yarn.lock | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index d793648768..11e92b530b 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,6 @@ ] }, "resolutions": { - "openid-client": "npm:openid-client-any-engine@^5.1.3", "@types/react": "^17", "@types/react-dom": "^17" }, diff --git a/yarn.lock b/yarn.lock index d967f0a877..5e34fdf91e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -31169,6 +31169,18 @@ __metadata: languageName: node linkType: hard +"openid-client@npm:^5.1.6": + version: 5.1.9 + resolution: "openid-client@npm:5.1.9" + dependencies: + jose: ^4.1.4 + lru-cache: ^6.0.0 + object-hash: ^2.0.1 + oidc-token-hash: ^5.0.1 + checksum: 55390a7eceaafdc340a5f2ece576eb4863fcb4cd8840e4a7a1af66bbaf830623b18cf1dd0b8ce472c6f36c6313e78f92db48ca0c10eb8c681a81e5a3d607fc9f + languageName: node + linkType: hard + "openid-client@npm:openid-client-any-engine@^5.1.3": version: 5.1.8 resolution: "openid-client-any-engine@npm:5.1.8" From 40c578eaf62fa1135f9be1c85d84be19be7399dc Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 1 Nov 2022 15:30:02 +0100 Subject: [PATCH 185/434] Revert "auth-backend: use openid-client-any-engine" This reverts commit fabe460cd5b4c3f5e9b75d5cb5635a87440c6465. Signed-off-by: Patrik Oldsberg --- plugins/auth-backend/package.json | 2 +- yarn.lock | 16 ++-------------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index a4033b90b0..4b3d7910e5 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -60,7 +60,7 @@ "morgan": "^1.10.0", "node-cache": "^5.1.2", "node-fetch": "^2.6.7", - "openid-client": "npm:openid-client-any-engine@^5.1.3", + "openid-client": "^5.1.3", "passport": "^0.6.0", "passport-auth0": "^1.4.3", "passport-bitbucket-oauth2": "^0.1.2", diff --git a/yarn.lock b/yarn.lock index 5e34fdf91e..286907726c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4296,7 +4296,7 @@ __metadata: msw: ^0.47.0 node-cache: ^5.1.2 node-fetch: ^2.6.7 - openid-client: "npm:openid-client-any-engine@^5.1.3" + openid-client: ^5.1.3 passport: ^0.6.0 passport-auth0: ^1.4.3 passport-bitbucket-oauth2: ^0.1.2 @@ -31169,7 +31169,7 @@ __metadata: languageName: node linkType: hard -"openid-client@npm:^5.1.6": +"openid-client@npm:^5.1.3, openid-client@npm:^5.1.6": version: 5.1.9 resolution: "openid-client@npm:5.1.9" dependencies: @@ -31181,18 +31181,6 @@ __metadata: languageName: node linkType: hard -"openid-client@npm:openid-client-any-engine@^5.1.3": - version: 5.1.8 - resolution: "openid-client-any-engine@npm:5.1.8" - dependencies: - jose: ^4.1.4 - lru-cache: ^6.0.0 - object-hash: ^2.0.1 - oidc-token-hash: ^5.0.1 - checksum: dbd6f54a1d9ec50b82299d117556003670c796db553b35a50c4dfa57824f33721d12b2afc0d92a5dece936ef35d190f6dceab0258c65eb78d045dfb966b64831 - languageName: node - linkType: hard - "optionator@npm:^0.8.1": version: 0.8.3 resolution: "optionator@npm:0.8.3" From 442cbba6256302ed7654099a021bf88fd24a3c72 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 1 Nov 2022 15:30:04 +0100 Subject: [PATCH 186/434] Revert "auth-backend: add script for re-publishing openid-client" This reverts commit 6c7a73e597bc53e0bbe93eab2518b5d4e4b26a05. Signed-off-by: Patrik Oldsberg --- .../scripts/republish-openid-client.js | 109 ------------------ 1 file changed, 109 deletions(-) delete mode 100755 plugins/auth-backend/scripts/republish-openid-client.js diff --git a/plugins/auth-backend/scripts/republish-openid-client.js b/plugins/auth-backend/scripts/republish-openid-client.js deleted file mode 100755 index 9d4497e590..0000000000 --- a/plugins/auth-backend/scripts/republish-openid-client.js +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env node -/* eslint-disable import/no-extraneous-dependencies */ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -const fetch = require('node-fetch'); -const zlib = require('zlib'); - -// eslint-disable-next-line import/no-extraneous-dependencies -const libpub = require('libnpmpublish'); -const concatStream = require('concat-stream'); -const tar = require('tar-stream'); - -/* - -This works around an incompatibility in node versioning policies between Backstage and -the openid-client package. This script downloads a target version of the openid-client -package and re-publishes it as a new version of the openid-client-any-engine package. - -Usage: ./republish-openid-client.js - -Environment Variables: - -NPM_TOKEN: The NPM auth token to use for publishing. -NPM_OTP: The NPM OTP (2FA one time password) to use for publishing. - -*/ - -async function main(args) { - const [version] = args; - if (!version) { - throw new Error('No version provided, Usage: $0 '); - } - - const res = await fetch( - `https://registry.npmjs.org/openid-client/-/openid-client-${version}.tgz`, - ); - if (!res.ok) { - throw new Error(`Failed to fetch openid-client: ${res.status}`); - } - - const { data, manifest } = await new Promise((resolve, reject) => { - const extract = tar.extract(); - const pack = tar.pack(); - let foundPackageJson = undefined; - - res.body.pipe(zlib.createGunzip()).pipe(extract).on('error', reject); - - extract.on('entry', (header, stream, callback) => { - if (header.name === 'package/package.json') { - stream.pipe( - concatStream(fileContents => { - const packageJson = JSON.parse(fileContents.toString('utf8')); - packageJson.name = 'openid-client-any-engine'; - packageJson.description = - 'Re-publish of openid-client that allows any Node.js version above 12.19.0'; - packageJson.engines.node = '>=12.19.0'; - - foundPackageJson = packageJson; - - pack.entry( - { name: 'package/package.json' }, - JSON.stringify(packageJson, null, 2), - ); - callback(); - }), - ); - } else { - stream.pipe(pack.entry(header, callback)); - } - }); - - extract.on('finish', () => { - pack.finalize(); - }); - - pack - .pipe(zlib.createGzip()) - .pipe( - concatStream(d => { - resolve({ data: d, manifest: foundPackageJson }); - }), - ) - .on('error', reject); - }); - - await libpub.publish(manifest, data, { - token: process.env.NPM_TOKEN, - otp: process.env.NPM_OTP, - }); -} - -main(process.argv.slice(2)).catch(error => { - console.error(error); - process.exit(1); -}); From 2008aec2b69ba005a4b744f25a2143bf15818b2c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 1 Nov 2022 15:34:34 +0100 Subject: [PATCH 187/434] pin @kubernetes/client-node to working version Signed-off-by: Patrik Oldsberg --- .changeset/silent-moles-chew.md | 2 +- packages/backend-common/package.json | 2 +- plugins/kubernetes-backend/package.json | 2 +- plugins/kubernetes-common/package.json | 2 +- plugins/kubernetes/package.json | 2 +- yarn.lock | 93 +++++++++++++++++++++---- 6 files changed, 85 insertions(+), 18 deletions(-) diff --git a/.changeset/silent-moles-chew.md b/.changeset/silent-moles-chew.md index 09d00ff81b..be71272e28 100644 --- a/.changeset/silent-moles-chew.md +++ b/.changeset/silent-moles-chew.md @@ -5,4 +5,4 @@ '@backstage/plugin-kubernetes-common': patch --- -Bumped `@kubernetes/client-node` to `^0.17.1`. +Pin `@kubernetes/client-node` version to `0.17.0`. diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 7dde8e6512..2847e86504 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -42,7 +42,7 @@ "@backstage/types": "workspace:^", "@google-cloud/storage": "^6.0.0", "@keyv/redis": "^2.2.3", - "@kubernetes/client-node": "^0.17.1", + "@kubernetes/client-node": "0.17.0", "@manypkg/get-packages": "^1.1.3", "@octokit/rest": "^19.0.3", "@types/cors": "^2.8.6", diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 2cef29c4bb..ea6a1146a8 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -43,7 +43,7 @@ "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-kubernetes-common": "workspace:^", "@google-cloud/container": "^4.0.0", - "@kubernetes/client-node": "^0.17.1", + "@kubernetes/client-node": "0.17.0", "@types/express": "^4.17.6", "@types/luxon": "^3.0.0", "aws-sdk": "^2.840.0", diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index 5ef960a396..401341a0e8 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -39,7 +39,7 @@ }, "dependencies": { "@backstage/catalog-model": "workspace:^", - "@kubernetes/client-node": "^0.17.1" + "@kubernetes/client-node": "0.17.0" }, "devDependencies": { "@backstage/cli": "workspace:^" diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 349642f65a..0bed1a213b 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -40,7 +40,7 @@ "@backstage/plugin-catalog-react": "workspace:^", "@backstage/plugin-kubernetes-common": "workspace:^", "@backstage/theme": "workspace:^", - "@kubernetes/client-node": "^0.17.1", + "@kubernetes/client-node": "0.17.0", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", diff --git a/yarn.lock b/yarn.lock index 286907726c..91baa366b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3148,7 +3148,7 @@ __metadata: "@backstage/types": "workspace:^" "@google-cloud/storage": ^6.0.0 "@keyv/redis": ^2.2.3 - "@kubernetes/client-node": ^0.17.1 + "@kubernetes/client-node": 0.17.0 "@manypkg/get-packages": ^1.1.3 "@octokit/rest": ^19.0.3 "@types/archiver": ^5.1.0 @@ -6220,7 +6220,7 @@ __metadata: "@backstage/plugin-auth-node": "workspace:^" "@backstage/plugin-kubernetes-common": "workspace:^" "@google-cloud/container": ^4.0.0 - "@kubernetes/client-node": ^0.17.1 + "@kubernetes/client-node": 0.17.0 "@types/aws4": ^1.5.1 "@types/express": ^4.17.6 "@types/luxon": ^3.0.0 @@ -6249,7 +6249,7 @@ __metadata: dependencies: "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" - "@kubernetes/client-node": ^0.17.1 + "@kubernetes/client-node": 0.17.0 languageName: unknown linkType: soft @@ -6268,7 +6268,7 @@ __metadata: "@backstage/plugin-kubernetes-common": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" - "@kubernetes/client-node": ^0.17.1 + "@kubernetes/client-node": 0.17.0 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.57 @@ -10671,10 +10671,17 @@ __metadata: languageName: node linkType: hard -"@kubernetes/client-node@npm:^0.17.1": - version: 0.17.1 - resolution: "@kubernetes/client-node@npm:0.17.1" +"@kubernetes/client-node@npm:0.17.0": + version: 0.17.0 + resolution: "@kubernetes/client-node@npm:0.17.0" dependencies: + "@types/js-yaml": ^4.0.1 + "@types/node": ^10.12.0 + "@types/request": ^2.47.1 + "@types/stream-buffers": ^3.0.3 + "@types/tar": ^4.0.3 + "@types/underscore": ^1.8.9 + "@types/ws": ^6.0.1 byline: ^5.0.0 execa: 5.0.0 isomorphic-ws: ^4.0.1 @@ -10690,10 +10697,7 @@ __metadata: tslib: ^1.9.3 underscore: ^1.9.1 ws: ^7.3.1 - dependenciesMeta: - openid-client: - optional: true - checksum: 834ab0ca1f8583b06c4102395ad712c115a6f99201f8dd7f0b59c1a0a5da67b006d1fe5857ad909d762b9cf82a75503665df19fdb640bf620f6123ddb36c8872 + checksum: 5a6edce96946966d8b61359ab043b42e69d1b31178133bc3bf4b5a5c9191766986e08f85d6ae814b56546ed20389817a79dca5101342543d79d750f30cba21f7 languageName: node linkType: hard @@ -13447,6 +13451,13 @@ __metadata: languageName: node linkType: hard +"@types/caseless@npm:*": + version: 0.12.2 + resolution: "@types/caseless@npm:0.12.2" + checksum: 430d15911184ad11e0a8aa21d1ec15fcc93b90b63570c37bf16ebd34457482bfc8de3f5eb6771e0ef986ce183270d4297823b0f492c346255967e78f7292388b + languageName: node + linkType: hard + "@types/classnames@npm:^2.2.9": version: 2.3.1 resolution: "@types/classnames@npm:2.3.1" @@ -14109,7 +14120,7 @@ __metadata: languageName: node linkType: hard -"@types/js-yaml@npm:^4.0.0": +"@types/js-yaml@npm:^4.0.0, @types/js-yaml@npm:^4.0.1": version: 4.0.5 resolution: "@types/js-yaml@npm:4.0.5" checksum: 7dcac8c50fec31643cc9d6444b5503239a861414cdfaa7ae9a38bc22597c4d850c4b8cec3d82d73b3fbca408348ce223b0408d598b32e094470dfffc6d486b4d @@ -14320,6 +14331,15 @@ __metadata: languageName: node linkType: hard +"@types/minipass@npm:*": + version: 3.1.2 + resolution: "@types/minipass@npm:3.1.2" + dependencies: + "@types/node": "*" + checksum: 0d01e11b5b959625385a482ad29ea16352be42506b459555b0f77fd82235e9c540946cc9c05a73fed1ae30b132914baaa4ccf257ed2cad20bc9773f0a06f4bac + languageName: node + linkType: hard + "@types/mock-fs@npm:^4.10.0, @types/mock-fs@npm:^4.13.0": version: 4.13.1 resolution: "@types/mock-fs@npm:4.13.1" @@ -14395,7 +14415,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^10.1.0": +"@types/node@npm:^10.1.0, @types/node@npm:^10.12.0": version: 10.17.60 resolution: "@types/node@npm:10.17.60" checksum: 2cdb3a77d071ba8513e5e8306fa64bf50e3c3302390feeaeff1fd325dd25c8441369715dfc8e3701011a72fed5958c7dfa94eb9239a81b3c286caa4d97db6eef @@ -14740,6 +14760,18 @@ __metadata: languageName: node linkType: hard +"@types/request@npm:^2.47.1": + version: 2.48.8 + resolution: "@types/request@npm:2.48.8" + dependencies: + "@types/caseless": "*" + "@types/node": "*" + "@types/tough-cookie": "*" + form-data: ^2.5.0 + checksum: 0b7754941e08205dce51635d894ec524df276d2b83ca13b9aab723f9281acecf1108841e9554494cb1cb60f6d6ddbb47ebea97392bcf2bf607f035b3a9b4af45 + languageName: node + linkType: hard + "@types/resize-observer-browser@npm:^0.1.6": version: 0.1.7 resolution: "@types/resize-observer-browser@npm:0.1.7" @@ -14926,6 +14958,15 @@ __metadata: languageName: node linkType: hard +"@types/stream-buffers@npm:^3.0.3": + version: 3.0.4 + resolution: "@types/stream-buffers@npm:3.0.4" + dependencies: + "@types/node": "*" + checksum: 5b432b2bf963d612747b79ac317562888236d6a9ea14414fb055c24e7be9643b5e3c7b7470841fa82802aa1c1c0d752a4ba935bbc0cfb12de6b89f7e1dadee92 + languageName: node + linkType: hard + "@types/styled-jsx@npm:^2.2.8": version: 2.2.8 resolution: "@types/styled-jsx@npm:2.2.8" @@ -14972,6 +15013,16 @@ __metadata: languageName: node linkType: hard +"@types/tar@npm:^4.0.3": + version: 4.0.5 + resolution: "@types/tar@npm:4.0.5" + dependencies: + "@types/minipass": "*" + "@types/node": "*" + checksum: 476d8af8f4cffcd973de026e043271be76171f9cb07bb869ba38a193ce89ee361b59ff8484e28b57216266063d91502c5208d2ab6b976e7370d9bdf4c4dadadc + languageName: node + linkType: hard + "@types/tar@npm:^6.1.1": version: 6.1.3 resolution: "@types/tar@npm:6.1.3" @@ -15041,6 +15092,13 @@ __metadata: languageName: node linkType: hard +"@types/underscore@npm:^1.8.9": + version: 1.11.4 + resolution: "@types/underscore@npm:1.11.4" + checksum: db9f8486bc851b732259e51f42d62aad1ae2158be5724612dc125ece5f5d61c51447f9dea28284c2a0f79cb95e788d01cb5ce97709880019213e69fab0dd1696 + languageName: node + linkType: hard + "@types/unist@npm:*, @types/unist@npm:^2.0.0": version: 2.0.6 resolution: "@types/unist@npm:2.0.6" @@ -15090,6 +15148,15 @@ __metadata: languageName: node linkType: hard +"@types/ws@npm:^6.0.1": + version: 6.0.4 + resolution: "@types/ws@npm:6.0.4" + dependencies: + "@types/node": "*" + checksum: b2656a76bfad0c17bb1e3fc237ba7122431c1373669977ed8edef45934c82f71c75d8c71f0a576dc6d98b0954fd94cae0166c6b4ccb40f7e0ee29cc92673519c + languageName: node + linkType: hard + "@types/ws@npm:^8.0.0, @types/ws@npm:^8.5.1": version: 8.5.3 resolution: "@types/ws@npm:8.5.3" From ee35a695dd72439ccb192211f8b145453e795c3d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 1 Nov 2022 15:37:13 +0100 Subject: [PATCH 188/434] auth-backend: bump openid-client to most recent version Signed-off-by: Patrik Oldsberg --- plugins/auth-backend/package.json | 2 +- yarn.lock | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 4b3d7910e5..67deb66b33 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -60,7 +60,7 @@ "morgan": "^1.10.0", "node-cache": "^5.1.2", "node-fetch": "^2.6.7", - "openid-client": "^5.1.3", + "openid-client": "^5.2.1", "passport": "^0.6.0", "passport-auth0": "^1.4.3", "passport-bitbucket-oauth2": "^0.1.2", diff --git a/yarn.lock b/yarn.lock index 91baa366b5..2c90ba57ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4296,7 +4296,7 @@ __metadata: msw: ^0.47.0 node-cache: ^5.1.2 node-fetch: ^2.6.7 - openid-client: ^5.1.3 + openid-client: ^5.2.1 passport: ^0.6.0 passport-auth0: ^1.4.3 passport-bitbucket-oauth2: ^0.1.2 @@ -27157,10 +27157,10 @@ __metadata: languageName: node linkType: hard -"jose@npm:^4.1.4": - version: 4.5.0 - resolution: "jose@npm:4.5.0" - checksum: 51142150a9f571ca318842d34ac0daec49fb70bfb6034c68fd46d8c804a8325065876067202310c8ff3cbfc5ca8e44d4712467b4da0d3cadf1e47c96989ca4ca +"jose@npm:^4.10.0": + version: 4.10.4 + resolution: "jose@npm:4.10.4" + checksum: 0e6caaae0b0303534c0ac23711d45eadfbdbff63d9aeed80965c668b5532c254ab25b48afddc3e1ecfcfd36b4275dee41174a097c5a47a25ce04268c78f3c130 languageName: node linkType: hard @@ -31236,15 +31236,15 @@ __metadata: languageName: node linkType: hard -"openid-client@npm:^5.1.3, openid-client@npm:^5.1.6": - version: 5.1.9 - resolution: "openid-client@npm:5.1.9" +"openid-client@npm:^5.1.6, openid-client@npm:^5.2.1": + version: 5.2.1 + resolution: "openid-client@npm:5.2.1" dependencies: - jose: ^4.1.4 + jose: ^4.10.0 lru-cache: ^6.0.0 object-hash: ^2.0.1 oidc-token-hash: ^5.0.1 - checksum: 55390a7eceaafdc340a5f2ece576eb4863fcb4cd8840e4a7a1af66bbaf830623b18cf1dd0b8ce472c6f36c6313e78f92db48ca0c10eb8c681a81e5a3d607fc9f + checksum: b2e9ee8bafb30981fe8eb4446d86578649f05e61d6289abfe79c863578ef8ab24eb4430461c2b8dbb50cbaff89af01e77439df5ebb87c391ed1e336a0e69e590 languageName: node linkType: hard From a8dac60b0813bd0929d06c612e0d4392b21805dc Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 1 Nov 2022 15:37:32 +0100 Subject: [PATCH 189/434] Revert "workflows: work around missing node-canvas binaries for node 18" This reverts commit 0ab270539ae9ba4ec0b34af9624e7d870f4515da. Signed-off-by: Patrik Oldsberg --- .github/workflows/ci.yml | 7 ------- .github/workflows/deploy_nightly.yml | 2 -- .github/workflows/deploy_packages.yml | 8 -------- .github/workflows/verify_e2e-linux.yml | 6 ------ .github/workflows/verify_e2e-techdocs.yml | 7 ------- .github/workflows/verify_e2e-windows.yml | 10 ---------- .github/workflows/verify_kubernetes.yml | 6 ------ .github/workflows/verify_windows.yml | 9 --------- 8 files changed, 55 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d8040e993..3ab979593c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,13 +32,6 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - # Needed until there are pre-built binaries of node-canvas for Node 18 - - name: node-canvas dependencies - if: matrix.node-version == '18.x' - run: | - sudo apt update - sudo apt install -y build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev - - name: yarn install uses: backstage/actions/yarn-install@v0.5.6 with: diff --git a/.github/workflows/deploy_nightly.yml b/.github/workflows/deploy_nightly.yml index bb41481cb1..74dc60783a 100644 --- a/.github/workflows/deploy_nightly.yml +++ b/.github/workflows/deploy_nightly.yml @@ -25,8 +25,6 @@ jobs: with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - - # Needed until there are pre-built binaries for Node 18 - name: yarn install uses: backstage/actions/yarn-install@v0.5.6 with: diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index 6fffe4d60a..56ff61c75b 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -66,14 +66,6 @@ jobs: with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - - # Needed until there are pre-built binaries of node-canvas for Node 18 - - name: node-canvas dependencies - if: matrix.node-version == '18.x' - run: | - sudo apt update - sudo apt install -y build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev - - name: yarn install uses: backstage/actions/yarn-install@v0.5.6 with: diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index db8f6662fe..fefdd1fdd5 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -51,12 +51,6 @@ jobs: with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - # Needed until there are pre-built binaries of node-canvas for Node 18 - - name: node-canvas dependencies - if: matrix.node-version == '18.x' - run: | - sudo apt update - sudo apt install -y build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev - name: yarn install uses: backstage/actions/yarn-install@v0.5.6 with: diff --git a/.github/workflows/verify_e2e-techdocs.yml b/.github/workflows/verify_e2e-techdocs.yml index 0d6836ad3a..8d59d15899 100644 --- a/.github/workflows/verify_e2e-techdocs.yml +++ b/.github/workflows/verify_e2e-techdocs.yml @@ -28,13 +28,6 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v3 - # Needed until there are pre-built binaries of node-canvas for Node 18 - - name: node-canvas dependencies - if: matrix.node-version == '18.x' - run: | - sudo apt update - sudo apt install -y build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev - - name: install dependencies run: yarn install --immutable diff --git a/.github/workflows/verify_e2e-windows.yml b/.github/workflows/verify_e2e-windows.yml index 9d1ba8a154..fc29c1f03b 100644 --- a/.github/workflows/verify_e2e-windows.yml +++ b/.github/workflows/verify_e2e-windows.yml @@ -52,16 +52,6 @@ jobs: uses: microsoft/setup-msbuild@v1.0.3 - name: setup chrome uses: browser-actions/setup-chrome@latest - - # Needed until there are pre-built binaries of node-canvas for Node 18 - - name: node-canvas dependencies - if: matrix.node-version == '18.x' - # From https://github.com/Automattic/node-canvas/blob/master/.github/workflows/ci.yaml - run: | - Invoke-WebRequest "https://ftp-osl.osuosl.org/pub/gnome/binaries/win64/gtk+/2.22/gtk+-bundle_2.22.1-20101229_win64.zip" -OutFile "gtk.zip" - Expand-Archive gtk.zip -DestinationPath "C:\GTK" - Invoke-WebRequest "https://downloads.sourceforge.net/project/libjpeg-turbo/2.0.4/libjpeg-turbo-2.0.4-vc64.exe" -OutFile "libjpeg.exe" -UserAgent NativeHost - .\libjpeg.exe /S - name: yarn install run: yarn install --immutable diff --git a/.github/workflows/verify_kubernetes.yml b/.github/workflows/verify_kubernetes.yml index ea5e3ebe4e..e8c248699a 100644 --- a/.github/workflows/verify_kubernetes.yml +++ b/.github/workflows/verify_kubernetes.yml @@ -27,12 +27,6 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - # Needed until there are pre-built binaries of node-canvas for Node 18 - - name: node-canvas dependencies - if: matrix.node-version == '18.x' - run: | - sudo apt update - sudo apt install -y build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev - name: yarn install uses: backstage/actions/yarn-install@v0.5.6 with: diff --git a/.github/workflows/verify_windows.yml b/.github/workflows/verify_windows.yml index a092c8d405..75a0633cbe 100644 --- a/.github/workflows/verify_windows.yml +++ b/.github/workflows/verify_windows.yml @@ -32,15 +32,6 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - # Needed until there are pre-built binaries of node-canvas for Node 18 - - name: node-canvas dependencies - if: matrix.node-version == '18.x' - # From https://github.com/Automattic/node-canvas/blob/master/.github/workflows/ci.yaml - run: | - Invoke-WebRequest "https://ftp-osl.osuosl.org/pub/gnome/binaries/win64/gtk+/2.22/gtk+-bundle_2.22.1-20101229_win64.zip" -OutFile "gtk.zip" - Expand-Archive gtk.zip -DestinationPath "C:\GTK" - Invoke-WebRequest "https://downloads.sourceforge.net/project/libjpeg-turbo/2.0.4/libjpeg-turbo-2.0.4-vc64.exe" -OutFile "libjpeg.exe" -UserAgent NativeHost - .\libjpeg.exe /S # Windows file operation slowness means there's no point caching this - name: yarn install run: yarn install --immutable From 93554b047cd34c1d6f44a81856cfe76218118eb6 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 1 Nov 2022 15:39:04 +0100 Subject: [PATCH 190/434] Revert "backend-common: work around premature close errors" This reverts commit b29587c3187fdd5c78341dce5c6f406b631e1f21. Signed-off-by: Patrik Oldsberg --- .changeset/swift-suits-reply.md | 5 -- .../src/reading/GerritUrlReader.ts | 8 ++- .../src/reading/tree/ReadableArrayResponse.ts | 10 +-- .../src/reading/tree/TarArchiveResponse.ts | 15 +++-- .../src/reading/tree/util.test.ts | 63 ------------------- .../backend-common/src/reading/tree/util.ts | 35 +++-------- 6 files changed, 27 insertions(+), 109 deletions(-) delete mode 100644 .changeset/swift-suits-reply.md delete mode 100644 packages/backend-common/src/reading/tree/util.test.ts diff --git a/.changeset/swift-suits-reply.md b/.changeset/swift-suits-reply.md deleted file mode 100644 index f81f39bee2..0000000000 --- a/.changeset/swift-suits-reply.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Refactored internal usage of the build-in `pipeline` from `'stream'` to work around `tar` bug in Node 18. diff --git a/packages/backend-common/src/reading/GerritUrlReader.ts b/packages/backend-common/src/reading/GerritUrlReader.ts index 9ec5e35f65..59b33bb2cb 100644 --- a/packages/backend-common/src/reading/GerritUrlReader.ts +++ b/packages/backend-common/src/reading/GerritUrlReader.ts @@ -32,7 +32,8 @@ import fetch, { Response } from 'node-fetch'; import os from 'os'; import { join as joinPath } from 'path'; import tar from 'tar'; -import { Readable } from 'stream'; +import { pipeline as pipelineCb, Readable } from 'stream'; +import { promisify } from 'util'; import { ReaderFactory, ReadTreeOptions, @@ -44,7 +45,8 @@ import { UrlReader, } from './types'; import { ScmIntegrations } from '@backstage/integration'; -import { pipeStream } from './tree/util'; + +const pipeline = promisify(pipelineCb); const createTemporaryDirectory = async (workDir: string): Promise => await fs.mkdtemp(joinPath(workDir, '/gerrit-clone-')); @@ -195,7 +197,7 @@ export class GerritUrlReader implements UrlReader { }); const data = await new Promise(async resolve => { - await pipeStream( + await pipeline( tar.create({ cwd: tempDir }, ['']), concatStream(resolve), ); diff --git a/packages/backend-common/src/reading/tree/ReadableArrayResponse.ts b/packages/backend-common/src/reading/tree/ReadableArrayResponse.ts index da145b0f4b..eabaa3bc56 100644 --- a/packages/backend-common/src/reading/tree/ReadableArrayResponse.ts +++ b/packages/backend-common/src/reading/tree/ReadableArrayResponse.ts @@ -19,15 +19,17 @@ import platformPath, { basename } from 'path'; import getRawBody from 'raw-body'; import fs from 'fs-extra'; +import { promisify } from 'util'; import tar from 'tar'; -import { Readable } from 'stream'; +import { pipeline as pipelineCb, Readable } from 'stream'; import { ReadTreeResponse, ReadTreeResponseFile, ReadTreeResponseDirOptions, FromReadableArrayOptions, } from '../types'; -import { pipeStream } from './util'; + +const pipeline = promisify(pipelineCb); /** * Wraps a array of Readable objects into a tree response reader. @@ -73,7 +75,7 @@ export class ReadableArrayResponse implements ReadTreeResponse { try { const data = await new Promise(async resolve => { - await pipeStream( + await pipeline( tar.create({ cwd: tmpDir }, ['']), concatStream(resolve), ); @@ -93,7 +95,7 @@ export class ReadableArrayResponse implements ReadTreeResponse { for (let i = 0; i < this.stream.length; i++) { if (!this.stream[i].path.endsWith('/')) { - await pipeStream( + await pipeline( this.stream[i].data, fs.createWriteStream( platformPath.join(dir, basename(this.stream[i].path)), diff --git a/packages/backend-common/src/reading/tree/TarArchiveResponse.ts b/packages/backend-common/src/reading/tree/TarArchiveResponse.ts index 7d0d8f42a2..493e283c5f 100644 --- a/packages/backend-common/src/reading/tree/TarArchiveResponse.ts +++ b/packages/backend-common/src/reading/tree/TarArchiveResponse.ts @@ -17,18 +17,21 @@ import concatStream from 'concat-stream'; import fs from 'fs-extra'; import platformPath from 'path'; -import { Readable } from 'stream'; +import { pipeline as pipelineCb, Readable } from 'stream'; import tar, { Parse, ParseStream, ReadEntry } from 'tar'; +import { promisify } from 'util'; import { ReadTreeResponse, ReadTreeResponseDirOptions, ReadTreeResponseFile, } from '../types'; -import { pipeStream, stripFirstDirectoryFromPath } from './util'; +import { stripFirstDirectoryFromPath } from './util'; // Tar types for `Parse` is not a proper constructor, but it should be const TarParseStream = Parse as unknown as { new (): ParseStream }; +const pipeline = promisify(pipelineCb); + /** * Wraps a tar archive stream into a tree response reader. */ @@ -96,7 +99,7 @@ export class TarArchiveResponse implements ReadTreeResponse { } const content = new Promise(async resolve => { - await pipeStream(entry, concatStream(resolve)); + await pipeline(entry, concatStream(resolve)); }); files.push({ @@ -107,7 +110,7 @@ export class TarArchiveResponse implements ReadTreeResponse { entry.resume(); }); - await pipeStream(this.stream, parser); + await pipeline(this.stream, parser); return files; } @@ -125,7 +128,7 @@ export class TarArchiveResponse implements ReadTreeResponse { try { const data = await new Promise(async resolve => { - await pipeStream( + await pipeline( tar.create({ cwd: tmpDir }, ['']), concatStream(resolve), ); @@ -149,7 +152,7 @@ export class TarArchiveResponse implements ReadTreeResponse { let filterError: Error | undefined = undefined; - await pipeStream( + await pipeline( this.stream, tar.extract({ strip, diff --git a/packages/backend-common/src/reading/tree/util.test.ts b/packages/backend-common/src/reading/tree/util.test.ts deleted file mode 100644 index 662ff3f194..0000000000 --- a/packages/backend-common/src/reading/tree/util.test.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 { Readable, Writable } from 'stream'; -import { pipeStream, streamToBuffer } from './util'; - -describe('pipeStream', () => { - it('should pipe a stream', async () => { - const from = Readable.from(['hello']); - - let written = ''; - const to = new Writable({ - write(chunk, encoding, callback) { - written = `${encoding}:${chunk}`; - callback(); - }, - }); - - await pipeStream(from, to); - expect(written).toBe('buffer:hello'); - }); - - it('should forward errors', async () => { - const from = new Readable({ - read() { - throw new Error('oh no'); - }, - }); - const to = new Writable(); - - await expect(pipeStream(from, to)).rejects.toThrow('oh no'); - }); -}); - -describe('streamToBuffer', () => { - it('should read a stream', async () => { - await expect(streamToBuffer(Readable.from(['hello']))).resolves.toBe( - 'hello', - ); - }); - - it('should fail on errors', async () => { - const stream = new Readable({ - read() { - throw new Error('oh no'); - }, - }); - await expect(streamToBuffer(stream)).rejects.toThrow('oh no'); - }); -}); diff --git a/packages/backend-common/src/reading/tree/util.ts b/packages/backend-common/src/reading/tree/util.ts index a4e9a6686c..63192102f4 100644 --- a/packages/backend-common/src/reading/tree/util.ts +++ b/packages/backend-common/src/reading/tree/util.ts @@ -14,9 +14,12 @@ * limitations under the License. */ -import { Readable, finished } from 'stream'; +import { Readable, pipeline as pipelineCb } from 'stream'; +import { promisify } from 'util'; import concatStream from 'concat-stream'; +const pipeline = promisify(pipelineCb); + // Matches a directory name + one `/` at the start of any string, // containing any character except `/` one or more times, and ending with a `/` // e.g. Will match `dirA/` in `dirA/dirB/file.ext` @@ -26,37 +29,13 @@ export function stripFirstDirectoryFromPath(path: string): string { return path.replace(directoryNameRegex, ''); } -// Custom pipeline implementation, since pipeline doesn't work well with tar on node 18 -// See https://github.com/npm/node-tar/issues/321 -export function pipeStream( - from: NodeJS.ReadableStream, - to: NodeJS.WritableStream, -): Promise { - return new Promise((resolve, reject) => { - from.pipe(to); - finished(from, fromErr => { - if (fromErr) { - reject(fromErr); - } else { - finished(to, toErr => { - if (toErr) { - reject(toErr); - } else { - resolve(); - } - }); - } - }); - }); -} - // Collect the stream into a buffer and return -export function streamToBuffer(stream: Readable): Promise { +export const streamToBuffer = (stream: Readable): Promise => { return new Promise(async (resolve, reject) => { try { - await pipeStream(stream, concatStream(resolve)); + await pipeline(stream, concatStream(resolve)); } catch (ex) { reject(ex); } }); -} +}; From e92aa15f011beb001c645d5df52623979bd953dc Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 1 Nov 2022 15:58:40 +0100 Subject: [PATCH 191/434] bump canvas to 2.10.2 Signed-off-by: Patrik Oldsberg --- .changeset/blue-items-shop.md | 6 ++++++ plugins/cost-insights/package.json | 2 +- plugins/techdocs/package.json | 2 +- yarn.lock | 15 ++++----------- 4 files changed, 12 insertions(+), 13 deletions(-) create mode 100644 .changeset/blue-items-shop.md diff --git a/.changeset/blue-items-shop.md b/.changeset/blue-items-shop.md new file mode 100644 index 0000000000..fbf2287864 --- /dev/null +++ b/.changeset/blue-items-shop.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-cost-insights': patch +'@backstage/plugin-techdocs': patch +--- + +Bumped `canvas` dependency to the latest version, which has better Node.js v18 support. diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index b5859fa886..aac87aa10f 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -71,7 +71,7 @@ "@types/recharts": "^1.8.14", "@types/regression": "^2.0.0", "@types/yup": "^0.29.13", - "canvas": "^2.6.1", + "canvas": "^2.10.2", "cross-fetch": "^3.1.5", "msw": "^0.47.0" }, diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index cb03cb9e3f..9eb6f6af3a 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -76,7 +76,7 @@ "@types/dompurify": "^2.2.2", "@types/event-source-polyfill": "^1.0.0", "@types/node": "^16.11.26", - "canvas": "^2.6.1", + "canvas": "^2.10.2", "cross-fetch": "^3.1.5", "msw": "^0.47.0" }, diff --git a/yarn.lock b/yarn.lock index 2c90ba57ec..8d6464f026 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5485,7 +5485,7 @@ __metadata: "@types/recharts": ^1.8.14 "@types/regression": ^2.0.0 "@types/yup": ^0.29.13 - canvas: ^2.6.1 + canvas: ^2.10.2 classnames: ^2.2.6 cross-fetch: ^3.1.5 history: ^5.0.0 @@ -7741,7 +7741,7 @@ __metadata: "@types/dompurify": ^2.2.2 "@types/event-source-polyfill": ^1.0.0 "@types/node": ^16.11.26 - canvas: ^2.6.1 + canvas: ^2.10.2 cross-fetch: ^3.1.5 dompurify: ^2.2.9 event-source-polyfill: 1.0.25 @@ -17991,7 +17991,7 @@ __metadata: languageName: node linkType: hard -"canvas@npm:^2.6.1": +"canvas@npm:^2.10.2": version: 2.10.2 resolution: "canvas@npm:2.10.2" dependencies: @@ -27157,14 +27157,7 @@ __metadata: languageName: node linkType: hard -"jose@npm:^4.10.0": - version: 4.10.4 - resolution: "jose@npm:4.10.4" - checksum: 0e6caaae0b0303534c0ac23711d45eadfbdbff63d9aeed80965c668b5532c254ab25b48afddc3e1ecfcfd36b4275dee41174a097c5a47a25ce04268c78f3c130 - languageName: node - linkType: hard - -"jose@npm:^4.6.0": +"jose@npm:^4.10.0, jose@npm:^4.6.0": version: 4.10.4 resolution: "jose@npm:4.10.4" checksum: 0e6caaae0b0303534c0ac23711d45eadfbdbff63d9aeed80965c668b5532c254ab25b48afddc3e1ecfcfd36b4275dee41174a097c5a47a25ce04268c78f3c130 From 88f99b8b1352d924de67b96115f910ca455f9ae0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 1 Nov 2022 17:44:20 +0100 Subject: [PATCH 192/434] bump tar to 6.1.12 Signed-off-by: Patrik Oldsberg --- .changeset/eighty-planets-train.md | 6 ++++++ packages/backend-common/package.json | 2 +- packages/cli/package.json | 2 +- yarn.lock | 6 +++--- 4 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 .changeset/eighty-planets-train.md diff --git a/.changeset/eighty-planets-train.md b/.changeset/eighty-planets-train.md new file mode 100644 index 0000000000..c4d5d57f6c --- /dev/null +++ b/.changeset/eighty-planets-train.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-common': patch +'@backstage/cli': patch +--- + +Bumped `tar` dependency to `^6.1.12` in order to ensure Node.js v18 compatibility. diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 2847e86504..28a4f91aa2 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -80,7 +80,7 @@ "request": "^2.88.2", "selfsigned": "^2.0.0", "stoppable": "^1.1.0", - "tar": "^6.1.2", + "tar": "^6.1.12", "uuid": "^8.3.2", "winston": "^3.2.1", "yauzl": "^2.10.0", diff --git a/packages/cli/package.json b/packages/cli/package.json index 9eb6bed3d6..be46d74a49 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -117,7 +117,7 @@ "style-loader": "^3.3.1", "sucrase": "^3.20.2", "swc-loader": "^0.2.3", - "tar": "^6.1.2", + "tar": "^6.1.12", "terser-webpack-plugin": "^5.1.3", "util": "^0.12.3", "webpack": "^5.70.0", diff --git a/yarn.lock b/yarn.lock index 8d6464f026..6e2d6fb8eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3209,7 +3209,7 @@ __metadata: selfsigned: ^2.0.0 stoppable: ^1.1.0 supertest: ^6.1.3 - tar: ^6.1.2 + tar: ^6.1.12 uuid: ^8.3.2 winston: ^3.2.1 yauzl: ^2.10.0 @@ -3474,7 +3474,7 @@ __metadata: style-loader: ^3.3.1 sucrase: ^3.20.2 swc-loader: ^0.2.3 - tar: ^6.1.2 + tar: ^6.1.12 terser-webpack-plugin: ^5.1.3 ts-node: ^10.0.0 type-fest: ^2.0.0 @@ -37530,7 +37530,7 @@ __metadata: languageName: node linkType: hard -"tar@npm:^6.1.2": +"tar@npm:^6.1.12, tar@npm:^6.1.2": version: 6.1.12 resolution: "tar@npm:6.1.12" dependencies: From f121e3fc6944496705e7dbd519087cbef7bf7e81 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 2 Nov 2022 15:08:45 +0100 Subject: [PATCH 193/434] e2e-test: add wait before checking backend availability Signed-off-by: Patrik Oldsberg --- packages/e2e-test/src/commands/run.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/e2e-test/src/commands/run.ts b/packages/e2e-test/src/commands/run.ts index 3f9d28eadd..f32d577cd4 100644 --- a/packages/e2e-test/src/commands/run.ts +++ b/packages/e2e-test/src/commands/run.ts @@ -507,6 +507,7 @@ async function testBackendStart(appDir: string, ...args: string[]) { // Skipping the whole block throw new Error(stderr); } + await new Promise(resolve => setTimeout(resolve, 500)); print('Try to fetch entities from the backend'); // Try fetch entities, should be ok From 864c876e57c950a1ccc8eb756dd6111e79e5371d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 3 Nov 2022 10:59:02 +0100 Subject: [PATCH 194/434] create-app: fix default backend listen config and comments Signed-off-by: Patrik Oldsberg --- .changeset/witty-carrots-live.md | 31 +++++++++++++++++++ .../default-app/app-config.production.yaml | 11 ++----- .../templates/default-app/app-config.yaml.hbs | 5 ++- 3 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 .changeset/witty-carrots-live.md diff --git a/.changeset/witty-carrots-live.md b/.changeset/witty-carrots-live.md new file mode 100644 index 0000000000..4bafd47dfa --- /dev/null +++ b/.changeset/witty-carrots-live.md @@ -0,0 +1,31 @@ +--- +'@backstage/create-app': patch +--- + +Fixed incorrect comments in the templated `app-config.yaml` and `app-config.production.yaml`. The `backend.listen` directive is not in fact needed to override the `backend.baseUrl`, the backend listens to all interfaces by default. The configuration has also been updated to listen to all interfaces, rather than just IPv4 ones, as this is required for Node.js v18. The production configuration now also shows the option to specify `backend.listen` as a single string. + +To apply this changes to an existing app, make the following change to `app-config.yaml`: + +```diff +- # Uncomment the following host directive to bind to all IPv4 interfaces and +- # not just the baseUrl hostname. +- # host: 0.0.0.0 ++ # Uncomment the following host directive to bind to specific interfaces ++ # host: 127.0.0.1 +``` + +And the following change to `app-config.production.yaml`: + +```diff +- listen: +- port: 7007 +- # The following host directive binds to all IPv4 interfaces when its value +- # is "0.0.0.0". This is the most permissive setting. The right value depends +- # on your specific deployment. If you remove the host line entirely, the +- # backend will bind on the interface that corresponds to the backend.baseUrl +- # hostname. +- host: 0.0.0.0 ++ # The listener can also be expressed as a single : string. In this case we bind to ++ # all interfaces, the most permissive setting. The right value depends on your specific deployment. ++ listen: ':7007' +``` diff --git a/packages/create-app/templates/default-app/app-config.production.yaml b/packages/create-app/templates/default-app/app-config.production.yaml index 6535d967d5..df09dac50a 100644 --- a/packages/create-app/templates/default-app/app-config.production.yaml +++ b/packages/create-app/templates/default-app/app-config.production.yaml @@ -9,14 +9,9 @@ backend: # callers. When its value is "http://localhost:7007", it's strictly private # and can't be reached by others. baseUrl: http://localhost:7007 - listen: - port: 7007 - # The following host directive binds to all IPv4 interfaces when its value - # is "0.0.0.0". This is the most permissive setting. The right value depends - # on your specific deployment. If you remove the host line entirely, the - # backend will bind on the interface that corresponds to the backend.baseUrl - # hostname. - host: 0.0.0.0 + # The listener can also be expressed as a single : string. In this case we bind to + # all interfaces, the most permissive setting. The right value depends on your specific deployment. + listen: ':7007' # config options: https://node-postgres.com/api/client database: diff --git a/packages/create-app/templates/default-app/app-config.yaml.hbs b/packages/create-app/templates/default-app/app-config.yaml.hbs index 4a058deefd..1a45d4015b 100644 --- a/packages/create-app/templates/default-app/app-config.yaml.hbs +++ b/packages/create-app/templates/default-app/app-config.yaml.hbs @@ -15,9 +15,8 @@ backend: baseUrl: http://localhost:7007 listen: port: 7007 - # Uncomment the following host directive to bind to all IPv4 interfaces and - # not just the baseUrl hostname. - # host: 0.0.0.0 + # Uncomment the following host directive to bind to specific interfaces + # host: 127.0.0.1 csp: connect-src: ["'self'", 'http:', 'https:'] # Content-Security-Policy directives follow the Helmet format: https://helmetjs.github.io/#reference From 5ec67065b1cc43531a22e4968c33bbef0ebb6166 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 7 Nov 2022 13:08:03 +0100 Subject: [PATCH 195/434] workflows/ci: try lower jest worker memory limit Signed-off-by: Patrik Oldsberg --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 64067188bb..2520b22a2d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -208,7 +208,7 @@ jobs: - name: test all packages (and upload coverage) if: ${{ steps.yarn-lock.outcome == 'failure' }} run: | - yarn backstage-cli repo test --maxWorkers=2 --workerIdleMemoryLimit=1300M --coverage + yarn backstage-cli repo test --maxWorkers=2 --workerIdleMemoryLimit=800M --coverage bash <(curl -s https://codecov.io/bash) -N $(git rev-parse FETCH_HEAD) env: BACKSTAGE_NEXT_TESTS: 1 From 474cf0bc66aa5d94c36dcc26df48e86d44a61cad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 12:50:55 +0000 Subject: [PATCH 196/434] Update dependency @codemirror/view to v6.4.1 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6e2d6fb8eb..750f788274 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8386,13 +8386,13 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0": - version: 6.4.0 - resolution: "@codemirror/view@npm:6.4.0" + version: 6.4.1 + resolution: "@codemirror/view@npm:6.4.1" dependencies: "@codemirror/state": ^6.0.0 style-mod: ^4.0.0 w3c-keyname: ^2.2.4 - checksum: 57ed7d9d51907f1ea549a2a158872fb7affa6cdff72e29e214f8437b7142ea2a2431ac3c780cbc0187dfff7cb5fd1055a45a887ea9b8c2a09d8430c60ebe9083 + checksum: 51f8e9bf1701cd490708784fd42a90dd9b2ad84aaebfacdbcfa9093e7f99ded38093ac49bc9eb037924b7734a58ed854a19621d931cce3f7962c2a0b30fecc23 languageName: node linkType: hard From 43d66cef85f7e07b19117fba0ac8129be9f22b64 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 7 Nov 2022 13:58:40 +0100 Subject: [PATCH 197/434] chore: pass through the form data like before in the context Signed-off-by: blam --- .../scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx index bed2515aaf..75f92916df 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx @@ -143,6 +143,7 @@ export const Stepper = (props: StepperProps) => { validator={validator} extraErrors={errors as unknown as ErrorSchema} formData={formState} + formContext={{ formData: formState }} schema={steps[activeStep].schema} uiSchema={steps[activeStep].uiSchema} onSubmit={handleNext} From 3b3fc3cc3c2d9334c648ca72dacd10ff5be40316 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 7 Nov 2022 13:59:58 +0100 Subject: [PATCH 198/434] chore: added changeset Signed-off-by: blam --- .changeset/moody-pots-end.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/moody-pots-end.md diff --git a/.changeset/moody-pots-end.md b/.changeset/moody-pots-end.md new file mode 100644 index 0000000000..80ee32c2c3 --- /dev/null +++ b/.changeset/moody-pots-end.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Fix `formData` not being present in the `next` version From 0a8c566afc3231ab8806e798ffeb5704f4c9efc0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 13:07:41 +0000 Subject: [PATCH 199/434] Update backstage/actions action to v0.5.7 Signed-off-by: Renovate Bot --- .github/workflows/ci.yml | 6 +++--- .github/workflows/cron.yml | 2 +- .github/workflows/deploy_nightly.yml | 2 +- .github/workflows/deploy_packages.yml | 4 ++-- .github/workflows/issue.yaml | 2 +- .github/workflows/pr-review-comment.yaml | 2 +- .github/workflows/pr.yaml | 2 +- .github/workflows/sync_code-formatting.yml | 2 +- .github/workflows/sync_snyk-github-issues.yml | 2 +- .github/workflows/verify_e2e-linux.yml | 2 +- .github/workflows/verify_kubernetes.yml | 2 +- .github/workflows/verify_storybook.yml | 2 +- 12 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f506b42f5..64d3c166aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.6 + uses: backstage/actions/yarn-install@v0.5.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -63,7 +63,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.6 + uses: backstage/actions/yarn-install@v0.5.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -178,7 +178,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.6 + uses: backstage/actions/yarn-install@v0.5.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index 467c817baf..4629d656ce 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -8,7 +8,7 @@ jobs: cron: runs-on: ubuntu-latest steps: - - uses: backstage/actions/cron@v0.5.6 + - uses: backstage/actions/cron@v0.5.7 with: app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }} diff --git a/.github/workflows/deploy_nightly.yml b/.github/workflows/deploy_nightly.yml index 74dc60783a..360a74e012 100644 --- a/.github/workflows/deploy_nightly.yml +++ b/.github/workflows/deploy_nightly.yml @@ -26,7 +26,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.6 + uses: backstage/actions/yarn-install@v0.5.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index 56ff61c75b..1d03c210cd 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -67,7 +67,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.6 + uses: backstage/actions/yarn-install@v0.5.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -145,7 +145,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.6 + uses: backstage/actions/yarn-install@v0.5.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/issue.yaml b/.github/workflows/issue.yaml index 95e91dda30..a42b9b6f7b 100644 --- a/.github/workflows/issue.yaml +++ b/.github/workflows/issue.yaml @@ -10,4 +10,4 @@ jobs: if: github.repository == 'backstage/backstage' steps: - name: Issue sync - uses: backstage/actions/issue-sync@v0.5.6 + uses: backstage/actions/issue-sync@v0.5.7 diff --git a/.github/workflows/pr-review-comment.yaml b/.github/workflows/pr-review-comment.yaml index e822209e03..6104a802d9 100644 --- a/.github/workflows/pr-review-comment.yaml +++ b/.github/workflows/pr-review-comment.yaml @@ -35,7 +35,7 @@ jobs: const prNumber = artifact.name.slice('pr_number-'.length) console.log(`::set-output name=pr-number::${prNumber}`); - - uses: backstage/actions/re-review@v0.5.6 + - uses: backstage/actions/re-review@v0.5.7 with: app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index e13928ccee..4ab7da8e07 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -18,7 +18,7 @@ jobs: if: github.repository == 'backstage/backstage' && ( github.event.pull_request || github.event.issue.pull_request ) steps: - name: PR sync - uses: backstage/actions/pr-sync@v0.5.6 + uses: backstage/actions/pr-sync@v0.5.7 with: github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} diff --git a/.github/workflows/sync_code-formatting.yml b/.github/workflows/sync_code-formatting.yml index 779284818f..2113efe924 100644 --- a/.github/workflows/sync_code-formatting.yml +++ b/.github/workflows/sync_code-formatting.yml @@ -20,7 +20,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.6 + uses: backstage/actions/yarn-install@v0.5.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml index de05c79300..c1fb727c33 100644 --- a/.github/workflows/sync_snyk-github-issues.yml +++ b/.github/workflows/sync_snyk-github-issues.yml @@ -23,7 +23,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.6 + uses: backstage/actions/yarn-install@v0.5.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index fefdd1fdd5..a84b315e33 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -52,7 +52,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.6 + uses: backstage/actions/yarn-install@v0.5.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_kubernetes.yml b/.github/workflows/verify_kubernetes.yml index e8c248699a..b92deb96ac 100644 --- a/.github/workflows/verify_kubernetes.yml +++ b/.github/workflows/verify_kubernetes.yml @@ -28,7 +28,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.6 + uses: backstage/actions/yarn-install@v0.5.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_storybook.yml b/.github/workflows/verify_storybook.yml index cac94ff682..4fe39fe244 100644 --- a/.github/workflows/verify_storybook.yml +++ b/.github/workflows/verify_storybook.yml @@ -35,7 +35,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.6 + uses: backstage/actions/yarn-install@v0.5.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - name: storybook yarn install From e5e9c6aa274b1577db690ed8344e09c474014b7d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 13:11:03 +0000 Subject: [PATCH 200/434] Update dependency luxon to v3.1.0 Signed-off-by: Renovate Bot --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 12c5af9fca..c6e8d06f64 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14257,9 +14257,9 @@ __metadata: linkType: hard "@types/luxon@npm:^3.0.0": - version: 3.0.2 - resolution: "@types/luxon@npm:3.0.2" - checksum: e47e199c5d70ce16e4eff54b21fdf385065f1134774109b40c36dba8b5fd29a732b763125e93863d6070dd22ba6a3f18dbdd368cf3748aae9f24bb335c5c210d + version: 3.1.0 + resolution: "@types/luxon@npm:3.1.0" + checksum: 04768029342ad76fc2a9339436c143ea64797b35cf9b03ddded787c13eae30f0ca1246e51c2c5365ed912f98068e13a967a3931b137eb4585248a0ad7ec3fa86 languageName: node linkType: hard @@ -28465,9 +28465,9 @@ __metadata: linkType: hard "luxon@npm:^3.0.0": - version: 3.0.4 - resolution: "luxon@npm:3.0.4" - checksum: d0908c3951da2a10ccf23040210ead23b0da5366a9d0954e7d5db3560189a7bd703d8af1e00084f197effc9cd7158d1bddf32886d98a70d59ce9bc3fe88bbce0 + version: 3.1.0 + resolution: "luxon@npm:3.1.0" + checksum: f8a850b759ba7a2e009d904c522ed7bc264bf4add57578f8948e52a0ed96b627b025b5aad8032295b570ae19fac41f0ffab91bdb128715fb0cc020798a7ba886 languageName: node linkType: hard From 8d987cc8091ca45272e87704c21f90c404dadb9e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 7 Nov 2022 15:38:18 +0100 Subject: [PATCH 201/434] docs: no space Signed-off-by: Patrik Oldsberg --- docs/auth/microsoft/provider.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/auth/microsoft/provider.md b/docs/auth/microsoft/provider.md index 787b95f2f3..583139cff1 100644 --- a/docs/auth/microsoft/provider.md +++ b/docs/auth/microsoft/provider.md @@ -59,7 +59,6 @@ hosts: code](https://github.com/seanfisher/passport-microsoft/blob/0456aa9bce05579c18e77f51330176eb26373658/lib/strategy.js#L93-L95)). If this host is unreachable, users may see an `Authentication failed, failed to fetch user profile` error when they attempt to log in. - ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `microsoftAuthApiRef` reference and From ca1b2e4d9bdce1338a2b6a03b9d75793161fb9e1 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 7 Nov 2022 15:21:50 +0100 Subject: [PATCH 202/434] scripts: remove isolated-release script Signed-off-by: Patrik Oldsberg --- scripts/isolated-release.js | 58 ------------------------------------- 1 file changed, 58 deletions(-) delete mode 100755 scripts/isolated-release.js diff --git a/scripts/isolated-release.js b/scripts/isolated-release.js deleted file mode 100755 index 4df900450e..0000000000 --- a/scripts/isolated-release.js +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env node -/* - * Copyright 2020 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. - */ - -const path = require('path'); -const childProcess = require('child_process'); -const { getPackages } = require('@manypkg/get-packages'); - -// Prepare a release of the provided packages, e.g. @backstage/core -async function main(args) { - if (args.includes('--help') || args.length === 0) { - const arg0 = path.relative(process.cwd(), process.argv[1]); - console.log(`Usage: ${process.argv0} ${arg0} ...`); - process.exit(1); - } - - const { packages } = await getPackages(__dirname); - const ignoreArgs = packages - .filter(p => !args.includes(p.packageJson.name)) - .flatMap(p => ['--ignore', p.packageJson.name]); - - const { status } = childProcess.spawnSync( - 'yarn', - ['changeset', 'version', ...ignoreArgs], - { - stdio: 'inherit', - }, - ); - if (status !== 0) { - return; - } - - childProcess.spawnSync( - 'yarn', - ['prettier', '--write', '{packages,plugins}/*/{package.json,CHANGELOG.md}'], - { - stdio: 'inherit', - }, - ); -} - -main(process.argv.slice(2)).catch(error => { - console.error(error.stack); - process.exit(1); -}); From b7cb6043a49e7ffdc6b00a4cc056c9549a78bd93 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 14:42:20 +0000 Subject: [PATCH 203/434] Update dependency mock-fs to v5.2.0 Signed-off-by: Renovate Bot --- yarn.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6e9fba135e..986b56a967 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3196,7 +3196,7 @@ __metadata: luxon: ^3.0.0 minimatch: ^5.0.0 minimist: ^1.2.5 - mock-fs: ^5.1.0 + mock-fs: ^5.1.1 morgan: ^1.10.0 msw: ^0.47.0 mysql2: ^2.2.5 @@ -3451,7 +3451,7 @@ __metadata: lodash: ^4.17.21 mini-css-extract-plugin: ^2.4.2 minimatch: 5.1.0 - mock-fs: ^5.1.0 + mock-fs: ^5.1.1 msw: ^0.47.0 node-fetch: ^2.6.7 node-libs-browser: ^2.2.1 @@ -3534,7 +3534,7 @@ __metadata: json-schema: ^0.4.0 json-schema-merge-allof: ^0.8.1 json-schema-traverse: ^1.0.0 - mock-fs: ^5.1.0 + mock-fs: ^5.1.1 msw: ^0.47.0 node-fetch: ^2.6.7 typescript-json-schema: ^0.54.0 @@ -4241,7 +4241,7 @@ __metadata: knex: ^2.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - mock-fs: ^5.1.0 + mock-fs: ^5.1.1 msw: ^0.47.0 node-fetch: ^2.6.7 supertest: ^6.1.3 @@ -6818,7 +6818,7 @@ __metadata: "@types/mock-fs": ^4.13.0 command-exists: ^1.2.9 fs-extra: 10.1.0 - mock-fs: ^5.1.0 + mock-fs: ^5.1.1 msw: ^0.47.0 winston: ^3.2.1 yn: ^4.0.0 @@ -6843,7 +6843,7 @@ __metadata: command-exists: ^1.2.9 fs-extra: ^10.0.1 jest-when: ^3.1.0 - mock-fs: ^5.1.0 + mock-fs: ^5.1.1 languageName: unknown linkType: soft @@ -6908,7 +6908,7 @@ __metadata: knex: ^2.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - mock-fs: ^5.1.0 + mock-fs: ^5.1.1 morgan: ^1.10.0 msw: ^0.47.0 node-fetch: ^2.6.7 @@ -7673,7 +7673,7 @@ __metadata: js-yaml: ^4.0.0 json5: ^2.1.3 mime-types: ^2.1.27 - mock-fs: ^5.1.0 + mock-fs: ^5.1.1 p-limit: ^3.1.0 recursive-readdir: ^2.2.2 supertest: ^6.1.3 @@ -29741,7 +29741,7 @@ __metadata: languageName: node linkType: hard -"mock-fs@npm:^5.1.0, mock-fs@npm:^5.1.1": +"mock-fs@npm:^5.1.1": version: 5.1.4 resolution: "mock-fs@npm:5.1.4" checksum: e5621c9162be71f88ba264c32cbbc2df737b4e243608ca9126f05b6b1410f1ca911e155a36d3785f194b4219438df8fa33d79cd7ef0b8c7701efd0e4a11f0630 From 6f9e0412a925136f966cd8aa1c63c43312c7ad92 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 7 Nov 2022 15:50:29 +0100 Subject: [PATCH 204/434] yarn.lock: actually bump mock-fs Signed-off-by: Patrik Oldsberg --- yarn.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/yarn.lock b/yarn.lock index 986b56a967..a9c942a290 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3196,7 +3196,7 @@ __metadata: luxon: ^3.0.0 minimatch: ^5.0.0 minimist: ^1.2.5 - mock-fs: ^5.1.1 + mock-fs: ^5.1.0 morgan: ^1.10.0 msw: ^0.47.0 mysql2: ^2.2.5 @@ -3451,7 +3451,7 @@ __metadata: lodash: ^4.17.21 mini-css-extract-plugin: ^2.4.2 minimatch: 5.1.0 - mock-fs: ^5.1.1 + mock-fs: ^5.1.0 msw: ^0.47.0 node-fetch: ^2.6.7 node-libs-browser: ^2.2.1 @@ -3534,7 +3534,7 @@ __metadata: json-schema: ^0.4.0 json-schema-merge-allof: ^0.8.1 json-schema-traverse: ^1.0.0 - mock-fs: ^5.1.1 + mock-fs: ^5.1.0 msw: ^0.47.0 node-fetch: ^2.6.7 typescript-json-schema: ^0.54.0 @@ -4241,7 +4241,7 @@ __metadata: knex: ^2.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - mock-fs: ^5.1.1 + mock-fs: ^5.1.0 msw: ^0.47.0 node-fetch: ^2.6.7 supertest: ^6.1.3 @@ -6818,7 +6818,7 @@ __metadata: "@types/mock-fs": ^4.13.0 command-exists: ^1.2.9 fs-extra: 10.1.0 - mock-fs: ^5.1.1 + mock-fs: ^5.1.0 msw: ^0.47.0 winston: ^3.2.1 yn: ^4.0.0 @@ -6843,7 +6843,7 @@ __metadata: command-exists: ^1.2.9 fs-extra: ^10.0.1 jest-when: ^3.1.0 - mock-fs: ^5.1.1 + mock-fs: ^5.1.0 languageName: unknown linkType: soft @@ -6908,7 +6908,7 @@ __metadata: knex: ^2.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - mock-fs: ^5.1.1 + mock-fs: ^5.1.0 morgan: ^1.10.0 msw: ^0.47.0 node-fetch: ^2.6.7 @@ -7673,7 +7673,7 @@ __metadata: js-yaml: ^4.0.0 json5: ^2.1.3 mime-types: ^2.1.27 - mock-fs: ^5.1.1 + mock-fs: ^5.1.0 p-limit: ^3.1.0 recursive-readdir: ^2.2.2 supertest: ^6.1.3 @@ -29741,10 +29741,10 @@ __metadata: languageName: node linkType: hard -"mock-fs@npm:^5.1.1": - version: 5.1.4 - resolution: "mock-fs@npm:5.1.4" - checksum: e5621c9162be71f88ba264c32cbbc2df737b4e243608ca9126f05b6b1410f1ca911e155a36d3785f194b4219438df8fa33d79cd7ef0b8c7701efd0e4a11f0630 +"mock-fs@npm:^5.1.0, mock-fs@npm:^5.1.1": + version: 5.2.0 + resolution: "mock-fs@npm:5.2.0" + checksum: c25835247bd26fa4e0189addd61f98973f61a72741e4d2a5694b143a2069b84978443a7ac0fdb1a71aead99273ec22ff4e9c968de11bbd076db020264c5b8312 languageName: node linkType: hard From 24152c0c52a75c3b633cbd5088994126ad57c536 Mon Sep 17 00:00:00 2001 From: kvmw Date: Thu, 3 Nov 2022 11:54:41 +0100 Subject: [PATCH 205/434] Inject optional CatalogApi in auth-backend router Signed-off-by: kvmw --- plugins/auth-backend/src/service/router.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/auth-backend/src/service/router.ts b/plugins/auth-backend/src/service/router.ts index 7240ba1bcb..8013777415 100644 --- a/plugins/auth-backend/src/service/router.ts +++ b/plugins/auth-backend/src/service/router.ts @@ -28,7 +28,7 @@ import { TokenManager, } from '@backstage/backend-common'; import { assertError, NotFoundError } from '@backstage/errors'; -import { CatalogClient } from '@backstage/catalog-client'; +import { CatalogApi, CatalogClient } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { createOidcRouter, TokenFactory, KeyStores } from '../identity'; import session from 'express-session'; @@ -48,6 +48,7 @@ export interface RouterOptions { tokenManager: TokenManager; tokenFactoryAlgorithm?: string; providerFactories?: ProviderFactories; + catalogApi?: CatalogApi; } /** @public */ @@ -62,6 +63,7 @@ export async function createRouter( tokenManager, tokenFactoryAlgorithm, providerFactories, + catalogApi, } = options; const router = Router(); @@ -78,7 +80,6 @@ export async function createRouter( logger: logger.child({ component: 'token-factory' }), algorithm: tokenFactoryAlgorithm, }); - const catalogApi = new CatalogClient({ discoveryApi: discovery }); const secret = config.getOptionalString('auth.session.secret'); if (secret) { @@ -127,7 +128,8 @@ export async function createRouter( logger, resolverContext: CatalogAuthResolverContext.create({ logger, - catalogApi, + catalogApi: + catalogApi ?? new CatalogClient({ discoveryApi: discovery }), tokenIssuer, tokenManager, }), From d80833fe0c401896aaa7477706c988b28ae9bb8d Mon Sep 17 00:00:00 2001 From: kvmw Date: Mon, 7 Nov 2022 14:25:07 +0100 Subject: [PATCH 206/434] Add changeset Signed-off-by: kvmw --- .changeset/wicked-pumas-nail.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wicked-pumas-nail.md diff --git a/.changeset/wicked-pumas-nail.md b/.changeset/wicked-pumas-nail.md new file mode 100644 index 0000000000..c9e05aff74 --- /dev/null +++ b/.changeset/wicked-pumas-nail.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Inject optional `CatalogApi` into auth-backend `createRouter` function. This will enable developers to use customized `CatalogApi` when creating the router. From a74a0ff182efd69b33b4f2390ad54538c1190b58 Mon Sep 17 00:00:00 2001 From: kvmw Date: Mon, 7 Nov 2022 15:39:33 +0100 Subject: [PATCH 207/434] Updates api-report.md Signed-off-by: kvmw --- plugins/auth-backend/api-report.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index cc6962cdbe..cec3422d9c 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -669,6 +669,8 @@ export const readState: (stateString: string) => OAuthState; // @public (undocumented) export interface RouterOptions { + // (undocumented) + catalogApi?: CatalogApi; // (undocumented) config: Config; // (undocumented) From a4496131fa5b97b8be8f05f0ef6aefe82006cbf2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 28 Sep 2022 18:10:43 +0200 Subject: [PATCH 208/434] release-manifests: add fallback that fetches from GitHub raw Signed-off-by: Patrik Oldsberg --- .changeset/dry-phones-type.md | 5 + .../release-manifests/src/manifest.test.ts | 53 +++++++++- packages/release-manifests/src/manifest.ts | 97 +++++++++++++++---- 3 files changed, 137 insertions(+), 18 deletions(-) create mode 100644 .changeset/dry-phones-type.md diff --git a/.changeset/dry-phones-type.md b/.changeset/dry-phones-type.md new file mode 100644 index 0000000000..ad2cf40113 --- /dev/null +++ b/.changeset/dry-phones-type.md @@ -0,0 +1,5 @@ +--- +'@backstage/release-manifests': patch +--- + +Added a fallback that fetches manifests from `https://raw.githubusercontent.com` if `https://versions.backstage.io` is unavailable. diff --git a/packages/release-manifests/src/manifest.test.ts b/packages/release-manifests/src/manifest.test.ts index 272555df70..6a53f993c8 100644 --- a/packages/release-manifests/src/manifest.test.ts +++ b/packages/release-manifests/src/manifest.test.ts @@ -17,7 +17,11 @@ import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { setupRequestMockHandlers } from '@backstage/test-utils'; -import { getManifestByReleaseLine, getManifestByVersion } from './manifest'; +import { + getManifestByReleaseLine, + getManifestByVersion, + withFallback, +} from './manifest'; describe('Release Manifests', () => { const worker = setupServer(); @@ -86,3 +90,50 @@ describe('Release Manifests', () => { }); }); }); + +describe('withFallback', () => { + it('should use the first value to resolve', async () => { + const fn1 = jest.fn((_s: AbortSignal) => Promise.resolve(1)); + const fn2 = jest.fn((_s: AbortSignal) => Promise.resolve(2)); + await expect(withFallback(fn1, fn2, 100)).resolves.toBe(1); + expect(fn1.mock.lastCall?.[0].aborted).toBe(false); + expect(fn2).not.toHaveBeenCalled(); + }); + + it('should fall back on rejection', async () => { + const fn1 = jest.fn((_s: AbortSignal) => Promise.reject(new Error('1'))); + const fn2 = jest.fn((_s: AbortSignal) => Promise.resolve(2)); + await expect(withFallback(fn1, fn2, 0)).resolves.toBe(2); + expect(fn1.mock.lastCall?.[0].aborted).toBe(true); + expect(fn2.mock.lastCall?.[0].aborted).toBe(false); + }); + + it('should fall back on timeout', async () => { + const fn1 = jest.fn((_s: AbortSignal) => new Promise(() => {})); + const fn2 = jest.fn((_s: AbortSignal) => Promise.resolve(2)); + await expect(withFallback(fn1, fn2, 0)).resolves.toBe(2); + expect(fn1.mock.lastCall?.[0].aborted).toBe(true); + expect(fn2.mock.lastCall?.[0].aborted).toBe(false); + }); + + it('should always reject with the first error', async () => { + const fn1 = jest.fn((_s: AbortSignal) => Promise.reject(new Error('1'))); + const fn2 = jest.fn((_s: AbortSignal) => Promise.reject(new Error('2'))); + await expect(withFallback(fn1, fn2, 0)).rejects.toThrow('1'); + expect(fn1.mock.lastCall?.[0].aborted).toBe(false); + expect(fn2.mock.lastCall?.[0].aborted).toBe(false); + }); + + it('should always reject with the first error even if rejected after', async () => { + const fn1 = jest.fn( + (_s: AbortSignal) => + new Promise((_resolve, reject) => { + setTimeout(() => reject(new Error('1')), 100); + }), + ); + const fn2 = jest.fn((_s: AbortSignal) => Promise.reject(new Error('2'))); + await expect(withFallback(fn1, fn2, 0)).rejects.toThrow('1'); + expect(fn1.mock.lastCall?.[0].aborted).toBe(false); + expect(fn2.mock.lastCall?.[0].aborted).toBe(false); + }); +}); diff --git a/packages/release-manifests/src/manifest.ts b/packages/release-manifests/src/manifest.ts index 955cf7308c..004ccfc77c 100644 --- a/packages/release-manifests/src/manifest.ts +++ b/packages/release-manifests/src/manifest.ts @@ -16,7 +16,9 @@ import fetch from 'cross-fetch'; -const VERSIONS_DOMAIN = 'https://versions.backstage.io'; +const VERSIONS_BASE_URL = 'https://versions.backstage.io'; +const GITHUB_RAW_BASE_URL = + 'https://raw.githubusercontent.com/backstage/versions/main'; /** * Contains mapping between Backstage release and package versions. @@ -35,6 +37,45 @@ export type GetManifestByVersionOptions = { version: string; }; +// Wait for waitMs, or until signal is aborted. +function wait(waitMs: number, signal: AbortSignal) { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + if (!signal.aborted) { + resolve(); + } + }, waitMs); + signal.addEventListener('abort', () => { + clearTimeout(timeout); + reject(new Error('Aborted')); + }); + }); +} + +// Run fn1 and then fn2 after fallbackDelayMs. Whichever one finishes +// first wins, and the other one is aborted through the provided signal. +export async function withFallback( + fn1: (signal: AbortSignal) => Promise, + fn2: (signal: AbortSignal) => Promise, + fallbackDelayMs: number, +): Promise { + const c1 = new AbortController(); + const c2 = new AbortController(); + + const promise1 = fn1(c1.signal).then(res => { + c2.abort(); + return res; + }); + const promise2 = wait(fallbackDelayMs, c2.signal) + .then(() => fn2(c2.signal)) + .then(res => { + c1.abort(); + return res; + }); + + return Promise.any([promise1, promise2]).catch(() => promise1); +} + /** * Returns a release manifest based on supplied version. * @public @@ -42,19 +83,27 @@ export type GetManifestByVersionOptions = { export async function getManifestByVersion( options: GetManifestByVersionOptions, ): Promise { - const url = `${VERSIONS_DOMAIN}/v1/releases/${encodeURIComponent( - options.version, - )}/manifest.json`; - const response = await fetch(url); - if (response.status === 404) { + const versionEnc = encodeURIComponent(options.version); + const res = await withFallback( + signal => + fetch(`${VERSIONS_BASE_URL}/v1/releases/${versionEnc}/manifest.json`, { + signal, + }), + signal => + fetch(`${GITHUB_RAW_BASE_URL}/v1/releases/${versionEnc}/manifest.json`, { + signal, + }), + 500, + ); + if (res.status === 404) { throw new Error(`No release found for ${options.version} version`); } - if (response.status !== 200) { + if (res.status !== 200) { throw new Error( - `Unexpected response status ${response.status} when fetching release from ${url}.`, + `Unexpected response status ${res.status} when fetching release from ${res.url}.`, ); } - return await response.json(); + return res.json(); } /** @@ -72,17 +121,31 @@ export type GetManifestByReleaseLineOptions = { export async function getManifestByReleaseLine( options: GetManifestByReleaseLineOptions, ): Promise { - const url = `${VERSIONS_DOMAIN}/v1/tags/${encodeURIComponent( - options.releaseLine, - )}/manifest.json`; - const response = await fetch(url); - if (response.status === 404) { + const releaseEnc = encodeURIComponent(options.releaseLine); + const res = await withFallback( + signal => + fetch(`${VERSIONS_BASE_URL}/v1/tags/${releaseEnc}/manifest.json`, { + signal, + }), + async signal => { + // The release tags are symlinks, which we need to follow manually when fetching from GitHub. + const baseUrl = `${GITHUB_RAW_BASE_URL}/v1/tags/${releaseEnc}`; + const linkRes = await fetch(baseUrl, { signal }); + if (!linkRes.ok) { + return linkRes; + } + const link = (await linkRes.text()).trim(); + return fetch(new URL(`${link}/manifest.json`, baseUrl), { signal }); + }, + 1000, + ); + if (res.status === 404) { throw new Error(`No '${options.releaseLine}' release line found`); } - if (response.status !== 200) { + if (res.status !== 200) { throw new Error( - `Unexpected response status ${response.status} when fetching release from ${url}.`, + `Unexpected response status ${res.status} when fetching release from ${res.url}.`, ); } - return await response.json(); + return res.json(); } From bdc44f025f993d8b3c51443212990680b0f41dc2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 28 Sep 2022 19:54:28 +0200 Subject: [PATCH 209/434] release-manifests: workaround for no Promise.any in Node 14 Signed-off-by: Patrik Oldsberg --- packages/release-manifests/src/manifest.ts | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/release-manifests/src/manifest.ts b/packages/release-manifests/src/manifest.ts index 004ccfc77c..d3b0c8ed5d 100644 --- a/packages/release-manifests/src/manifest.ts +++ b/packages/release-manifests/src/manifest.ts @@ -73,7 +73,25 @@ export async function withFallback( return res; }); - return Promise.any([promise1, promise2]).catch(() => promise1); + // TODO(Rugvip): Replace with this once we no longer support Node 14 + // return Promise.any([promise1, promise2]).catch(() => promise1); + return new Promise((resolve, reject) => { + let rejection: Error | undefined = undefined; + promise1.then(resolve, e => { + if (rejection) { + reject(e); + } else { + rejection = e; + } + }); + promise2.then(resolve, e => { + if (rejection) { + reject(rejection); + } else { + rejection = e; + } + }); + }); } /** From 13bca51ec1d909e8986c10ae7848c7d7cf873055 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 7 Nov 2022 16:39:34 +0100 Subject: [PATCH 210/434] Revert "release-manifests: workaround for no Promise.any in Node 14" This reverts commit bdc44f025f993d8b3c51443212990680b0f41dc2. Signed-off-by: Patrik Oldsberg --- packages/release-manifests/src/manifest.ts | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/packages/release-manifests/src/manifest.ts b/packages/release-manifests/src/manifest.ts index d3b0c8ed5d..004ccfc77c 100644 --- a/packages/release-manifests/src/manifest.ts +++ b/packages/release-manifests/src/manifest.ts @@ -73,25 +73,7 @@ export async function withFallback( return res; }); - // TODO(Rugvip): Replace with this once we no longer support Node 14 - // return Promise.any([promise1, promise2]).catch(() => promise1); - return new Promise((resolve, reject) => { - let rejection: Error | undefined = undefined; - promise1.then(resolve, e => { - if (rejection) { - reject(e); - } else { - rejection = e; - } - }); - promise2.then(resolve, e => { - if (rejection) { - reject(rejection); - } else { - rejection = e; - } - }); - }); + return Promise.any([promise1, promise2]).catch(() => promise1); } /** From eed5427a325cf3718680b3a18466a8ab88cc081a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 15:39:42 +0000 Subject: [PATCH 211/434] Update dependency keyv to v4.5.2 Signed-off-by: Renovate Bot --- yarn.lock | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index a9c942a290..1085b6483c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27611,7 +27611,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.0.0, keyv@npm:^4.0.3": +"keyv@npm:^4.0.0": version: 4.5.0 resolution: "keyv@npm:4.5.0" dependencies: @@ -27620,6 +27620,15 @@ __metadata: languageName: node linkType: hard +"keyv@npm:^4.0.3": + version: 4.5.2 + resolution: "keyv@npm:4.5.2" + dependencies: + json-buffer: 3.0.1 + checksum: 13ad58303acd2261c0d4831b4658451603fd159e61daea2121fcb15feb623e75ee328cded0572da9ca76b7b3ceaf8e614f1806c6b3af5db73c9c35a345259651 + languageName: node + linkType: hard + "kind-of@npm:^6.0.2, kind-of@npm:^6.0.3": version: 6.0.3 resolution: "kind-of@npm:6.0.3" From 55bd36b18a995fa0038919c536c51d52b8d3f7f3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 15:40:54 +0000 Subject: [PATCH 212/434] Update dependency node-gyp to v9.3.0 Signed-off-by: Renovate Bot --- yarn.lock | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index a9c942a290..20b26540ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15789,7 +15789,7 @@ __metadata: languageName: node linkType: hard -"abbrev@npm:1": +"abbrev@npm:1, abbrev@npm:^1.0.0": version: 1.1.1 resolution: "abbrev@npm:1.1.1" checksum: a4a97ec07d7ea112c517036882b2ac22f3109b7b19077dc656316d07d308438aac28e4d9746dc4d84bf6b1e75b4a7b0a5f3cb30592419f128ca9a8cee3bcfa17 @@ -30136,7 +30136,27 @@ __metadata: languageName: node linkType: hard -"node-gyp@npm:^9.1.0, node-gyp@npm:latest": +"node-gyp@npm:^9.1.0": + version: 9.3.0 + resolution: "node-gyp@npm:9.3.0" + dependencies: + env-paths: ^2.2.0 + glob: ^7.1.4 + graceful-fs: ^4.2.6 + make-fetch-happen: ^10.0.3 + nopt: ^6.0.0 + npmlog: ^6.0.0 + rimraf: ^3.0.2 + semver: ^7.3.5 + tar: ^6.1.2 + which: ^2.0.2 + bin: + node-gyp: bin/node-gyp.js + checksum: 589ddd3ed967724ef425f9624bfa47cf73022640ab3eba6d556e92cdc4ddef33b63fce3a467c93b995a3f61df92eafd3c3d1e8dbe4a2c00c383334487dea99c3 + languageName: node + linkType: hard + +"node-gyp@npm:latest": version: 9.1.0 resolution: "node-gyp@npm:9.1.0" dependencies: @@ -30257,6 +30277,17 @@ __metadata: languageName: node linkType: hard +"nopt@npm:^6.0.0": + version: 6.0.0 + resolution: "nopt@npm:6.0.0" + dependencies: + abbrev: ^1.0.0 + bin: + nopt: bin/nopt.js + checksum: 82149371f8be0c4b9ec2f863cc6509a7fd0fa729929c009f3a58e4eb0c9e4cae9920e8f1f8eb46e7d032fec8fb01bede7f0f41a67eb3553b7b8e14fa53de1dac + languageName: node + linkType: hard + "normalize-package-data@npm:^2.3.2, normalize-package-data@npm:^2.5.0": version: 2.5.0 resolution: "normalize-package-data@npm:2.5.0" From e1b3c3ed3d4c74e4041f41ec932726f98babd6d5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 16:23:48 +0000 Subject: [PATCH 213/434] Update dependency octokit-plugin-create-pull-request to v3.13.1 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1085b6483c..f1309e3230 100644 --- a/yarn.lock +++ b/yarn.lock @@ -30633,11 +30633,11 @@ __metadata: linkType: hard "octokit-plugin-create-pull-request@npm:^3.10.0": - version: 3.12.2 - resolution: "octokit-plugin-create-pull-request@npm:3.12.2" + version: 3.13.1 + resolution: "octokit-plugin-create-pull-request@npm:3.13.1" dependencies: "@octokit/types": ^6.8.2 - checksum: 1f23b6ab62f148795eb7d0109bbfbaf022760ccd17eca2d8d6e0dd860ec76d509fcc0e94841caedaf1e5fe48885cec080fdf8c1cddf0736d0c119070eb7f371f + checksum: 169e393046cecc51b9c9be23321086fc60681bfdfe2bcec5477d0916e5b8e3b64b54588f631f61d98677a0561f5d44fa85589abd75ff851122c798795921292b languageName: node linkType: hard From cf032af4941f46179ae0fd0f36bf1f1934bd3c36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Nov 2022 08:37:32 +0000 Subject: [PATCH 214/434] build(deps): bump loader-utils from 1.4.0 to 1.4.1 Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.0 to 1.4.1. - [Release notes](https://github.com/webpack/loader-utils/releases) - [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.1/CHANGELOG.md) - [Commits](https://github.com/webpack/loader-utils/compare/v1.4.0...v1.4.1) --- updated-dependencies: - dependency-name: loader-utils dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1085b6483c..a0b5279121 100644 --- a/yarn.lock +++ b/yarn.lock @@ -28004,13 +28004,13 @@ __metadata: linkType: hard "loader-utils@npm:^1.1.0": - version: 1.4.0 - resolution: "loader-utils@npm:1.4.0" + version: 1.4.1 + resolution: "loader-utils@npm:1.4.1" dependencies: big.js: ^5.2.2 emojis-list: ^3.0.0 json5: ^1.0.1 - checksum: d150b15e7a42ac47d935c8b484b79e44ff6ab4c75df7cc4cb9093350cf014ec0b17bdb60c5d6f91a37b8b218bd63b973e263c65944f58ca2573e402b9a27e717 + checksum: ea0b648cba0194e04a90aab6270619f0e35be009e33a443d9e642e93056cd49e6ca4c9678bd1c777a2392551bc5f4d0f24a87f5040608da1274aa84c6eebb502 languageName: node linkType: hard From 05d4d71dd925ec92983fedb25360c3b27a41cb04 Mon Sep 17 00:00:00 2001 From: Loybin Date: Tue, 8 Nov 2022 12:42:43 +0400 Subject: [PATCH 215/434] Featrue: Add dag-run-status, update DagTable Signed-off-by: Loybin --- .../src/api/ApacheAirflowApi.ts | 5 + .../src/api/ApacheAirflowClient.test.ts | 132 ++++++--- .../src/api/ApacheAirflowClient.ts | 46 ++++ plugins/apache-airflow/src/api/types/Dags.ts | 11 + .../DagTableComponent/DagTableComponent.tsx | 251 ++++++++++++------ .../LatestDagRunsStatus.test.tsx | 67 +++++ .../LatestDagRunsStatus.tsx | 161 +++++++++++ .../components/LatestDagRunsStatus/index.ts | 17 ++ 8 files changed, 560 insertions(+), 130 deletions(-) create mode 100644 plugins/apache-airflow/src/components/LatestDagRunsStatus/LatestDagRunsStatus.test.tsx create mode 100644 plugins/apache-airflow/src/components/LatestDagRunsStatus/LatestDagRunsStatus.tsx create mode 100644 plugins/apache-airflow/src/components/LatestDagRunsStatus/index.ts diff --git a/plugins/apache-airflow/src/api/ApacheAirflowApi.ts b/plugins/apache-airflow/src/api/ApacheAirflowApi.ts index 838292524a..128f6e551d 100644 --- a/plugins/apache-airflow/src/api/ApacheAirflowApi.ts +++ b/plugins/apache-airflow/src/api/ApacheAirflowApi.ts @@ -16,6 +16,7 @@ import { createApiRef, DiscoveryApi } from '@backstage/core-plugin-api'; import { Dag, InstanceStatus, InstanceVersion } from './types'; +import { DagRun } from './types/Dags'; export const apacheAirflowApiRef = createApiRef({ id: 'plugin.apacheairflow.service', @@ -27,6 +28,10 @@ export type ApacheAirflowApi = { listDags(options?: { objectsPerRequest: number }): Promise; getDags(dagIds: string[]): Promise<{ dags: Dag[]; dagsNotFound: string[] }>; updateDag(dagId: string, isPaused: boolean): Promise; + getDagRuns( + dagId: string, + options?: { objectsPerRequest?: number; limit?: number }, + ): Promise; getInstanceStatus(): Promise; getInstanceVersion(): Promise; }; diff --git a/plugins/apache-airflow/src/api/ApacheAirflowClient.test.ts b/plugins/apache-airflow/src/api/ApacheAirflowClient.test.ts index b9bdb02283..ab0565f4e4 100644 --- a/plugins/apache-airflow/src/api/ApacheAirflowClient.test.ts +++ b/plugins/apache-airflow/src/api/ApacheAirflowClient.test.ts @@ -20,6 +20,7 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { ApacheAirflowClient } from './index'; import { Dag } from './types'; +import { DagRun } from './types/Dags'; const server = setupServer(); @@ -66,12 +67,45 @@ const dags: Dag[] = [ }, ]; +const dagRuns: DagRun[] = [ + { + dag_run_id: 'mock dag run 1', + dag_id: 'mock_dag_1', + logical_date: '2022-05-27T11:25:23.251274+00:00', + start_date: '2022-05-27T11:25:23.251274+00:00', + end_date: '2022-05-27T11:25:23.251274+00:00', + state: 'success', + external_trigger: true, + conf: {}, + }, + { + dag_run_id: 'mock dag run 2', + dag_id: 'mock_dag_2', + logical_date: '2022-05-27T11:25:23.251274+00:00', + start_date: '2022-05-27T11:25:23.251274+00:00', + end_date: '2022-05-27T11:25:23.251274+00:00', + state: 'running', + external_trigger: true, + conf: {}, + }, + { + dag_run_id: 'mock dag run 3', + dag_id: 'mock_dag_1', + logical_date: '2022-05-27T11:25:23.251274+00:00', + start_date: '2022-05-27T11:25:23.251274+00:00', + end_date: '2022-05-27T11:25:23.251274+00:00', + state: 'failed', + external_trigger: true, + conf: {}, + }, +]; + describe('ApacheAirflowClient', () => { setupRequestMockHandlers(server); const mockBaseUrl = 'http://backstage:9191/api/proxy'; const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl); - + let client: ApacheAirflowClient; const setupHandlers = () => { server.use( rest.get(`${mockBaseUrl}/airflow/dags`, (req, res, ctx) => { @@ -116,41 +150,61 @@ describe('ApacheAirflowClient', () => { return res(ctx.status(404)); }), - rest.patch(`${mockBaseUrl}/airflow/dags/:dag_id`, (req, res, ctx) => { - const { dag_id } = req.params; - const body = JSON.parse(req.body as string); - expect(body.is_paused).toBeDefined(); - return res( - ctx.json({ - dag_id: dag_id, - root_dag_id: 'string', - is_paused: body.is_paused, - is_active: true, - is_subdag: true, - fileloc: 'string', - file_token: 'string', - owners: ['string'], - description: 'string', - schedule_interval: { - __type: 'string', - days: 0, - seconds: 0, - microseconds: 0, - }, - tags: [{}], - }), - ); - }), + rest.get( + `${mockBaseUrl}/airflow/dags/:dag_id/dagRuns`, + (req, res, ctx) => { + const { dag_id } = req.params; + const runs = dagRuns.filter(run => run.dag_id === dag_id); + // event if the dag_id is invalid, airflow returns a valid response (with 0 dag runs) + return res( + ctx.json({ + dag_runs: runs, + total_entries: runs.length, + }), + ); + }, + ), + + rest.patch( + `${mockBaseUrl}/airflow/dags/:dag_id`, + async (req, res, ctx) => { + const { dag_id } = req.params; + const body = JSON.parse(await req.text()); + expect(body.is_paused).toBeDefined(); + return res( + ctx.json({ + dag_id: dag_id, + root_dag_id: 'string', + is_paused: body.is_paused, + is_active: true, + is_subdag: true, + fileloc: 'string', + file_token: 'string', + owners: ['string'], + description: 'string', + schedule_interval: { + __type: 'string', + days: 0, + seconds: 0, + microseconds: 0, + }, + tags: [{}], + }), + ); + }, + ), ); }; - it('list dags should return all dags with emulated pagination', async () => { + beforeEach(() => { setupHandlers(); - const client = new ApacheAirflowClient({ + client = new ApacheAirflowClient({ discoveryApi: discoveryApi, baseUrl: 'localhost:8080/', }); + }); + it('list dags should return all dags with emulated pagination', async () => { // call with limit of 2, to force two paginations in requesting all dags // as our mocked response has 4 total entries const responseDags = await client.listDags({ objectsPerRequest: 2 }); @@ -159,11 +213,6 @@ describe('ApacheAirflowClient', () => { }); it('update dag should return dag information with updated paused attribute', async () => { - setupHandlers(); - const client = new ApacheAirflowClient({ - discoveryApi: discoveryApi, - baseUrl: 'localhost:8080/', - }); const dagId = 'mock_dag_1'; const response: Dag = await client.updateDag(dagId, true); expect(response.dag_id).toEqual(dagId); @@ -171,11 +220,6 @@ describe('ApacheAirflowClient', () => { }); it('get only some dags', async () => { - setupHandlers(); - const client = new ApacheAirflowClient({ - discoveryApi: discoveryApi, - baseUrl: 'localhost:8080/', - }); const dagIds = ['mock_dag_1', 'mock_dag_3']; const response = await client.getDags(dagIds); expect(response.dags.length).toEqual(dagIds.length); @@ -186,11 +230,6 @@ describe('ApacheAirflowClient', () => { }); it('get dags but ignore NOT FOUND errors', async () => { - setupHandlers(); - const client = new ApacheAirflowClient({ - discoveryApi: discoveryApi, - baseUrl: 'localhost:8080/', - }); const dagIds = ['mock_dag_1', 'a-random-DAG-id']; const response = await client.getDags(dagIds); expect(response.dags.length).toEqual(1); @@ -198,4 +237,11 @@ describe('ApacheAirflowClient', () => { expect(response.dagsNotFound.length).toEqual(1); expect(response.dagsNotFound[0]).toEqual('a-random-DAG-id'); }); + + it('should get dag runs', async () => { + const dagId = 'mock_dag_1'; + const response = await client.getDagRuns(dagId); + expect(response.length).toEqual(2); + response.forEach(run => expect(run.dag_id).toEqual(dagId)); + }); }); diff --git a/plugins/apache-airflow/src/api/ApacheAirflowClient.ts b/plugins/apache-airflow/src/api/ApacheAirflowClient.ts index c722f5977d..ebd60b668a 100644 --- a/plugins/apache-airflow/src/api/ApacheAirflowClient.ts +++ b/plugins/apache-airflow/src/api/ApacheAirflowClient.ts @@ -25,6 +25,7 @@ import { InstanceVersion, ListDagsParams, } from './types'; +import { DagRun } from './types/Dags'; export class ApacheAirflowClient implements ApacheAirflowApi { discoveryApi: DiscoveryApi; @@ -97,11 +98,56 @@ export class ApacheAirflowClient implements ApacheAirflowApi { async updateDag(dagId: string, isPaused: boolean): Promise { const init = { method: 'PATCH', + headers: { + 'Content-Type': 'application/json', + }, body: JSON.stringify({ is_paused: isPaused }), }; return await this.fetch(`/dags/${dagId}`, init); } + /** + * Get the latest DAG Runs of a specific DAG. + * The DAG runs are ordered by start date + * + * @remarks + * + * The "limit" option means the maximum number of DAG runs to return + * "objectsPerRequest" means the maximum number of DAG runs to be taken per fetch request. + * This is just to make sure the response payloads are not too big + */ + async getDagRuns( + dagId: string, + options = { objectsPerRequest: 100, limit: 5 }, + ): Promise { + const dagRuns: DagRun[] = []; + const searchParams: ListDagsParams = { + limit: Math.min(options.objectsPerRequest || 100, options.limit || 5), + offset: 0, + order_by: '-start_date', + }; + + for (;;) { + const response = await this.fetch<{ + dag_runs: DagRun[]; + total_entries: number; + }>(`/dags/${dagId}/dagRuns?${qs.stringify(searchParams)}`); + dagRuns.push(...response.dag_runs); + + if (response.dag_runs.length < searchParams.limit!) { + break; + } + if ( + dagRuns.length >= response.total_entries || + dagRuns.length >= options.limit + ) { + break; + } + searchParams.offset! += response.dag_runs.length; + } + return dagRuns; + } + async getInstanceStatus(): Promise { return await this.fetch('/health'); } diff --git a/plugins/apache-airflow/src/api/types/Dags.ts b/plugins/apache-airflow/src/api/types/Dags.ts index 8f1d68fb2d..702a6470e7 100644 --- a/plugins/apache-airflow/src/api/types/Dags.ts +++ b/plugins/apache-airflow/src/api/types/Dags.ts @@ -44,6 +44,17 @@ export interface Dag { tags: Tag[]; } +export interface DagRun { + dag_run_id: string; + dag_id: string; + logical_date: string; + start_date: string; + end_date: string; + state: 'queued' | 'running' | 'success' | 'failed'; + external_trigger: boolean; + conf: {}; +} + export interface TimeDelta { __type: 'TimeDelta'; days: number; diff --git a/plugins/apache-airflow/src/components/DagTableComponent/DagTableComponent.tsx b/plugins/apache-airflow/src/components/DagTableComponent/DagTableComponent.tsx index fcd87b2020..2660e9380e 100644 --- a/plugins/apache-airflow/src/components/DagTableComponent/DagTableComponent.tsx +++ b/plugins/apache-airflow/src/components/DagTableComponent/DagTableComponent.tsx @@ -22,7 +22,7 @@ import { TableColumn, WarningPanel, } from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; +import { storageApiRef, useApi } from '@backstage/core-plugin-api'; import Box from '@material-ui/core/Box'; import Chip from '@material-ui/core/Chip'; import IconButton from '@material-ui/core/IconButton'; @@ -31,101 +31,151 @@ import Tooltip from '@material-ui/core/Tooltip'; import Typography from '@material-ui/core/Typography'; import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser'; import Alert from '@material-ui/lab/Alert'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import useAsync from 'react-use/lib/useAsync'; import { apacheAirflowApiRef } from '../../api'; import { Dag } from '../../api/types'; import { ScheduleIntervalLabel } from '../ScheduleIntervalLabel'; +import { LatestDagRunsStatus } from '../LatestDagRunsStatus'; type DagTableRow = Dag & { id: string; dagUrl: string; }; -const columns: TableColumn[] = [ - { - title: 'Paused', - field: 'is_paused', - render: (row: Partial) => ( - - - - ), - width: '5%', - }, - { - title: 'DAG', - field: 'id', - render: (row: Partial) => ( -
- - {row.id} - - - {row.tags?.map((tag, ix) => ( - - ))} - -
- ), - width: '60%', - }, - { - title: 'Owner', - field: 'owners', - render: (row: Partial) => ( - - {row.owners?.map((owner, ix) => ( - - ))} - - ), - width: '10%', - }, - { - title: 'Active', - render: (row: Partial) => ( - - {row.is_active ? : } - - {row.is_active ? 'Active' : 'Inactive'} - - - ), - width: '10%', - }, - { - title: 'Schedule', - render: (row: Partial) => ( - - ), - width: '10%', - }, - { - title: 'Link', - field: 'dagUrl', - render: (row: Partial) => ( - - - - - - ), - width: '5%', - }, -]; - type DenseTableProps = { dags: Dag[]; + rowClick: Function; }; -export const DenseTable = ({ dags }: DenseTableProps) => { +export const DenseTable = ({ dags, rowClick }: DenseTableProps) => { + const storage = useApi(storageApiRef); + const hiddenColumnsKey = 'dag-table-hidden-columns'; + const [hiddenColumns, setHiddenColumns] = useState([]); + + useEffect(() => { + const hiddenState = storage.snapshot(hiddenColumnsKey); + if (hiddenState.presence === 'present') { + setHiddenColumns(hiddenState.value as string[]); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const columns: TableColumn[] = [ + { + title: 'Paused', + field: 'is_paused', + render: (row: Partial) => ( + + + + ), + width: '5%', + hidden: hiddenColumns.some(field => field === 'is_paused'), + }, + { + title: 'DAG', + field: 'id', + render: (row: Partial) => ( +
+ + {row.id} + + + {row.tags?.map((tag, ix) => ( + + ))} + +
+ ), + width: '50%', + disableClick: true, + hidden: hiddenColumns.some(field => field === 'id'), + }, + { + title: 'Runs', + field: 'runs', + render: (row: Partial) => ( + + ), + width: '10%', + disableClick: true, + hidden: hiddenColumns.some(field => field === 'runs'), + }, + { + title: 'Owner', + field: 'owners', + render: (row: Partial) => ( + + {row.owners?.map((owner, ix) => ( + + ))} + + ), + width: '10%', + disableClick: true, + hidden: hiddenColumns.some(field => field === 'owners'), + }, + { + title: 'Active', + field: 'active', + render: (row: Partial) => ( + + {row.is_active ? : } + + {row.is_active ? 'Active' : 'Inactive'} + + + ), + width: '10%', + disableClick: true, + hidden: hiddenColumns.some(field => field === 'active'), + }, + { + title: 'Schedule', + field: 'schedule', + render: (row: Partial) => ( + + ), + width: '10%', + disableClick: true, + hidden: hiddenColumns.some(field => field === 'schedule'), + }, + { + title: 'Link', + field: 'dagUrl', + render: (row: Partial) => ( + + + + + + ), + width: '5%', + disableClick: true, + hidden: hiddenColumns.some(field => field === 'dagUrl'), + }, + ]; + return ( rowClick(rowData)} + onChangeColumnHidden={(column, hidden) => { + if (column.field) { + let newHiddenColumns: string[]; + if (hidden) { + newHiddenColumns = hiddenColumns.concat(column.field); + } else { + newHiddenColumns = hiddenColumns.filter(v => v !== column.field); + } + setHiddenColumns(newHiddenColumns); + storage.set(hiddenColumnsKey, newHiddenColumns); + } + }} /> ); }; @@ -136,27 +186,54 @@ type DagTableComponentProps = { export const DagTableComponent = (props: DagTableComponentProps) => { const { dagIds } = props; + const [dagsData, setDagsData] = useState([]); const apiClient = useApi(apacheAirflowApiRef); - const { value, loading, error } = useAsync(async (): Promise => { + const updatePaused = async (rowData: Dag): Promise => { + const newDag = await apiClient.updateDag( + rowData.dag_id, + !rowData.is_paused, + ); + + const newDags = dagsData.map(el => { + if (el.dag_id === newDag.dag_id) { + return { ...el, is_paused: newDag.is_paused }; + } + return el; + }); + + setDagsData(newDags); + return newDag; + }; + + const { value, loading, error } = useAsync(async (): Promise< + DagTableRow[] + > => { + let dags: Dag[] = []; if (dagIds) { - const { dags } = await apiClient.getDags(dagIds); - return dags; + dags = (await apiClient.getDags(dagIds)).dags; + } else { + dags = await apiClient.listDags(); } - return await apiClient.listDags(); + return dags.map(el => ({ + ...el, + id: el.dag_id, // table records require `id` attribute + dagUrl: `${apiClient.baseUrl}dag_details?dag_id=${el.dag_id}`, // construct path to DAG using `baseUrl` + })); }, []); + useEffect(() => { + if (value) { + setDagsData(value); + } + }, [value]); + if (loading) { return ; } else if (error) { return {error.message}; } - const data = value?.map(el => ({ - ...el, - id: el.dag_id, // table records require `id` attribute - dagUrl: `${apiClient.baseUrl}dag_details?dag_id=${el.dag_id}`, // construct path to DAG using `baseUrl` - })); const dagsNotFound = dagIds && value ? dagIds.filter(id => !value.find(d => d.dag_id === id)) @@ -172,7 +249,7 @@ export const DagTableComponent = (props: DagTableComponentProps) => { ) : ( '' )} - + ); }; diff --git a/plugins/apache-airflow/src/components/LatestDagRunsStatus/LatestDagRunsStatus.test.tsx b/plugins/apache-airflow/src/components/LatestDagRunsStatus/LatestDagRunsStatus.test.tsx new file mode 100644 index 0000000000..fb020ee9e9 --- /dev/null +++ b/plugins/apache-airflow/src/components/LatestDagRunsStatus/LatestDagRunsStatus.test.tsx @@ -0,0 +1,67 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ApacheAirflowApi, apacheAirflowApiRef } from '../../api'; +import { DagRun } from '../../api/types/Dags'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import React from 'react'; +import { LatestDagRunsStatus } from './LatestDagRunsStatus'; + +describe('LatestDagRunsStatus', () => { + const baseDagRun: Partial = { + dag_run_id: 'mock dag run 1', + dag_id: 'mock_dag_1', + logical_date: '2022-05-27T11:25:23.251274+00:00', + start_date: '2022-05-27T11:25:23.251274+00:00', + end_date: '2022-05-27T11:25:23.251274+00:00', + state: 'success', + external_trigger: true, + conf: {}, + }; + const mockApi: jest.Mocked = { + getDagRuns: jest.fn().mockResolvedValue([ + baseDagRun, + { + ...baseDagRun, + dag_run_id: 'mock dag run 2', + state: 'running', + }, + { + ...baseDagRun, + dag_run_id: 'mock dag run 3', + state: 'failed', + }, + { + ...baseDagRun, + dag_run_id: 'mock dag run 3', + state: 'queued', + }, + ] as DagRun[]), + } as any; + + it('should render the status of mock dag 1', async () => { + const dagId = 'mock_dag_1'; + + const { getByLabelText } = await renderInTestApp( + + + , + ); + expect(getByLabelText('Status ok')).toBeInTheDocument(); + expect(getByLabelText('Status running')).toBeInTheDocument(); + expect(getByLabelText('Status error')).toBeInTheDocument(); + expect(getByLabelText('Status pending')).toBeInTheDocument(); + }); +}); diff --git a/plugins/apache-airflow/src/components/LatestDagRunsStatus/LatestDagRunsStatus.tsx b/plugins/apache-airflow/src/components/LatestDagRunsStatus/LatestDagRunsStatus.tsx new file mode 100644 index 0000000000..90cb0694f8 --- /dev/null +++ b/plugins/apache-airflow/src/components/LatestDagRunsStatus/LatestDagRunsStatus.tsx @@ -0,0 +1,161 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { apacheAirflowApiRef } from '../../api'; +import useAsync from 'react-use/lib/useAsync'; +import { DagRun } from '../../api/types/Dags'; +import { useApi } from '@backstage/core-plugin-api'; +import { + Box, + Button, + CircularProgress, + List, + ListItem, + ListItemIcon, + makeStyles, + Tooltip, + Typography, +} from '@material-ui/core'; +import { + Link, + StatusError, + StatusOK, + StatusPending, + StatusRunning, +} from '@backstage/core-components'; +import DirectionsRun from '@material-ui/icons/DirectionsRun'; +import Check from '@material-ui/icons/Check'; +import CalendarToday from '@material-ui/icons/CalendarToday'; +import qs from 'qs'; +import AccountTree from '@material-ui/icons/AccountTree'; + +interface LatestDagRunsStatusProps { + dagId: string; + limit?: number; +} + +const useStyles = makeStyles(() => ({ + noMaxWidth: { + maxWidth: 'none', + }, +})); + +const DagRunTooltip = ({ + dagRun, + graphUrl, +}: { + dagRun: DagRun; + graphUrl: string; +}) => { + return ( + + + + + + {dagRun.dag_run_id} + + + + + + {new Date(dagRun.start_date).toLocaleString()} + + + + + + + {dagRun.end_date ? new Date(dagRun.end_date).toLocaleString() : '-'} + + + + + + + ); +}; + +export const LatestDagRunsStatus = ({ + dagId, + limit = 5, +}: LatestDagRunsStatusProps) => { + const classes = useStyles(); + const apiClient = useApi(apacheAirflowApiRef); + const { value, loading, error } = useAsync( + async (): Promise => await apiClient.getDagRuns(dagId, { limit }), + [dagId, limit], + ); + + if (loading) { + return ( + + + + ); + } + + if (error) { + return Can't get dag runs; + } + + const statusDots: JSX.Element[] | undefined = value?.map(dagRun => { + function status() { + switch (dagRun.state) { + case 'success': + return ; + case 'failed': + return ; + case 'running': + return ; + case 'queued': + return ; + default: + return Unrecognized state; + } + } + + const key = dagRun.dag_id + dagRun.dag_run_id; + const dagRunParams = { + dag_id: dagRun.dag_id, + execution_date: dagRun.logical_date, + }; + const graphUrl = `${apiClient.baseUrl}graph?${qs.stringify(dagRunParams)}`; + return ( + } + key={key} + classes={{ tooltip: classes.noMaxWidth }} + interactive + > + + {status()} + + + ); + }); + + return {statusDots}; +}; diff --git a/plugins/apache-airflow/src/components/LatestDagRunsStatus/index.ts b/plugins/apache-airflow/src/components/LatestDagRunsStatus/index.ts new file mode 100644 index 0000000000..acd84a3584 --- /dev/null +++ b/plugins/apache-airflow/src/components/LatestDagRunsStatus/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 { LatestDagRunsStatus } from './LatestDagRunsStatus'; From 989731cabf4b201aefd433b5f1696d69d9c09d33 Mon Sep 17 00:00:00 2001 From: Loybin Date: Tue, 8 Nov 2022 13:00:15 +0400 Subject: [PATCH 216/434] add changeset info Signed-off-by: Loybin --- .changeset/brave-bugs-teach.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/brave-bugs-teach.md diff --git a/.changeset/brave-bugs-teach.md b/.changeset/brave-bugs-teach.md new file mode 100644 index 0000000000..2869796c2a --- /dev/null +++ b/.changeset/brave-bugs-teach.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-apache-airflow': patch +--- + +1. Added a new column in the table to quickly view the latest DAG runs, plus a link to it if you want to have a deeper look. +2. Table columns are togglable +3. Set hidden columns +4. Fixed bug with turning on/off the DAGs From 23484ac4426e3fd46e17e373a09dd0e15991448f Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Mon, 7 Nov 2022 18:30:52 +0000 Subject: [PATCH 217/434] cli: allow passing --config option to repo build command Signed-off-by: MT Lewis --- .changeset/large-flies-check.md | 5 +++++ packages/cli/cli-report.md | 1 + packages/cli/src/commands/index.ts | 1 + packages/cli/src/commands/repo/build.ts | 7 ++++++- 4 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 .changeset/large-flies-check.md diff --git a/.changeset/large-flies-check.md b/.changeset/large-flies-check.md new file mode 100644 index 0000000000..4abeedb97c --- /dev/null +++ b/.changeset/large-flies-check.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Allow passing `--config` option to `repo build` command diff --git a/packages/cli/cli-report.md b/packages/cli/cli-report.md index 9afd12fb48..220980cd06 100644 --- a/packages/cli/cli-report.md +++ b/packages/cli/cli-report.md @@ -400,6 +400,7 @@ Commands: Usage: backstage-cli repo build [options] Options: + --config --all --since -h, --help diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 266b4fd9f1..7456394bcb 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -35,6 +35,7 @@ export function registerRepoCommand(program: Command) { .description( 'Build packages in the project, excluding bundled app and backend packages.', ) + .option(...configOption) .option( '--all', 'Build all packages, including bundled app and backend packages.', diff --git a/packages/cli/src/commands/repo/build.ts b/packages/cli/src/commands/repo/build.ts index 21b1580cb9..0cef474ee6 100644 --- a/packages/cli/src/commands/repo/build.ts +++ b/packages/cli/src/commands/repo/build.ts @@ -152,9 +152,14 @@ export async function command(opts: OptionValues, cmd: Command): Promise { ); return; } + + const configPaths = opts.config?.length + ? opts.config + : buildOptions.config ?? []; + await buildFrontend({ targetDir: pkg.dir, - configPaths: (buildOptions.config as string[]) ?? [], + configPaths, writeStats: Boolean(buildOptions.stats), }); }, From cee9c22da85e9ab9fd57ca1982b8afb9da1086a2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 8 Nov 2022 11:47:40 +0100 Subject: [PATCH 218/434] scripts/prepare-release: update to handle workspace ranges Signed-off-by: Patrik Oldsberg --- scripts/prepare-release.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/prepare-release.js b/scripts/prepare-release.js index 962d54abb0..973f4fad58 100755 --- a/scripts/prepare-release.js +++ b/scripts/prepare-release.js @@ -209,7 +209,11 @@ async function applyPatchVersions(repo, patchVersions) { const deps = packageJson[depType]; for (const depName of Object.keys(deps ?? {})) { const currentRange = deps[depName]; - if (currentRange === '*' || currentRange === '') { + if ( + currentRange === '*' || + currentRange === '' || + currentRange.startsWith('workspace:') + ) { continue; } From 3c1ce2f1b99daeee2bd2a1e258973e1cc5fd14bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Nov 2022 11:50:25 +0000 Subject: [PATCH 219/434] Update dependency @graphql-tools/schema to v9.0.9 Signed-off-by: Renovate Bot --- yarn.lock | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1085b6483c..33273c8b9d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9281,15 +9281,15 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/merge@npm:8.3.10": - version: 8.3.10 - resolution: "@graphql-tools/merge@npm:8.3.10" +"@graphql-tools/merge@npm:8.3.11": + version: 8.3.11 + resolution: "@graphql-tools/merge@npm:8.3.11" dependencies: - "@graphql-tools/utils": 9.0.1 + "@graphql-tools/utils": 9.1.0 tslib: ^2.4.0 peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: dbe2c6faee8034339c5708a43157b185b8523c131dde1b37bb511d96ac527da51f5be9501d9ffe0a8c424e419d64bb8415ec96e8443d3d0a5a6582a37b0aafa2 + checksum: 3cd16577f1ea1bcc389d232fa620adc0fefc91a6b42b48e7bb5e7bb67b67d206d409a9a8d60cac4d8cd5f0f1c5353369f7c5eb4054b44ce2277545e1fd1de17f languageName: node linkType: hard @@ -9429,16 +9429,16 @@ __metadata: linkType: hard "@graphql-tools/schema@npm:^9.0.0": - version: 9.0.8 - resolution: "@graphql-tools/schema@npm:9.0.8" + version: 9.0.9 + resolution: "@graphql-tools/schema@npm:9.0.9" dependencies: - "@graphql-tools/merge": 8.3.10 - "@graphql-tools/utils": 9.0.1 + "@graphql-tools/merge": 8.3.11 + "@graphql-tools/utils": 9.1.0 tslib: ^2.4.0 value-or-promise: 1.0.11 peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: fb29c29269622f2636ecccac868fa44a585622e16be74286a4cd97b259ba2d2dad5ec67e77b00117f70e500a9262e0edc58a35a83cea0618618993e5e1d809fb + checksum: 23620a993eff57723302315100d947b81664d6a1e00010ff293b3649f51ab423946d73920cce0ce822b7f7f42b99ea23240902ff47df3d252639613c0df7b971 languageName: node linkType: hard @@ -9547,14 +9547,14 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/utils@npm:9.0.1": - version: 9.0.1 - resolution: "@graphql-tools/utils@npm:9.0.1" +"@graphql-tools/utils@npm:9.1.0": + version: 9.1.0 + resolution: "@graphql-tools/utils@npm:9.1.0" dependencies: tslib: ^2.4.0 peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: a41221d8568bfaafa76526eaa89550d67965c43e0cd1ff94979f61c117d0caf880938799b351c4b637ce26309ba5d2ef8c4a657298f5d46702f43759b89bfa05 + checksum: dcf08df3bd1715e25e3b80bf2dd332376239ebcd2a9b93f4d6b72a7bd3feffe2207b9683bb8fcaed9d0d1286f701d0686fe99ac803b91c0df54509b869c0554d languageName: node linkType: hard From 45f87a94c4d2fe5099bd35cbe776bc77e12b73be Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Nov 2022 12:53:33 +0000 Subject: [PATCH 220/434] Update dependency @types/inquirer to v8.2.5 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index f1309e3230..197992ebf3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14017,11 +14017,11 @@ __metadata: linkType: hard "@types/inquirer@npm:^8.1.3": - version: 8.2.4 - resolution: "@types/inquirer@npm:8.2.4" + version: 8.2.5 + resolution: "@types/inquirer@npm:8.2.5" dependencies: "@types/through": "*" - checksum: 3a46231faac1e5df4863a2d501617b3f25e9481ea8a966a9b866bafef01fcc151606d9f25cb66f90492dd0d1d7af7c675a2314f50db85a7f2aeed265d93eb412 + checksum: 932c432e634697bcff5d50fdc9e64f90d2e31c5ebcda909f2e9704d0433b5ec608b6ece985c6e57a283f3b62434f1cd3619b64ca61433d7c3bdb41d3c5f27586 languageName: node linkType: hard From 28d4f4f117efaf33d7a92898a7d38536dc99a711 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 8 Nov 2022 14:17:15 +0100 Subject: [PATCH 221/434] Revert "cli: allow passing --config option to repo build command" Signed-off-by: Patrik Oldsberg --- .changeset/large-flies-check.md | 5 ----- packages/cli/cli-report.md | 1 - packages/cli/src/commands/index.ts | 1 - packages/cli/src/commands/repo/build.ts | 7 +------ 4 files changed, 1 insertion(+), 13 deletions(-) delete mode 100644 .changeset/large-flies-check.md diff --git a/.changeset/large-flies-check.md b/.changeset/large-flies-check.md deleted file mode 100644 index 4abeedb97c..0000000000 --- a/.changeset/large-flies-check.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Allow passing `--config` option to `repo build` command diff --git a/packages/cli/cli-report.md b/packages/cli/cli-report.md index 220980cd06..9afd12fb48 100644 --- a/packages/cli/cli-report.md +++ b/packages/cli/cli-report.md @@ -400,7 +400,6 @@ Commands: Usage: backstage-cli repo build [options] Options: - --config --all --since -h, --help diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 7456394bcb..266b4fd9f1 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -35,7 +35,6 @@ export function registerRepoCommand(program: Command) { .description( 'Build packages in the project, excluding bundled app and backend packages.', ) - .option(...configOption) .option( '--all', 'Build all packages, including bundled app and backend packages.', diff --git a/packages/cli/src/commands/repo/build.ts b/packages/cli/src/commands/repo/build.ts index 0cef474ee6..21b1580cb9 100644 --- a/packages/cli/src/commands/repo/build.ts +++ b/packages/cli/src/commands/repo/build.ts @@ -152,14 +152,9 @@ export async function command(opts: OptionValues, cmd: Command): Promise { ); return; } - - const configPaths = opts.config?.length - ? opts.config - : buildOptions.config ?? []; - await buildFrontend({ targetDir: pkg.dir, - configPaths, + configPaths: (buildOptions.config as string[]) ?? [], writeStats: Boolean(buildOptions.stats), }); }, From 1a7568a0c47072992dba48e555c1904c786e84ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Nov 2022 13:58:37 +0000 Subject: [PATCH 222/434] build(deps): bump loader-utils from 1.4.0 to 1.4.1 in /storybook Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.0 to 1.4.1. - [Release notes](https://github.com/webpack/loader-utils/releases) - [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.1/CHANGELOG.md) - [Commits](https://github.com/webpack/loader-utils/compare/v1.4.0...v1.4.1) --- updated-dependencies: - dependency-name: loader-utils dependency-type: indirect ... Signed-off-by: dependabot[bot] --- storybook/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/storybook/yarn.lock b/storybook/yarn.lock index c864d817ab..80e863e803 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -7875,13 +7875,13 @@ __metadata: linkType: hard "loader-utils@npm:^1.1.0, loader-utils@npm:^1.2.3": - version: 1.4.0 - resolution: "loader-utils@npm:1.4.0" + version: 1.4.1 + resolution: "loader-utils@npm:1.4.1" dependencies: big.js: ^5.2.2 emojis-list: ^3.0.0 json5: ^1.0.1 - checksum: d150b15e7a42ac47d935c8b484b79e44ff6ab4c75df7cc4cb9093350cf014ec0b17bdb60c5d6f91a37b8b218bd63b973e263c65944f58ca2573e402b9a27e717 + checksum: ea0b648cba0194e04a90aab6270619f0e35be009e33a443d9e642e93056cd49e6ca4c9678bd1c777a2392551bc5f4d0f24a87f5040608da1274aa84c6eebb502 languageName: node linkType: hard From b01fea7b8cb440c438f3e186534dba0272a25080 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 8 Nov 2022 14:04:37 +0000 Subject: [PATCH 223/434] Version Packages (next) --- .changeset/pre.json | 29 +- docs/releases/v1.8.0-next.2-changelog.md | 1903 +++++++++++++++++ package.json | 2 +- packages/app-defaults/CHANGELOG.md | 11 + packages/app-defaults/package.json | 2 +- packages/app/CHANGELOG.md | 63 + packages/app/package.json | 2 +- packages/backend-app-api/CHANGELOG.md | 11 + packages/backend-app-api/package.json | 2 +- packages/backend-common/CHANGELOG.md | 14 + packages/backend-common/package.json | 2 +- packages/backend-defaults/CHANGELOG.md | 8 + packages/backend-defaults/package.json | 2 +- packages/backend-next/CHANGELOG.md | 10 + packages/backend-next/package.json | 2 +- packages/backend-plugin-api/CHANGELOG.md | 10 + packages/backend-plugin-api/package.json | 2 +- packages/backend-tasks/CHANGELOG.md | 10 + packages/backend-tasks/package.json | 2 +- packages/backend-test-utils/CHANGELOG.md | 11 + packages/backend-test-utils/package.json | 2 +- packages/backend/CHANGELOG.md | 43 + packages/backend/package.json | 2 +- packages/cli/CHANGELOG.md | 18 + packages/cli/package.json | 2 +- packages/codemods/CHANGELOG.md | 8 + packages/codemods/package.json | 2 +- packages/core-components/CHANGELOG.md | 12 + packages/core-components/package.json | 2 +- packages/create-app/CHANGELOG.md | 51 + packages/create-app/package.json | 2 +- packages/dev-utils/CHANGELOG.md | 15 + packages/dev-utils/package.json | 2 +- packages/integration-react/CHANGELOG.md | 11 + packages/integration-react/package.json | 2 +- packages/release-manifests/CHANGELOG.md | 6 + packages/release-manifests/package.json | 2 +- .../techdocs-cli-embedded-app/CHANGELOG.md | 19 + .../techdocs-cli-embedded-app/package.json | 2 +- packages/techdocs-cli/CHANGELOG.md | 11 + packages/techdocs-cli/package.json | 2 +- plugins/adr-backend/CHANGELOG.md | 14 + plugins/adr-backend/package.json | 2 +- plugins/adr/CHANGELOG.md | 15 + plugins/adr/package.json | 2 +- plugins/airbrake-backend/CHANGELOG.md | 8 + plugins/airbrake-backend/package.json | 2 +- plugins/airbrake/CHANGELOG.md | 13 + plugins/airbrake/package.json | 2 +- plugins/allure/CHANGELOG.md | 11 + plugins/allure/package.json | 2 +- plugins/analytics-module-ga/CHANGELOG.md | 10 + plugins/analytics-module-ga/package.json | 2 +- plugins/apache-airflow/CHANGELOG.md | 8 + plugins/apache-airflow/package.json | 2 +- plugins/api-docs/CHANGELOG.md | 12 + plugins/api-docs/package.json | 2 +- plugins/apollo-explorer/CHANGELOG.md | 9 + plugins/apollo-explorer/package.json | 2 +- plugins/app-backend/CHANGELOG.md | 11 + plugins/app-backend/package.json | 2 +- plugins/auth-backend/CHANGELOG.md | 15 + plugins/auth-backend/package.json | 2 +- plugins/auth-node/CHANGELOG.md | 9 + plugins/auth-node/package.json | 2 +- plugins/azure-devops-backend/CHANGELOG.md | 9 + plugins/azure-devops-backend/package.json | 2 +- plugins/azure-devops/CHANGELOG.md | 13 + plugins/azure-devops/package.json | 2 +- plugins/azure-sites-backend/CHANGELOG.md | 9 + plugins/azure-sites-backend/package.json | 2 +- plugins/azure-sites/CHANGELOG.md | 12 + plugins/azure-sites/package.json | 2 +- plugins/badges-backend/CHANGELOG.md | 11 + plugins/badges-backend/package.json | 2 +- plugins/badges/CHANGELOG.md | 12 + plugins/badges/package.json | 2 +- plugins/bazaar-backend/CHANGELOG.md | 11 + plugins/bazaar-backend/package.json | 2 +- plugins/bazaar/CHANGELOG.md | 14 + plugins/bazaar/package.json | 2 +- plugins/bitrise/CHANGELOG.md | 11 + plugins/bitrise/package.json | 2 +- .../catalog-backend-module-aws/CHANGELOG.md | 16 + .../catalog-backend-module-aws/package.json | 2 +- .../catalog-backend-module-azure/CHANGELOG.md | 16 + .../catalog-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 17 + .../package.json | 2 +- .../CHANGELOG.md | 16 + .../package.json | 2 +- .../catalog-backend-module-ldap/CHANGELOG.md | 12 + .../catalog-backend-module-ldap/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- plugins/catalog-backend/CHANGELOG.md | 20 + plugins/catalog-backend/package.json | 2 +- plugins/catalog-customized/CHANGELOG.md | 8 + plugins/catalog-customized/package.json | 2 +- plugins/catalog-graph/CHANGELOG.md | 21 + plugins/catalog-graph/package.json | 2 +- plugins/catalog-import/CHANGELOG.md | 16 + plugins/catalog-import/package.json | 2 +- plugins/catalog-node/CHANGELOG.md | 12 + plugins/catalog-node/package.json | 2 +- plugins/catalog-react/CHANGELOG.md | 18 + plugins/catalog-react/package.json | 2 +- plugins/catalog/CHANGELOG.md | 18 + plugins/catalog/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/cicd-statistics/CHANGELOG.md | 9 + plugins/cicd-statistics/package.json | 2 +- plugins/circleci/CHANGELOG.md | 11 + plugins/circleci/package.json | 2 +- plugins/cloudbuild/CHANGELOG.md | 11 + plugins/cloudbuild/package.json | 2 +- plugins/code-climate/CHANGELOG.md | 11 + plugins/code-climate/package.json | 2 +- plugins/code-coverage-backend/CHANGELOG.md | 13 + plugins/code-coverage-backend/package.json | 2 +- plugins/code-coverage/CHANGELOG.md | 14 + plugins/code-coverage/package.json | 2 +- plugins/codescene/CHANGELOG.md | 11 + plugins/codescene/package.json | 2 +- plugins/config-schema/CHANGELOG.md | 12 + plugins/config-schema/package.json | 2 +- plugins/cost-insights/CHANGELOG.md | 13 + plugins/cost-insights/package.json | 2 +- plugins/dynatrace/CHANGELOG.md | 11 + plugins/dynatrace/package.json | 2 +- .../example-todo-list-backend/CHANGELOG.md | 10 + .../example-todo-list-backend/package.json | 2 +- plugins/example-todo-list/CHANGELOG.md | 9 + plugins/example-todo-list/package.json | 2 +- plugins/explore/CHANGELOG.md | 13 + plugins/explore/package.json | 2 +- plugins/firehydrant/CHANGELOG.md | 10 + plugins/firehydrant/package.json | 2 +- plugins/fossa/CHANGELOG.md | 12 + plugins/fossa/package.json | 2 +- plugins/gcalendar/CHANGELOG.md | 10 + plugins/gcalendar/package.json | 2 +- plugins/gcp-projects/CHANGELOG.md | 9 + plugins/gcp-projects/package.json | 2 +- plugins/git-release-manager/CHANGELOG.md | 10 + plugins/git-release-manager/package.json | 2 +- plugins/github-actions/CHANGELOG.md | 14 + plugins/github-actions/package.json | 2 +- plugins/github-deployments/CHANGELOG.md | 14 + plugins/github-deployments/package.json | 2 +- plugins/github-issues/CHANGELOG.md | 13 + plugins/github-issues/package.json | 2 +- .../github-pull-requests-board/CHANGELOG.md | 12 + .../github-pull-requests-board/package.json | 2 +- plugins/gitops-profiles/CHANGELOG.md | 9 + plugins/gitops-profiles/package.json | 2 +- plugins/gocd/CHANGELOG.md | 12 + plugins/gocd/package.json | 2 +- plugins/graphiql/CHANGELOG.md | 9 + plugins/graphiql/package.json | 2 +- plugins/graphql-backend/CHANGELOG.md | 9 + plugins/graphql-backend/package.json | 2 +- plugins/home/CHANGELOG.md | 13 + plugins/home/package.json | 2 +- plugins/ilert/CHANGELOG.md | 12 + plugins/ilert/package.json | 2 +- plugins/jenkins-backend/CHANGELOG.md | 14 + plugins/jenkins-backend/package.json | 2 +- plugins/jenkins/CHANGELOG.md | 13 + plugins/jenkins/package.json | 2 +- plugins/kafka-backend/CHANGELOG.md | 10 + plugins/kafka-backend/package.json | 2 +- plugins/kafka/CHANGELOG.md | 12 + plugins/kafka/package.json | 2 +- plugins/kubernetes-backend/CHANGELOG.md | 14 + plugins/kubernetes-backend/package.json | 2 +- plugins/kubernetes-common/CHANGELOG.md | 8 + plugins/kubernetes-common/package.json | 2 +- plugins/kubernetes/CHANGELOG.md | 14 + plugins/kubernetes/package.json | 2 +- plugins/lighthouse/CHANGELOG.md | 12 + plugins/lighthouse/package.json | 2 +- plugins/newrelic-dashboard/CHANGELOG.md | 11 + plugins/newrelic-dashboard/package.json | 2 +- plugins/newrelic/CHANGELOG.md | 9 + plugins/newrelic/package.json | 2 +- plugins/org-react/CHANGELOG.md | 17 + plugins/org-react/package.json | 2 +- plugins/org/CHANGELOG.md | 15 + plugins/org/package.json | 2 +- plugins/pagerduty/CHANGELOG.md | 12 + plugins/pagerduty/package.json | 2 +- plugins/periskop-backend/CHANGELOG.md | 8 + plugins/periskop-backend/package.json | 2 +- plugins/periskop/CHANGELOG.md | 12 + plugins/periskop/package.json | 2 +- plugins/permission-backend/CHANGELOG.md | 12 + plugins/permission-backend/package.json | 2 +- plugins/permission-node/CHANGELOG.md | 11 + plugins/permission-node/package.json | 2 +- plugins/playlist-backend/CHANGELOG.md | 16 + plugins/playlist-backend/package.json | 2 +- plugins/playlist/CHANGELOG.md | 17 + plugins/playlist/package.json | 2 +- plugins/proxy-backend/CHANGELOG.md | 8 + plugins/proxy-backend/package.json | 2 +- plugins/rollbar-backend/CHANGELOG.md | 8 + plugins/rollbar-backend/package.json | 2 +- plugins/rollbar/CHANGELOG.md | 11 + plugins/rollbar/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/scaffolder-backend/CHANGELOG.md | 25 + plugins/scaffolder-backend/package.json | 2 +- plugins/scaffolder/CHANGELOG.md | 22 + plugins/scaffolder/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/search-backend-module-pg/CHANGELOG.md | 10 + plugins/search-backend-module-pg/package.json | 2 +- plugins/search-backend-node/CHANGELOG.md | 12 + plugins/search-backend-node/package.json | 2 +- plugins/search-backend/CHANGELOG.md | 15 + plugins/search-backend/package.json | 2 +- plugins/search-react/CHANGELOG.md | 12 + plugins/search-react/package.json | 2 +- plugins/search/CHANGELOG.md | 17 + plugins/search/package.json | 2 +- plugins/sentry/CHANGELOG.md | 11 + plugins/sentry/package.json | 2 +- plugins/shortcuts/CHANGELOG.md | 10 + plugins/shortcuts/package.json | 2 +- plugins/sonarqube-backend/CHANGELOG.md | 9 + plugins/sonarqube-backend/package.json | 2 +- plugins/sonarqube/CHANGELOG.md | 11 + plugins/sonarqube/package.json | 2 +- plugins/splunk-on-call/CHANGELOG.md | 19 + plugins/splunk-on-call/package.json | 2 +- plugins/stack-overflow-backend/CHANGELOG.md | 9 + plugins/stack-overflow-backend/package.json | 2 +- plugins/stack-overflow/CHANGELOG.md | 12 + plugins/stack-overflow/package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- plugins/tech-insights-backend/CHANGELOG.md | 16 + plugins/tech-insights-backend/package.json | 2 +- plugins/tech-insights-node/CHANGELOG.md | 11 + plugins/tech-insights-node/package.json | 2 +- plugins/tech-insights/CHANGELOG.md | 14 + plugins/tech-insights/package.json | 2 +- plugins/tech-radar/CHANGELOG.md | 9 + plugins/tech-radar/package.json | 2 +- .../techdocs-addons-test-utils/CHANGELOG.md | 16 + .../techdocs-addons-test-utils/package.json | 2 +- plugins/techdocs-backend/CHANGELOG.md | 16 + plugins/techdocs-backend/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- plugins/techdocs-node/CHANGELOG.md | 12 + plugins/techdocs-node/package.json | 2 +- plugins/techdocs-react/CHANGELOG.md | 11 + plugins/techdocs-react/package.json | 2 +- plugins/techdocs/CHANGELOG.md | 19 + plugins/techdocs/package.json | 2 +- plugins/todo-backend/CHANGELOG.md | 12 + plugins/todo-backend/package.json | 2 +- plugins/todo/CHANGELOG.md | 12 + plugins/todo/package.json | 2 +- plugins/user-settings-backend/CHANGELOG.md | 11 + plugins/user-settings-backend/package.json | 2 +- plugins/user-settings/CHANGELOG.md | 12 + plugins/user-settings/package.json | 2 +- plugins/vault-backend/CHANGELOG.md | 11 + plugins/vault-backend/package.json | 2 +- plugins/vault/CHANGELOG.md | 12 + plugins/vault/package.json | 2 +- plugins/xcmetrics/CHANGELOG.md | 10 + plugins/xcmetrics/package.json | 2 +- 293 files changed, 3979 insertions(+), 148 deletions(-) create mode 100644 docs/releases/v1.8.0-next.2-changelog.md create mode 100644 plugins/org-react/CHANGELOG.md diff --git a/.changeset/pre.json b/.changeset/pre.json index 9aa5bbdfdf..75e70fc165 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -176,23 +176,31 @@ "@backstage/plugin-xcmetrics": "0.2.30", "@backstage/plugin-azure-sites": "0.0.0", "@backstage/plugin-azure-sites-backend": "0.0.0", - "@backstage/plugin-azure-sites-common": "0.0.0" + "@backstage/plugin-azure-sites-common": "0.0.0", + "@backstage/plugin-org-react": "0.0.0" }, "changesets": [ + "analyze-next-software-creation", "analyze-software-creation", "analyze-software-exploration", "beige-gorillas-sip", "big-islands-add", + "blue-items-shop", "brave-eels-allow", + "bright-pillows-build", "brown-days-pretend", "calm-bottles-happen", + "calm-clouds-smoke", "chatty-planets-flash", "clean-feet-remain", "clean-planets-rhyme", + "cool-suns-add", "create-app-1667233110", "dirty-birds-burn", + "dry-phones-type", "dull-oranges-tap", "eight-pears-attack", + "eighty-planets-train", "eleven-pets-sneeze", "few-books-remember", "flat-items-perform", @@ -201,29 +209,39 @@ "forty-jokes-lie", "fresh-cooks-sing", "fresh-weeks-share", + "funny-singers-serve", "gorgeous-balloons-sit", "gorgeous-onions-thank", "gorgeous-queens-pull", "great-colts-invite", + "great-planes-arrive", "grumpy-clouds-drum", "grumpy-pigs-reflect", "happy-avocados-tan", "heavy-elephants-nail", + "hungry-kiwis-scream", "itchy-paws-protect", "kind-emus-juggle", + "large-spies-doubt", "lazy-planes-repair", "little-bikes-eat", + "little-plums-look", "lucky-cats-peel", "lucky-cobras-sell", "lucky-spoons-hide", "mean-files-fly", "metal-dogs-swim", "metal-hairs-mix", + "moody-pots-end", "nasty-crabs-share", "orange-trees-peel", + "pink-snails-hammer", + "popular-ants-mix", "popular-bulldogs-lie", "popular-mails-wave", "real-swans-repair", + "renovate-25512c2", + "renovate-3d08223", "renovate-6fb5f1b", "selfish-kiwis-matter", "shaggy-birds-happen", @@ -231,22 +249,29 @@ "sharp-goats-itch", "shiny-beers-relax", "short-balloons-work", + "silent-moles-chew", + "silly-meals-teach", "sixty-islands-develop", "sixty-pigs-shave", "sixty-singers-push", "spicy-parents-lick", "spotty-dryers-explain", + "stale-dots-love", "stupid-pens-occur", "sweet-readers-compare", "tame-ads-appear", "tasty-colts-hug", "tasty-scissors-tickle", + "ten-hats-tickle", "ten-pens-draw", + "thirty-deers-float", "three-houses-agree", "three-poems-think", "two-oranges-joke", + "two-timers-pump", "two-yaks-wave", "unlucky-buttons-poke", - "wet-cameras-call" + "wet-cameras-call", + "witty-carrots-live" ] } diff --git a/docs/releases/v1.8.0-next.2-changelog.md b/docs/releases/v1.8.0-next.2-changelog.md new file mode 100644 index 0000000000..d6c55998f6 --- /dev/null +++ b/docs/releases/v1.8.0-next.2-changelog.md @@ -0,0 +1,1903 @@ +# Release v1.8.0-next.2 + +## @backstage/cli@0.21.0-next.1 + +### Minor Changes + +- 384eaa2307: Switched `tsconfig.json` to target and support `ES2021`, in line with the bump to Node.js 16 & 18. + +### Patch Changes + +- 88f99b8b13: Bumped `tar` dependency to `^6.1.12` in order to ensure Node.js v18 compatibility. +- 969a8444ea: Updated dependency `esbuild` to `^0.15.0`. +- Updated dependencies + - @backstage/release-manifests@0.0.7-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4-next.0 + - @backstage/config-loader@1.1.6-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-org@0.6.0-next.1 + +### Minor Changes + +- 0b11500151: Updates the User and Group Profile cards to add the links from the UserEntity or the GroupEntity + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-org-react@0.1.0-next.0 + +### Minor Changes + +- e96274f1fe: Implemented the org-react plugin, with it's first component being: a `GroupListPicker` component that will give the user the ability to choose a group + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-scaffolder-backend@1.8.0-next.2 + +### Minor Changes + +- 5025d2e8b6: Adds the ability to pass (an optional) array of strings that will be applied to the newly scaffolded repository as topic labels. + +### Patch Changes + +- 969a8444ea: Updated dependency `esbuild` to `^0.15.0`. +- 9ff4ff3745: Implement "Branch protection rules" support for "publish:github" action +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-scaffolder-common@1.2.2-next.0 + +## @backstage/plugin-splunk-on-call@0.4.0-next.1 + +### Minor Changes + +- 34b772ef31: Use the routing key if it's available instead of team name when triggering incidents. + + BREAKING CHANGE: + Before, the team name was used even if the routing key (with or without team) was used. + Now, the routing key defined for the component will be used instead of the team name. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/app-defaults@1.0.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-app-api@1.2.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-permission-react@0.4.7-next.0 + +## @backstage/backend-app-api@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-permission-node@0.7.1-next.1 + - @backstage/errors@1.1.3-next.0 + +## @backstage/backend-common@0.16.0-next.1 + +### Patch Changes + +- 88f99b8b13: Bumped `tar` dependency to `^6.1.12` in order to ensure Node.js v18 compatibility. +- cfb30b700c: Pin `@kubernetes/client-node` version to `0.17.0`. +- Updated dependencies + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4-next.0 + - @backstage/config-loader@1.1.6-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/backend-defaults@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@0.2.3-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + +## @backstage/backend-plugin-api@0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + +## @backstage/backend-tasks@0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/backend-test-utils@0.1.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/cli@0.21.0-next.1 + - @backstage/backend-app-api@0.2.3-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/config@1.0.4-next.0 + +## @backstage/codemods@0.1.41-next.0 + +### Patch Changes + +- 58502ec285: Updated dependency `jscodeshift` to `^0.14.0`. +- Updated dependencies + - @backstage/cli-common@0.1.10 + +## @backstage/core-components@0.12.0-next.1 + +### Patch Changes + +- b4fb5c8ecc: MissingAnnotationEmptyState now accepts either a string or an array of strings to support multiple missing annotations. +- Updated dependencies + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/version-bridge@1.0.1 + +## @backstage/create-app@0.4.34-next.2 + +### Patch Changes + +- 384eaa2307: Switched Node.js version to support version 16 & 18, rather than 14 & 16. To switch the Node.js version in your own project, apply the following change to the root `package.json`: + + ```diff + "engines": { + - "node": "14 || 16" + + "node": "16 || 18" + }, + ``` + + As well as the following change to `packages/app/package.json`: + + ```diff + - "@types/node": "^14.14.32", + + "@types/node": "^16.11.26", + ``` + +- 864c876e57: Fixed incorrect comments in the templated `app-config.yaml` and `app-config.production.yaml`. The `backend.listen` directive is not in fact needed to override the `backend.baseUrl`, the backend listens to all interfaces by default. The configuration has also been updated to listen to all interfaces, rather than just IPv4 ones, as this is required for Node.js v18. The production configuration now also shows the option to specify `backend.listen` as a single string. + + To apply this changes to an existing app, make the following change to `app-config.yaml`: + + ```diff + - # Uncomment the following host directive to bind to all IPv4 interfaces and + - # not just the baseUrl hostname. + - # host: 0.0.0.0 + + # Uncomment the following host directive to bind to specific interfaces + + # host: 127.0.0.1 + ``` + + And the following change to `app-config.production.yaml`: + + ```diff + - listen: + - port: 7007 + - # The following host directive binds to all IPv4 interfaces when its value + - # is "0.0.0.0". This is the most permissive setting. The right value depends + - # on your specific deployment. If you remove the host line entirely, the + - # backend will bind on the interface that corresponds to the backend.baseUrl + - # hostname. + - host: 0.0.0.0 + + # The listener can also be expressed as a single : string. In this case we bind to + + # all interfaces, the most permissive setting. The right value depends on your specific deployment. + + listen: ':7007' + ``` + +- Updated dependencies + - @backstage/cli-common@0.1.10 + +## @backstage/dev-utils@1.0.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/app-defaults@1.0.8-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-app-api@1.2.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/test-utils@1.2.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/integration-react@1.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/theme@0.2.16 + +## @backstage/release-manifests@0.0.7-next.0 + +### Patch Changes + +- a4496131fa: Added a fallback that fetches manifests from `https://raw.githubusercontent.com` if `https://versions.backstage.io` is unavailable. + +## @techdocs/cli@1.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-techdocs-node@1.4.2-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4-next.0 + +## @backstage/plugin-adr@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-adr-common@0.2.3-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + +## @backstage/plugin-adr-backend@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/plugin-adr-common@0.2.3-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + +## @backstage/plugin-airbrake@0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/dev-utils@1.0.8-next.1 + - @backstage/test-utils@1.2.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-airbrake-backend@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + +## @backstage/plugin-allure@0.1.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-analytics-module-ga@0.1.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-apache-airflow@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + +## @backstage/plugin-api-docs@0.8.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog@1.6.1-next.1 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-apollo-explorer@0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-app-backend@0.3.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/config-loader@1.1.6-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-auth-backend@0.17.1-next.1 + +### Patch Changes + +- 0d6837ca4e: Fix wrong GitHub callback URL documentation +- abaed9770e: Improve logging +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-auth-node@0.2.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + +## @backstage/plugin-azure-devops@0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-azure-devops-common@0.3.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-azure-devops-backend@0.3.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-azure-devops-common@0.3.0 + +## @backstage/plugin-azure-sites@0.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-azure-sites-common@0.1.0-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-azure-sites-backend@0.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-azure-sites-common@0.1.0-next.0 + +## @backstage/plugin-badges@0.2.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-badges-backend@0.1.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + +## @backstage/plugin-bazaar@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.21.0-next.1 + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-catalog@1.6.1-next.1 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-bazaar-backend@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-test-utils@0.1.30-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + +## @backstage/plugin-bitrise@0.1.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-catalog@1.6.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + +## @backstage/plugin-catalog-backend@1.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/plugin-permission-node@0.7.1-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-scaffolder-common@1.2.2-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + +## @backstage/plugin-catalog-backend-module-aws@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-catalog-backend-module-azure@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket@0.2.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.1-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.1-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-catalog-graph@0.2.23-next.1 + +### Patch Changes + +- da0bf25d1a: Preserve graph options and increment `maxDepth` by 1. + + The change will preserve options used at the `CatalogGraphCard` + (displayed at the entity page) and additionally, increments the + `maxDepth` option by 1 to increase the scope slightly compared to + the graph already seen by the users. + + The default for `maxDepth` at `CatalogGraphCard` is 1. + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-catalog-import@0.9.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-catalog-node@1.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-catalog-common@1.0.8-next.0 + +## @backstage/plugin-catalog-react@1.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + - @backstage/version-bridge@1.0.1 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-permission-react@0.4.7-next.0 + +## @backstage/plugin-cicd-statistics@0.1.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/plugin-cicd-statistics@0.1.13-next.1 + +## @backstage/plugin-circleci@0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-cloudbuild@0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-code-climate@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-code-coverage@0.2.4-next.1 + +### Patch Changes + +- fcab2579a0: Adds installation instructions +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-code-coverage-backend@0.2.4-next.1 + +### Patch Changes + +- fcab2579a0: Adds installation instructions +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + +## @backstage/plugin-codescene@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-config-schema@0.1.34-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-cost-insights@0.12.0-next.1 + +### Patch Changes + +- e92aa15f01: Bumped `canvas` dependency to the latest version, which has better Node.js v18 support. +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-cost-insights-common@0.1.1 + +## @backstage/plugin-dynatrace@1.0.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-explore@0.3.42-next.1 + +### Patch Changes + +- 5c25ce6d9e: Added a section to explore plugin README that describes the customization of explore tools content. +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-explore-react@0.0.23-next.0 + +## @backstage/plugin-firehydrant@0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-fossa@0.2.43-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-gcalendar@0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-gcp-projects@0.3.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-git-release-manager@0.3.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-github-actions@0.5.11-next.1 + +### Patch Changes + +- ed438a3ba5: Add error panel when the plugin fails. +- 0d6837ca4e: Fix wrong GitHub callback URL documentation +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-github-deployments@0.1.42-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-github-issues@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-github-pull-requests-board@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-gitops-profiles@0.3.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-gocd@0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-graphiql@0.2.43-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-graphql-backend@0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-catalog-graphql@0.3.15-next.0 + +## @backstage/plugin-home@0.4.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-stack-overflow@0.1.7-next.1 + +## @backstage/plugin-ilert@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-jenkins@0.7.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-jenkins-common@0.1.10-next.0 + +## @backstage/plugin-jenkins-backend@0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-jenkins-common@0.1.10-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + +## @backstage/plugin-kafka@0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-kafka-backend@0.2.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + +## @backstage/plugin-kubernetes@0.7.4-next.1 + +### Patch Changes + +- cfb30b700c: Pin `@kubernetes/client-node` version to `0.17.0`. +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/plugin-kubernetes-common@0.4.4-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-kubernetes-backend@0.8.0-next.1 + +### Patch Changes + +- cfb30b700c: Pin `@kubernetes/client-node` version to `0.17.0`. +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-kubernetes-common@0.4.4-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + +## @backstage/plugin-kubernetes-common@0.4.4-next.1 + +### Patch Changes + +- cfb30b700c: Pin `@kubernetes/client-node` version to `0.17.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.3-next.0 + +## @backstage/plugin-lighthouse@0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-newrelic@0.3.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-newrelic-dashboard@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-pagerduty@0.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-periskop@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-periskop-backend@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + +## @backstage/plugin-permission-backend@0.5.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/plugin-permission-node@0.7.1-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + +## @backstage/plugin-permission-node@0.7.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + +## @backstage/plugin-playlist@0.1.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-permission-react@0.4.7-next.0 + - @backstage/plugin-playlist-common@0.1.2-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + +## @backstage/plugin-playlist-backend@0.2.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-test-utils@0.1.30-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/plugin-permission-node@0.7.1-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-playlist-common@0.1.2-next.0 + +## @backstage/plugin-proxy-backend@0.2.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + +## @backstage/plugin-rollbar@0.4.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-rollbar-backend@0.1.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + +## @backstage/plugin-scaffolder@1.8.0-next.1 + +### Patch Changes + +- 580285787d: The `create` and `click` analytics events are now also captured on the "next" version of the component creation page. +- 3b3fc3cc3c: Fix `formData` not being present in the `next` version +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-permission-react@0.4.7-next.0 + - @backstage/plugin-scaffolder-common@1.2.2-next.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-scaffolder-backend@1.8.0-next.2 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-scaffolder-backend@1.8.0-next.2 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.0-next.2 + - @backstage/config@1.0.4-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-search@1.0.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + - @backstage/version-bridge@1.0.1 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + +## @backstage/plugin-search-backend@1.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/plugin-permission-node@0.7.1-next.1 + - @backstage/plugin-search-backend-node@1.0.4-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + +## @backstage/plugin-search-backend-module-elasticsearch@1.0.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.0.4-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + +## @backstage/plugin-search-backend-module-pg@0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-search-backend-node@1.0.4-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + +## @backstage/plugin-search-backend-node@1.0.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + +## @backstage/plugin-search-react@1.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + - @backstage/version-bridge@1.0.1 + - @backstage/plugin-search-common@1.1.1-next.0 + +## @backstage/plugin-sentry@0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-shortcuts@0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-sonarqube@0.4.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-sonarqube-backend@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + +## @backstage/plugin-stack-overflow@0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-home@0.4.27-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + +## @backstage/plugin-stack-overflow-backend@0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.21.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + +## @backstage/plugin-tech-insights@0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-tech-insights-common@0.2.8-next.0 + +## @backstage/plugin-tech-insights-backend@0.5.4-next.1 + +### Patch Changes + +- f12e9e5b8c: Add Documentation on 404 Errors +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-tech-insights-node@0.3.6-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-tech-insights-common@0.2.8-next.0 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-tech-insights-node@0.3.6-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-tech-insights-common@0.2.8-next.0 + +## @backstage/plugin-tech-insights-node@0.3.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-tech-insights-common@0.2.8-next.0 + +## @backstage/plugin-tech-radar@0.5.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-techdocs@1.4.0-next.2 + +### Patch Changes + +- e92aa15f01: Bumped `canvas` dependency to the latest version, which has better Node.js v18 support. +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + - @backstage/plugin-techdocs-react@1.0.6-next.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.4.0-next.2 + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-app-api@1.2.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/test-utils@1.2.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog@1.6.1-next.1 + - @backstage/plugin-search-react@1.2.1-next.1 + - @backstage/plugin-techdocs-react@1.0.6-next.1 + +## @backstage/plugin-techdocs-backend@1.4.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-techdocs-node@1.4.2-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.0.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-techdocs-react@1.0.6-next.1 + +## @backstage/plugin-techdocs-node@1.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + +## @backstage/plugin-techdocs-react@1.0.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/version-bridge@1.0.1 + +## @backstage/plugin-todo@0.2.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-todo-backend@0.1.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + +## @backstage/plugin-user-settings@0.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-app-api@1.2.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-user-settings-backend@0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + +## @backstage/plugin-vault@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @backstage/plugin-vault-backend@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/backend-test-utils@0.1.30-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + +## @backstage/plugin-xcmetrics@0.2.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + +## example-app@0.2.77-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.8.0-next.1 + - @backstage/plugin-cost-insights@0.12.0-next.1 + - @backstage/plugin-techdocs@1.4.0-next.2 + - @backstage/plugin-explore@0.3.42-next.1 + - @backstage/plugin-github-actions@0.5.11-next.1 + - @backstage/cli@0.21.0-next.1 + - @backstage/plugin-catalog-graph@0.2.23-next.1 + - @backstage/core-components@0.12.0-next.1 + - @backstage/plugin-code-coverage@0.2.4-next.1 + - @backstage/plugin-org@0.6.0-next.1 + - @backstage/plugin-kubernetes@0.7.4-next.1 + - @backstage/app-defaults@1.0.8-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-app-api@1.2.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-airbrake@0.3.11-next.1 + - @backstage/plugin-apache-airflow@0.2.4-next.1 + - @backstage/plugin-api-docs@0.8.11-next.1 + - @backstage/plugin-azure-devops@0.2.2-next.1 + - @backstage/plugin-azure-sites@0.1.0-next.1 + - @backstage/plugin-badges@0.2.35-next.1 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-catalog-import@0.9.1-next.1 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-circleci@0.3.11-next.1 + - @backstage/plugin-cloudbuild@0.3.11-next.1 + - @backstage/plugin-dynatrace@1.0.1-next.1 + - @backstage/plugin-gcalendar@0.3.7-next.1 + - @backstage/plugin-gcp-projects@0.3.30-next.1 + - @backstage/plugin-gocd@0.1.17-next.1 + - @backstage/plugin-graphiql@0.2.43-next.1 + - @backstage/plugin-home@0.4.27-next.1 + - @backstage/plugin-jenkins@0.7.10-next.1 + - @backstage/plugin-kafka@0.3.11-next.1 + - @backstage/plugin-lighthouse@0.3.11-next.1 + - @backstage/plugin-newrelic@0.3.29-next.1 + - @backstage/plugin-newrelic-dashboard@0.2.4-next.1 + - @backstage/plugin-pagerduty@0.5.4-next.1 + - @backstage/plugin-permission-react@0.4.7-next.0 + - @backstage/plugin-playlist@0.1.2-next.2 + - @backstage/plugin-rollbar@0.4.11-next.1 + - @backstage/plugin-search@1.0.4-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + - @backstage/plugin-sentry@0.4.4-next.1 + - @backstage/plugin-shortcuts@0.3.3-next.1 + - @backstage/plugin-stack-overflow@0.1.7-next.1 + - @backstage/plugin-tech-insights@0.3.3-next.1 + - @backstage/plugin-tech-radar@0.5.18-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.6-next.1 + - @backstage/plugin-techdocs-react@1.0.6-next.1 + - @backstage/plugin-todo@0.2.13-next.1 + - @backstage/plugin-user-settings@0.5.1-next.1 + - @internal/plugin-catalog-customized@0.0.4-next.1 + +## example-backend@0.2.77-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.17.1-next.1 + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-scaffolder-backend@1.8.0-next.2 + - @backstage/plugin-code-coverage-backend@0.2.4-next.1 + - @backstage/plugin-kubernetes-backend@0.8.0-next.1 + - @backstage/plugin-tech-insights-backend@0.5.4-next.1 + - example-app@0.2.77-next.2 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-app-backend@0.3.38-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/plugin-azure-devops-backend@0.3.17-next.2 + - @backstage/plugin-azure-sites-backend@0.1.0-next.1 + - @backstage/plugin-badges-backend@0.1.32-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-graphql-backend@0.1.28-next.1 + - @backstage/plugin-jenkins-backend@0.1.28-next.1 + - @backstage/plugin-kafka-backend@0.2.31-next.1 + - @backstage/plugin-permission-backend@0.5.13-next.1 + - @backstage/plugin-permission-node@0.7.1-next.1 + - @backstage/plugin-playlist-backend@0.2.1-next.2 + - @backstage/plugin-proxy-backend@0.2.32-next.1 + - @backstage/plugin-rollbar-backend@0.1.35-next.1 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.6-next.2 + - @backstage/plugin-search-backend@1.1.1-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.0.4-next.1 + - @backstage/plugin-search-backend-module-pg@0.4.2-next.1 + - @backstage/plugin-search-backend-node@1.0.4-next.1 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.22-next.1 + - @backstage/plugin-tech-insights-node@0.3.6-next.1 + - @backstage/plugin-techdocs-backend@1.4.1-next.1 + - @backstage/plugin-todo-backend@0.1.35-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + +## example-backend-next@0.0.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.0-next.2 + - @backstage/plugin-app-backend@0.3.38-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/backend-defaults@0.1.3-next.1 + +## techdocs-cli-embedded-app@0.2.76-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.4.0-next.2 + - @backstage/cli@0.21.0-next.1 + - @backstage/core-components@0.12.0-next.1 + - @backstage/app-defaults@1.0.8-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-app-api@1.2.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/test-utils@1.2.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog@1.6.1-next.1 + - @backstage/plugin-techdocs-react@1.0.6-next.1 + +## @internal/plugin-catalog-customized@0.0.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.6.1-next.1 + - @backstage/plugin-catalog-react@1.2.1-next.1 + +## @internal/plugin-todo-list@1.0.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + +## @internal/plugin-todo-list-backend@1.0.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 diff --git a/package.json b/package.json index 11e92b530b..3977bcc18f 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@types/react": "^17", "@types/react-dom": "^17" }, - "version": "1.8.0-next.1", + "version": "1.8.0-next.2", "dependencies": { "@backstage/errors": "workspace:^", "@manypkg/get-packages": "^1.1.3", diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index 12b6a0894f..aa79c74c87 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/app-defaults +## 1.0.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-app-api@1.2.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-permission-react@0.4.7-next.0 + ## 1.0.8-next.0 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 6658f0a8bd..71d3eb5824 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/app-defaults", "description": "Provides the default wiring of a Backstage App", - "version": "1.0.8-next.0", + "version": "1.0.8-next.1", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index b713987116..5780e61681 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,68 @@ # example-app +## 0.2.77-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.8.0-next.1 + - @backstage/plugin-cost-insights@0.12.0-next.1 + - @backstage/plugin-techdocs@1.4.0-next.2 + - @backstage/plugin-explore@0.3.42-next.1 + - @backstage/plugin-github-actions@0.5.11-next.1 + - @backstage/cli@0.21.0-next.1 + - @backstage/plugin-catalog-graph@0.2.23-next.1 + - @backstage/core-components@0.12.0-next.1 + - @backstage/plugin-code-coverage@0.2.4-next.1 + - @backstage/plugin-org@0.6.0-next.1 + - @backstage/plugin-kubernetes@0.7.4-next.1 + - @backstage/app-defaults@1.0.8-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-app-api@1.2.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-airbrake@0.3.11-next.1 + - @backstage/plugin-apache-airflow@0.2.4-next.1 + - @backstage/plugin-api-docs@0.8.11-next.1 + - @backstage/plugin-azure-devops@0.2.2-next.1 + - @backstage/plugin-azure-sites@0.1.0-next.1 + - @backstage/plugin-badges@0.2.35-next.1 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-catalog-import@0.9.1-next.1 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-circleci@0.3.11-next.1 + - @backstage/plugin-cloudbuild@0.3.11-next.1 + - @backstage/plugin-dynatrace@1.0.1-next.1 + - @backstage/plugin-gcalendar@0.3.7-next.1 + - @backstage/plugin-gcp-projects@0.3.30-next.1 + - @backstage/plugin-gocd@0.1.17-next.1 + - @backstage/plugin-graphiql@0.2.43-next.1 + - @backstage/plugin-home@0.4.27-next.1 + - @backstage/plugin-jenkins@0.7.10-next.1 + - @backstage/plugin-kafka@0.3.11-next.1 + - @backstage/plugin-lighthouse@0.3.11-next.1 + - @backstage/plugin-newrelic@0.3.29-next.1 + - @backstage/plugin-newrelic-dashboard@0.2.4-next.1 + - @backstage/plugin-pagerduty@0.5.4-next.1 + - @backstage/plugin-permission-react@0.4.7-next.0 + - @backstage/plugin-playlist@0.1.2-next.2 + - @backstage/plugin-rollbar@0.4.11-next.1 + - @backstage/plugin-search@1.0.4-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + - @backstage/plugin-sentry@0.4.4-next.1 + - @backstage/plugin-shortcuts@0.3.3-next.1 + - @backstage/plugin-stack-overflow@0.1.7-next.1 + - @backstage/plugin-tech-insights@0.3.3-next.1 + - @backstage/plugin-tech-radar@0.5.18-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.6-next.1 + - @backstage/plugin-techdocs-react@1.0.6-next.1 + - @backstage/plugin-todo@0.2.13-next.1 + - @backstage/plugin-user-settings@0.5.1-next.1 + - @internal/plugin-catalog-customized@0.0.4-next.1 + ## 0.2.77-next.1 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 3f93c523a3..b7f7f40b89 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.77-next.1", + "version": "0.2.77-next.2", "private": true, "backstage": { "role": "frontend" diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index d8b2cd7c3b..57173d0ed0 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/backend-app-api +## 0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-permission-node@0.7.1-next.1 + - @backstage/errors@1.1.3-next.0 + ## 0.2.3-next.0 ### Patch Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 0658176962..c248891ab2 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-app-api", "description": "Core API used by Backstage backend apps", - "version": "0.2.3-next.0", + "version": "0.2.3-next.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index 3c219161d0..35e78b6de0 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/backend-common +## 0.16.0-next.1 + +### Patch Changes + +- 88f99b8b13: Bumped `tar` dependency to `^6.1.12` in order to ensure Node.js v18 compatibility. +- cfb30b700c: Pin `@kubernetes/client-node` version to `0.17.0`. +- Updated dependencies + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4-next.0 + - @backstage/config-loader@1.1.6-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.16.0-next.0 ### Minor Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 28a4f91aa2..e2f6360871 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-common", "description": "Common functionality library for Backstage backends", - "version": "0.16.0-next.0", + "version": "0.16.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index 9defd1025a..bb140bfe03 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/backend-defaults +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@0.2.3-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + ## 0.1.3-next.0 ### Patch Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 07fa8c16eb..2e0eceecdd 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-defaults", "description": "Backend defaults used by Backstage backend apps", - "version": "0.1.3-next.0", + "version": "0.1.3-next.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-next/CHANGELOG.md b/packages/backend-next/CHANGELOG.md index 6c66580e6f..f495784e70 100644 --- a/packages/backend-next/CHANGELOG.md +++ b/packages/backend-next/CHANGELOG.md @@ -1,5 +1,15 @@ # example-backend-next +## 0.0.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.0-next.2 + - @backstage/plugin-app-backend@0.3.38-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/backend-defaults@0.1.3-next.1 + ## 0.0.5-next.1 ### Patch Changes diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index cc689aa1a8..14b6e5430d 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-next", - "version": "0.0.5-next.1", + "version": "0.0.5-next.2", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index 512f0562f6..647b0c1472 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/backend-plugin-api +## 0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + ## 0.1.4-next.0 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 4804213f5c..31efbb0616 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-plugin-api", "description": "Core API used by Backstage backend plugins", - "version": "0.1.4-next.0", + "version": "0.1.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index ecef237ff0..8fffc056c3 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/backend-tasks +## 0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.3.7-next.0 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index 69ab5713dd..75903d2708 100644 --- a/packages/backend-tasks/package.json +++ b/packages/backend-tasks/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-tasks", "description": "Common distributed task management library for Backstage backends", - "version": "0.3.7-next.0", + "version": "0.3.7-next.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 6847198298..61e8a131be 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/backend-test-utils +## 0.1.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/cli@0.21.0-next.1 + - @backstage/backend-app-api@0.2.3-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/config@1.0.4-next.0 + ## 0.1.30-next.0 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 96fb7657bd..79b5ed6d97 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-test-utils", "description": "Test helpers library for Backstage backends", - "version": "0.1.30-next.0", + "version": "0.1.30-next.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index bc8087bcc1..70be2433db 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,48 @@ # example-backend +## 0.2.77-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.17.1-next.1 + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-scaffolder-backend@1.8.0-next.2 + - @backstage/plugin-code-coverage-backend@0.2.4-next.1 + - @backstage/plugin-kubernetes-backend@0.8.0-next.1 + - @backstage/plugin-tech-insights-backend@0.5.4-next.1 + - example-app@0.2.77-next.2 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-app-backend@0.3.38-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/plugin-azure-devops-backend@0.3.17-next.2 + - @backstage/plugin-azure-sites-backend@0.1.0-next.1 + - @backstage/plugin-badges-backend@0.1.32-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-graphql-backend@0.1.28-next.1 + - @backstage/plugin-jenkins-backend@0.1.28-next.1 + - @backstage/plugin-kafka-backend@0.2.31-next.1 + - @backstage/plugin-permission-backend@0.5.13-next.1 + - @backstage/plugin-permission-node@0.7.1-next.1 + - @backstage/plugin-playlist-backend@0.2.1-next.2 + - @backstage/plugin-proxy-backend@0.2.32-next.1 + - @backstage/plugin-rollbar-backend@0.1.35-next.1 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.6-next.2 + - @backstage/plugin-search-backend@1.1.1-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.0.4-next.1 + - @backstage/plugin-search-backend-module-pg@0.4.2-next.1 + - @backstage/plugin-search-backend-node@1.0.4-next.1 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.22-next.1 + - @backstage/plugin-tech-insights-node@0.3.6-next.1 + - @backstage/plugin-techdocs-backend@1.4.1-next.1 + - @backstage/plugin-todo-backend@0.1.35-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + ## 0.2.77-next.1 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index d9500db73d..260af8c137 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.77-next.1", + "version": "0.2.77-next.2", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index c3f0dde1fe..96373f79e6 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/cli +## 0.21.0-next.1 + +### Minor Changes + +- 384eaa2307: Switched `tsconfig.json` to target and support `ES2021`, in line with the bump to Node.js 16 & 18. + +### Patch Changes + +- 88f99b8b13: Bumped `tar` dependency to `^6.1.12` in order to ensure Node.js v18 compatibility. +- 969a8444ea: Updated dependency `esbuild` to `^0.15.0`. +- Updated dependencies + - @backstage/release-manifests@0.0.7-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4-next.0 + - @backstage/config-loader@1.1.6-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.21.0-next.0 ### Minor Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index be46d74a49..08d1ddeab5 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli", "description": "CLI for developing Backstage plugins and apps", - "version": "0.21.0-next.0", + "version": "0.21.0-next.1", "publishConfig": { "access": "public" }, diff --git a/packages/codemods/CHANGELOG.md b/packages/codemods/CHANGELOG.md index 161a8dbdf9..e0df55aca1 100644 --- a/packages/codemods/CHANGELOG.md +++ b/packages/codemods/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/codemods +## 0.1.41-next.0 + +### Patch Changes + +- 58502ec285: Updated dependency `jscodeshift` to `^0.14.0`. +- Updated dependencies + - @backstage/cli-common@0.1.10 + ## 0.1.40 ### Patch Changes diff --git a/packages/codemods/package.json b/packages/codemods/package.json index af8a68cb55..087f9bb79e 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/codemods", "description": "A collection of codemods for Backstage projects", - "version": "0.1.40", + "version": "0.1.41-next.0", "publishConfig": { "access": "public", "main": "dist/index.cjs.js" diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index 00b1c55fdc..c756328cc6 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/core-components +## 0.12.0-next.1 + +### Patch Changes + +- b4fb5c8ecc: MissingAnnotationEmptyState now accepts either a string or an array of strings to support multiple missing annotations. +- Updated dependencies + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/version-bridge@1.0.1 + ## 0.12.0-next.0 ### Minor Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index 33dfc762c9..f2d82fc4d8 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-components", "description": "Core components used by Backstage plugins and apps", - "version": "0.12.0-next.0", + "version": "0.12.0-next.1", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 702f3d4d4e..a0b2878a09 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,56 @@ # @backstage/create-app +## 0.4.34-next.2 + +### Patch Changes + +- 384eaa2307: Switched Node.js version to support version 16 & 18, rather than 14 & 16. To switch the Node.js version in your own project, apply the following change to the root `package.json`: + + ```diff + "engines": { + - "node": "14 || 16" + + "node": "16 || 18" + }, + ``` + + As well as the following change to `packages/app/package.json`: + + ```diff + - "@types/node": "^14.14.32", + + "@types/node": "^16.11.26", + ``` + +- 864c876e57: Fixed incorrect comments in the templated `app-config.yaml` and `app-config.production.yaml`. The `backend.listen` directive is not in fact needed to override the `backend.baseUrl`, the backend listens to all interfaces by default. The configuration has also been updated to listen to all interfaces, rather than just IPv4 ones, as this is required for Node.js v18. The production configuration now also shows the option to specify `backend.listen` as a single string. + + To apply this changes to an existing app, make the following change to `app-config.yaml`: + + ```diff + - # Uncomment the following host directive to bind to all IPv4 interfaces and + - # not just the baseUrl hostname. + - # host: 0.0.0.0 + + # Uncomment the following host directive to bind to specific interfaces + + # host: 127.0.0.1 + ``` + + And the following change to `app-config.production.yaml`: + + ```diff + - listen: + - port: 7007 + - # The following host directive binds to all IPv4 interfaces when its value + - # is "0.0.0.0". This is the most permissive setting. The right value depends + - # on your specific deployment. If you remove the host line entirely, the + - # backend will bind on the interface that corresponds to the backend.baseUrl + - # hostname. + - host: 0.0.0.0 + + # The listener can also be expressed as a single : string. In this case we bind to + + # all interfaces, the most permissive setting. The right value depends on your specific deployment. + + listen: ':7007' + ``` + +- Updated dependencies + - @backstage/cli-common@0.1.10 + ## 0.4.33-next.1 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 932d54ee03..c4f77ec51d 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "A CLI that helps you create your own Backstage app", - "version": "0.4.33-next.1", + "version": "0.4.34-next.2", "publishConfig": { "access": "public" }, diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index 7177a25fb2..bbf36f42bd 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/dev-utils +## 1.0.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/app-defaults@1.0.8-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-app-api@1.2.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/test-utils@1.2.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 1.0.8-next.0 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 0decdbe985..4e2666e34f 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/dev-utils", "description": "Utilities for developing Backstage plugins.", - "version": "1.0.8-next.0", + "version": "1.0.8-next.1", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md index b396593d12..606b6f0f80 100644 --- a/packages/integration-react/CHANGELOG.md +++ b/packages/integration-react/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/integration-react +## 1.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/theme@0.2.16 + ## 1.1.6-next.0 ### Patch Changes diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index 7efea2e74a..c1ee32ae1e 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/integration-react", "description": "Frontend package for managing integrations towards external systems", - "version": "1.1.6-next.0", + "version": "1.1.6-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/release-manifests/CHANGELOG.md b/packages/release-manifests/CHANGELOG.md index 177ea55a5a..6e2de9598f 100644 --- a/packages/release-manifests/CHANGELOG.md +++ b/packages/release-manifests/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/release-manifests +## 0.0.7-next.0 + +### Patch Changes + +- a4496131fa: Added a fallback that fetches manifests from `https://raw.githubusercontent.com` if `https://versions.backstage.io` is unavailable. + ## 0.0.6 ### Patch Changes diff --git a/packages/release-manifests/package.json b/packages/release-manifests/package.json index 949cd2bcd5..27be30f5f3 100644 --- a/packages/release-manifests/package.json +++ b/packages/release-manifests/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/release-manifests", "description": "Helper library for receiving release manifests", - "version": "0.0.6", + "version": "0.0.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 35515eb5d2..e6d842d121 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,24 @@ # techdocs-cli-embedded-app +## 0.2.76-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.4.0-next.2 + - @backstage/cli@0.21.0-next.1 + - @backstage/core-components@0.12.0-next.1 + - @backstage/app-defaults@1.0.8-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-app-api@1.2.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/test-utils@1.2.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog@1.6.1-next.1 + - @backstage/plugin-techdocs-react@1.0.6-next.1 + ## 0.2.76-next.1 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 740889a661..4006fbe4c9 100644 --- a/packages/techdocs-cli-embedded-app/package.json +++ b/packages/techdocs-cli-embedded-app/package.json @@ -1,6 +1,6 @@ { "name": "techdocs-cli-embedded-app", - "version": "0.2.76-next.1", + "version": "0.2.76-next.2", "private": true, "backstage": { "role": "frontend" diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index 26f085b6ce..3e39ba06d3 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @techdocs/cli +## 1.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-techdocs-node@1.4.2-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4-next.0 + ## 1.2.3-next.0 ### Patch Changes diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 10b738c025..615651d6f9 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -1,7 +1,7 @@ { "name": "@techdocs/cli", "description": "Utility CLI for managing TechDocs sites in Backstage.", - "version": "1.2.3-next.0", + "version": "1.2.3-next.1", "publishConfig": { "access": "public" }, diff --git a/plugins/adr-backend/CHANGELOG.md b/plugins/adr-backend/CHANGELOG.md index 84143ccf78..4b3c7bf9d6 100644 --- a/plugins/adr-backend/CHANGELOG.md +++ b/plugins/adr-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-adr-backend +## 0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/plugin-adr-common@0.2.3-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + ## 0.2.3-next.0 ### Patch Changes diff --git a/plugins/adr-backend/package.json b/plugins/adr-backend/package.json index ccbd3f119e..8f73088fbf 100644 --- a/plugins/adr-backend/package.json +++ b/plugins/adr-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr-backend", - "version": "0.2.3-next.0", + "version": "0.2.3-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/adr/CHANGELOG.md b/plugins/adr/CHANGELOG.md index e1f34381e4..018b90a5dd 100644 --- a/plugins/adr/CHANGELOG.md +++ b/plugins/adr/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-adr +## 0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-adr-common@0.2.3-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + ## 0.2.3-next.0 ### Patch Changes diff --git a/plugins/adr/package.json b/plugins/adr/package.json index e6113c7a83..533a581b47 100644 --- a/plugins/adr/package.json +++ b/plugins/adr/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr", - "version": "0.2.3-next.0", + "version": "0.2.3-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/airbrake-backend/CHANGELOG.md b/plugins/airbrake-backend/CHANGELOG.md index 38ed0acbc7..24caeabf88 100644 --- a/plugins/airbrake-backend/CHANGELOG.md +++ b/plugins/airbrake-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-airbrake-backend +## 0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + ## 0.2.11-next.0 ### Patch Changes diff --git a/plugins/airbrake-backend/package.json b/plugins/airbrake-backend/package.json index f8904563a4..d23a068e63 100644 --- a/plugins/airbrake-backend/package.json +++ b/plugins/airbrake-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake-backend", - "version": "0.2.11-next.0", + "version": "0.2.11-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/airbrake/CHANGELOG.md b/plugins/airbrake/CHANGELOG.md index a714e4d69f..b81d9ccfcd 100644 --- a/plugins/airbrake/CHANGELOG.md +++ b/plugins/airbrake/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-airbrake +## 0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/dev-utils@1.0.8-next.1 + - @backstage/test-utils@1.2.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.3.11-next.0 ### Patch Changes diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json index 3f04501019..639514f073 100644 --- a/plugins/airbrake/package.json +++ b/plugins/airbrake/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake", - "version": "0.3.11-next.0", + "version": "0.3.11-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/allure/CHANGELOG.md b/plugins/allure/CHANGELOG.md index 0f57d596c5..0184290777 100644 --- a/plugins/allure/CHANGELOG.md +++ b/plugins/allure/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-allure +## 0.1.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.1.27-next.0 ### Patch Changes diff --git a/plugins/allure/package.json b/plugins/allure/package.json index 68808cf511..ffb06c52ae 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.27-next.0", + "version": "0.1.27-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/analytics-module-ga/CHANGELOG.md b/plugins/analytics-module-ga/CHANGELOG.md index 149215b223..5f28f9b0e8 100644 --- a/plugins/analytics-module-ga/CHANGELOG.md +++ b/plugins/analytics-module-ga/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-analytics-module-ga +## 0.1.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + ## 0.1.22-next.0 ### Patch Changes diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json index ac94ad8979..093a44939b 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.22-next.0", + "version": "0.1.22-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/apache-airflow/CHANGELOG.md b/plugins/apache-airflow/CHANGELOG.md index b4dee086eb..8d60af0baf 100644 --- a/plugins/apache-airflow/CHANGELOG.md +++ b/plugins/apache-airflow/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-apache-airflow +## 0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + ## 0.2.4-next.0 ### Patch Changes diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json index bba1177b06..2ed0bcbf73 100644 --- a/plugins/apache-airflow/package.json +++ b/plugins/apache-airflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apache-airflow", - "version": "0.2.4-next.0", + "version": "0.2.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index de93784591..716cd44e05 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-api-docs +## 0.8.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog@1.6.1-next.1 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.8.11-next.0 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index ecb6fe3ff4..d67e035345 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.8.11-next.0", + "version": "0.8.11-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/apollo-explorer/CHANGELOG.md b/plugins/apollo-explorer/CHANGELOG.md index 5ef5cb16f9..c388e42e6e 100644 --- a/plugins/apollo-explorer/CHANGELOG.md +++ b/plugins/apollo-explorer/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-apollo-explorer +## 0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + ## 0.1.4-next.0 ### Patch Changes diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json index 91fe56950e..877b6218c7 100644 --- a/plugins/apollo-explorer/package.json +++ b/plugins/apollo-explorer/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apollo-explorer", - "version": "0.1.4-next.0", + "version": "0.1.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index 81c2020152..3d0508a9a0 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-app-backend +## 0.3.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/config-loader@1.1.6-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.3.38-next.0 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index 5e72d7b666..3c7801e9b2 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.38-next.0", + "version": "0.3.38-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index a65fa417d8..31ea050088 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-auth-backend +## 0.17.1-next.1 + +### Patch Changes + +- 0d6837ca4e: Fix wrong GitHub callback URL documentation +- abaed9770e: Improve logging +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.17.1-next.0 ### Patch Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 67deb66b33..ec1b3a3b23 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.17.1-next.0", + "version": "0.17.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index aac75b87e9..8f31f276dc 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-node +## 0.2.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + ## 0.2.7-next.0 ### Patch Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 79dcc6d6b8..2fc83f5002 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-node", - "version": "0.2.7-next.0", + "version": "0.2.7-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-devops-backend/CHANGELOG.md b/plugins/azure-devops-backend/CHANGELOG.md index ae57ae23a9..e6a148f278 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.3.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-azure-devops-common@0.3.0 + ## 0.3.17-next.1 ### Patch Changes diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json index 50a99dbc2a..a5fe6e2488 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.3.17-next.1", + "version": "0.3.17-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-devops/CHANGELOG.md b/plugins/azure-devops/CHANGELOG.md index 1317547b7f..2dc9629a4b 100644 --- a/plugins/azure-devops/CHANGELOG.md +++ b/plugins/azure-devops/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-azure-devops +## 0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-azure-devops-common@0.3.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.2.2-next.0 ### Patch Changes diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index a2ffd77c84..351d22eab7 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops", - "version": "0.2.2-next.0", + "version": "0.2.2-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-sites-backend/CHANGELOG.md b/plugins/azure-sites-backend/CHANGELOG.md index b06742648f..230c8912a8 100644 --- a/plugins/azure-sites-backend/CHANGELOG.md +++ b/plugins/azure-sites-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-azure-sites-backend +## 0.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-azure-sites-common@0.1.0-next.0 + ## 0.1.0-next.0 ### Minor Changes diff --git a/plugins/azure-sites-backend/package.json b/plugins/azure-sites-backend/package.json index f6529b7a3d..fb495033d4 100644 --- a/plugins/azure-sites-backend/package.json +++ b/plugins/azure-sites-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-sites-backend", - "version": "0.1.0-next.0", + "version": "0.1.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-sites/CHANGELOG.md b/plugins/azure-sites/CHANGELOG.md index 4e1b2bb12b..ad4e9a5f41 100644 --- a/plugins/azure-sites/CHANGELOG.md +++ b/plugins/azure-sites/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-azure-sites +## 0.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-azure-sites-common@0.1.0-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.1.0-next.0 ### Minor Changes diff --git a/plugins/azure-sites/package.json b/plugins/azure-sites/package.json index feff8e8645..186052c5c4 100644 --- a/plugins/azure-sites/package.json +++ b/plugins/azure-sites/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-sites", - "version": "0.1.0-next.0", + "version": "0.1.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/badges-backend/CHANGELOG.md b/plugins/badges-backend/CHANGELOG.md index c88b7cf763..9566bfa567 100644 --- a/plugins/badges-backend/CHANGELOG.md +++ b/plugins/badges-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-badges-backend +## 0.1.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + ## 0.1.32-next.0 ### Patch Changes diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json index a8e465597c..09eee82efb 100644 --- a/plugins/badges-backend/package.json +++ b/plugins/badges-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges-backend", "description": "A Backstage backend plugin that generates README badges for your entities", - "version": "0.1.32-next.0", + "version": "0.1.32-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/badges/CHANGELOG.md b/plugins/badges/CHANGELOG.md index f736588933..7eea420307 100644 --- a/plugins/badges/CHANGELOG.md +++ b/plugins/badges/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-badges +## 0.2.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.2.35-next.0 ### Patch Changes diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 68d47e08ac..c5810532f6 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.35-next.0", + "version": "0.2.35-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bazaar-backend/CHANGELOG.md b/plugins/bazaar-backend/CHANGELOG.md index d0524bd9f5..743f89dc74 100644 --- a/plugins/bazaar-backend/CHANGELOG.md +++ b/plugins/bazaar-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-bazaar-backend +## 0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-test-utils@0.1.30-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + ## 0.2.1-next.0 ### Patch Changes diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json index 2f0e766917..1721508fcb 100644 --- a/plugins/bazaar-backend/package.json +++ b/plugins/bazaar-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar-backend", - "version": "0.2.1-next.0", + "version": "0.2.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bazaar/CHANGELOG.md b/plugins/bazaar/CHANGELOG.md index 7ff38b63f8..0db71d8fed 100644 --- a/plugins/bazaar/CHANGELOG.md +++ b/plugins/bazaar/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-bazaar +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.21.0-next.1 + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-catalog@1.6.1-next.1 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.2.0-next.0 ### Minor Changes diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json index eb0542a504..a197baee72 100644 --- a/plugins/bazaar/package.json +++ b/plugins/bazaar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar", - "version": "0.2.0-next.0", + "version": "0.2.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bitrise/CHANGELOG.md b/plugins/bitrise/CHANGELOG.md index 2ec214ea00..e9f27547da 100644 --- a/plugins/bitrise/CHANGELOG.md +++ b/plugins/bitrise/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-bitrise +## 0.1.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.1.38-next.0 ### Patch Changes diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index cb23af3b90..a4943b2a0c 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.38-next.0", + "version": "0.1.38-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index 59ab7970f2..487f0d9f77 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.1.11-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index a000ee9d84..4d4dcfec3d 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", "description": "A Backstage catalog backend module that helps integrate towards AWS", - "version": "0.1.11-next.0", + "version": "0.1.11-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index 7fed636045..52ee6b7dd0 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.1.9-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 204321f876..cf5c1997e0 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", "description": "A Backstage catalog backend module that helps integrate towards Azure", - "version": "0.1.9-next.0", + "version": "0.1.9-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index 47cc94f257..933bf23b65 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.1-next.0 + ## 0.1.5-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index 93a9407aa1..0210d0040e 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", - "version": "0.1.5-next.0", + "version": "0.1.5-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md index 1224da8bdd..6bd52de4b1 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + ## 0.1.3-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index 594b5f0852..c75a4b531c 100644 --- a/plugins/catalog-backend-module-bitbucket-server/package.json +++ b/plugins/catalog-backend-module-bitbucket-server/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-server", - "version": "0.1.3-next.0", + "version": "0.1.3-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md index 571c18de00..6a238bba10 100644 --- a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-bitbucket +## 0.2.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.1-next.0 + ## 0.2.5-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket/package.json b/plugins/catalog-backend-module-bitbucket/package.json index 8ee6661b01..cde873d069 100644 --- a/plugins/catalog-backend-module-bitbucket/package.json +++ b/plugins/catalog-backend-module-bitbucket/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket", - "version": "0.2.5-next.0", + "version": "0.2.5-next.1", "deprecated": true, "main": "src/index.ts", "types": "src/index.ts", diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index a6babaf4fc..d249c5a9cb 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + ## 0.1.6-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index c6d342640f..0b46e4e820 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gerrit", - "version": "0.1.6-next.0", + "version": "0.1.6-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index b89231a422..fe13d4fb2a 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-github +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.2.0-next.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index 60185636ea..e939594b67 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-github", "description": "A Backstage catalog backend module that helps integrate towards GitHub", - "version": "0.2.0-next.0", + "version": "0.2.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index 18cce9e01e..e4faffa798 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.1.9-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index e556d4b2de..a94aa6e6a5 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", "description": "A Backstage catalog backend module that helps integrate towards GitLab", - "version": "0.1.9-next.0", + "version": "0.1.9-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index 8a58fce1f5..b440841f88 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.5.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.5.5-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index d095be6b5c..9154272cac 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", "description": "A Backstage catalog backend module that helps integrate towards LDAP", - "version": "0.5.5-next.0", + "version": "0.5.5-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index 8b8d4479d3..cf0885b81a 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + ## 0.4.4-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index cf301c71a0..6d9770fce1 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", - "version": "0.4.4-next.0", + "version": "0.4.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index 0dc46b07a7..9be6f527f7 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.1.4-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index 6f21b8b2e0..86039aa2c7 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", - "version": "0.1.4-next.0", + "version": "0.1.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 494f332c12..ef86889498 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-catalog-backend +## 1.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/plugin-permission-node@0.7.1-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-scaffolder-common@1.2.2-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + ## 1.5.1-next.0 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index b18a133505..3f78439d58 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": "1.5.1-next.0", + "version": "1.5.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-customized/CHANGELOG.md b/plugins/catalog-customized/CHANGELOG.md index 04be429ab6..f515902ead 100644 --- a/plugins/catalog-customized/CHANGELOG.md +++ b/plugins/catalog-customized/CHANGELOG.md @@ -1,5 +1,13 @@ # @internal/plugin-catalog-customized +## 0.0.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.6.1-next.1 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.0.4-next.0 ### Patch Changes diff --git a/plugins/catalog-customized/package.json b/plugins/catalog-customized/package.json index 537180f05e..ea61d95bdd 100644 --- a/plugins/catalog-customized/package.json +++ b/plugins/catalog-customized/package.json @@ -1,7 +1,7 @@ { "name": "@internal/plugin-catalog-customized", "description": "The internal Backstage Customizable plugin for browsing the Backstage catalog", - "version": "0.0.4-next.0", + "version": "0.0.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index 7f8e1e0277..38b921bb1f 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-catalog-graph +## 0.2.23-next.1 + +### Patch Changes + +- da0bf25d1a: Preserve graph options and increment `maxDepth` by 1. + + The change will preserve options used at the `CatalogGraphCard` + (displayed at the entity page) and additionally, increments the + `maxDepth` option by 1 to increase the scope slightly compared to + the graph already seen by the users. + + The default for `maxDepth` at `CatalogGraphCard` is 1. + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.2.23-next.0 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 3b78d5d7ba..43983c171a 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.23-next.0", + "version": "0.2.23-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 8562b77510..1d0d1d56af 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-import +## 0.9.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.9.1-next.0 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index b8cacc4450..aaa99ada4b 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.9.1-next.0", + "version": "0.9.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index ffbd18cd8e..f145bf6595 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-node +## 1.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-catalog-common@1.0.8-next.0 + ## 1.2.1-next.0 ### Patch Changes diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index 320f372249..3e64105dff 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-node", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", - "version": "1.2.1-next.0", + "version": "1.2.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 3019049086..df8ae144a0 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-catalog-react +## 1.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + - @backstage/version-bridge@1.0.1 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-permission-react@0.4.7-next.0 + ## 1.2.1-next.0 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index c2363fdc76..c15190eaca 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": "1.2.1-next.0", + "version": "1.2.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index e95afd8617..8251b94a22 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-catalog +## 1.6.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + ## 1.6.1-next.0 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index de2833c470..9354e6ca5a 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": "1.6.1-next.0", + "version": "1.6.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md index e394418c24..ede5ef942a 100644 --- a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md +++ b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-cicd-statistics-module-gitlab +## 0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/plugin-cicd-statistics@0.1.13-next.1 + ## 0.1.7-next.0 ### Patch Changes diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json index 5f6d5039bf..e6a0b84833 100644 --- a/plugins/cicd-statistics-module-gitlab/package.json +++ b/plugins/cicd-statistics-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics-module-gitlab", "description": "CI/CD Statistics plugin module; Gitlab CICD", - "version": "0.1.7-next.0", + "version": "0.1.7-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cicd-statistics/CHANGELOG.md b/plugins/cicd-statistics/CHANGELOG.md index 29852c597f..028ac177e7 100644 --- a/plugins/cicd-statistics/CHANGELOG.md +++ b/plugins/cicd-statistics/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-cicd-statistics +## 0.1.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.1.13-next.0 ### Patch Changes diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index 5cfac4666e..b12bbb7643 100644 --- a/plugins/cicd-statistics/package.json +++ b/plugins/cicd-statistics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics", "description": "A frontend plugin visualizing CI/CD pipeline statistics (build time)", - "version": "0.1.13-next.0", + "version": "0.1.13-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/circleci/CHANGELOG.md b/plugins/circleci/CHANGELOG.md index b9d916f75a..5bd5ed01fa 100644 --- a/plugins/circleci/CHANGELOG.md +++ b/plugins/circleci/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-circleci +## 0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.3.11-next.0 ### Patch Changes diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index d5f36ba7d6..a31158e0df 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.3.11-next.0", + "version": "0.3.11-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cloudbuild/CHANGELOG.md b/plugins/cloudbuild/CHANGELOG.md index bc83c46375..1f91ea1d5d 100644 --- a/plugins/cloudbuild/CHANGELOG.md +++ b/plugins/cloudbuild/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-cloudbuild +## 0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.3.11-next.0 ### Patch Changes diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index ee2cf54177..a50ded8d0f 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.3.11-next.0", + "version": "0.3.11-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-climate/CHANGELOG.md b/plugins/code-climate/CHANGELOG.md index 20965a33a5..b4f701f7fa 100644 --- a/plugins/code-climate/CHANGELOG.md +++ b/plugins/code-climate/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-code-climate +## 0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.1.11-next.0 ### Patch Changes diff --git a/plugins/code-climate/package.json b/plugins/code-climate/package.json index 735c5d2c5e..193842dc0e 100644 --- a/plugins/code-climate/package.json +++ b/plugins/code-climate/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-code-climate", - "version": "0.1.11-next.0", + "version": "0.1.11-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md index 251cfa1b33..d798c3ec74 100644 --- a/plugins/code-coverage-backend/CHANGELOG.md +++ b/plugins/code-coverage-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-code-coverage-backend +## 0.2.4-next.1 + +### Patch Changes + +- fcab2579a0: Adds installation instructions +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + ## 0.2.4-next.0 ### Patch Changes diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index 70be7268cf..5b8c925884 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage-backend", "description": "A Backstage backend plugin that helps you keep track of your code coverage", - "version": "0.2.4-next.0", + "version": "0.2.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-coverage/CHANGELOG.md b/plugins/code-coverage/CHANGELOG.md index 5ccbf4eed0..5a379e423f 100644 --- a/plugins/code-coverage/CHANGELOG.md +++ b/plugins/code-coverage/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-code-coverage +## 0.2.4-next.1 + +### Patch Changes + +- fcab2579a0: Adds installation instructions +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.2.4-next.0 ### Patch Changes diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 647c7d2fb0..357a4d9ebf 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.2.4-next.0", + "version": "0.2.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/codescene/CHANGELOG.md b/plugins/codescene/CHANGELOG.md index d21ec8c71d..7ddd7f5d4a 100644 --- a/plugins/codescene/CHANGELOG.md +++ b/plugins/codescene/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-codescene +## 0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + ## 0.1.6-next.0 ### Patch Changes diff --git a/plugins/codescene/package.json b/plugins/codescene/package.json index ffd297e8ed..f190c4db5a 100644 --- a/plugins/codescene/package.json +++ b/plugins/codescene/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-codescene", - "version": "0.1.6-next.0", + "version": "0.1.6-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index 6d62429875..f5f5872e55 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-config-schema +## 0.1.34-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + ## 0.1.34-next.0 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index b111738405..51ae7ed86b 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.34-next.0", + "version": "0.1.34-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md index ce062fa7e1..a7eb444f37 100644 --- a/plugins/cost-insights/CHANGELOG.md +++ b/plugins/cost-insights/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-cost-insights +## 0.12.0-next.1 + +### Patch Changes + +- e92aa15f01: Bumped `canvas` dependency to the latest version, which has better Node.js v18 support. +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-cost-insights-common@0.1.1 + ## 0.12.0-next.0 ### Minor Changes diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index aac87aa10f..9896c3e60e 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.12.0-next.0", + "version": "0.12.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/dynatrace/CHANGELOG.md b/plugins/dynatrace/CHANGELOG.md index 4ab45e9df6..9274a296db 100644 --- a/plugins/dynatrace/CHANGELOG.md +++ b/plugins/dynatrace/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-dynatrace +## 1.0.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 1.0.1-next.0 ### Patch Changes diff --git a/plugins/dynatrace/package.json b/plugins/dynatrace/package.json index bdd54bf865..3a973c6779 100644 --- a/plugins/dynatrace/package.json +++ b/plugins/dynatrace/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-dynatrace", - "version": "1.0.1-next.0", + "version": "1.0.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index df0c013892..90893229c8 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @internal/plugin-todo-list-backend +## 1.0.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + ## 1.0.7-next.0 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index 9d6419a76d..863de06e21 100644 --- a/plugins/example-todo-list-backend/package.json +++ b/plugins/example-todo-list-backend/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-backend", - "version": "1.0.7-next.0", + "version": "1.0.7-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/example-todo-list/CHANGELOG.md b/plugins/example-todo-list/CHANGELOG.md index f08094181d..3a692cede5 100644 --- a/plugins/example-todo-list/CHANGELOG.md +++ b/plugins/example-todo-list/CHANGELOG.md @@ -1,5 +1,14 @@ # @internal/plugin-todo-list +## 1.0.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + ## 1.0.7-next.0 ### Patch Changes diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index 0b12ae6208..cc3fb43222 100644 --- a/plugins/example-todo-list/package.json +++ b/plugins/example-todo-list/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list", - "version": "1.0.7-next.0", + "version": "1.0.7-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/explore/CHANGELOG.md b/plugins/explore/CHANGELOG.md index bc31cd1ec6..56a41c0e6a 100644 --- a/plugins/explore/CHANGELOG.md +++ b/plugins/explore/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-explore +## 0.3.42-next.1 + +### Patch Changes + +- 5c25ce6d9e: Added a section to explore plugin README that describes the customization of explore tools content. +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-explore-react@0.0.23-next.0 + ## 0.3.42-next.0 ### Patch Changes diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 7ff382b9ce..7924524c3c 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.42-next.0", + "version": "0.3.42-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/firehydrant/CHANGELOG.md b/plugins/firehydrant/CHANGELOG.md index cd01270cbe..f9c72f56e7 100644 --- a/plugins/firehydrant/CHANGELOG.md +++ b/plugins/firehydrant/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-firehydrant +## 0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.1.28-next.0 ### Patch Changes diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index 2c455fbd82..0a520c1928 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.28-next.0", + "version": "0.1.28-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/fossa/CHANGELOG.md b/plugins/fossa/CHANGELOG.md index bd43f4d7b8..b425da715a 100644 --- a/plugins/fossa/CHANGELOG.md +++ b/plugins/fossa/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-fossa +## 0.2.43-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.2.43-next.0 ### Patch Changes diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index 32d9da5146..1eb4bdf4a9 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.43-next.0", + "version": "0.2.43-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gcalendar/CHANGELOG.md b/plugins/gcalendar/CHANGELOG.md index 3e4cc2473c..cb9a289a56 100644 --- a/plugins/gcalendar/CHANGELOG.md +++ b/plugins/gcalendar/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-gcalendar +## 0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + ## 0.3.7-next.0 ### Patch Changes diff --git a/plugins/gcalendar/package.json b/plugins/gcalendar/package.json index c6f748c6a2..875958a9d9 100644 --- a/plugins/gcalendar/package.json +++ b/plugins/gcalendar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-gcalendar", - "version": "0.3.7-next.0", + "version": "0.3.7-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gcp-projects/CHANGELOG.md b/plugins/gcp-projects/CHANGELOG.md index 3e4f8df529..3046eccda2 100644 --- a/plugins/gcp-projects/CHANGELOG.md +++ b/plugins/gcp-projects/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-gcp-projects +## 0.3.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + ## 0.3.30-next.0 ### Patch Changes diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 6b1ea7a0d4..1209998237 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.30-next.0", + "version": "0.3.30-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/git-release-manager/CHANGELOG.md b/plugins/git-release-manager/CHANGELOG.md index 00b079b7cd..1ffb9f6b3a 100644 --- a/plugins/git-release-manager/CHANGELOG.md +++ b/plugins/git-release-manager/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-git-release-manager +## 0.3.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/theme@0.2.16 + ## 0.3.24-next.0 ### Patch Changes diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json index 9b3533d994..cad07ef6b8 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.24-next.0", + "version": "0.3.24-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md index b3570d20cf..9bbe18ff4d 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-github-actions +## 0.5.11-next.1 + +### Patch Changes + +- ed438a3ba5: Add error panel when the plugin fails. +- 0d6837ca4e: Fix wrong GitHub callback URL documentation +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.5.11-next.0 ### Patch Changes diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 8247c48fa5..444591bd5d 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.5.11-next.0", + "version": "0.5.11-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-deployments/CHANGELOG.md b/plugins/github-deployments/CHANGELOG.md index 0a9a4215df..e29edb4604 100644 --- a/plugins/github-deployments/CHANGELOG.md +++ b/plugins/github-deployments/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-github-deployments +## 0.1.42-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.1.42-next.0 ### Patch Changes diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index a25fab05db..10424aa926 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.42-next.0", + "version": "0.1.42-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-issues/CHANGELOG.md b/plugins/github-issues/CHANGELOG.md index a812495a5f..a1d5aeb0c6 100644 --- a/plugins/github-issues/CHANGELOG.md +++ b/plugins/github-issues/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-github-issues +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.2.0-next.0 ### Minor Changes diff --git a/plugins/github-issues/package.json b/plugins/github-issues/package.json index 3853e845a6..798ed54214 100644 --- a/plugins/github-issues/package.json +++ b/plugins/github-issues/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-github-issues", - "version": "0.2.0-next.0", + "version": "0.2.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-pull-requests-board/CHANGELOG.md b/plugins/github-pull-requests-board/CHANGELOG.md index a91ceae5f0..150a4c2ffb 100644 --- a/plugins/github-pull-requests-board/CHANGELOG.md +++ b/plugins/github-pull-requests-board/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-github-pull-requests-board +## 0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.1.5-next.0 ### Patch Changes diff --git a/plugins/github-pull-requests-board/package.json b/plugins/github-pull-requests-board/package.json index c6f58ebf0f..0932c6bd4b 100644 --- a/plugins/github-pull-requests-board/package.json +++ b/plugins/github-pull-requests-board/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-pull-requests-board", "description": "A Backstage plugin that allows you to see all open Pull Requests for all the repositories owned by your team", - "version": "0.1.5-next.0", + "version": "0.1.5-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gitops-profiles/CHANGELOG.md b/plugins/gitops-profiles/CHANGELOG.md index a578fe2077..ec3771c87f 100644 --- a/plugins/gitops-profiles/CHANGELOG.md +++ b/plugins/gitops-profiles/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-gitops-profiles +## 0.3.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + ## 0.3.29-next.0 ### Patch Changes diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index 000f1c4b6c..029a6ce5d6 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.29-next.0", + "version": "0.3.29-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gocd/CHANGELOG.md b/plugins/gocd/CHANGELOG.md index 4409bc5861..6fb6bee3c1 100644 --- a/plugins/gocd/CHANGELOG.md +++ b/plugins/gocd/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-gocd +## 0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.1.17-next.0 ### Patch Changes diff --git a/plugins/gocd/package.json b/plugins/gocd/package.json index e8ba4b9374..e16957a975 100644 --- a/plugins/gocd/package.json +++ b/plugins/gocd/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gocd", "description": "A Backstage plugin that integrates towards GoCD", - "version": "0.1.17-next.0", + "version": "0.1.17-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/graphiql/CHANGELOG.md b/plugins/graphiql/CHANGELOG.md index 912c4e972b..3dbf192aff 100644 --- a/plugins/graphiql/CHANGELOG.md +++ b/plugins/graphiql/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-graphiql +## 0.2.43-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + ## 0.2.43-next.0 ### Patch Changes diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 6f10a179a7..1103e9f718 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.43-next.0", + "version": "0.2.43-next.1", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/plugins/graphql-backend/CHANGELOG.md b/plugins/graphql-backend/CHANGELOG.md index 2fa54c680f..ed7bc2dbcf 100644 --- a/plugins/graphql-backend/CHANGELOG.md +++ b/plugins/graphql-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-graphql-backend +## 0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-catalog-graphql@0.3.15-next.0 + ## 0.1.28-next.0 ### Patch Changes diff --git a/plugins/graphql-backend/package.json b/plugins/graphql-backend/package.json index 70c8fb0c6f..61b18a493b 100644 --- a/plugins/graphql-backend/package.json +++ b/plugins/graphql-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphql-backend", "description": "An experimental Backstage backend plugin for GraphQL", - "version": "0.1.28-next.0", + "version": "0.1.28-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index b9c43b0af8..4e9dfbe22d 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-home +## 0.4.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-stack-overflow@0.1.7-next.1 + ## 0.4.27-next.0 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index 8c267f4d25..e1a31b0b65 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.27-next.0", + "version": "0.4.27-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/ilert/CHANGELOG.md b/plugins/ilert/CHANGELOG.md index d1810178cc..796b375801 100644 --- a/plugins/ilert/CHANGELOG.md +++ b/plugins/ilert/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-ilert +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.2.0-next.0 ### Minor Changes diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index 5399a19bd7..154f0e30fd 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.2.0-next.0", + "version": "0.2.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins-backend/CHANGELOG.md b/plugins/jenkins-backend/CHANGELOG.md index 54573cdaec..593c9d5b97 100644 --- a/plugins/jenkins-backend/CHANGELOG.md +++ b/plugins/jenkins-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-jenkins-backend +## 0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-jenkins-common@0.1.10-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + ## 0.1.28-next.0 ### Patch Changes diff --git a/plugins/jenkins-backend/package.json b/plugins/jenkins-backend/package.json index 3a7a930f95..756dda53ed 100644 --- a/plugins/jenkins-backend/package.json +++ b/plugins/jenkins-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins-backend", "description": "A Backstage backend plugin that integrates towards Jenkins", - "version": "0.1.28-next.0", + "version": "0.1.28-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins/CHANGELOG.md b/plugins/jenkins/CHANGELOG.md index 2a15d2917a..5c39dcadb2 100644 --- a/plugins/jenkins/CHANGELOG.md +++ b/plugins/jenkins/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-jenkins +## 0.7.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-jenkins-common@0.1.10-next.0 + ## 0.7.10-next.0 ### Patch Changes diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index a77f3d2439..2b3edf3d00 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.7.10-next.0", + "version": "0.7.10-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kafka-backend/CHANGELOG.md b/plugins/kafka-backend/CHANGELOG.md index 5999228785..bd93e4eccb 100644 --- a/plugins/kafka-backend/CHANGELOG.md +++ b/plugins/kafka-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-kafka-backend +## 0.2.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + ## 0.2.31-next.0 ### Patch Changes diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json index 096170dc7e..ec377ee5a9 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.31-next.0", + "version": "0.2.31-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kafka/CHANGELOG.md b/plugins/kafka/CHANGELOG.md index ec8563d64b..2cb4cb5a64 100644 --- a/plugins/kafka/CHANGELOG.md +++ b/plugins/kafka/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kafka +## 0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.3.11-next.0 ### Patch Changes diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index 0bcb7dfa24..21320f28da 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.3.11-next.0", + "version": "0.3.11-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index 804112324d..6420598fa5 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-kubernetes-backend +## 0.8.0-next.1 + +### Patch Changes + +- cfb30b700c: Pin `@kubernetes/client-node` version to `0.17.0`. +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-kubernetes-common@0.4.4-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + ## 0.8.0-next.0 ### Minor Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index ea6a1146a8..60112c41d1 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-backend", "description": "A Backstage backend plugin that integrates towards Kubernetes", - "version": "0.8.0-next.0", + "version": "0.8.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-common/CHANGELOG.md b/plugins/kubernetes-common/CHANGELOG.md index b85e3c00ee..3cacfd6037 100644 --- a/plugins/kubernetes-common/CHANGELOG.md +++ b/plugins/kubernetes-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-kubernetes-common +## 0.4.4-next.1 + +### Patch Changes + +- cfb30b700c: Pin `@kubernetes/client-node` version to `0.17.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.3-next.0 + ## 0.4.4-next.0 ### Patch Changes diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index 401341a0e8..627d642dde 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-common", "description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin", - "version": "0.4.4-next.0", + "version": "0.4.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index 2272804b22..f07b0d942c 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-kubernetes +## 0.7.4-next.1 + +### Patch Changes + +- cfb30b700c: Pin `@kubernetes/client-node` version to `0.17.0`. +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/plugin-kubernetes-common@0.4.4-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.7.4-next.0 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 0bed1a213b..09ce173b82 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.7.4-next.0", + "version": "0.7.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/lighthouse/CHANGELOG.md b/plugins/lighthouse/CHANGELOG.md index 8a5a1bee97..0600fff13e 100644 --- a/plugins/lighthouse/CHANGELOG.md +++ b/plugins/lighthouse/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-lighthouse +## 0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.3.11-next.0 ### Patch Changes diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 8c87e8eec3..5cc2071372 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.3.11-next.0", + "version": "0.3.11-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/newrelic-dashboard/CHANGELOG.md b/plugins/newrelic-dashboard/CHANGELOG.md index 81efe251d3..0db2b8cb32 100644 --- a/plugins/newrelic-dashboard/CHANGELOG.md +++ b/plugins/newrelic-dashboard/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-newrelic-dashboard +## 0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.2.4-next.0 ### Patch Changes diff --git a/plugins/newrelic-dashboard/package.json b/plugins/newrelic-dashboard/package.json index a8100bdd38..4daad1ff0b 100644 --- a/plugins/newrelic-dashboard/package.json +++ b/plugins/newrelic-dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-newrelic-dashboard", - "version": "0.2.4-next.0", + "version": "0.2.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/newrelic/CHANGELOG.md b/plugins/newrelic/CHANGELOG.md index 526010f2f8..35e97b5780 100644 --- a/plugins/newrelic/CHANGELOG.md +++ b/plugins/newrelic/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-newrelic +## 0.3.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + ## 0.3.29-next.0 ### Patch Changes diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index 0eedad1ced..325fde6c62 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.29-next.0", + "version": "0.3.29-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/org-react/CHANGELOG.md b/plugins/org-react/CHANGELOG.md new file mode 100644 index 0000000000..e009146419 --- /dev/null +++ b/plugins/org-react/CHANGELOG.md @@ -0,0 +1,17 @@ +# @backstage/plugin-org-react + +## 0.1.0-next.0 + +### Minor Changes + +- e96274f1fe: Implemented the org-react plugin, with it's first component being: a `GroupListPicker` component that will give the user the ability to choose a group + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index b7b87f9aca..7f500a09a7 100644 --- a/plugins/org-react/package.json +++ b/plugins/org-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org-react", - "version": "0.0.0", + "version": "0.1.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index 682da2da91..0b461c09d9 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-org +## 0.6.0-next.1 + +### Minor Changes + +- 0b11500151: Updates the User and Group Profile cards to add the links from the UserEntity or the GroupEntity + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.5.11-next.0 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index 507660f1a3..54d6f3f9c4 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.5.11-next.0", + "version": "0.6.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/pagerduty/CHANGELOG.md b/plugins/pagerduty/CHANGELOG.md index ec4a152a4d..56c004d3d8 100644 --- a/plugins/pagerduty/CHANGELOG.md +++ b/plugins/pagerduty/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-pagerduty +## 0.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.5.4-next.0 ### Patch Changes diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index 64ab795489..aa958e7f06 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.5.4-next.0", + "version": "0.5.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/periskop-backend/CHANGELOG.md b/plugins/periskop-backend/CHANGELOG.md index 63ca36cc60..cabf964815 100644 --- a/plugins/periskop-backend/CHANGELOG.md +++ b/plugins/periskop-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-periskop-backend +## 0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + ## 0.1.9-next.0 ### Patch Changes diff --git a/plugins/periskop-backend/package.json b/plugins/periskop-backend/package.json index 3a91af5252..bda4c40d86 100644 --- a/plugins/periskop-backend/package.json +++ b/plugins/periskop-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop-backend", - "version": "0.1.9-next.0", + "version": "0.1.9-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/periskop/CHANGELOG.md b/plugins/periskop/CHANGELOG.md index afec1859f2..fa639ab4b0 100644 --- a/plugins/periskop/CHANGELOG.md +++ b/plugins/periskop/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-periskop +## 0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.1.9-next.0 ### Patch Changes diff --git a/plugins/periskop/package.json b/plugins/periskop/package.json index 53971e9930..e86bb4de5f 100644 --- a/plugins/periskop/package.json +++ b/plugins/periskop/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop", - "version": "0.1.9-next.0", + "version": "0.1.9-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md index d57c79ca08..31bd75e948 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-permission-backend +## 0.5.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/plugin-permission-node@0.7.1-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + ## 0.5.13-next.0 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 16351d26b9..8a31c60716 100644 --- a/plugins/permission-backend/package.json +++ b/plugins/permission-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-backend", - "version": "0.5.13-next.0", + "version": "0.5.13-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md index 2d31993117..2c2759ff95 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-permission-node +## 0.7.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + ## 0.7.1-next.0 ### Patch Changes diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index 33baf825ac..c462575627 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-node", "description": "Common permission and authorization utilities for backend plugins", - "version": "0.7.1-next.0", + "version": "0.7.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/playlist-backend/CHANGELOG.md b/plugins/playlist-backend/CHANGELOG.md index 9798c12013..a892d6a8dc 100644 --- a/plugins/playlist-backend/CHANGELOG.md +++ b/plugins/playlist-backend/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-playlist-backend +## 0.2.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-test-utils@0.1.30-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/plugin-permission-node@0.7.1-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-playlist-common@0.1.2-next.0 + ## 0.2.1-next.1 ### Patch Changes diff --git a/plugins/playlist-backend/package.json b/plugins/playlist-backend/package.json index 8548a3e4b8..7997d72711 100644 --- a/plugins/playlist-backend/package.json +++ b/plugins/playlist-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist-backend", - "version": "0.2.1-next.1", + "version": "0.2.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/playlist/CHANGELOG.md b/plugins/playlist/CHANGELOG.md index d7135e79a0..f49f0c6301 100644 --- a/plugins/playlist/CHANGELOG.md +++ b/plugins/playlist/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-playlist +## 0.1.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-permission-react@0.4.7-next.0 + - @backstage/plugin-playlist-common@0.1.2-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + ## 0.1.2-next.1 ### Patch Changes diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index e8fc47a2a9..5fc21a733a 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist", - "version": "0.1.2-next.1", + "version": "0.1.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index 91c3419ccd..2688a5b6c2 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-proxy-backend +## 0.2.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + ## 0.2.32-next.0 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 2deee67f17..c68fe15c4f 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-proxy-backend", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", - "version": "0.2.32-next.0", + "version": "0.2.32-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/rollbar-backend/CHANGELOG.md b/plugins/rollbar-backend/CHANGELOG.md index 962b167902..bcf422ffcf 100644 --- a/plugins/rollbar-backend/CHANGELOG.md +++ b/plugins/rollbar-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-rollbar-backend +## 0.1.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + ## 0.1.35-next.0 ### Patch Changes diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index 0fb2c0a4e0..8265dde9f0 100644 --- a/plugins/rollbar-backend/package.json +++ b/plugins/rollbar-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar-backend", "description": "A Backstage backend plugin that integrates towards Rollbar", - "version": "0.1.35-next.0", + "version": "0.1.35-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/rollbar/CHANGELOG.md b/plugins/rollbar/CHANGELOG.md index 340e06d265..dc2a34ac3b 100644 --- a/plugins/rollbar/CHANGELOG.md +++ b/plugins/rollbar/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-rollbar +## 0.4.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.4.11-next.0 ### Patch Changes diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index 1c4b585f5f..a2627ae7d1 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.4.11-next.0", + "version": "0.4.11-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index 37d00c6885..35f52ccfaf 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.2.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-scaffolder-backend@1.8.0-next.2 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.2.13-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index 939e2801da..0cc04104c0 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", - "version": "0.2.13-next.1", + "version": "0.2.13-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index 65f0b6cc49..7917e73068 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.4.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-scaffolder-backend@1.8.0-next.2 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.4.6-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index 8f39024301..d7561788d8 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", "description": "A module for the scaffolder backend that lets you template projects using Rails", - "version": "0.4.6-next.1", + "version": "0.4.6-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index 56cc580bbd..2019b9a0a4 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.0-next.2 + - @backstage/config@1.0.4-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.2.11-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index cf7a13a7a4..be16e9b508 100644 --- a/plugins/scaffolder-backend-module-yeoman/package.json +++ b/plugins/scaffolder-backend-module-yeoman/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-yeoman", - "version": "0.2.11-next.1", + "version": "0.2.11-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 0a86b5e9bb..1a0135f5f6 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-scaffolder-backend +## 1.8.0-next.2 + +### Minor Changes + +- 5025d2e8b6: Adds the ability to pass (an optional) array of strings that will be applied to the newly scaffolded repository as topic labels. + +### Patch Changes + +- 969a8444ea: Updated dependency `esbuild` to `^0.15.0`. +- 9ff4ff3745: Implement "Branch protection rules" support for "publish:github" action +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-plugin-api@0.1.4-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/plugin-catalog-backend@1.5.1-next.1 + - @backstage/plugin-catalog-node@1.2.1-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-scaffolder-common@1.2.2-next.0 + ## 1.8.0-next.1 ### Minor Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 816704705e..45300224c7 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": "1.8.0-next.1", + "version": "1.8.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index 709809f5f7..42c911e511 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-scaffolder +## 1.8.0-next.1 + +### Patch Changes + +- 580285787d: The `create` and `click` analytics events are now also captured on the "next" version of the component creation page. +- 3b3fc3cc3c: Fix `formData` not being present in the `next` version +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-permission-react@0.4.7-next.0 + - @backstage/plugin-scaffolder-common@1.2.2-next.0 + ## 1.8.0-next.0 ### Minor Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index cfa69c128a..399c86bfd5 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": "1.8.0-next.0", + "version": "1.8.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index 30a3367bf4..d2dbb132d1 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.0.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.0.4-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + ## 1.0.4-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index a45c3c43e5..63735691a3 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", "description": "A module for the search backend that implements search using ElasticSearch", - "version": "1.0.4-next.0", + "version": "1.0.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index dcd0bbdc78..cc2c25de46 100644 --- a/plugins/search-backend-module-pg/CHANGELOG.md +++ b/plugins/search-backend-module-pg/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-search-backend-module-pg +## 0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-search-backend-node@1.0.4-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + ## 0.4.2-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 5e91bfabeb..d89c2cdcda 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-pg", "description": "A module for the search backend that implements search using PostgreSQL", - "version": "0.4.2-next.0", + "version": "0.4.2-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index bfcd09dcad..4a8bb84934 100644 --- a/plugins/search-backend-node/CHANGELOG.md +++ b/plugins/search-backend-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-node +## 1.0.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + ## 1.0.4-next.0 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index a0c4964ccf..5d8e08d661 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-node", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", - "version": "1.0.4-next.0", + "version": "1.0.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index c2cc89ac5b..c52b2fe13e 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-search-backend +## 1.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/plugin-permission-node@0.7.1-next.1 + - @backstage/plugin-search-backend-node@1.0.4-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + ## 1.1.1-next.0 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index d221cf1ea5..4ea9db283c 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend", "description": "The Backstage backend plugin that provides your backstage app with search", - "version": "1.1.1-next.0", + "version": "1.1.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index d5f100d97c..043d87828f 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-react +## 1.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + - @backstage/version-bridge@1.0.1 + - @backstage/plugin-search-common@1.1.1-next.0 + ## 1.2.1-next.0 ### Patch Changes diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 7097d8fa4e..3d8fa634d4 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-react", - "version": "1.2.1-next.0", + "version": "1.2.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index 5e71299d1e..a673a8c2b1 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-search +## 1.0.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + - @backstage/version-bridge@1.0.1 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + ## 1.0.4-next.0 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index 7d0f6d4f52..7d4dad7e2c 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": "1.0.4-next.0", + "version": "1.0.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sentry/CHANGELOG.md b/plugins/sentry/CHANGELOG.md index 661950e6ca..da4ab7914d 100644 --- a/plugins/sentry/CHANGELOG.md +++ b/plugins/sentry/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-sentry +## 0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.4.4-next.0 ### Patch Changes diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index 190e9b048b..99f63f83f6 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.4.4-next.0", + "version": "0.4.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/shortcuts/CHANGELOG.md b/plugins/shortcuts/CHANGELOG.md index e918aa8608..26da68d31e 100644 --- a/plugins/shortcuts/CHANGELOG.md +++ b/plugins/shortcuts/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-shortcuts +## 0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + ## 0.3.3-next.0 ### Patch Changes diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index 2bd0204af7..6f3971458e 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.3.3-next.0", + "version": "0.3.3-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sonarqube-backend/CHANGELOG.md b/plugins/sonarqube-backend/CHANGELOG.md index e752ee9a2b..30a02a3f2f 100644 --- a/plugins/sonarqube-backend/CHANGELOG.md +++ b/plugins/sonarqube-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-sonarqube-backend +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + ## 0.1.3-next.0 ### Patch Changes diff --git a/plugins/sonarqube-backend/package.json b/plugins/sonarqube-backend/package.json index 59f02b2950..2f6dad8fd6 100644 --- a/plugins/sonarqube-backend/package.json +++ b/plugins/sonarqube-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sonarqube-backend", - "version": "0.1.3-next.0", + "version": "0.1.3-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sonarqube/CHANGELOG.md b/plugins/sonarqube/CHANGELOG.md index dd5aa80817..0839fd4009 100644 --- a/plugins/sonarqube/CHANGELOG.md +++ b/plugins/sonarqube/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-sonarqube +## 0.4.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.4.3-next.0 ### Patch Changes diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index b46cb5c0b1..a731150dd9 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sonarqube", "description": "", - "version": "0.4.3-next.0", + "version": "0.4.3-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/splunk-on-call/CHANGELOG.md b/plugins/splunk-on-call/CHANGELOG.md index 02a736b782..c4bc4eca7e 100644 --- a/plugins/splunk-on-call/CHANGELOG.md +++ b/plugins/splunk-on-call/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-splunk-on-call +## 0.4.0-next.1 + +### Minor Changes + +- 34b772ef31: Use the routing key if it's available instead of team name when triggering incidents. + + BREAKING CHANGE: + Before, the team name was used even if the routing key (with or without team) was used. + Now, the routing key defined for the component will be used instead of the team name. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.3.35-next.0 ### Patch Changes diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index 0434c7b07b..fc415994d3 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.35-next.0", + "version": "0.4.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/stack-overflow-backend/CHANGELOG.md b/plugins/stack-overflow-backend/CHANGELOG.md index 50b989079a..e1e06fc69e 100644 --- a/plugins/stack-overflow-backend/CHANGELOG.md +++ b/plugins/stack-overflow-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-stack-overflow-backend +## 0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.21.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + ## 0.1.7-next.0 ### Patch Changes diff --git a/plugins/stack-overflow-backend/package.json b/plugins/stack-overflow-backend/package.json index 4714c29551..34203bb2f7 100644 --- a/plugins/stack-overflow-backend/package.json +++ b/plugins/stack-overflow-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow-backend", - "version": "0.1.7-next.0", + "version": "0.1.7-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/stack-overflow/CHANGELOG.md b/plugins/stack-overflow/CHANGELOG.md index a725475f69..0d68732761 100644 --- a/plugins/stack-overflow/CHANGELOG.md +++ b/plugins/stack-overflow/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-stack-overflow +## 0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-home@0.4.27-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + ## 0.1.7-next.0 ### Patch Changes diff --git a/plugins/stack-overflow/package.json b/plugins/stack-overflow/package.json index 2b0910bbae..185ed36ccd 100644 --- a/plugins/stack-overflow/package.json +++ b/plugins/stack-overflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow", - "version": "0.1.7-next.0", + "version": "0.1.7-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md index 84a682dc8e..73e429cc3a 100644 --- a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md +++ b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-tech-insights-backend-module-jsonfc +## 0.1.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-tech-insights-node@0.3.6-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/plugin-tech-insights-common@0.2.8-next.0 + ## 0.1.22-next.0 ### Patch Changes diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json index 9a811bc65a..51e2e56f84 100644 --- a/plugins/tech-insights-backend-module-jsonfc/package.json +++ b/plugins/tech-insights-backend-module-jsonfc/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend-module-jsonfc", - "version": "0.1.22-next.0", + "version": "0.1.22-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-backend/CHANGELOG.md b/plugins/tech-insights-backend/CHANGELOG.md index b39c640ddb..d48694aa11 100644 --- a/plugins/tech-insights-backend/CHANGELOG.md +++ b/plugins/tech-insights-backend/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-tech-insights-backend +## 0.5.4-next.1 + +### Patch Changes + +- f12e9e5b8c: Add Documentation on 404 Errors +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/plugin-tech-insights-node@0.3.6-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-tech-insights-common@0.2.8-next.0 + ## 0.5.4-next.0 ### Patch Changes diff --git a/plugins/tech-insights-backend/package.json b/plugins/tech-insights-backend/package.json index 6d42c1aecc..9d87dc38a2 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.5.4-next.0", + "version": "0.5.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-node/CHANGELOG.md b/plugins/tech-insights-node/CHANGELOG.md index 8173dbc132..4fa01df31c 100644 --- a/plugins/tech-insights-node/CHANGELOG.md +++ b/plugins/tech-insights-node/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-tech-insights-node +## 0.3.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-tech-insights-common@0.2.8-next.0 + ## 0.3.6-next.0 ### Patch Changes diff --git a/plugins/tech-insights-node/package.json b/plugins/tech-insights-node/package.json index 7300089744..7628e3816e 100644 --- a/plugins/tech-insights-node/package.json +++ b/plugins/tech-insights-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-node", - "version": "0.3.6-next.0", + "version": "0.3.6-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights/CHANGELOG.md b/plugins/tech-insights/CHANGELOG.md index f60027e045..924bd3450d 100644 --- a/plugins/tech-insights/CHANGELOG.md +++ b/plugins/tech-insights/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-tech-insights +## 0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-tech-insights-common@0.2.8-next.0 + ## 0.3.2-next.0 ### Patch Changes diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index cb9def285e..be79cb2c14 100644 --- a/plugins/tech-insights/package.json +++ b/plugins/tech-insights/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights", - "version": "0.3.2-next.0", + "version": "0.3.3-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-radar/CHANGELOG.md b/plugins/tech-radar/CHANGELOG.md index df5bee360a..5a028de613 100644 --- a/plugins/tech-radar/CHANGELOG.md +++ b/plugins/tech-radar/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-tech-radar +## 0.5.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/theme@0.2.16 + ## 0.5.18-next.0 ### Patch Changes diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index a4dd1f0848..b04d50a7c8 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.5.18-next.0", + "version": "0.5.18-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index ba3141919a..4e9bedff96 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.4.0-next.2 + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-app-api@1.2.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/test-utils@1.2.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog@1.6.1-next.1 + - @backstage/plugin-search-react@1.2.1-next.1 + - @backstage/plugin-techdocs-react@1.0.6-next.1 + ## 1.0.6-next.1 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index a7b6abd782..425ece8faf 100644 --- a/plugins/techdocs-addons-test-utils/package.json +++ b/plugins/techdocs-addons-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-addons-test-utils", - "version": "1.0.6-next.1", + "version": "1.0.6-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index b038fa202f..dce071d223 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-techdocs-backend +## 1.4.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-techdocs-node@1.4.2-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/plugin-catalog-common@1.0.8-next.0 + - @backstage/plugin-permission-common@0.7.1-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + ## 1.4.1-next.0 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 5e74c47d3c..736c409af5 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": "1.4.1-next.0", + "version": "1.4.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index c56e9cbf12..33139a90ed 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.0.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-techdocs-react@1.0.6-next.1 + ## 1.0.6-next.0 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index 782273e8c0..c06425f27a 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", "description": "Plugin module for contributed TechDocs Addons", - "version": "1.0.6-next.0", + "version": "1.0.6-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index cc8770c34b..cddc42e91b 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-techdocs-node +## 1.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/plugin-search-common@1.1.1-next.0 + ## 1.4.2-next.0 ### Patch Changes diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index eef2da8ccb..b43e5eed82 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-node", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", - "version": "1.4.2-next.0", + "version": "1.4.2-next.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index 9418517a6c..5c5b289d77 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-techdocs-react +## 1.0.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/version-bridge@1.0.1 + ## 1.0.6-next.0 ### Patch Changes diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index d7ff40bed8..9dead41490 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-react", "description": "Shared frontend utilities for TechDocs and Addons", - "version": "1.0.6-next.0", + "version": "1.0.6-next.1", "publishConfig": { "access": "public", "alphaTypes": "dist/index.alpha.d.ts", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index d146a4d576..3ed95372a4 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-techdocs +## 1.4.0-next.2 + +### Patch Changes + +- e92aa15f01: Bumped `canvas` dependency to the latest version, which has better Node.js v18 support. +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + - @backstage/plugin-techdocs-react@1.0.6-next.1 + ## 1.4.0-next.1 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 9eb6f6af3a..e36eeba8ef 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": "1.4.0-next.1", + "version": "1.4.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/todo-backend/CHANGELOG.md b/plugins/todo-backend/CHANGELOG.md index f4827591df..47b3b3d42b 100644 --- a/plugins/todo-backend/CHANGELOG.md +++ b/plugins/todo-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-todo-backend +## 0.1.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/catalog-client@1.1.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + ## 0.1.35-next.0 ### Patch Changes diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index ae227478b6..9318e10d0a 100644 --- a/plugins/todo-backend/package.json +++ b/plugins/todo-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo-backend", "description": "A Backstage backend plugin that lets you browse TODO comments in your source code", - "version": "0.1.35-next.0", + "version": "0.1.35-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/todo/CHANGELOG.md b/plugins/todo/CHANGELOG.md index c97576555d..8729bc8ee7 100644 --- a/plugins/todo/CHANGELOG.md +++ b/plugins/todo/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-todo +## 0.2.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.2.13-next.0 ### Patch Changes diff --git a/plugins/todo/package.json b/plugins/todo/package.json index c5cd8df216..04aec7ea7c 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.2.13-next.0", + "version": "0.2.13-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index 54a75f3888..fef6843ff0 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-user-settings-backend +## 0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-auth-node@0.2.7-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/types@1.0.1-next.0 + ## 0.1.2-next.0 ### Patch Changes diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index 5015b60456..b648159b9c 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings-backend", "description": "The Backstage backend plugin to manage user settings", - "version": "0.1.2-next.0", + "version": "0.1.2-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index d73d533cba..f81cbbe831 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-user-settings +## 0.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-app-api@1.2.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/types@1.0.1-next.0 + ## 0.5.1-next.0 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 744cf40eec..56b9601091 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.5.1-next.0", + "version": "0.5.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/vault-backend/CHANGELOG.md b/plugins/vault-backend/CHANGELOG.md index 6f3270dba1..02986aff92 100644 --- a/plugins/vault-backend/CHANGELOG.md +++ b/plugins/vault-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-vault-backend +## 0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/backend-tasks@0.3.7-next.1 + - @backstage/backend-test-utils@0.1.30-next.1 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + ## 0.2.4-next.0 ### Patch Changes diff --git a/plugins/vault-backend/package.json b/plugins/vault-backend/package.json index 2cc170337a..219ccbb319 100644 --- a/plugins/vault-backend/package.json +++ b/plugins/vault-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault-backend", "description": "A Backstage backend plugin that integrates towards Vault", - "version": "0.2.4-next.0", + "version": "0.2.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/vault/CHANGELOG.md b/plugins/vault/CHANGELOG.md index ce0f6c41cf..ec9b7bf25f 100644 --- a/plugins/vault/CHANGELOG.md +++ b/plugins/vault/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-vault +## 0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + ## 0.1.5-next.0 ### Patch Changes diff --git a/plugins/vault/package.json b/plugins/vault/package.json index dc5e7b0c13..37a8bd6805 100644 --- a/plugins/vault/package.json +++ b/plugins/vault/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault", "description": "A Backstage plugin that integrates towards Vault", - "version": "0.1.5-next.0", + "version": "0.1.5-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/xcmetrics/CHANGELOG.md b/plugins/xcmetrics/CHANGELOG.md index 8c68404127..cc7938df81 100644 --- a/plugins/xcmetrics/CHANGELOG.md +++ b/plugins/xcmetrics/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-xcmetrics +## 0.2.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + ## 0.2.31-next.0 ### Patch Changes diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index 6946095a01..b4d575535c 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.31-next.0", + "version": "0.2.31-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", From bef063dc8d39b730fb2c4ba1669e1157703985d2 Mon Sep 17 00:00:00 2001 From: Scott Guymer Date: Tue, 8 Nov 2022 14:58:55 +0100 Subject: [PATCH 224/434] feat: Enable User and Team transformers in GitHub Provider Introduces the ability to use custom transformers to generate entities from GitHub users and teams. Meaning you can now transform them however you like as they are being imported. Signed-off-by: Scott Guymer --- .changeset/proud-queens-warn.md | 5 + docs/integrations/github/org.md | 60 ++++ .../api-report.md | 57 ++++ .../src/index.ts | 19 +- .../src/lib/defaultTransformers.ts | 127 ++++++++ .../src/lib/github.test.ts | 297 +++++++++++++++++- .../src/lib/github.ts | 196 ++++++------ .../src/lib/index.ts | 9 + .../src/lib/org.test.ts | 46 ++- .../src/lib/org.ts | 11 +- .../GithubMultiOrgReaderProcessor.ts | 26 +- .../processors/GithubOrgReaderProcessor.ts | 7 +- ...Provider.ts => GitHubOrgEntityProvider.ts} | 28 +- .../src/providers/GithubEntityProvider.ts | 8 +- .../providers/GithubOrgEntityProvider.test.ts | 1 + 15 files changed, 744 insertions(+), 153 deletions(-) create mode 100644 .changeset/proud-queens-warn.md create mode 100644 plugins/catalog-backend-module-github/src/lib/defaultTransformers.ts rename plugins/catalog-backend-module-github/src/providers/{GithubOrgEntityProvider.ts => GitHubOrgEntityProvider.ts} (90%) diff --git a/.changeset/proud-queens-warn.md b/.changeset/proud-queens-warn.md new file mode 100644 index 0000000000..0eb133f290 --- /dev/null +++ b/.changeset/proud-queens-warn.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-github': patch +--- + +- Make it possible to inject custom user and team transformers when configuring the `GithubOrgEntityProvider` diff --git a/docs/integrations/github/org.md b/docs/integrations/github/org.md index 8212c254d7..9e3c450adc 100644 --- a/docs/integrations/github/org.md +++ b/docs/integrations/github/org.md @@ -97,6 +97,66 @@ that must be approved first before the changes are applied.** ![email](../../assets/integrations/github/email.png) +### Custom Transformers + +You can inject your own transformation logic to help map from GH API responses +into backstage entities. You can do this on the user and team requests to +enable you to do further processing or updates to the entities. + +To enable this you pass a function into the `GitHubOrgEntityProvider`. You can +pass a `UserTransformer`, `TeamTransformer` or both. The function is invoked +for each item (user or team) that is returned from the API. You can either +return an Entity (User or Group) or `undefined` if you do not want to import +that item. + +There is also a `defaultUserTransformer` and `defaultOrganizationTeamTransformer`. +You could use these and simply decorate the response from the default +transformation if you only need to change a few properties. + +### Resolving GitHub users via organization email + +When you authenticate users you should resolve them to an entity within the +catalog. Often the authentication you use could be a corporate SSO system that +provides you with email as a key. To enable you to find and resolve GitHub users +it's useful to also import the private domain verified emails into the User +entity in backstage. + +The integration attempts to return `organizationVerifiedDomainEmails` from the +GitHub API and makes this available as part of the object passed to +`UserTransformer`. The GitHub API will only return emails that use a domain +that's a verified domain for your GitHub Org. It also relies on the user having +configured such an email in their own account. The API will only return these +values when using GitHub App authentication and with the correct app permission +allowing access to emails. + +You can decorate the `defaultUserTransformer` to replace the org email in the +returned identity. + +```typescript +async (user, ctx): Promise => { + const entity = await defaultUserTransformer(user, ctx); + + if (entity && user.organizationVerifiedDomainEmails) { + entity.spec.profile!.email = user.organizationVerifiedDomainEmails[0] || ''; + } + + return entity; +}, +``` + +Once you have imported the emails you can resolve users in your sign-in in +resolver using the catalog entity search via email + +```typescript +// packages/backend/src/plugins/auth.ts +ctx.signInWithCatalogUser({ + filter: { + kind: ['User'], + 'spec.profile.email': email as string, + }, +}); +``` + ## Using a Processor instead of a Provider An alternative to using the Provider for ingesting organizational entities is to diff --git a/plugins/catalog-backend-module-github/api-report.md b/plugins/catalog-backend-module-github/api-report.md index a9587e172b..ea6bc9e0ea 100644 --- a/plugins/catalog-backend-module-github/api-report.md +++ b/plugins/catalog-backend-module-github/api-report.md @@ -13,6 +13,8 @@ import { EntityProvider } from '@backstage/plugin-catalog-backend'; import { EntityProviderConnection } from '@backstage/plugin-catalog-backend'; import { GithubCredentialsProvider } from '@backstage/integration'; import { GithubIntegrationConfig } from '@backstage/integration'; +import { graphql } from '@octokit/graphql'; +import { GroupEntity } from '@backstage/catalog-model'; import { LocationSpec } from '@backstage/plugin-catalog-backend'; import { Logger } from 'winston'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; @@ -21,6 +23,13 @@ import { ScmIntegrationRegistry } from '@backstage/integration'; import { ScmLocationAnalyzer } from '@backstage/plugin-catalog-backend'; import { TaskRunner } from '@backstage/backend-tasks'; import { TokenManager } from '@backstage/backend-common'; +import { UserEntity } from '@backstage/catalog-model'; + +// @public +export const defaultOrganizationTeamTransformer: TeamTransformer; + +// @public +export const defaultUserTransformer: UserTransformer; // @public export class GithubDiscoveryProcessor implements CatalogProcessor { @@ -165,6 +174,8 @@ export class GithubOrgEntityProvider implements EntityProvider { gitHubConfig: GithubIntegrationConfig; logger: Logger; githubCredentialsProvider?: GithubCredentialsProvider; + userTransformer?: UserTransformer; + teamTransformer?: TeamTransformer; }); // (undocumented) connect(connection: EntityProviderConnection): Promise; @@ -188,6 +199,8 @@ export interface GithubOrgEntityProviderOptions { logger: Logger; orgUrl: string; schedule?: 'manual' | TaskRunner; + teamTransformer?: TeamTransformer; + userTransformer?: UserTransformer; } // @public @@ -214,4 +227,48 @@ export class GithubOrgReaderProcessor implements CatalogProcessor { emit: CatalogProcessorEmit, ): Promise; } + +// @public +export type GithubTeam = { + slug: string; + combinedSlug: string; + name?: string; + description?: string; + avatarUrl?: string; + editTeamUrl?: string; + parentTeam?: GithubTeam; + members: GithubUser[]; +}; + +// @public +export type GithubUser = { + login: string; + bio?: string; + avatarUrl?: string; + email?: string; + name?: string; + organizationVerifiedDomainEmails?: string[]; +}; + +// @public +export type TeamTransformer = ( + item: GithubTeam, + ctx: TransformerContext, +) => Promise; + +// @public +export interface TransformerContext { + // (undocumented) + client: typeof graphql; + // (undocumented) + org: string; + // (undocumented) + query: string; +} + +// @public +export type UserTransformer = ( + item: GithubUser, + ctx: TransformerContext, +) => Promise; ``` diff --git a/plugins/catalog-backend-module-github/src/index.ts b/plugins/catalog-backend-module-github/src/index.ts index f38035db15..5e2e55fc24 100644 --- a/plugins/catalog-backend-module-github/src/index.ts +++ b/plugins/catalog-backend-module-github/src/index.ts @@ -15,20 +15,31 @@ */ /** - * A Backstage catalog backend module that helps integrate towards GitHub + * A Backstage catalog backend module that helps integrate towards Github * * @packageDocumentation */ export { GithubLocationAnalyzer } from './analyzers/GithubLocationAnalyzer'; export type { GithubLocationAnalyzerOptions } from './analyzers/GithubLocationAnalyzer'; -export type { GithubMultiOrgConfig } from './lib'; export { GithubDiscoveryProcessor } from './processors/GithubDiscoveryProcessor'; export { GithubMultiOrgReaderProcessor } from './processors/GithubMultiOrgReaderProcessor'; export { GithubOrgReaderProcessor } from './processors/GithubOrgReaderProcessor'; export { GithubEntityProvider } from './providers/GithubEntityProvider'; -export { GithubOrgEntityProvider } from './providers/GithubOrgEntityProvider'; -export type { GithubOrgEntityProviderOptions } from './providers/GithubOrgEntityProvider'; +export type { + GithubOrgEntityProvider, + GithubOrgEntityProviderOptions, +} from './providers/GithubOrgEntityProvider'; export { githubEntityProviderCatalogModule } from './service/GithubEntityProviderCatalogModule'; +export { + type GithubMultiOrgConfig, + type GithubTeam, + type GithubUser, + type UserTransformer, + defaultUserTransformer, + type TeamTransformer, + defaultOrganizationTeamTransformer, + type TransformerContext, +} from './lib'; export * from './deprecated'; diff --git a/plugins/catalog-backend-module-github/src/lib/defaultTransformers.ts b/plugins/catalog-backend-module-github/src/lib/defaultTransformers.ts new file mode 100644 index 0000000000..efd3eedd5d --- /dev/null +++ b/plugins/catalog-backend-module-github/src/lib/defaultTransformers.ts @@ -0,0 +1,127 @@ +/* + * Copyright 2020 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 { GroupEntity, UserEntity } from '@backstage/catalog-model'; +import { graphql } from '@octokit/graphql'; +import { GithubTeam, GithubUser } from './github'; + +/** + * Context passed to Transformers + * + * @public + */ +export interface TransformerContext { + client: typeof graphql; + query: string; + org: string; +} + +/** + * Transformer for GitHub users to UserEntity + * + * @public + */ +export type UserTransformer = ( + item: GithubUser, + ctx: TransformerContext, +) => Promise; + +/** + * Transformer for GitHub Team to GroupEntity + * + * @public + */ +export type TeamTransformer = ( + item: GithubTeam, + ctx: TransformerContext, +) => Promise; + +/** + * Default transformer for GitHub users to UserEntity + * + * @public + */ +export const defaultUserTransformer: UserTransformer = async ( + item: GithubUser, +) => { + const entity: UserEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + name: item.login, + annotations: { + 'github.com/user-login': item.login, + }, + }, + spec: { + profile: {}, + memberOf: [], + }, + }; + + if (item.bio) entity.metadata.description = item.bio; + if (item.name) entity.spec.profile!.displayName = item.name; + if (item.email) entity.spec.profile!.email = item.email; + if (item.avatarUrl) entity.spec.profile!.picture = item.avatarUrl; + return entity; +}; + +/** + * Default transformer for GitHub Team to GroupEntity + * + * @public + */ +export const defaultOrganizationTeamTransformer: TeamTransformer = + async team => { + const annotations: { [annotationName: string]: string } = { + 'github.com/team-slug': team.combinedSlug, + }; + + if (team.editTeamUrl) { + annotations['backstage.io/edit-url'] = team.editTeamUrl; + } + + const entity: GroupEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: team.slug, + annotations, + }, + spec: { + type: 'team', + profile: {}, + children: [], + }, + }; + + if (team.description) { + entity.metadata.description = team.description; + } + if (team.name) { + entity.spec.profile!.displayName = team.name; + } + if (team.avatarUrl) { + entity.spec.profile!.picture = team.avatarUrl; + } + if (team.parentTeam) { + entity.spec.parent = team.parentTeam.slug; + } + + entity.spec.members = team.members.map(user => user.login); + + return entity; + }; diff --git a/plugins/catalog-backend-module-github/src/lib/github.test.ts b/plugins/catalog-backend-module-github/src/lib/github.test.ts index 0002c4cef0..d07d2f6af8 100644 --- a/plugins/catalog-backend-module-github/src/lib/github.test.ts +++ b/plugins/catalog-backend-module-github/src/lib/github.test.ts @@ -15,15 +15,20 @@ */ import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { GroupEntity, UserEntity } from '@backstage/catalog-model'; import { graphql } from '@octokit/graphql'; import { graphql as graphqlMsw } from 'msw'; import { setupServer } from 'msw/node'; +import { TeamTransformer, UserTransformer } from './defaultTransformers'; + import { getOrganizationTeams, getOrganizationUsers, getTeamMembers, getOrganizationRepositories, QueryResponse, + GithubUser, + GithubTeam, } from './github'; import fetch from 'node-fetch'; @@ -35,7 +40,7 @@ describe('github', () => { const server = setupServer(); setupRequestMockHandlers(server); - describe('getOrganizationUsers', () => { + describe('getOrganizationUsers using defaultUserMapper', () => { it('reads members', async () => { const input: QueryResponse = { organization: { @@ -76,7 +81,120 @@ describe('github', () => { }); }); - describe('getOrganizationTeams', () => { + describe('getOrganizationUsers using custom UserTransformer', () => { + const customUserTransformer: UserTransformer = async ( + item: GithubUser, + {}, + ) => { + if (item.login === 'aa') { + return undefined; + } + + return { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + name: `${item.login}-custom`, + annotations: { + 'github.com/user-login': item.login, + }, + }, + spec: { + profile: {}, + memberOf: [], + }, + } as UserEntity; + }; + + it('reads members', async () => { + const input: QueryResponse = { + organization: { + membersWithRole: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + login: 'a', + name: 'b', + bio: 'c', + email: 'd', + avatarUrl: 'e', + }, + ], + }, + }, + }; + + const output = { + users: [ + expect.objectContaining({ + metadata: expect.objectContaining({ + name: 'a-custom', + }), + }), + ], + }; + + server.use( + graphqlMsw.query('users', (_req, res, ctx) => res(ctx.data(input))), + ); + + await expect( + getOrganizationUsers(graphql, 'a', 'token', customUserTransformer), + ).resolves.toEqual(output); + }); + + it('reads members if undefined is returned from transformer', async () => { + const input: QueryResponse = { + organization: { + membersWithRole: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + login: 'a', + name: 'b', + bio: 'c', + email: 'd', + avatarUrl: 'e', + }, + { + login: 'aa', + name: 'bb', + bio: 'cc', + email: 'dd', + avatarUrl: 'ee', + }, + ], + }, + }, + }; + + const output = { + users: [ + expect.objectContaining({ + metadata: expect.objectContaining({ + name: 'a-custom', + }), + }), + ], + }; + + server.use( + graphqlMsw.query('users', (_req, res, ctx) => res(ctx.data(input))), + ); + + const users = await getOrganizationUsers( + graphql, + 'a', + 'token', + customUserTransformer, + ); + + expect(users.users).toHaveLength(1); + expect(users).toEqual(output); + }); + }); + + describe('getOrganizationTeams using default TeamTransformer', () => { let input: QueryResponse; beforeEach(() => { @@ -95,7 +213,7 @@ describe('github', () => { parentTeam: { slug: 'parent', combinedSlug: '', - members: { pageInfo: { hasNextPage: false }, nodes: [] }, + members: [], }, members: { pageInfo: { hasNextPage: false }, @@ -129,10 +247,10 @@ describe('github', () => { }, parent: 'parent', children: [], + members: ['user'], }, }), ], - groupMemberUsers: new Map([['team', ['user']]]), }; server.use( @@ -141,37 +259,192 @@ describe('github', () => { await expect(getOrganizationTeams(graphql, 'a')).resolves.toEqual(output); }); + }); - it('applies namespaces', async () => { + describe('getOrganizationTeams using custom TeamTransformer', () => { + let input: QueryResponse; + + const customTeamTransformer: TeamTransformer = async ( + item: GithubTeam, + {}, + ) => { + if (item.name === 'aa') { + return undefined; + } + + return { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: `${item.name}-custom`, + annotations: { + 'github.com/team-slug': 'blah/team', + 'backstage.io/edit-url': + 'http://example.com/orgs/blah/teams/team/edit', + }, + description: item.description, + }, + spec: { + type: 'team', + profile: { + displayName: `${item.name}-custom`, + picture: 'http://example.com/team.jpeg', + }, + parent: 'parent', + children: [], + members: ['user'], + }, + } as GroupEntity; + }; + + beforeEach(() => { + input = { + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + slug: 'team', + combinedSlug: 'blah/team', + name: 'Team', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'http://example.com/orgs/blah/teams/team/edit', + parentTeam: { + slug: 'parent', + combinedSlug: '', + members: [], + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'user' }], + }, + }, + ], + }, + }, + }; + }); + + it('reads teams', async () => { const output = { groups: [ expect.objectContaining({ metadata: expect.objectContaining({ - name: 'team', - namespace: 'foo', + name: 'Team-custom', description: 'The one and only team', + annotations: { + 'github.com/team-slug': 'blah/team', + 'backstage.io/edit-url': + 'http://example.com/orgs/blah/teams/team/edit', + }, }), spec: { type: 'team', profile: { - displayName: 'Team', + displayName: 'Team-custom', picture: 'http://example.com/team.jpeg', }, parent: 'parent', children: [], + members: ['user'], }, }), ], - groupMemberUsers: new Map([['foo/team', ['user']]]), }; server.use( graphqlMsw.query('teams', (_req, res, ctx) => res(ctx.data(input))), ); - await expect(getOrganizationTeams(graphql, 'a', 'foo')).resolves.toEqual( - output, + await expect( + getOrganizationTeams(graphql, 'a', customTeamTransformer), + ).resolves.toEqual(output); + }); + + it('reads teams if undefined is returned', async () => { + input = { + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + slug: 'team', + combinedSlug: 'blah/team', + name: 'Team', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'http://example.com/orgs/blah/teams/team/edit', + parentTeam: { + slug: 'parent', + combinedSlug: '', + members: [], + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'user' }], + }, + }, + { + slug: 'team', + combinedSlug: 'blah/team', + name: 'aa', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'http://example.com/orgs/blah/teams/team/edit', + parentTeam: { + slug: 'parent', + combinedSlug: '', + members: [], + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'user' }], + }, + }, + ], + }, + }, + }; + + const output = { + groups: [ + expect.objectContaining({ + metadata: expect.objectContaining({ + name: 'Team-custom', + description: 'The one and only team', + annotations: { + 'github.com/team-slug': 'blah/team', + 'backstage.io/edit-url': + 'http://example.com/orgs/blah/teams/team/edit', + }, + }), + spec: { + type: 'team', + profile: { + displayName: 'Team-custom', + picture: 'http://example.com/team.jpeg', + }, + parent: 'parent', + children: [], + members: ['user'], + }, + }), + ], + }; + + server.use( + graphqlMsw.query('teams', (_req, res, ctx) => res(ctx.data(input))), ); + + const teams = await getOrganizationTeams( + graphql, + 'a', + customTeamTransformer, + ); + + expect(teams.groups).toHaveLength(1); + expect(teams).toEqual(output); }); }); @@ -191,7 +464,7 @@ describe('github', () => { }; const output = { - members: ['user'], + members: [{ login: 'user' }], }; server.use( diff --git a/plugins/catalog-backend-module-github/src/lib/github.ts b/plugins/catalog-backend-module-github/src/lib/github.ts index ef6a7f817a..4d583d0730 100644 --- a/plugins/catalog-backend-module-github/src/lib/github.ts +++ b/plugins/catalog-backend-module-github/src/lib/github.ts @@ -17,19 +17,30 @@ import { GroupEntity, UserEntity } from '@backstage/catalog-model'; import { GithubCredentialType } from '@backstage/integration'; import { graphql } from '@octokit/graphql'; +import { + defaultOrganizationTeamTransformer, + defaultUserTransformer, + TeamTransformer, + TransformerContext, + UserTransformer, +} from './defaultTransformers'; // Graphql types export type QueryResponse = { - organization?: Organization; - repositoryOwner?: Organization | User; + organization?: OrganizationResponse; + repositoryOwner?: RepositoryOwnerResponse; }; -export type Organization = { - membersWithRole?: Connection; - team?: Team; - teams?: Connection; - repositories?: Connection; +type RepositoryOwnerResponse = { + repositories?: Connection; +}; + +export type OrganizationResponse = { + membersWithRole?: Connection; + team?: GithubTeamResponse; + teams?: Connection; + repositories?: Connection; }; export type PageInfo = { @@ -37,27 +48,41 @@ export type PageInfo = { endCursor?: string; }; -export type User = { +/** + * Github User + * + * @public + */ +export type GithubUser = { login: string; bio?: string; avatarUrl?: string; email?: string; name?: string; - repositories?: Connection; + organizationVerifiedDomainEmails?: string[]; }; -export type Team = { +/** + * Github Team + * + * @public + */ +export type GithubTeam = { slug: string; combinedSlug: string; name?: string; description?: string; avatarUrl?: string; editTeamUrl?: string; - parentTeam?: Team; - members: Connection; + parentTeam?: GithubTeam; + members: GithubUser[]; }; -export type Repository = { +export type GithubTeamResponse = Omit & { + members: Connection; +}; + +export type RepositoryResponse = { name: string; url: string; isArchived: boolean; @@ -88,7 +113,7 @@ export type Connection = { }; /** - * Gets all the users out of a GitHub organization. + * Gets all the users out of a Github organization. * * Note that the users will not have their memberships filled in. * @@ -99,7 +124,7 @@ export async function getOrganizationUsers( client: typeof graphql, org: string, tokenType: GithubCredentialType, - userNamespace?: string, + userTransformer: UserTransformer = defaultUserTransformer, ): Promise<{ users: UserEntity[] }> { const query = ` query users($org: String!, $email: Boolean!, $cursor: String) { @@ -111,7 +136,8 @@ export async function getOrganizationUsers( bio, email @include(if: $email), login, - name + name, + organizationVerifiedDomainEmails(login: $org) } } } @@ -119,44 +145,24 @@ export async function getOrganizationUsers( // There is no user -> teams edge, so we leave the memberships empty for // now and let the team iteration handle it instead - const mapper = (user: User) => { - const entity: UserEntity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'User', - metadata: { - name: user.login, - annotations: { - 'github.com/user-login': user.login, - }, - }, - spec: { - profile: {}, - memberOf: [], - }, - }; - - if (userNamespace) entity.metadata.namespace = userNamespace; - if (user.bio) entity.metadata.description = user.bio; - if (user.name) entity.spec.profile!.displayName = user.name; - if (user.email) entity.spec.profile!.email = user.email; - if (user.avatarUrl) entity.spec.profile!.picture = user.avatarUrl; - - return entity; - }; const users = await queryWithPaging( client, query, + org, r => r.organization?.membersWithRole, - mapper, - { org, email: tokenType === 'token' }, + userTransformer, + { + org, + email: tokenType === 'token', + }, ); return { users }; } /** - * Gets all the teams out of a GitHub organization. + * Gets all the teams out of a Github organization. * * Note that the teams will not have any relations apart from parent filled in. * @@ -166,10 +172,9 @@ export async function getOrganizationUsers( export async function getOrganizationTeams( client: typeof graphql, org: string, - orgNamespace?: string, + teamTransformer: TeamTransformer = defaultOrganizationTeamTransformer, ): Promise<{ groups: GroupEntity[]; - groupMemberUsers: Map; }> { const query = ` query teams($org: String!, $cursor: String) { @@ -193,86 +198,51 @@ export async function getOrganizationTeams( } }`; - // Gets populated inside the mapper below - const groupMemberUsers = new Map(); + const materialisedTeams = async ( + item: GithubTeamResponse, + ctx: TransformerContext, + ): Promise => { + const memberNames: GithubUser[] = []; - const mapper = async (team: Team) => { - const annotations: { [annotationName: string]: string } = { - 'github.com/team-slug': team.combinedSlug, - }; - - if (team.editTeamUrl) { - annotations['backstage.io/edit-url'] = team.editTeamUrl; - } - - const entity: GroupEntity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Group', - metadata: { - name: team.slug, - annotations, - }, - spec: { - type: 'team', - profile: {}, - children: [], - }, - }; - - if (orgNamespace) { - entity.metadata.namespace = orgNamespace; - } - - if (team.description) { - entity.metadata.description = team.description; - } - if (team.name) { - entity.spec.profile!.displayName = team.name; - } - if (team.avatarUrl) { - entity.spec.profile!.picture = team.avatarUrl; - } - if (team.parentTeam) { - entity.spec.parent = team.parentTeam.slug; - } - - const memberNames: string[] = []; - const groupKey = orgNamespace ? `${orgNamespace}/${team.slug}` : team.slug; - groupMemberUsers.set(groupKey, memberNames); - - if (!team.members.pageInfo.hasNextPage) { + if (!item.members.pageInfo.hasNextPage) { // We got all the members in one go, run the fast path - for (const user of team.members.nodes) { - memberNames.push(user.login); + for (const user of item.members.nodes) { + memberNames.push(user); } } else { // There were more than a hundred immediate members - run the slow // path of fetching them explicitly - const { members } = await getTeamMembers(client, org, team.slug); + const { members } = await getTeamMembers(ctx.client, ctx.org, item.slug); for (const userLogin of members) { memberNames.push(userLogin); } } - return entity; + const team: GithubTeam = { + ...item, + members: memberNames, + }; + + return await teamTransformer(team, ctx); }; const groups = await queryWithPaging( client, query, + org, r => r.organization?.teams, - mapper, + materialisedTeams, { org }, ); - return { groups, groupMemberUsers }; + return { groups }; } export async function getOrganizationRepositories( client: typeof graphql, org: string, catalogPath: string, -): Promise<{ repositories: Repository[] }> { +): Promise<{ repositories: RepositoryResponse[] }> { let relativeCatalogPathRef: string; // We must strip the leading slash or the query for objects does not work if (catalogPath.startsWith('/')) { @@ -321,8 +291,9 @@ export async function getOrganizationRepositories( const repositories = await queryWithPaging( client, query, + org, r => r.repositoryOwner?.repositories, - x => x, + async x => x, { org, catalogPathRef }, ); @@ -330,7 +301,7 @@ export async function getOrganizationRepositories( } /** - * Gets all the users out of a GitHub organization. + * Gets all the users out of a Github organization. * * Note that the users will not have their memberships filled in. * @@ -342,7 +313,7 @@ export async function getTeamMembers( client: typeof graphql, org: string, teamSlug: string, -): Promise<{ members: string[] }> { +): Promise<{ members: GithubUser[] }> { const query = ` query members($org: String!, $teamSlug: String!, $cursor: String) { organization(login: $org) { @@ -358,8 +329,9 @@ export async function getTeamMembers( const members = await queryWithPaging( client, query, + org, r => r.organization?.team?.members, - user => user.login, + async user => user, { org, teamSlug }, ); @@ -379,7 +351,7 @@ export async function getTeamMembers( * @param query - The query to execute * @param connection - A function that, given the response, picks out the actual * Connection object that's being iterated - * @param mapper - A function that, given one of the nodes in the Connection, + * @param transformer - A function that, given one of the nodes in the Connection, * returns the model mapped form of it * @param variables - The variable values that the query needs, minus the cursor */ @@ -391,8 +363,12 @@ export async function queryWithPaging< >( client: typeof graphql, query: string, + org: string, connection: (response: Response) => Connection | undefined, - mapper: (item: GraphqlType) => Promise | OutputType, + transformer: ( + item: GraphqlType, + ctx: TransformerContext, + ) => Promise, variables: Variables, ): Promise { const result: OutputType[] = []; @@ -410,7 +386,15 @@ export async function queryWithPaging< } for (const node of conn.nodes) { - result.push(await mapper(node)); + const transformedNode = await transformer(node, { + client, + query, + org, + }); + + if (transformedNode) { + result.push(transformedNode); + } } if (!conn.pageInfo.hasNextPage) { diff --git a/plugins/catalog-backend-module-github/src/lib/index.ts b/plugins/catalog-backend-module-github/src/lib/index.ts index 6402b69121..14f78fdeee 100644 --- a/plugins/catalog-backend-module-github/src/lib/index.ts +++ b/plugins/catalog-backend-module-github/src/lib/index.ts @@ -20,6 +20,15 @@ export { getOrganizationRepositories, getOrganizationTeams, getOrganizationUsers, + type GithubUser, + type GithubTeam, } from './github'; +export { + type UserTransformer, + defaultUserTransformer, + type TeamTransformer, + defaultOrganizationTeamTransformer, + type TransformerContext, +} from './defaultTransformers'; export { assignGroupsToUsers, buildOrgHierarchy } from './org'; export { parseGithubOrgUrl } from './util'; diff --git a/plugins/catalog-backend-module-github/src/lib/org.test.ts b/plugins/catalog-backend-module-github/src/lib/org.test.ts index 8a8f47642a..712c7c0b88 100644 --- a/plugins/catalog-backend-module-github/src/lib/org.test.ts +++ b/plugins/catalog-backend-module-github/src/lib/org.test.ts @@ -68,13 +68,47 @@ describe('buildOrgHierarchy', () => { describe('assignGroupsToUsers', () => { it('should assign groups to users', () => { const users: UserEntity[] = [u('u1'), u('u2')]; - const groupMemberUsers = new Map([ - ['g1', ['u1', 'u2']], - ['g2', ['u2']], - ['g3', ['u3']], - ]); - assignGroupsToUsers(users, groupMemberUsers); + const groups: GroupEntity[] = [ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: 'g1', + }, + spec: { + type: 'team', + children: [], + members: ['u1', 'u2'], + }, + }, + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: 'g2', + }, + spec: { + type: 'team', + children: [], + members: ['u2'], + }, + }, + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: 'g3', + }, + spec: { + type: 'team', + children: [], + members: ['u3'], + }, + }, + ]; + + assignGroupsToUsers(users, groups); expect(users[0].spec.memberOf).toEqual(['g1']); expect(users[1].spec.memberOf).toEqual(['g1', 'g2']); diff --git a/plugins/catalog-backend-module-github/src/lib/org.ts b/plugins/catalog-backend-module-github/src/lib/org.ts index 79a96b5e71..4642be0e8c 100644 --- a/plugins/catalog-backend-module-github/src/lib/org.ts +++ b/plugins/catalog-backend-module-github/src/lib/org.ts @@ -52,8 +52,17 @@ export function buildOrgHierarchy(groups: GroupEntity[]) { // Ensure that users have their direct group memberships. export function assignGroupsToUsers( users: UserEntity[], - groupMemberUsers: Map, + groups: GroupEntity[], ) { + const groupMemberUsers = new Map( + groups.map(group => { + const groupKey = group.metadata.namespace + ? `${group.metadata.namespace}/${group.metadata.name}` + : group.metadata.name; + return [groupKey, group.spec.members || []]; + }), + ); + const usersByName = new Map(users.map(u => [u.metadata.name, u])); for (const [groupName, userNames] of groupMemberUsers.entries()) { for (const userName of userNames) { diff --git a/plugins/catalog-backend-module-github/src/processors/GithubMultiOrgReaderProcessor.ts b/plugins/catalog-backend-module-github/src/processors/GithubMultiOrgReaderProcessor.ts index 7bb73990b3..59f9fdeeba 100644 --- a/plugins/catalog-backend-module-github/src/processors/GithubMultiOrgReaderProcessor.ts +++ b/plugins/catalog-backend-module-github/src/processors/GithubMultiOrgReaderProcessor.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { GroupEntity } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { DefaultGithubCredentialsProvider, @@ -32,7 +33,9 @@ import { import { graphql } from '@octokit/graphql'; import { Logger } from 'winston'; import { + assignGroupsToUsers, buildOrgHierarchy, + defaultOrganizationTeamTransformer, getOrganizationTeams, getOrganizationUsers, GithubMultiOrgConfig, @@ -130,12 +133,19 @@ export class GithubMultiOrgReaderProcessor implements CatalogProcessor { client, orgConfig.name, tokenType, - orgConfig.userNamespace, ); - const { groups, groupMemberUsers } = await getOrganizationTeams( + const { groups } = await getOrganizationTeams( client, orgConfig.name, - orgConfig.groupNamespace, + async (team, ctx): Promise => { + const result = await defaultOrganizationTeamTransformer(team, ctx); + + if (result) { + result.metadata.namespace = orgConfig.groupNamespace; + } + + return result; + }, ); const duration = ((Date.now() - startTimestamp) / 1000).toFixed(1); @@ -151,15 +161,7 @@ export class GithubMultiOrgReaderProcessor implements CatalogProcessor { allUsersMap.set(prefix + u.metadata.name, u); } }); - - for (const [groupName, userNames] of groupMemberUsers.entries()) { - for (const userName of userNames) { - const user = allUsersMap.get(prefix + userName); - if (user && !user.spec.memberOf.includes(groupName)) { - user.spec.memberOf.push(groupName); - } - } - } + assignGroupsToUsers(users, groups); buildOrgHierarchy(groups); for (const group of groups) { diff --git a/plugins/catalog-backend-module-github/src/processors/GithubOrgReaderProcessor.ts b/plugins/catalog-backend-module-github/src/processors/GithubOrgReaderProcessor.ts index 0ef81ac907..90c168ccf4 100644 --- a/plugins/catalog-backend-module-github/src/processors/GithubOrgReaderProcessor.ts +++ b/plugins/catalog-backend-module-github/src/processors/GithubOrgReaderProcessor.ts @@ -101,17 +101,14 @@ export class GithubOrgReaderProcessor implements CatalogProcessor { this.logger.info('Reading GitHub users and groups'); const { users } = await getOrganizationUsers(client, org, tokenType); - const { groups, groupMemberUsers } = await getOrganizationTeams( - client, - org, - ); + const { groups } = await getOrganizationTeams(client, org); const duration = ((Date.now() - startTimestamp) / 1000).toFixed(1); this.logger.debug( `Read ${users.length} GitHub users and ${groups.length} GitHub groups in ${duration} seconds`, ); - assignGroupsToUsers(users, groupMemberUsers); + assignGroupsToUsers(users, groups); buildOrgHierarchy(groups); // Done! diff --git a/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts b/plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.ts similarity index 90% rename from plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts rename to plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.ts index 2fc8ce7300..cf4adbb18d 100644 --- a/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts +++ b/plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.ts @@ -43,6 +43,7 @@ import { getOrganizationUsers, parseGithubOrgUrl, } from '../lib'; +import { TeamTransformer, UserTransformer } from '../lib/defaultTransformers'; /** * Options for {@link GithubOrgEntityProvider}. @@ -88,6 +89,16 @@ export interface GithubOrgEntityProviderOptions { * Optionally supply a custom credentials provider, replacing the default one. */ githubCredentialsProvider?: GithubCredentialsProvider; + + /** + * Optionally include a user transformer for transforming from GitHub users to User Entities + */ + userTransformer?: UserTransformer; + + /** + * Optionally include a user transformer for transforming from GitHub users to User Entities + */ + teamTransformer?: TeamTransformer; } // TODO: Consider supporting an (optional) webhook that reacts on org changes @@ -123,6 +134,8 @@ export class GithubOrgEntityProvider implements EntityProvider { githubCredentialsProvider: options.githubCredentialsProvider || DefaultGithubCredentialsProvider.fromIntegrations(integrations), + userTransformer: options.userTransformer, + teamTransformer: options.teamTransformer, }); provider.schedule(options.schedule); @@ -137,6 +150,8 @@ export class GithubOrgEntityProvider implements EntityProvider { gitHubConfig: GithubIntegrationConfig; logger: Logger; githubCredentialsProvider?: GithubCredentialsProvider; + userTransformer?: UserTransformer; + teamTransformer?: TeamTransformer; }, ) { this.credentialsProvider = @@ -177,12 +192,19 @@ export class GithubOrgEntityProvider implements EntityProvider { }); const { org } = parseGithubOrgUrl(this.options.orgUrl); - const { users } = await getOrganizationUsers(client, org, tokenType); - const { groups, groupMemberUsers } = await getOrganizationTeams( + const { users } = await getOrganizationUsers( client, org, + tokenType, + this.options.userTransformer, ); - assignGroupsToUsers(users, groupMemberUsers); + const { groups } = await getOrganizationTeams( + client, + org, + this.options.teamTransformer, + ); + + assignGroupsToUsers(users, groups); buildOrgHierarchy(groups); const { markCommitComplete } = markReadComplete({ users, groups }); diff --git a/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.ts b/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.ts index 6d3badf865..9a75f52afa 100644 --- a/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.ts +++ b/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.ts @@ -37,7 +37,7 @@ import { readProviderConfigs, GithubEntityProviderConfig, } from './GithubEntityProviderConfig'; -import { getOrganizationRepositories, Repository } from '../lib/github'; +import { getOrganizationRepositories, RepositoryResponse } from '../lib/github'; import { satisfiesTopicFilter } from '../lib/util'; /** @@ -175,7 +175,7 @@ export class GithubEntityProvider implements EntityProvider { } // go to the server and get all of the repositories - private async findCatalogFiles(): Promise { + private async findCatalogFiles(): Promise { const organization = this.config.organization; const host = this.integration.host; const catalogPath = this.config.catalogPath; @@ -208,7 +208,7 @@ export class GithubEntityProvider implements EntityProvider { return repositories; } - private matchesFilters(repositories: Repository[]) { + private matchesFilters(repositories: RepositoryResponse[]) { const repositoryFilter = this.config.filters?.repository; const topicFilters = this.config.filters?.topic; @@ -226,7 +226,7 @@ export class GithubEntityProvider implements EntityProvider { return matchingRepositories; } - private createLocationUrl(repository: Repository): string { + private createLocationUrl(repository: RepositoryResponse): string { const branch = this.config.filters?.branch || repository.defaultBranchRef?.name || '-'; const catalogFile = this.config.catalogPath.startsWith('/') diff --git a/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.test.ts b/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.test.ts index b3fc5022ec..0b8765b93e 100644 --- a/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.test.ts +++ b/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.test.ts @@ -163,6 +163,7 @@ describe('GithubOrgEntityProvider', () => { picture: 'http://example.com/team.jpeg', }, type: 'team', + members: ['a'], }, }, locationKey: 'github-org-provider:my-id', From 39403911c7863923ba44ca8661b8c60f168b9144 Mon Sep 17 00:00:00 2001 From: Scott Guymer Date: Tue, 8 Nov 2022 15:07:29 +0100 Subject: [PATCH 225/434] Docs should reflect the correct usage of the property Signed-off-by: Scott Guymer --- .../src/providers/GitHubOrgEntityProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.ts b/plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.ts index cf4adbb18d..210df46363 100644 --- a/plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.ts +++ b/plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.ts @@ -96,7 +96,7 @@ export interface GithubOrgEntityProviderOptions { userTransformer?: UserTransformer; /** - * Optionally include a user transformer for transforming from GitHub users to User Entities + * Optionally include a team transformer for transforming from GitHub teams to Group Entities */ teamTransformer?: TeamTransformer; } From 0e7a67de4cc10f87f5ef7279fcae027ebbcbec6d Mon Sep 17 00:00:00 2001 From: Scott Guymer Date: Tue, 8 Nov 2022 15:19:24 +0100 Subject: [PATCH 226/434] Small fixes from review Signed-off-by: Scott Guymer --- .../api-report.md | 4 +++ .../src/lib/org.ts | 14 ++++++++--- .../GithubMultiOrgReaderProcessor.ts | 25 +++++++++++++------ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/plugins/catalog-backend-module-github/api-report.md b/plugins/catalog-backend-module-github/api-report.md index ea6bc9e0ea..e749549646 100644 --- a/plugins/catalog-backend-module-github/api-report.md +++ b/plugins/catalog-backend-module-github/api-report.md @@ -138,6 +138,8 @@ export class GithubMultiOrgReaderProcessor implements CatalogProcessor { logger: Logger; orgs: GithubMultiOrgConfig; githubCredentialsProvider?: GithubCredentialsProvider; + userTransformer?: UserTransformer; + teamTransformer?: TeamTransformer; }); // (undocumented) static fromConfig( @@ -145,6 +147,8 @@ export class GithubMultiOrgReaderProcessor implements CatalogProcessor { options: { logger: Logger; githubCredentialsProvider?: GithubCredentialsProvider; + userTransformer?: UserTransformer; + teamTransformer?: TeamTransformer; }, ): GithubMultiOrgReaderProcessor; // (undocumented) diff --git a/plugins/catalog-backend-module-github/src/lib/org.ts b/plugins/catalog-backend-module-github/src/lib/org.ts index 4642be0e8c..275c5f4aeb 100644 --- a/plugins/catalog-backend-module-github/src/lib/org.ts +++ b/plugins/catalog-backend-module-github/src/lib/org.ts @@ -14,7 +14,11 @@ * limitations under the License. */ -import { GroupEntity, UserEntity } from '@backstage/catalog-model'; +import { + DEFAULT_NAMESPACE, + GroupEntity, + UserEntity, +} from '@backstage/catalog-model'; export function buildOrgHierarchy(groups: GroupEntity[]) { const groupsByName = new Map(groups.map(g => [g.metadata.name, g])); @@ -56,9 +60,11 @@ export function assignGroupsToUsers( ) { const groupMemberUsers = new Map( groups.map(group => { - const groupKey = group.metadata.namespace - ? `${group.metadata.namespace}/${group.metadata.name}` - : group.metadata.name; + const groupKey = + group.metadata.namespace && + group.metadata.namespace !== DEFAULT_NAMESPACE + ? `${group.metadata.namespace}/${group.metadata.name}` + : group.metadata.name; return [groupKey, group.spec.members || []]; }), ); diff --git a/plugins/catalog-backend-module-github/src/processors/GithubMultiOrgReaderProcessor.ts b/plugins/catalog-backend-module-github/src/processors/GithubMultiOrgReaderProcessor.ts index 59f9fdeeba..745f52d6c5 100644 --- a/plugins/catalog-backend-module-github/src/processors/GithubMultiOrgReaderProcessor.ts +++ b/plugins/catalog-backend-module-github/src/processors/GithubMultiOrgReaderProcessor.ts @@ -40,6 +40,8 @@ import { getOrganizationUsers, GithubMultiOrgConfig, readGithubMultiOrgConfig, + TeamTransformer, + UserTransformer, } from '../lib'; /** @@ -60,6 +62,8 @@ export class GithubMultiOrgReaderProcessor implements CatalogProcessor { options: { logger: Logger; githubCredentialsProvider?: GithubCredentialsProvider; + userTransformer?: UserTransformer; + teamTransformer?: TeamTransformer; }, ) { const c = config.getOptionalConfig('catalog.processors.githubMultiOrg'); @@ -72,12 +76,16 @@ export class GithubMultiOrgReaderProcessor implements CatalogProcessor { }); } - constructor(options: { - integrations: ScmIntegrationRegistry; - logger: Logger; - orgs: GithubMultiOrgConfig; - githubCredentialsProvider?: GithubCredentialsProvider; - }) { + constructor( + private options: { + integrations: ScmIntegrationRegistry; + logger: Logger; + orgs: GithubMultiOrgConfig; + githubCredentialsProvider?: GithubCredentialsProvider; + userTransformer?: UserTransformer; + teamTransformer?: TeamTransformer; + }, + ) { this.integrations = options.integrations; this.logger = options.logger; this.orgs = options.orgs; @@ -133,12 +141,15 @@ export class GithubMultiOrgReaderProcessor implements CatalogProcessor { client, orgConfig.name, tokenType, + this.options.userTransformer, ); const { groups } = await getOrganizationTeams( client, orgConfig.name, async (team, ctx): Promise => { - const result = await defaultOrganizationTeamTransformer(team, ctx); + const result = this.options.teamTransformer + ? await this.options.teamTransformer(team, ctx) + : await defaultOrganizationTeamTransformer(team, ctx); if (result) { result.metadata.namespace = orgConfig.groupNamespace; From 0ce26695a5f9a6e124eb4b846da2278cd50a70d3 Mon Sep 17 00:00:00 2001 From: Scott Guymer Date: Tue, 8 Nov 2022 15:21:24 +0100 Subject: [PATCH 227/434] Fix file casing Signed-off-by: Scott Guymer --- .../{GitHubOrgEntityProvider.ts => GithubOrgEntityProvider.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename plugins/catalog-backend-module-github/src/providers/{GitHubOrgEntityProvider.ts => GithubOrgEntityProvider.ts} (100%) diff --git a/plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.ts b/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts similarity index 100% rename from plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.ts rename to plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts From db7c3c9fcb3e3d0db64c2e87222b915570b4e9e2 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 8 Nov 2022 15:41:12 +0100 Subject: [PATCH 228/434] chore: remove backstagecon banner Signed-off-by: blam --- microsite/pages/en/index.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/microsite/pages/en/index.js b/microsite/pages/en/index.js index 8e963c2453..ab3dabe14e 100644 --- a/microsite/pages/en/index.js +++ b/microsite/pages/en/index.js @@ -31,15 +31,6 @@ class Index extends React.Component { ! - -
- 🤩 Join us for the first{' '} - - BackstageCon - {' '} - on October 24, 2022! -
-
From a9bf2829fc7d3cca6947ecbbef739fd9c519e3a5 Mon Sep 17 00:00:00 2001 From: Paulo Eduardo Peixoto Date: Tue, 8 Nov 2022 12:06:00 -0300 Subject: [PATCH 229/434] docs(ADOPTERS.md): update list. Signed-off-by: Paulo Eduardo Peixoto --- ADOPTERS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ADOPTERS.md b/ADOPTERS.md index da56d592b3..61058c3dda 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -141,7 +141,7 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Kambi AB](https://www.kambi.com) | [Martin Norum](mailto:martin.norum@kambi.com) | We want to kick ass at speed, so we're currently building up a catalog of our existing software, and looking into how Backstage can support us in our journey towards autonomous product teams. Both to improve speed to market and operational awareness. | | [ANZ](https://www.anz.com.au/personal/) | [Elliot Jackson](mailto:elliot.jackson@anz.com) | Catalog, tech docs and automation | | [Genie Solutions](https://www.geniesolutionssoftware.com.au) | [Zainab Bagasrawala](mailto:zainabbagasrawala@geniesolutions.com.au) | Developer Portal to track our projects, documentation, observability tools and more | -| [MadeiraMadeira](https://www.madeiramadeira.com.br) | [Paulo Eduardo Peixoto](mailto:paulo.peixoto@madeiramadeira.com.br) | As a support tool for developers, following the principles of "Developer Experience". In order to make the developer's day to day more practical, efficient and, why not, happy. | +| [MadeiraMadeira](https://www.madeiramadeira.com.br) | [DX Team](mailto:dxteam@madeiramadeira.com.br) | As a support tool for developers, following the principles of "Developer Experience". In order to make the developer's day to day more practical, efficient and, why not, happy. | | [Sonatype](https://www.sonatype.com) | [Srikar Ananthula](mailto:sananthula@sonatype.com) | Centralize services used internally with many plugins | | [CVS Health](https://www.cvshealth.com) | [Ari Ben-Elazar](mailto:abenelazar@gmail.com) | Cataloging and documenting our service offerings to offer our internal developers a better operational journey | | [Yatra.com](https://www.yatra.com) | [Matiur Rahman Maitur](mailto:arifrahman4u@gmail.com) | Easy to find out Project details, ownership, dependent services, Documentation, it is very useful for developer. | @@ -217,3 +217,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [StatusNeo](https://statusneo.com/) | [Karan Nangru](mailto:nangru@statusneo.com), [@NishkarshRaj](https://github.com/NishkarshRaj), and [Gaurav Sarien](mailto:gaurav.sarien@statusneo.com) | Harnessing the power of central catalog inventory and self-serving software templates | | [Alaska Airlines](https://alaskaair.com) | [@swerdick](https://github.com/swerdick) | Backstage is the developer portal for our 'software delivery platform'. Consolidating developer tools to one place, and providing automation to make it easy for developers to create and deploy applications to Kubernetes | [Loft](https://loft.com.br) | [Squad DevTools](mailto:squad_devtools@loft.com.br) | We're using Backstage to give visibility and promote ownership of all our applications, resources and tools. Now moving to use it as a Developer Portal to create applications, AWS resources etc. | +| [Raízen](https://www.raizen.com) | [Melquisedque Bernardes Pereira](https://github.com/rayleshh) and [Paulo Eduardo Peixoto](https://github.com/padupe) | Backstage helps us to organize and make available, in a simple and direct way, all the infrastructure for new projects. In addition, it has become a great support tool for our developers. | From bc07e5f1c62320d117f8cab88cb610aeebdea64e Mon Sep 17 00:00:00 2001 From: Casper Thygesen <73483987+cthtrifork@users.noreply.github.com> Date: Tue, 8 Nov 2022 19:48:03 +0100 Subject: [PATCH 230/434] Add default errorHandler() to vault-backend Right now any uncaught error causes backstarte to crash We should use `packages/backend-common/src/middleware/errorHandler.ts` middleware like the other backend plugins Signed-off-by: Casper Thygesen <73483987+cthtrifork@users.noreply.github.com> Signed-off-by: cthtrifork --- plugins/vault-backend/src/service/VaultBuilder.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/vault-backend/src/service/VaultBuilder.ts b/plugins/vault-backend/src/service/VaultBuilder.ts index 67260f45ca..b82a5802bb 100644 --- a/plugins/vault-backend/src/service/VaultBuilder.ts +++ b/plugins/vault-backend/src/service/VaultBuilder.ts @@ -20,6 +20,7 @@ import { Logger } from 'winston'; import express, { Router } from 'express'; import { VaultClient } from './vaultApi'; import { TaskRunner, PluginTaskScheduler } from '@backstage/backend-tasks'; +import { errorHandler } from '@backstage/backend-common'; /** * Environment values needed by the VaultBuilder @@ -145,6 +146,7 @@ export class VaultBuilder { res.json({ items: secrets }); }); + router.use(errorHandler()); return router; } } From 687237da4c83040cecae7a8858630ca14de30e78 Mon Sep 17 00:00:00 2001 From: Casper Thygesen <73483987+cthtrifork@users.noreply.github.com> Date: Tue, 8 Nov 2022 19:51:34 +0100 Subject: [PATCH 231/434] added changeset Signed-off-by: cthtrifork --- .changeset/rude-mayflies-heal.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/rude-mayflies-heal.md diff --git a/.changeset/rude-mayflies-heal.md b/.changeset/rude-mayflies-heal.md new file mode 100644 index 0000000000..738ade0f3c --- /dev/null +++ b/.changeset/rude-mayflies-heal.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-vault-backend': patch +--- + +Added errorHandler() middleware to vault-backend to prevent errors to cause a crash From cba57dfd0110e122a874301d6f7e7c6535557277 Mon Sep 17 00:00:00 2001 From: thisisobate Date: Tue, 8 Nov 2022 21:59:43 +0100 Subject: [PATCH 232/434] Feat: add training section to backstage.io Signed-off-by: thisisobate --- microsite/pages/en/community.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/microsite/pages/en/community.js b/microsite/pages/en/community.js index 0580ec045a..63d5e04d20 100644 --- a/microsite/pages/en/community.js +++ b/microsite/pages/en/community.js @@ -149,7 +149,7 @@ const Background = props => { - + Community initiatives @@ -183,6 +183,29 @@ const Background = props => { + + + + Trainings and Certifications + + + + + + + Introduction to Backstage: Developer Portals Made Easy (LFS142x) + + This is a course produced and curated by the Linux Foundation. This course introduces you to Backstage and how to get started with the project. + + + + Learn more + + + + + + From 2f0aa0a4575e24f26310cf253ae21f0a8a1f8314 Mon Sep 17 00:00:00 2001 From: cthtrifork Date: Tue, 8 Nov 2022 19:25:46 +0000 Subject: [PATCH 233/434] docs(ADOPTERS.md): added Trifork. Signed-off-by: cthtrifork --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index 61058c3dda..cd2e0e761c 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -218,3 +218,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Alaska Airlines](https://alaskaair.com) | [@swerdick](https://github.com/swerdick) | Backstage is the developer portal for our 'software delivery platform'. Consolidating developer tools to one place, and providing automation to make it easy for developers to create and deploy applications to Kubernetes | [Loft](https://loft.com.br) | [Squad DevTools](mailto:squad_devtools@loft.com.br) | We're using Backstage to give visibility and promote ownership of all our applications, resources and tools. Now moving to use it as a Developer Portal to create applications, AWS resources etc. | | [Raízen](https://www.raizen.com) | [Melquisedque Bernardes Pereira](https://github.com/rayleshh) and [Paulo Eduardo Peixoto](https://github.com/padupe) | Backstage helps us to organize and make available, in a simple and direct way, all the infrastructure for new projects. In addition, it has become a great support tool for our developers. | +| [Trifork](https://trifork.com) | [Casper Thygesen](https://github.com/cthtrifork) | We're using Backstage as part of our dataplatform product. It integrates with the infrastructure components and is the developer portal for all the platform users. | From 70a06dd3fc1e1c0e677fc7a6c6df45d8b0ef9235 Mon Sep 17 00:00:00 2001 From: thisisobate Date: Tue, 8 Nov 2022 23:02:31 +0100 Subject: [PATCH 234/434] chore: fix prettier error Signed-off-by: thisisobate --- microsite/pages/en/community.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/microsite/pages/en/community.js b/microsite/pages/en/community.js index 63d5e04d20..2742784fbf 100644 --- a/microsite/pages/en/community.js +++ b/microsite/pages/en/community.js @@ -188,18 +188,23 @@ const Background = props => { Trainings and Certifications - - Introduction to Backstage: Developer Portals Made Easy (LFS142x) + + Introduction to Backstage: Developer Portals Made Easy + (LFS142x) + - This is a course produced and curated by the Linux Foundation. This course introduces you to Backstage and how to get started with the project. + This is a course produced and curated by the Linux Foundation. + This course introduces you to Backstage and how to get started + with the project. + - Learn more + Learn more From 5e14b067ecfe99553edc48df950cca244b54248e Mon Sep 17 00:00:00 2001 From: thisisobate Date: Tue, 8 Nov 2022 23:14:09 +0100 Subject: [PATCH 235/434] chore: set background colors to blend well Signed-off-by: thisisobate --- microsite/pages/en/community.js | 35 ++++++++++++++------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/microsite/pages/en/community.js b/microsite/pages/en/community.js index 2742784fbf..a5fd5353e0 100644 --- a/microsite/pages/en/community.js +++ b/microsite/pages/en/community.js @@ -149,7 +149,7 @@ const Background = props => { - + Community initiatives @@ -188,26 +188,21 @@ const Background = props => { Trainings and Certifications - - - - - - Introduction to Backstage: Developer Portals Made Easy - (LFS142x) - - - This is a course produced and curated by the Linux Foundation. - This course introduces you to Backstage and how to get started - with the project. - - + + + + Introduction to Backstage: Developer Portals Made Easy (LFS142x) + + + This is a course produced and curated by the Linux Foundation. + This course introduces you to Backstage and how to get started + with the project. + - - Learn more - - - + + Learn more + + From 2da4ef9020a749bd422e6233677c6fb24e92e1b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= Date: Sun, 30 Oct 2022 22:30:16 +0100 Subject: [PATCH 236/434] Make CostOverviewBreakdownChart responsive by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez --- .../CostOverviewCard/CostOverviewBreakdownChart.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewBreakdownChart.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewBreakdownChart.tsx index f6463b65ed..962dc6b332 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewBreakdownChart.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewBreakdownChart.tsx @@ -54,12 +54,14 @@ import { TooltipRenderer } from '../../types/Tooltip'; export type CostOverviewBreakdownChartProps = { costBreakdown: Cost[]; + responsive?: boolean; }; const LOW_COST_THRESHOLD = 0.1; export const CostOverviewBreakdownChart = ({ costBreakdown, + responsive = true, }: CostOverviewBreakdownChartProps) => { const theme = useTheme(); const classes = useStyles(theme); @@ -228,7 +230,7 @@ export const CostOverviewBreakdownChart = ({ /> Date: Sun, 30 Oct 2022 22:30:58 +0100 Subject: [PATCH 237/434] Define a EntityCostInsightsContent extension to show costs per catalog entity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez --- plugins/cost-insights/package.json | 1 + .../cost-insights/src/api/CostInsightsApi.ts | 20 +++ .../CostOverviewCard/CostOverviewCard.tsx | 3 +- .../components/EntityCosts/EntityCosts.tsx | 160 ++++++++++++++++++ .../src/components/EntityCosts/index.ts | 16 ++ plugins/cost-insights/src/example/client.ts | 24 +++ plugins/cost-insights/src/index.ts | 1 + plugins/cost-insights/src/plugin.ts | 14 ++ yarn.lock | 1 + 9 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 plugins/cost-insights/src/components/EntityCosts/EntityCosts.tsx create mode 100644 plugins/cost-insights/src/components/EntityCosts/index.ts diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index 9896c3e60e..0f53d22457 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -36,6 +36,7 @@ "@backstage/config": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", + "@backstage/plugin-catalog-react": "workspace:^", "@backstage/plugin-cost-insights-common": "workspace:^", "@backstage/theme": "workspace:^", "@material-ui/core": "^4.12.2", diff --git a/plugins/cost-insights/src/api/CostInsightsApi.ts b/plugins/cost-insights/src/api/CostInsightsApi.ts index 3c97407f08..ffc2314435 100644 --- a/plugins/cost-insights/src/api/CostInsightsApi.ts +++ b/plugins/cost-insights/src/api/CostInsightsApi.ts @@ -24,6 +24,7 @@ import { MetricData, } from '../types'; import { createApiRef } from '@backstage/core-plugin-api'; +import { Entity as CatalogEntity } from '@backstage/catalog-model'; /** @public */ export type ProductInsightsOptions = { @@ -77,6 +78,25 @@ export type CostInsightsApi = { */ getGroupProjects(group: string): Promise; + /** + * Get daily cost aggregations for a given entity and interval time frame. + * + * The return type includes an array of daily cost aggregations as well as statistics about the + * change in cost over the intervals. Calculating these statistics requires us to bucket costs + * into two or more time periods, hence a repeating interval format rather than just a start and + * end date. + * + * The rate of change in this comparison allows teams to reason about their cost growth (or + * reduction) and compare it to metrics important to the business. + * + * Note: implementing this is only required when using the `EntityCostInsightsContent` extension. + * + * @param entity - The catalog entity + * @param intervals - An ISO 8601 repeating interval string, such as R2/P30D/2020-09-01 + * https://en.wikipedia.org/wiki/ISO_8601#Repeating_intervals + */ + getEntityDailyCost?(entity: CatalogEntity, intervals: string): Promise; + /** * Get daily cost aggregations for a given group and interval time frame. * diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.tsx index 3e77858967..9eb5f1e190 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.tsx @@ -103,7 +103,8 @@ export const CostOverviewCard = ({ }; // Metrics can only be selected on the total cost graph - const showMetricSelect = config.metrics.length && safeTabIndex === 0; + const showMetricSelect = + metricData && config.metrics.length && safeTabIndex === 0; return ( diff --git a/plugins/cost-insights/src/components/EntityCosts/EntityCosts.tsx b/plugins/cost-insights/src/components/EntityCosts/EntityCosts.tsx new file mode 100644 index 0000000000..9fdcb9c98b --- /dev/null +++ b/plugins/cost-insights/src/components/EntityCosts/EntityCosts.tsx @@ -0,0 +1,160 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { useCallback, useEffect, useState } from 'react'; +import { CostOverviewCard } from '../CostOverviewCard'; +import { + BillingDateProvider, + ConfigProvider, + CurrencyProvider, + FilterProvider, + GroupsProvider, + LoadingProvider, + ScrollProvider, + useFilters, + useLastCompleteBillingDate, + useLoading, +} from '../../hooks'; +import { CostInsightsThemeProvider } from '../CostInsightsPage/CostInsightsThemeProvider'; +import { Progress, WarningPanel } from '@backstage/core-components'; +import { default as MaterialAlert } from '@material-ui/lab/Alert'; +import { mapLoadingToProps } from '../CostInsightsPage/selector'; +import { intervalsOf } from '../../utils/duration'; +import { costInsightsApiRef } from '../../api'; +import { useApi } from '@backstage/core-plugin-api'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import { Cost, Maybe } from '@backstage/plugin-cost-insights-common'; + +export const EntityCostsCard = () => { + const client = useApi(costInsightsApiRef); + const { entity } = useEntity(); + + const { + loadingActions, + loadingGroups, + loadingBillingDate, + loadingInitial, + dispatchInitial, + dispatchInsights, + dispatchNone, + } = useLoading(mapLoadingToProps); + + /* eslint-disable react-hooks/exhaustive-deps */ + // The dispatchLoading functions are derived from loading state using mapLoadingToProps, to + // provide nicer props for the component. These are re-derived whenever loading state changes, + // which causes an infinite loop as product panels load and re-trigger the useEffect below. + // Since the functions don't change, we can memoize - but we trigger the same loop if we satisfy + // exhaustive-deps by including the function itself in dependencies. + + const dispatchLoadingInitial = useCallback(dispatchInitial, []); + const dispatchLoadingInsights = useCallback(dispatchInsights, []); + const dispatchLoadingNone = useCallback(dispatchNone, []); + /* eslint-enable react-hooks/exhaustive-deps */ + + const lastCompleteBillingDate = useLastCompleteBillingDate(); + const [dailyCost, setDailyCost] = useState>(null); + const [error, setError] = useState>(null); + const { pageFilters } = useFilters(p => p); + + useEffect(() => { + async function getInsights() { + setError(null); + try { + dispatchLoadingInsights(true); + const intervals = intervalsOf( + pageFilters.duration, + lastCompleteBillingDate, + ); + + const fetchedDailyCost = await client.getEntityDailyCost!( + entity, + intervals, + ); + setDailyCost(fetchedDailyCost); + } catch (e) { + setError(e); + dispatchLoadingNone(loadingActions); + } finally { + dispatchLoadingNone(loadingActions); + dispatchLoadingInitial(false); + dispatchLoadingInsights(false); + } + } + + // Wait for metadata to finish loading + if (!loadingBillingDate) { + getInsights(); + } + }, [ + client, + entity, + pageFilters, + loadingActions, + loadingGroups, + loadingBillingDate, + dispatchLoadingInsights, + dispatchLoadingInitial, + dispatchLoadingNone, + lastCompleteBillingDate, + ]); + + if (loadingInitial) { + return ; + } + + if (error) { + return {error.message}; + } + + if (!dailyCost) { + return No daily costs; + } + + return ; +}; + +export const EntityCosts = () => { + const client = useApi(costInsightsApiRef); + + if (!client.getEntityDailyCost) { + return ( + + ); + } + + return ( + + + + + + + + + + + + + + + + + + ); +}; diff --git a/plugins/cost-insights/src/components/EntityCosts/index.ts b/plugins/cost-insights/src/components/EntityCosts/index.ts new file mode 100644 index 0000000000..b8d5106090 --- /dev/null +++ b/plugins/cost-insights/src/components/EntityCosts/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { EntityCosts } from './EntityCosts'; diff --git a/plugins/cost-insights/src/example/client.ts b/plugins/cost-insights/src/example/client.ts index 9c3e20c2b3..a1401a06a2 100644 --- a/plugins/cost-insights/src/example/client.ts +++ b/plugins/cost-insights/src/example/client.ts @@ -38,6 +38,7 @@ import { getGroupedProjects, trendlineOf, } from '../testUtils'; +import { Entity as CatalogEntity } from '@backstage/catalog-model'; /** @public */ export class ExampleCostInsightsClient implements CostInsightsApi { @@ -92,6 +93,29 @@ export class ExampleCostInsightsClient implements CostInsightsApi { return cost; } + async getEntityDailyCost( + entity: CatalogEntity, + intervals: string, + ): Promise { + const aggregation = aggregationFor(intervals, 8_000); + const groupDailyCost: Cost = await this.request( + { entity, intervals }, + { + aggregation: aggregation, + change: changeOf(aggregation), + trendline: trendlineOf(aggregation), + // Optional field providing cost groupings / breakdowns keyed by the type. In this example, + // daily cost grouped by cloud product OR by project / billing account. + groupedCosts: { + product: getGroupedProducts(intervals), + project: getGroupedProjects(intervals), + }, + }, + ); + + return groupDailyCost; + } + async getGroupDailyCost(group: string, intervals: string): Promise { const aggregation = aggregationFor(intervals, 8_000); const groupDailyCost: Cost = await this.request( diff --git a/plugins/cost-insights/src/index.ts b/plugins/cost-insights/src/index.ts index 2c46156005..8a17b1bf43 100644 --- a/plugins/cost-insights/src/index.ts +++ b/plugins/cost-insights/src/index.ts @@ -24,6 +24,7 @@ export { costInsightsPlugin, costInsightsPlugin as plugin, CostInsightsPage, + EntityCostInsightsContent, CostInsightsProjectGrowthInstructionsPage, CostInsightsLabelDataflowInstructionsPage, } from './plugin'; diff --git a/plugins/cost-insights/src/plugin.ts b/plugins/cost-insights/src/plugin.ts index 789d803438..04d58d1877 100644 --- a/plugins/cost-insights/src/plugin.ts +++ b/plugins/cost-insights/src/plugin.ts @@ -53,6 +53,20 @@ export const CostInsightsPage = costInsightsPlugin.provide( }), ); +/** + * An extension for displaying costs on an entity page. + * + * @public + */ +export const EntityCostInsightsContent = costInsightsPlugin.provide( + createRoutableExtension({ + name: 'EntityCostInsightsContent', + component: () => + import('./components/EntityCosts').then(m => m.EntityCosts), + mountPoint: rootRouteRef, + }), +); + /** @public */ export const CostInsightsProjectGrowthInstructionsPage = costInsightsPlugin.provide( diff --git a/yarn.lock b/yarn.lock index 6a88a61621..74b78b52d9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5470,6 +5470,7 @@ __metadata: "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" "@backstage/dev-utils": "workspace:^" + "@backstage/plugin-catalog-react": "workspace:^" "@backstage/plugin-cost-insights-common": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" From 6b2933a0a134f1b880faa411f6ec0e0d519d77dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= Date: Sun, 30 Oct 2022 22:31:09 +0100 Subject: [PATCH 238/434] Update demo app to show costs for service components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez --- packages/app/src/components/catalog/EntityPage.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index 8e72bb03e4..02b00f038c 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -153,6 +153,7 @@ import { TextSize, ReportIssue, } from '@backstage/plugin-techdocs-module-addons-contrib'; +import { EntityCostInsightsContent } from '@backstage/plugin-cost-insights'; const customEntityFilterKind = ['Component', 'API', 'System']; @@ -489,6 +490,10 @@ const serviceEntityPage = ( + + + + Date: Sun, 30 Oct 2022 22:48:31 +0100 Subject: [PATCH 239/434] Add a simple test showing that it doesn't explode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez --- .../EntityCosts/EntityCost.test.tsx | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx diff --git a/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx b/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx new file mode 100644 index 0000000000..395480c6df --- /dev/null +++ b/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx @@ -0,0 +1,99 @@ +/* + * 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 React from 'react'; +import { renderInTestApp } from '@backstage/test-utils'; +import { + changeOf, + MockAggregatedDailyCosts, + MockBillingDateProvider, + MockConfigProvider, + MockFilterProvider, + MockScrollProvider, + trendlineOf, +} from '../../testUtils'; +import { CostInsightsThemeProvider } from '../CostInsightsPage/CostInsightsThemeProvider'; +import { EntityCostsCard } from './EntityCosts'; +import { TestApiProvider } from '@backstage/test-utils'; +import { CostInsightsApi, costInsightsApiRef } from '../../api'; +import { EntityProvider } from '@backstage/plugin-catalog-react'; +import { Entity } from '@backstage/catalog-model'; +import { LoadingProvider } from '../../hooks'; +import { Cost } from '@backstage/plugin-cost-insights-common'; + +function renderInContext(children: JSX.Element) { + const mockEntity = { + metadata: { name: 'mock' }, + kind: 'MockKind', + } as Entity; + const mockGroupDailyCost: Cost = { + id: 'test-group', + aggregation: MockAggregatedDailyCosts, + change: changeOf(MockAggregatedDailyCosts), + trendline: trendlineOf(MockAggregatedDailyCosts), + }; + const mockApi: jest.Mocked = { + getLastCompleteBillingDate: jest.fn().mockResolvedValue('2022-10-30'), + getUserGroups: jest.fn().mockResolvedValue(['team-a']), + getGroupProjects: jest.fn().mockResolvedValue(['project-a', 'project-b']), + getEntityDailyCost: jest.fn().mockResolvedValue(mockGroupDailyCost), + getGroupDailyCost: jest.fn().mockResolvedValue({}), + getProjectDailyCost: jest.fn().mockResolvedValue({}), + getDailyMetricData: jest.fn().mockResolvedValue({}), + getProductInsights: jest.fn().mockResolvedValue({}), + getAlerts: jest.fn().mockResolvedValue({}), + }; + + return renderInTestApp( + + + + + + + + {children} + + + + + + + , + ); +} + +describe('', () => { + beforeEach(() => { + // @ts-expect-error: Since we have strictNullChecks enabled, this will throw an error as window.ResizeObserver + // it's not an optional operand + delete window.ResizeObserver; + window.ResizeObserver = jest.fn().mockImplementation(() => ({ + observe: jest.fn(), + unobserve: jest.fn(), + disconnect: jest.fn(), + })); + }); + + afterEach(() => { + window.ResizeObserver = ResizeObserver; + jest.restoreAllMocks(); + }); + + it('Renders without exploding', async () => { + const { getByText } = await renderInContext(); + expect(getByText('Cloud Cost')).toBeInTheDocument(); + }); +}); From bc4353ca19ef075f0439ee311b48bf43ae9cf1ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= Date: Tue, 8 Nov 2022 23:22:13 +0100 Subject: [PATCH 240/434] Use reference instead of plain entities in the CostInsightsApi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez --- plugins/cost-insights/api-report.md | 12 ++++++++++++ plugins/cost-insights/src/api/CostInsightsApi.ts | 11 +++++++---- .../src/components/EntityCosts/EntityCost.test.tsx | 2 +- .../src/components/EntityCosts/EntityCosts.tsx | 9 +++++---- plugins/cost-insights/src/example/client.ts | 7 +++---- .../src/example/templates/CostInsightsClient.ts | 11 +++++++++++ 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/plugins/cost-insights/api-report.md b/plugins/cost-insights/api-report.md index f50f0b0c81..dd4e404450 100644 --- a/plugins/cost-insights/api-report.md +++ b/plugins/cost-insights/api-report.md @@ -267,6 +267,10 @@ export type CostInsightsApi = { getLastCompleteBillingDate(): Promise; getUserGroups(userId: string): Promise; getGroupProjects(group: string): Promise; + getCatalogEntityDailyCost?( + catalogEntityRef: string, + intervals: string, + ): Promise; getGroupDailyCost(group: string, intervals: string): Promise; getProjectDailyCost(project: string, intervals: string): Promise; getDailyMetricData(metric: string, intervals: string): Promise; @@ -404,11 +408,19 @@ export const EngineerThreshold = 0.5; // @public @deprecated (undocumented) export type Entity = common.Entity; +// @public +export const EntityCostInsightsContent: () => JSX.Element; + // @public (undocumented) export class ExampleCostInsightsClient implements CostInsightsApi { // (undocumented) getAlerts(group: string): Promise; // (undocumented) + getCatalogEntityDailyCost( + entityRef: string, + intervals: string, + ): Promise; + // (undocumented) getDailyMetricData(metric: string, intervals: string): Promise; // (undocumented) getGroupDailyCost(group: string, intervals: string): Promise; diff --git a/plugins/cost-insights/src/api/CostInsightsApi.ts b/plugins/cost-insights/src/api/CostInsightsApi.ts index ffc2314435..a7065a04aa 100644 --- a/plugins/cost-insights/src/api/CostInsightsApi.ts +++ b/plugins/cost-insights/src/api/CostInsightsApi.ts @@ -24,7 +24,6 @@ import { MetricData, } from '../types'; import { createApiRef } from '@backstage/core-plugin-api'; -import { Entity as CatalogEntity } from '@backstage/catalog-model'; /** @public */ export type ProductInsightsOptions = { @@ -79,7 +78,7 @@ export type CostInsightsApi = { getGroupProjects(group: string): Promise; /** - * Get daily cost aggregations for a given entity and interval time frame. + * Get daily cost aggregations for a given catalog entity and interval time frame. * * The return type includes an array of daily cost aggregations as well as statistics about the * change in cost over the intervals. Calculating these statistics requires us to bucket costs @@ -91,11 +90,15 @@ export type CostInsightsApi = { * * Note: implementing this is only required when using the `EntityCostInsightsContent` extension. * - * @param entity - The catalog entity + * @param catalogEntityRef - A reference to the catalog entity, as described in + * https://backstage.io/docs/features/software-catalog/references * @param intervals - An ISO 8601 repeating interval string, such as R2/P30D/2020-09-01 * https://en.wikipedia.org/wiki/ISO_8601#Repeating_intervals */ - getEntityDailyCost?(entity: CatalogEntity, intervals: string): Promise; + getCatalogEntityDailyCost?( + catalogEntityRef: string, + intervals: string, + ): Promise; /** * Get daily cost aggregations for a given group and interval time frame. diff --git a/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx b/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx index 395480c6df..53e1a13ebf 100644 --- a/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx +++ b/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx @@ -48,7 +48,7 @@ function renderInContext(children: JSX.Element) { getLastCompleteBillingDate: jest.fn().mockResolvedValue('2022-10-30'), getUserGroups: jest.fn().mockResolvedValue(['team-a']), getGroupProjects: jest.fn().mockResolvedValue(['project-a', 'project-b']), - getEntityDailyCost: jest.fn().mockResolvedValue(mockGroupDailyCost), + getCatalogEntityDailyCost: jest.fn().mockResolvedValue(mockGroupDailyCost), getGroupDailyCost: jest.fn().mockResolvedValue({}), getProjectDailyCost: jest.fn().mockResolvedValue({}), getDailyMetricData: jest.fn().mockResolvedValue({}), diff --git a/plugins/cost-insights/src/components/EntityCosts/EntityCosts.tsx b/plugins/cost-insights/src/components/EntityCosts/EntityCosts.tsx index 9fdcb9c98b..9dda1c65e3 100644 --- a/plugins/cost-insights/src/components/EntityCosts/EntityCosts.tsx +++ b/plugins/cost-insights/src/components/EntityCosts/EntityCosts.tsx @@ -37,6 +37,7 @@ import { costInsightsApiRef } from '../../api'; import { useApi } from '@backstage/core-plugin-api'; import { useEntity } from '@backstage/plugin-catalog-react'; import { Cost, Maybe } from '@backstage/plugin-cost-insights-common'; +import { stringifyEntityRef } from '@backstage/catalog-model'; export const EntityCostsCard = () => { const client = useApi(costInsightsApiRef); @@ -79,8 +80,8 @@ export const EntityCostsCard = () => { lastCompleteBillingDate, ); - const fetchedDailyCost = await client.getEntityDailyCost!( - entity, + const fetchedDailyCost = await client.getCatalogEntityDailyCost!( + stringifyEntityRef(entity), intervals, ); setDailyCost(fetchedDailyCost); @@ -129,11 +130,11 @@ export const EntityCostsCard = () => { export const EntityCosts = () => { const client = useApi(costInsightsApiRef); - if (!client.getEntityDailyCost) { + if (!client.getCatalogEntityDailyCost) { return ( ); } diff --git a/plugins/cost-insights/src/example/client.ts b/plugins/cost-insights/src/example/client.ts index a1401a06a2..e2a183b682 100644 --- a/plugins/cost-insights/src/example/client.ts +++ b/plugins/cost-insights/src/example/client.ts @@ -38,7 +38,6 @@ import { getGroupedProjects, trendlineOf, } from '../testUtils'; -import { Entity as CatalogEntity } from '@backstage/catalog-model'; /** @public */ export class ExampleCostInsightsClient implements CostInsightsApi { @@ -93,13 +92,13 @@ export class ExampleCostInsightsClient implements CostInsightsApi { return cost; } - async getEntityDailyCost( - entity: CatalogEntity, + async getCatalogEntityDailyCost( + entityRef: string, intervals: string, ): Promise { const aggregation = aggregationFor(intervals, 8_000); const groupDailyCost: Cost = await this.request( - { entity, intervals }, + { entityRef, intervals }, { aggregation: aggregation, change: changeOf(aggregation), diff --git a/plugins/cost-insights/src/example/templates/CostInsightsClient.ts b/plugins/cost-insights/src/example/templates/CostInsightsClient.ts index fc68eb62c7..50c3bb1470 100644 --- a/plugins/cost-insights/src/example/templates/CostInsightsClient.ts +++ b/plugins/cost-insights/src/example/templates/CostInsightsClient.ts @@ -87,6 +87,17 @@ export class CostInsightsClient implements CostInsightsApi { } } + async getCatalogEntityDailyCost(catalogEntityRef: string, intervals: string): Promise { + return { + id: 'remove-me', + aggregation: [], + change: { + ratio: 0, + amount: 0 + } + } + } + async getProductInsights(options: ProductInsightsOptions): Promise { return { id: 'remove-me', From a446ce237e836fc5b8d44cacb3953ee68a75857f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= Date: Tue, 8 Nov 2022 23:36:05 +0100 Subject: [PATCH 241/434] Add EntityCostInsightsContent to the dev mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez --- plugins/cost-insights/dev/index.tsx | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/plugins/cost-insights/dev/index.tsx b/plugins/cost-insights/dev/index.tsx index 4be788427a..622abaffc9 100644 --- a/plugins/cost-insights/dev/index.tsx +++ b/plugins/cost-insights/dev/index.tsx @@ -23,7 +23,26 @@ import { CostInsightsPage, CostInsightsProjectGrowthInstructionsPage, CostInsightsLabelDataflowInstructionsPage, + EntityCostInsightsContent, } from '../src/plugin'; +import { Content, Header, Page } from '@backstage/core-components'; +import { Grid } from '@material-ui/core'; +import { EntityProvider } from '@backstage/plugin-catalog-react'; +import { Entity } from '@backstage/catalog-model'; + +const mockEntity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'backstage', + description: 'backstage.io', + }, + spec: { + lifecycle: 'production', + type: 'service', + owner: 'user:guest', + }, +}; createDevApp() .registerPlugin(costInsightsPlugin) @@ -44,4 +63,22 @@ createDevApp() title: 'Labelling', element: , }) + .addPage({ + title: 'Entity', + element: ( + +
+ + + + + + + + + + + + ), + }) .render(); From 0443e0ebfab85110a9a6d7ed6cac3afc84238abd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= Date: Wed, 9 Nov 2022 01:07:14 +0100 Subject: [PATCH 242/434] Add announcements plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez --- microsite/data/plugins/announcements.yaml | 10 ++++++++++ .../static/img/plugin-announcements-logo.png | Bin 0 -> 20496 bytes 2 files changed, 10 insertions(+) create mode 100644 microsite/data/plugins/announcements.yaml create mode 100644 microsite/static/img/plugin-announcements-logo.png diff --git a/microsite/data/plugins/announcements.yaml b/microsite/data/plugins/announcements.yaml new file mode 100644 index 0000000000..de80dcf6fe --- /dev/null +++ b/microsite/data/plugins/announcements.yaml @@ -0,0 +1,10 @@ +--- +title: Announcements +author: K-Phoen +authorUrl: https://github.com/K-Phoen +category: Discovery +description: Write and share announcements within Backstage. +documentation: https://github.com/K-Phoen/backstage-plugin-announcements/ +iconUrl: img/plugin-announcements-logo.png +npmPackageName: '@k-phoen/backstage-plugin-announcements' +addedDate: '2022-11-09' diff --git a/microsite/static/img/plugin-announcements-logo.png b/microsite/static/img/plugin-announcements-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..edb0caf8d9cce829df52de4c54149a0c4df85118 GIT binary patch literal 20496 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 literal 0 HcmV?d00001 From d65b19a3683a99f7b9134788531c7b5cbeb3e293 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 01:00:58 +0000 Subject: [PATCH 243/434] Update dependency husky to v8.0.2 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b7752e5f79..423b88c057 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24856,11 +24856,11 @@ __metadata: linkType: hard "husky@npm:^8.0.0": - version: 8.0.1 - resolution: "husky@npm:8.0.1" + version: 8.0.2 + resolution: "husky@npm:8.0.2" bin: husky: lib/bin.js - checksum: 943a73a13d0201318fd30e83d299bb81d866bd245b69e6277804c3b462638dc1921694cb94c2b8c920a4a187060f7d6058d3365152865406352e934c5fff70dc + checksum: e101656fcb56163d610488f186448c78b132626aa427094489d886ce9374955a90274912b0f3a34af3326eaa74977883b032e5f701d7aaf4554daa5a7931be43 languageName: node linkType: hard From b14bedf2d6ab50ccb9cd5961e449857fec0f021d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 01:11:50 +0000 Subject: [PATCH 244/434] Update dependency rollup-plugin-esbuild to v4.10.3 Signed-off-by: Renovate Bot --- yarn.lock | 68 ++++++++++--------------------------------------------- 1 file changed, 12 insertions(+), 56 deletions(-) diff --git a/yarn.lock b/yarn.lock index b7752e5f79..f00588d821 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12551,7 +12551,7 @@ __metadata: languageName: node linkType: hard -"@rollup/pluginutils@npm:^4.2.1": +"@rollup/pluginutils@npm:^4.1.1, @rollup/pluginutils@npm:^4.2.1": version: 4.2.1 resolution: "@rollup/pluginutils@npm:4.2.1" dependencies: @@ -12561,22 +12561,6 @@ __metadata: languageName: node linkType: hard -"@rollup/pluginutils@npm:^5.0.1": - version: 5.0.2 - resolution: "@rollup/pluginutils@npm:5.0.2" - dependencies: - "@types/estree": ^1.0.0 - estree-walker: ^2.0.2 - picomatch: ^2.3.1 - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 - peerDependenciesMeta: - rollup: - optional: true - checksum: edea15e543bebc7dcac3b0ac8bc7b8e8e6dbd46e2864dbe5dd28072de1fbd5b0e10d545a610c0edaa178e8a7ac432e2a2a52e547ece1308471412caba47db8ce - languageName: node - linkType: hard - "@rushstack/node-core-library@npm:3.45.4": version: 3.45.4 resolution: "@rushstack/node-core-library@npm:3.45.4" @@ -13817,13 +13801,6 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:^1.0.0": - version: 1.0.0 - resolution: "@types/estree@npm:1.0.0" - checksum: 910d97fb7092c6738d30a7430ae4786a38542023c6302b95d46f49420b797f21619cdde11fa92b338366268795884111c2eb10356e4bd2c8ad5b92941e9e6443 - languageName: node - linkType: hard - "@types/event-source-polyfill@npm:^1.0.0": version: 1.0.0 resolution: "@types/event-source-polyfill@npm:1.0.0" @@ -21111,20 +21088,13 @@ __metadata: languageName: node linkType: hard -"es-module-lexer@npm:^0.9.0": +"es-module-lexer@npm:^0.9.0, es-module-lexer@npm:^0.9.3": version: 0.9.3 resolution: "es-module-lexer@npm:0.9.3" checksum: 84bbab23c396281db2c906c766af58b1ae2a1a2599844a504df10b9e8dc77ec800b3211fdaa133ff700f5703d791198807bba25d9667392d27a5e9feda344da8 languageName: node linkType: hard -"es-module-lexer@npm:^1.0.5": - version: 1.1.0 - resolution: "es-module-lexer@npm:1.1.0" - checksum: 3e9f5019b69c6b2f04eb8478c4fdb4ed72cb8b4c97511b5dd39c1f498386ed8f5083c32067c15efcfabc7e8460cb65ed4627dd32405475715a898009922f41fa - languageName: node - linkType: hard - "es-shim-unscopables@npm:^1.0.0": version: 1.0.0 resolution: "es-shim-unscopables@npm:1.0.0" @@ -22077,13 +22047,6 @@ __metadata: languageName: node linkType: hard -"estree-walker@npm:^2.0.2": - version: 2.0.2 - resolution: "estree-walker@npm:2.0.2" - checksum: 6151e6f9828abe2259e57f5fd3761335bb0d2ebd76dc1a01048ccee22fabcfef3c0859300f6d83ff0d1927849368775ec5a6d265dde2f6de5a1be1721cd94efc - languageName: node - linkType: hard - "esutils@npm:^2.0.2": version: 2.0.3 resolution: "esutils@npm:2.0.3" @@ -26806,13 +26769,6 @@ __metadata: languageName: node linkType: hard -"joycon@npm:^3.1.1": - version: 3.1.1 - resolution: "joycon@npm:3.1.1" - checksum: 8003c9c3fc79c5c7602b1c7e9f7a2df2e9916f046b0dbad862aa589be78c15734d11beb9fe846f5e06138df22cb2ad29961b6a986ba81c4920ce2b15a7f11067 - languageName: node - linkType: hard - "jpeg-js@npm:^0.3.4": version: 0.3.7 resolution: "jpeg-js@npm:0.3.7" @@ -27289,7 +27245,7 @@ __metadata: languageName: node linkType: hard -"jsonc-parser@npm:^3.2.0": +"jsonc-parser@npm:^3.0.0, jsonc-parser@npm:^3.2.0": version: 3.2.0 resolution: "jsonc-parser@npm:3.2.0" checksum: 946dd9a5f326b745aa326d48a7257e3f4a4b62c5e98ec8e49fa2bdd8d96cef7e6febf1399f5c7016114fd1f68a1c62c6138826d5d90bc650448e3cf0951c53c7 @@ -34798,18 +34754,18 @@ __metadata: linkType: hard "rollup-plugin-esbuild@npm:^4.7.2": - version: 4.10.2 - resolution: "rollup-plugin-esbuild@npm:4.10.2" + version: 4.10.3 + resolution: "rollup-plugin-esbuild@npm:4.10.3" dependencies: - "@rollup/pluginutils": ^5.0.1 - debug: ^4.3.4 - es-module-lexer: ^1.0.5 - joycon: ^3.1.1 - jsonc-parser: ^3.2.0 + "@rollup/pluginutils": ^4.1.1 + debug: ^4.3.3 + es-module-lexer: ^0.9.3 + joycon: ^3.0.1 + jsonc-parser: ^3.0.0 peerDependencies: esbuild: ">=0.10.1" - rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 - checksum: 0f8e57fe40bf3b9a575cec039bf6d6789dedcbdc3ffee868fccdfe15f5e30e7fd68d7c6550cdbe9de1db7855c700f0bda8b4f10bf3d09b9f6b7516bc48334bc4 + rollup: ^1.20.0 || ^2.0.0 + checksum: 490a6a77573672cfda64a0222bb0dc2c202060bf4e9162571e24f2c26689e0e9faffced9c409eac80b35943dab06d1f0bd8bb3e2d3c6957b6bac1c0d6e5155cc languageName: node linkType: hard From b839cda297f971ce4e7a4c66c97022843b8284d0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 03:10:16 +0000 Subject: [PATCH 245/434] Update dependency @uiw/react-codemirror to v4.13.0 Signed-off-by: Renovate Bot --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index f1281b3332..e2e6929762 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15456,9 +15456,9 @@ __metadata: languageName: node linkType: hard -"@uiw/codemirror-extensions-basic-setup@npm:4.12.4": - version: 4.12.4 - resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.12.4" +"@uiw/codemirror-extensions-basic-setup@npm:4.13.0": + version: 4.13.0 + resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.13.0" dependencies: "@codemirror/autocomplete": ^6.0.0 "@codemirror/commands": ^6.0.0 @@ -15475,19 +15475,19 @@ __metadata: "@codemirror/search": ">=6.0.0" "@codemirror/state": ">=6.0.0" "@codemirror/view": ">=6.0.0" - checksum: 27c65e051383cedf0ea63b3c923caf10aa45dba7cec01b3a767d81d1d0114ba221665bf0d8166f8de67946806fde7348768cf4a7683a70907e9f2eef9c99dbea + checksum: bdff9fc4e32ecd9a31be75a1e003793ead1e7164748542307c92d50ffae1d66c5b1b2dbe9cbd6b4df1e31cac5fa8c27b8d5de4afb59373abae30b2cee96964d5 languageName: node linkType: hard "@uiw/react-codemirror@npm:^4.9.3": - version: 4.12.4 - resolution: "@uiw/react-codemirror@npm:4.12.4" + version: 4.13.0 + resolution: "@uiw/react-codemirror@npm:4.13.0" dependencies: "@babel/runtime": ^7.18.6 "@codemirror/commands": ^6.1.0 "@codemirror/state": ^6.1.1 "@codemirror/theme-one-dark": ^6.0.0 - "@uiw/codemirror-extensions-basic-setup": 4.12.4 + "@uiw/codemirror-extensions-basic-setup": 4.13.0 codemirror: ^6.0.0 peerDependencies: "@babel/runtime": ">=7.11.0" @@ -15497,7 +15497,7 @@ __metadata: codemirror: ">=6.0.0" react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: e7228beb95e918929e99e819c4f3b3920a16c5aca2477775c41bd16166af5bb7b5cefe240bd75b80fd9f61cde82086f93f8cd2dc1e2a4ecf02ff6d756cfd6f42 + checksum: ff5d4166dadf1ce14b8368fb1f98a6044410ebf315aa57ffc3c7721cea7b5eafd02e205230fc8be98700959d3732e435953495fbc8343af4be5f402b3444eb34 languageName: node linkType: hard From 2518959d3ab956c89cd2cb69e9e1c751c86b22a3 Mon Sep 17 00:00:00 2001 From: Casper Thygesen <73483987+cthtrifork@users.noreply.github.com> Date: Wed, 9 Nov 2022 06:43:09 +0100 Subject: [PATCH 246/434] Improved patch notes Co-authored-by: Philipp Hugenroth Signed-off-by: Casper Thygesen <73483987+cthtrifork@users.noreply.github.com> --- .changeset/rude-mayflies-heal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/rude-mayflies-heal.md b/.changeset/rude-mayflies-heal.md index 738ade0f3c..01cbf01e28 100644 --- a/.changeset/rude-mayflies-heal.md +++ b/.changeset/rude-mayflies-heal.md @@ -2,4 +2,4 @@ '@backstage/plugin-vault-backend': patch --- -Added errorHandler() middleware to vault-backend to prevent errors to cause a crash +Added `errorHandler()` middleware to `router` to prevent crashes caused by fatal errors in plugin backend From 85e57584f0b022d4dc9e90e0650d17202e54f0de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 9 Nov 2022 09:04:49 +0100 Subject: [PATCH 247/434] add togglable to word list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .github/vale/Vocab/Backstage/accept.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index 839afaa256..67213133dc 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -352,6 +352,7 @@ theia thumbsup todo todos +togglable tolerations Tolerations toolchain From 964186628e719fed0c2cd6c7bad72fac39a6f2dd Mon Sep 17 00:00:00 2001 From: Pascal Lukanek Date: Wed, 9 Nov 2022 09:38:16 +0100 Subject: [PATCH 248/434] Move name calculation to the EntityCountTile itself Signed-off-by: Pascal Lukanek --- .../Cards/OwnershipCard/ComponentsGrid.tsx | 15 +++++++-------- .../Cards/OwnershipCard/useGetEntities.ts | 9 ++------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx b/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx index ba037f791c..f996342454 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx +++ b/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx @@ -57,16 +57,16 @@ const EntityCountTile = ({ counter, type, kind, - name, url, }: { counter: number; - type: string; + type?: string; kind: string; - name: string; url: string; }) => { - const classes = useStyles({ type }); + const classes = useStyles({ type: type ?? kind }); + + const rawTitle = type ?? kind; return ( @@ -80,9 +80,9 @@ const EntityCountTile = ({ {counter} - {pluralize(name, counter)} + {pluralize(rawTitle.toLocaleUpperCase('en-US'), counter)} - {kind !== type && {kind}} + {type && {kind}} ); @@ -116,12 +116,11 @@ export const ComponentsGrid = ({ return ( {componentsWithCounters?.map(c => ( - + diff --git a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts index 3756e6827e..b36c41c459 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts +++ b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts @@ -136,7 +136,6 @@ export function useGetEntities( counter: number; type: string; kind: string; - name: string; queryParams: string; }[] | undefined; @@ -174,16 +173,14 @@ export function useGetEntities( const counts = ownedEntitiesList.items.reduce( (acc: EntityTypeProps[], ownedEntity) => { const match = acc.find( - x => - x.kind === ownedEntity.kind && - x.type === (ownedEntity.spec?.type ?? ownedEntity.kind), + x => x.kind === ownedEntity.kind && x.type === ownedEntity.spec?.type, ); if (match) { match.count += 1; } else { acc.push({ kind: ownedEntity.kind, - type: ownedEntity.spec?.type?.toString() ?? ownedEntity.kind, + type: ownedEntity.spec?.type?.toString(), count: 1, }); } @@ -199,13 +196,11 @@ export function useGetEntities( counter: topOwnedEntity.count, type: topOwnedEntity.type, kind: topOwnedEntity.kind, - name: topOwnedEntity.type.toLocaleUpperCase('en-US'), queryParams: getQueryParams(owners, topOwnedEntity), })) as Array<{ counter: number; type: string; kind: string; - name: string; queryParams: string; }>; }, [catalogApi, entity, relationsType]); From 81f8f95585845905ea7e1ca7232bb86bbebe7d78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Fri, 28 Oct 2022 14:54:30 +0200 Subject: [PATCH 249/434] feat(version-bridge): Make version bridge inspectable, to ease debugging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- .../version-bridge/src/lib/VersionedValue.ts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/version-bridge/src/lib/VersionedValue.ts b/packages/version-bridge/src/lib/VersionedValue.ts index b7c2153e38..cc8ae2aeae 100644 --- a/packages/version-bridge/src/lib/VersionedValue.ts +++ b/packages/version-bridge/src/lib/VersionedValue.ts @@ -36,9 +36,27 @@ export function createVersionedValueMap< Versions extends { [version: number]: unknown }, >(versions: Versions): VersionedValue { Object.freeze(versions); - return { + const versionedValue: VersionedValue = { atVersion(version) { return versions[version]; }, }; + Object.defineProperty(versionedValue, '$value', { + configurable: false, + enumerable: true, + get() { + const highest = Object.keys(versions) + .map(v => parseInt(v, 10)) + .sort((a, b) => b - a)[0]; + return versions[highest]; + }, + }); + Object.defineProperty(versionedValue, '$map', { + configurable: false, + enumerable: true, + get() { + return versions; + }, + }); + return versionedValue; } From e70984325dc88254f512f85a55ec75570415db2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Fri, 28 Oct 2022 15:36:07 +0200 Subject: [PATCH 250/434] chore(changeset): Add changeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- .changeset/early-jars-laugh.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/early-jars-laugh.md diff --git a/.changeset/early-jars-laugh.md b/.changeset/early-jars-laugh.md new file mode 100644 index 0000000000..1cf0a0e036 --- /dev/null +++ b/.changeset/early-jars-laugh.md @@ -0,0 +1,5 @@ +--- +'@backstage/version-bridge': minor +--- + +Debuggable/inspectable versioned values From dc5b8f7b3083df1dfa3db9abc5429104dd08b18f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Wed, 9 Nov 2022 10:22:42 +0100 Subject: [PATCH 251/434] chore(version-bridge): Removed highest-version shortcut, and made the map configurable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- .changeset/early-jars-laugh.md | 2 +- packages/version-bridge/src/lib/VersionedValue.ts | 12 +----------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/.changeset/early-jars-laugh.md b/.changeset/early-jars-laugh.md index 1cf0a0e036..9b9de4ab80 100644 --- a/.changeset/early-jars-laugh.md +++ b/.changeset/early-jars-laugh.md @@ -1,5 +1,5 @@ --- -'@backstage/version-bridge': minor +'@backstage/version-bridge': patch --- Debuggable/inspectable versioned values diff --git a/packages/version-bridge/src/lib/VersionedValue.ts b/packages/version-bridge/src/lib/VersionedValue.ts index cc8ae2aeae..51a9fd7879 100644 --- a/packages/version-bridge/src/lib/VersionedValue.ts +++ b/packages/version-bridge/src/lib/VersionedValue.ts @@ -41,18 +41,8 @@ export function createVersionedValueMap< return versions[version]; }, }; - Object.defineProperty(versionedValue, '$value', { - configurable: false, - enumerable: true, - get() { - const highest = Object.keys(versions) - .map(v => parseInt(v, 10)) - .sort((a, b) => b - a)[0]; - return versions[highest]; - }, - }); Object.defineProperty(versionedValue, '$map', { - configurable: false, + configurable: true, enumerable: true, get() { return versions; From 7869fab942c213c061656a41a66010f92f830e8a Mon Sep 17 00:00:00 2001 From: Pascal Lukanek Date: Wed, 9 Nov 2022 10:40:05 +0100 Subject: [PATCH 252/434] Type Signed-off-by: Pascal Lukanek --- .../org/src/components/Cards/OwnershipCard/useGetEntities.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts index b36c41c459..c928d9b55f 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts +++ b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts @@ -36,7 +36,7 @@ const limiter = limiterFactory(10); type EntityTypeProps = { kind: string; - type: string; + type?: string; count: number; }; From 48d5735ccce7aa091623df21bb06fe396af1d1f5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 10:03:39 +0000 Subject: [PATCH 253/434] Update dependency jose to v4.11.0 Signed-off-by: Renovate Bot --- yarn.lock | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index e2e6929762..3ec80a4b34 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26755,13 +26755,20 @@ __metadata: languageName: node linkType: hard -"jose@npm:^4.10.0, jose@npm:^4.6.0": +"jose@npm:^4.10.0": version: 4.10.4 resolution: "jose@npm:4.10.4" checksum: 0e6caaae0b0303534c0ac23711d45eadfbdbff63d9aeed80965c668b5532c254ab25b48afddc3e1ecfcfd36b4275dee41174a097c5a47a25ce04268c78f3c130 languageName: node linkType: hard +"jose@npm:^4.6.0": + version: 4.11.0 + resolution: "jose@npm:4.11.0" + checksum: 8d81e978e0da306911b61b1de1e2d78bd4903b4aa68a4b338b7c89c41edc3d56aea4d5ef4784a078a630dd6aa81f6328901ae3ce215f33b90d51ee8ebf4c9dbd + languageName: node + linkType: hard + "joycon@npm:^3.0.1": version: 3.1.0 resolution: "joycon@npm:3.1.0" From e13cd3feaf8494b04bb608b67dca85d9aee7e32e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 10:14:43 +0000 Subject: [PATCH 254/434] Update dependency msw to ^0.48.0 Signed-off-by: Renovate Bot --- .changeset/renovate-9097e77.md | 113 +++++++++ packages/backend-common/package.json | 2 +- packages/backend-test-utils/package.json | 2 +- packages/catalog-client/package.json | 2 +- packages/cli/package.json | 2 +- packages/config-loader/package.json | 2 +- packages/core-app-api/package.json | 2 +- packages/core-components/package.json | 2 +- packages/core-plugin-api/package.json | 2 +- packages/integration-react/package.json | 2 +- packages/integration/package.json | 2 +- packages/release-manifests/package.json | 2 +- packages/test-utils/package.json | 2 +- plugins/adr-backend/package.json | 2 +- plugins/adr/package.json | 2 +- plugins/airbrake-backend/package.json | 2 +- plugins/airbrake/package.json | 2 +- plugins/allure/package.json | 2 +- plugins/analytics-module-ga/package.json | 2 +- plugins/apache-airflow/package.json | 2 +- plugins/api-docs/package.json | 2 +- plugins/apollo-explorer/package.json | 2 +- plugins/app-backend/package.json | 2 +- plugins/auth-backend/package.json | 2 +- plugins/auth-node/package.json | 2 +- plugins/azure-devops-backend/package.json | 2 +- plugins/azure-devops/package.json | 2 +- plugins/azure-sites-backend/package.json | 2 +- plugins/azure-sites/package.json | 2 +- plugins/badges/package.json | 2 +- plugins/bitbucket-cloud-common/package.json | 2 +- plugins/bitrise/package.json | 2 +- .../catalog-backend-module-azure/package.json | 2 +- .../package.json | 2 +- .../package.json | 2 +- .../package.json | 2 +- .../package.json | 2 +- .../package.json | 2 +- .../package.json | 2 +- .../package.json | 2 +- plugins/catalog-backend/package.json | 2 +- plugins/catalog-graphql/package.json | 2 +- plugins/catalog-import/package.json | 2 +- plugins/circleci/package.json | 2 +- plugins/cloudbuild/package.json | 2 +- plugins/code-climate/package.json | 2 +- plugins/code-coverage-backend/package.json | 2 +- plugins/code-coverage/package.json | 2 +- plugins/codescene/package.json | 2 +- plugins/config-schema/package.json | 2 +- plugins/cost-insights/package.json | 2 +- plugins/dynatrace/package.json | 2 +- .../example-todo-list-backend/package.json | 2 +- plugins/example-todo-list-common/package.json | 2 +- plugins/example-todo-list/package.json | 2 +- plugins/explore-react/package.json | 2 +- plugins/explore/package.json | 2 +- plugins/firehydrant/package.json | 2 +- plugins/fossa/package.json | 2 +- plugins/gcalendar/package.json | 2 +- plugins/gcp-projects/package.json | 2 +- plugins/git-release-manager/package.json | 2 +- plugins/github-actions/package.json | 2 +- plugins/github-deployments/package.json | 2 +- plugins/github-issues/package.json | 2 +- .../github-pull-requests-board/package.json | 2 +- plugins/gitops-profiles/package.json | 2 +- plugins/gocd/package.json | 2 +- plugins/graphiql/package.json | 2 +- plugins/graphql-backend/package.json | 2 +- plugins/home/package.json | 2 +- plugins/ilert/package.json | 2 +- plugins/jenkins-backend/package.json | 2 +- plugins/jenkins/package.json | 2 +- plugins/kafka/package.json | 2 +- plugins/kubernetes/package.json | 2 +- plugins/lighthouse/package.json | 2 +- plugins/newrelic/package.json | 2 +- plugins/org-react/package.json | 2 +- plugins/org/package.json | 2 +- plugins/pagerduty/package.json | 2 +- plugins/periskop-backend/package.json | 2 +- plugins/periskop/package.json | 2 +- plugins/permission-backend/package.json | 2 +- plugins/permission-common/package.json | 2 +- plugins/permission-node/package.json | 2 +- plugins/playlist-backend/package.json | 2 +- plugins/playlist/package.json | 2 +- plugins/proxy-backend/package.json | 2 +- plugins/rollbar-backend/package.json | 2 +- plugins/rollbar/package.json | 2 +- .../package.json | 2 +- plugins/scaffolder-backend/package.json | 2 +- plugins/scaffolder/package.json | 2 +- plugins/search/package.json | 2 +- plugins/sentry/package.json | 2 +- plugins/shortcuts/package.json | 2 +- plugins/sonarqube-backend/package.json | 2 +- plugins/sonarqube/package.json | 2 +- plugins/splunk-on-call/package.json | 2 +- plugins/stack-overflow/package.json | 2 +- plugins/tech-insights/package.json | 2 +- plugins/tech-radar/package.json | 2 +- .../techdocs-addons-test-utils/package.json | 2 +- plugins/techdocs-backend/package.json | 2 +- .../package.json | 2 +- plugins/techdocs/package.json | 2 +- plugins/todo-backend/package.json | 2 +- plugins/todo/package.json | 2 +- plugins/user-settings/package.json | 2 +- plugins/vault-backend/package.json | 2 +- plugins/vault/package.json | 2 +- plugins/xcmetrics/package.json | 2 +- yarn.lock | 232 +++++++++--------- 114 files changed, 341 insertions(+), 228 deletions(-) create mode 100644 .changeset/renovate-9097e77.md diff --git a/.changeset/renovate-9097e77.md b/.changeset/renovate-9097e77.md new file mode 100644 index 0000000000..5981a320d0 --- /dev/null +++ b/.changeset/renovate-9097e77.md @@ -0,0 +1,113 @@ +--- +'@backstage/backend-common': patch +'@backstage/backend-test-utils': patch +'@backstage/catalog-client': patch +'@backstage/cli': patch +'@backstage/config-loader': patch +'@backstage/core-app-api': patch +'@backstage/core-components': patch +'@backstage/core-plugin-api': patch +'@backstage/integration-react': patch +'@backstage/integration': patch +'@backstage/release-manifests': patch +'@backstage/test-utils': patch +'@backstage/plugin-adr-backend': patch +'@backstage/plugin-adr': patch +'@backstage/plugin-airbrake-backend': patch +'@backstage/plugin-airbrake': patch +'@backstage/plugin-allure': patch +'@backstage/plugin-analytics-module-ga': patch +'@backstage/plugin-apache-airflow': patch +'@backstage/plugin-api-docs': patch +'@backstage/plugin-apollo-explorer': patch +'@backstage/plugin-app-backend': patch +'@backstage/plugin-auth-backend': patch +'@backstage/plugin-auth-node': patch +'@backstage/plugin-azure-devops-backend': patch +'@backstage/plugin-azure-devops': patch +'@backstage/plugin-azure-sites-backend': patch +'@backstage/plugin-azure-sites': patch +'@backstage/plugin-badges': patch +'@backstage/plugin-bitbucket-cloud-common': patch +'@backstage/plugin-bitrise': patch +'@backstage/plugin-catalog-backend-module-azure': patch +'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch +'@backstage/plugin-catalog-backend-module-bitbucket-server': patch +'@backstage/plugin-catalog-backend-module-bitbucket': patch +'@backstage/plugin-catalog-backend-module-gerrit': patch +'@backstage/plugin-catalog-backend-module-github': patch +'@backstage/plugin-catalog-backend-module-gitlab': patch +'@backstage/plugin-catalog-backend-module-msgraph': patch +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-catalog-graphql': patch +'@backstage/plugin-catalog-import': patch +'@backstage/plugin-circleci': patch +'@backstage/plugin-cloudbuild': patch +'@backstage/plugin-code-climate': patch +'@backstage/plugin-code-coverage-backend': patch +'@backstage/plugin-code-coverage': patch +'@backstage/plugin-codescene': patch +'@backstage/plugin-config-schema': patch +'@backstage/plugin-cost-insights': patch +'@backstage/plugin-dynatrace': patch +'@backstage/plugin-explore-react': patch +'@backstage/plugin-explore': patch +'@backstage/plugin-firehydrant': patch +'@backstage/plugin-fossa': patch +'@backstage/plugin-gcalendar': patch +'@backstage/plugin-gcp-projects': patch +'@backstage/plugin-git-release-manager': patch +'@backstage/plugin-github-actions': patch +'@backstage/plugin-github-deployments': patch +'@backstage/plugin-github-issues': patch +'@backstage/plugin-github-pull-requests-board': patch +'@backstage/plugin-gitops-profiles': patch +'@backstage/plugin-gocd': patch +'@backstage/plugin-graphiql': patch +'@backstage/plugin-graphql-backend': patch +'@backstage/plugin-home': patch +'@backstage/plugin-ilert': patch +'@backstage/plugin-jenkins-backend': patch +'@backstage/plugin-jenkins': patch +'@backstage/plugin-kafka': patch +'@backstage/plugin-kubernetes': patch +'@backstage/plugin-lighthouse': patch +'@backstage/plugin-newrelic': patch +'@backstage/plugin-org-react': patch +'@backstage/plugin-org': patch +'@backstage/plugin-pagerduty': patch +'@backstage/plugin-periskop-backend': patch +'@backstage/plugin-periskop': patch +'@backstage/plugin-permission-backend': patch +'@backstage/plugin-permission-common': patch +'@backstage/plugin-permission-node': patch +'@backstage/plugin-playlist-backend': patch +'@backstage/plugin-playlist': patch +'@backstage/plugin-proxy-backend': patch +'@backstage/plugin-rollbar-backend': patch +'@backstage/plugin-rollbar': patch +'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch +'@backstage/plugin-scaffolder-backend': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-search': patch +'@backstage/plugin-sentry': patch +'@backstage/plugin-shortcuts': patch +'@backstage/plugin-sonarqube-backend': patch +'@backstage/plugin-sonarqube': patch +'@backstage/plugin-splunk-on-call': patch +'@backstage/plugin-stack-overflow': patch +'@backstage/plugin-tech-insights': patch +'@backstage/plugin-tech-radar': patch +'@backstage/plugin-techdocs-addons-test-utils': patch +'@backstage/plugin-techdocs-backend': patch +'@backstage/plugin-techdocs-module-addons-contrib': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-todo-backend': patch +'@backstage/plugin-todo': patch +'@backstage/plugin-user-settings': patch +'@backstage/plugin-vault-backend': patch +'@backstage/plugin-vault': patch +'@backstage/plugin-xcmetrics': patch +--- + +Updated dependency `msw` to `^0.48.0`. diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index e2f6360871..ed934f64f8 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -117,7 +117,7 @@ "better-sqlite3": "^7.5.0", "http-errors": "^2.0.0", "mock-fs": "^5.1.0", - "msw": "^0.47.0", + "msw": "^0.48.0", "mysql2": "^2.2.5", "recursive-readdir": "^2.2.2", "supertest": "^6.1.3" diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 79b5ed6d97..12c00ee2ea 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -41,7 +41,7 @@ "@backstage/config": "workspace:^", "better-sqlite3": "^7.5.0", "knex": "^2.0.0", - "msw": "^0.47.0", + "msw": "^0.48.0", "mysql2": "^2.2.5", "pg": "^8.3.0", "testcontainers": "^8.1.2", diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index b5f4d69858..ac98d976bd 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -38,7 +38,7 @@ }, "devDependencies": { "@backstage/cli": "workspace:^", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/packages/cli/package.json b/packages/cli/package.json index 08d1ddeab5..3868f59623 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -155,7 +155,7 @@ "@types/yarnpkg__lockfile": "^1.1.4", "del": "^6.0.0", "mock-fs": "^5.1.0", - "msw": "^0.47.0", + "msw": "^0.48.0", "nodemon": "^2.0.2", "ts-node": "^10.0.0", "type-fest": "^2.0.0" diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index e322636d35..f784e1a556 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -56,7 +56,7 @@ "@types/node": "^16.11.26", "@types/yup": "^0.29.13", "mock-fs": "^5.1.0", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 09d5c75fa8..6f6eda59ab 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -57,7 +57,7 @@ "@types/node": "^16.11.26", "@types/zen-observable": "^0.8.0", "cross-fetch": "^3.1.5", - "msw": "^0.47.0", + "msw": "^0.48.0", "react-router-beta": "npm:react-router@6.0.0-beta.0", "react-router-dom-beta": "npm:react-router-dom@6.0.0-beta.0", "react-router-dom-stable": "npm:react-router-dom@^6.3.0", diff --git a/packages/core-components/package.json b/packages/core-components/package.json index f2d82fc4d8..c7a667e7e2 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -99,7 +99,7 @@ "@types/react-window": "^1.8.5", "@types/zen-observable": "^0.8.0", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index 7de98c55f9..f305a8d51d 100644 --- a/packages/core-plugin-api/package.json +++ b/packages/core-plugin-api/package.json @@ -57,7 +57,7 @@ "@types/prop-types": "^15.7.3", "@types/zen-observable": "^0.8.0", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index c1ee32ae1e..d1a4250efb 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -45,7 +45,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/packages/integration/package.json b/packages/integration/package.json index bbed7de2d1..07c42eb206 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -46,7 +46,7 @@ "@backstage/config-loader": "workspace:^", "@backstage/test-utils": "workspace:^", "@types/luxon": "^3.0.0", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/packages/release-manifests/package.json b/packages/release-manifests/package.json index 27be30f5f3..6bd8f8ca4d 100644 --- a/packages/release-manifests/package.json +++ b/packages/release-manifests/package.json @@ -38,7 +38,7 @@ "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "@types/node": "^16.0.0", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 70e6dca4cc..b9c164b97d 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -57,7 +57,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/node": "^16.11.26", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/adr-backend/package.json b/plugins/adr-backend/package.json index 8f73088fbf..7ab4aab172 100644 --- a/plugins/adr-backend/package.json +++ b/plugins/adr-backend/package.json @@ -46,7 +46,7 @@ "@backstage/cli": "workspace:^", "@types/marked": "^4.0.0", "@types/supertest": "^2.0.8", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/adr/package.json b/plugins/adr/package.json index 533a581b47..0495be1614 100644 --- a/plugins/adr/package.json +++ b/plugins/adr/package.json @@ -55,7 +55,7 @@ "@types/git-url-parse": "^9.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/airbrake-backend/package.json b/plugins/airbrake-backend/package.json index d23a068e63..d2bc8206eb 100644 --- a/plugins/airbrake-backend/package.json +++ b/plugins/airbrake-backend/package.json @@ -35,7 +35,7 @@ "@backstage/cli": "workspace:^", "@types/http-proxy-middleware": "^0.19.3", "@types/supertest": "^2.0.8", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json index 639514f073..d34c31e89b 100644 --- a/plugins/airbrake/package.json +++ b/plugins/airbrake/package.json @@ -50,7 +50,7 @@ "@types/node": "^16.11.26", "@types/object-hash": "^2.2.1", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/allure/package.json b/plugins/allure/package.json index ffb06c52ae..18b3a21612 100644 --- a/plugins/allure/package.json +++ b/plugins/allure/package.json @@ -47,7 +47,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json index 093a44939b..a442a8f686 100644 --- a/plugins/analytics-module-ga/package.json +++ b/plugins/analytics-module-ga/package.json @@ -45,7 +45,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json index 2ed0bcbf73..55db3b6b75 100644 --- a/plugins/apache-airflow/package.json +++ b/plugins/apache-airflow/package.json @@ -43,7 +43,7 @@ "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index d67e035345..9041176057 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -66,7 +66,7 @@ "@types/node": "^16.11.26", "@types/swagger-ui-react": "^4.1.1", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json index 877b6218c7..02b5883d07 100644 --- a/plugins/apollo-explorer/package.json +++ b/plugins/apollo-explorer/package.json @@ -45,7 +45,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index 3c7801e9b2..a2eea49792 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -58,7 +58,7 @@ "@types/supertest": "^2.0.8", "get-port": "^6.1.2", "mock-fs": "^5.1.0", - "msw": "^0.47.0", + "msw": "^0.48.0", "node-fetch": "^2.6.7", "supertest": "^6.1.3" }, diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index ec1b3a3b23..ff6534814a 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -89,7 +89,7 @@ "@types/passport-saml": "^1.1.3", "@types/passport-strategy": "^0.2.35", "@types/xml2js": "^0.4.7", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 2fc83f5002..156af7f1bf 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -35,7 +35,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "lodash": "^4.17.21", - "msw": "^0.47.0", + "msw": "^0.48.0", "uuid": "^8.0.0" }, "files": [ diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json index a5fe6e2488..eaf689d676 100644 --- a/plugins/azure-devops-backend/package.json +++ b/plugins/azure-devops-backend/package.json @@ -37,7 +37,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index 351d22eab7..33b3d05ff8 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -56,7 +56,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/azure-sites-backend/package.json b/plugins/azure-sites-backend/package.json index fb495033d4..ae1f2a6f3d 100644 --- a/plugins/azure-sites-backend/package.json +++ b/plugins/azure-sites-backend/package.json @@ -48,7 +48,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/azure-sites/package.json b/plugins/azure-sites/package.json index 186052c5c4..ac152be385 100644 --- a/plugins/azure-sites/package.json +++ b/plugins/azure-sites/package.json @@ -57,7 +57,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/badges/package.json b/plugins/badges/package.json index c5810532f6..bd3b2f64b1 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -54,7 +54,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/bitbucket-cloud-common/package.json b/plugins/bitbucket-cloud-common/package.json index fbc63e4497..3423a09b3e 100644 --- a/plugins/bitbucket-cloud-common/package.json +++ b/plugins/bitbucket-cloud-common/package.json @@ -33,7 +33,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@openapitools/openapi-generator-cli": "^2.4.26", - "msw": "^0.47.0", + "msw": "^0.48.0", "ts-morph": "^15.0.0" }, "files": [ diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index a4943b2a0c..d6527f9973 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -51,7 +51,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "@types/recharts": "^1.8.15", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index cf5c1997e0..ae8f7e5bfe 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -44,7 +44,7 @@ "@backstage/plugin-catalog-node": "workspace:^", "@backstage/types": "workspace:^", "lodash": "^4.17.21", - "msw": "^0.47.0", + "msw": "^0.48.0", "node-fetch": "^2.6.7", "uuid": "^8.0.0", "winston": "^3.2.1" diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index 0210d0040e..45876470d4 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -48,7 +48,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "luxon": "^3.0.0", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "alpha", diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index c75a4b531c..b2e3f81f04 100644 --- a/plugins/catalog-backend-module-bitbucket-server/package.json +++ b/plugins/catalog-backend-module-bitbucket-server/package.json @@ -50,7 +50,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "luxon": "^3.0.0", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "alpha", diff --git a/plugins/catalog-backend-module-bitbucket/package.json b/plugins/catalog-backend-module-bitbucket/package.json index cde873d069..2d36eaf5a6 100644 --- a/plugins/catalog-backend-module-bitbucket/package.json +++ b/plugins/catalog-backend-module-bitbucket/package.json @@ -42,7 +42,7 @@ "@backstage/plugin-catalog-backend": "workspace:^", "@backstage/types": "workspace:^", "lodash": "^4.17.21", - "msw": "^0.47.0", + "msw": "^0.48.0", "node-fetch": "^2.6.7", "winston": "^3.2.1" }, diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 0b46e4e820..9cfe9d111e 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -39,7 +39,7 @@ "@backstage/plugin-catalog-backend": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", "fs-extra": "10.1.0", - "msw": "^0.47.0", + "msw": "^0.48.0", "node-fetch": "^2.6.7", "uuid": "^8.0.0", "winston": "^3.2.1" diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index e939594b67..3189384c7e 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -48,7 +48,7 @@ "@octokit/rest": "^19.0.3", "git-url-parse": "^13.0.0", "lodash": "^4.17.21", - "msw": "^0.47.0", + "msw": "^0.48.0", "node-fetch": "^2.6.7", "uuid": "^8.0.0", "winston": "^3.2.1" diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index a94aa6e6a5..71f14ba57f 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -44,7 +44,7 @@ "@backstage/plugin-catalog-node": "workspace:^", "@backstage/types": "workspace:^", "lodash": "^4.17.21", - "msw": "^0.47.0", + "msw": "^0.48.0", "node-fetch": "^2.6.7", "uuid": "^8.0.0", "winston": "^3.2.1" diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index 6d9770fce1..1aa5bc82c7 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -55,7 +55,7 @@ "@backstage/cli": "workspace:^", "@types/lodash": "^4.14.151", "luxon": "^3.0.0", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "alpha", diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 3f78439d58..abfd64c20f 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -80,7 +80,7 @@ "@types/uuid": "^8.0.0", "better-sqlite3": "^7.5.0", "luxon": "^3.0.0", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.3", "wait-for-expect": "^3.0.2" }, diff --git a/plugins/catalog-graphql/package.json b/plugins/catalog-graphql/package.json index 503c7eb3b0..1accb40a49 100644 --- a/plugins/catalog-graphql/package.json +++ b/plugins/catalog-graphql/package.json @@ -53,7 +53,7 @@ "@graphql-codegen/typescript": "^2.4.2", "@graphql-codegen/typescript-resolvers": "^2.4.3", "@graphql-tools/schema": "^9.0.0", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index aaa99ada4b..a097e2efeb 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -68,7 +68,7 @@ "@testing-library/react-hooks": "^8.0.0", "@testing-library/user-event": "^14.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index a31158e0df..fa4fa12d07 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -63,7 +63,7 @@ "@types/humanize-duration": "^3.25.1", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index a50ded8d0f..5727c55bc7 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -60,7 +60,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/code-climate/package.json b/plugins/code-climate/package.json index 193842dc0e..8cde9a28ed 100644 --- a/plugins/code-climate/package.json +++ b/plugins/code-climate/package.json @@ -49,7 +49,7 @@ "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index 5b8c925884..d6b9fa99b5 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -42,7 +42,7 @@ "@backstage/cli": "workspace:^", "@types/express-xml-bodyparser": "^0.3.2", "@types/supertest": "^2.0.8", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.6", "xml2js": "^0.4.23" }, diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 357a4d9ebf..fbb24dcd94 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -56,7 +56,7 @@ "@types/node": "^16.11.26", "@types/recharts": "^1.8.15", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/codescene/package.json b/plugins/codescene/package.json index f190c4db5a..31970219e3 100644 --- a/plugins/codescene/package.json +++ b/plugins/codescene/package.json @@ -47,7 +47,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 51ae7ed86b..a4e4f6f715 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -49,7 +49,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index 9896c3e60e..4f882fc431 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -73,7 +73,7 @@ "@types/yup": "^0.29.13", "canvas": "^2.10.2", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/dynatrace/package.json b/plugins/dynatrace/package.json index 3a973c6779..6b7d4f3781 100644 --- a/plugins/dynatrace/package.json +++ b/plugins/dynatrace/package.json @@ -45,7 +45,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "express": "^4.18.1", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index 863de06e21..152404f292 100644 --- a/plugins/example-todo-list-backend/package.json +++ b/plugins/example-todo-list-backend/package.json @@ -38,7 +38,7 @@ "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", "@types/uuid": "^8.0.0", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/example-todo-list-common/package.json b/plugins/example-todo-list-common/package.json index 23a16e10c7..87e759177c 100644 --- a/plugins/example-todo-list-common/package.json +++ b/plugins/example-todo-list-common/package.json @@ -32,7 +32,7 @@ "@backstage/test-utils": "workspace:^", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index cc3fb43222..df25b76395 100644 --- a/plugins/example-todo-list/package.json +++ b/plugins/example-todo-list/package.json @@ -43,7 +43,7 @@ "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/explore-react/package.json b/plugins/explore-react/package.json index 27ee4c23df..b029d2bf9b 100644 --- a/plugins/explore-react/package.json +++ b/plugins/explore-react/package.json @@ -43,7 +43,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 7924524c3c..61a58c6d45 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -61,7 +61,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index 0a520c1928..e1ffe6c3d8 100644 --- a/plugins/firehydrant/package.json +++ b/plugins/firehydrant/package.json @@ -46,7 +46,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index 1eb4bdf4a9..17f1b3c2a5 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -59,7 +59,7 @@ "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/gcalendar/package.json b/plugins/gcalendar/package.json index 875958a9d9..15cfdc0dba 100644 --- a/plugins/gcalendar/package.json +++ b/plugins/gcalendar/package.json @@ -54,7 +54,7 @@ "@types/node": "^16.11.26", "@types/sanitize-html": "^2.6.2", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 1209998237..74e7bc332c 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -55,7 +55,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json index cad07ef6b8..3253629b04 100644 --- a/plugins/git-release-manager/package.json +++ b/plugins/git-release-manager/package.json @@ -53,7 +53,7 @@ "@types/node": "^16.11.26", "@types/recharts": "^1.8.15", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 444591bd5d..f8081bae08 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -62,7 +62,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index 10424aa926..534804cf50 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -51,7 +51,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/github-issues/package.json b/plugins/github-issues/package.json index 798ed54214..122e0e7709 100644 --- a/plugins/github-issues/package.json +++ b/plugins/github-issues/package.json @@ -51,7 +51,7 @@ "@types/node": "*", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/github-pull-requests-board/package.json b/plugins/github-pull-requests-board/package.json index 0932c6bd4b..e551b12fa2 100644 --- a/plugins/github-pull-requests-board/package.json +++ b/plugins/github-pull-requests-board/package.json @@ -58,7 +58,7 @@ "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "peerDependencies": { "react": "^16.13.1 || ^17.0.0", diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index 029a6ce5d6..f5b6f5cc40 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -55,7 +55,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/gocd/package.json b/plugins/gocd/package.json index e16957a975..f8128f0e93 100644 --- a/plugins/gocd/package.json +++ b/plugins/gocd/package.json @@ -58,7 +58,7 @@ "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 1103e9f718..8bcc6ea95c 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -58,7 +58,7 @@ "@types/codemirror": "^5.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/graphql-backend/package.json b/plugins/graphql-backend/package.json index 61b18a493b..c6c2d3559e 100644 --- a/plugins/graphql-backend/package.json +++ b/plugins/graphql-backend/package.json @@ -52,7 +52,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/home/package.json b/plugins/home/package.json index e1a31b0b65..6048316f6b 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -61,7 +61,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index 154f0e30fd..0f5c8faa62 100644 --- a/plugins/ilert/package.json +++ b/plugins/ilert/package.json @@ -51,7 +51,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/jenkins-backend/package.json b/plugins/jenkins-backend/package.json index 756dda53ed..f9ce0826a0 100644 --- a/plugins/jenkins-backend/package.json +++ b/plugins/jenkins-backend/package.json @@ -44,7 +44,7 @@ "@backstage/cli": "workspace:^", "@types/jenkins": "^0.23.1", "@types/supertest": "^2.0.8", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index 2b3edf3d00..3068f794be 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -62,7 +62,7 @@ "@types/node": "^16.11.26", "@types/testing-library__jest-dom": "^5.9.1", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index 21320f28da..b4c2276301 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -51,7 +51,7 @@ "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", "jest-when": "^3.1.0", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 09ce173b82..e1e2c783fe 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -66,7 +66,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 5cc2071372..0e6f684360 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -60,7 +60,7 @@ "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index 325fde6c62..45576eb07a 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -54,7 +54,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index 7f500a09a7..bc2b7f426d 100644 --- a/plugins/org-react/package.json +++ b/plugins/org-react/package.json @@ -54,7 +54,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/org/package.json b/plugins/org/package.json index 54d6f3f9c4..a8ea9946ec 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -57,7 +57,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index aa958e7f06..4ceb3d2193 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -61,7 +61,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/periskop-backend/package.json b/plugins/periskop-backend/package.json index bda4c40d86..276c0aa137 100644 --- a/plugins/periskop-backend/package.json +++ b/plugins/periskop-backend/package.json @@ -35,7 +35,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/periskop/package.json b/plugins/periskop/package.json index e86bb4de5f..3bc1136acb 100644 --- a/plugins/periskop/package.json +++ b/plugins/periskop/package.json @@ -50,7 +50,7 @@ "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 8a31c60716..5566520b6a 100644 --- a/plugins/permission-backend/package.json +++ b/plugins/permission-backend/package.json @@ -42,7 +42,7 @@ "@backstage/cli": "workspace:^", "@types/lodash": "^4.14.151", "@types/supertest": "^2.0.8", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/permission-common/package.json b/plugins/permission-common/package.json index 394cbe896f..9afa8576fe 100644 --- a/plugins/permission-common/package.json +++ b/plugins/permission-common/package.json @@ -50,6 +50,6 @@ }, "devDependencies": { "@backstage/cli": "workspace:^", - "msw": "^0.47.0" + "msw": "^0.48.0" } } diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index c462575627..4543292cc1 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -48,7 +48,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/playlist-backend/package.json b/plugins/playlist-backend/package.json index 7997d72711..72c58e1c32 100644 --- a/plugins/playlist-backend/package.json +++ b/plugins/playlist-backend/package.json @@ -45,7 +45,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index 5fc21a733a..f50b666c6b 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -62,7 +62,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.47.0", + "msw": "^0.48.0", "swr": "^1.1.2" }, "files": [ diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index c68fe15c4f..dd9678a28a 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -51,7 +51,7 @@ "@types/supertest": "^2.0.8", "@types/uuid": "^8.0.0", "@types/yup": "^0.29.13", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index 8265dde9f0..2e7a97fe8b 100644 --- a/plugins/rollbar-backend/package.json +++ b/plugins/rollbar-backend/package.json @@ -52,7 +52,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index a2627ae7d1..0664b0c41b 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -62,7 +62,7 @@ "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index 0cc04104c0..6c5ddc160c 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -40,7 +40,7 @@ "@types/fs-extra": "^9.0.1", "@types/mock-fs": "^4.13.0", "mock-fs": "^5.1.0", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 45300224c7..0eaa9aca2d 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -93,7 +93,7 @@ "esbuild": "^0.15.0", "jest-when": "^3.1.0", "mock-fs": "^5.1.0", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.3", "yaml": "^2.0.0" }, diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 399c86bfd5..c2d4bdd334 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -96,7 +96,7 @@ "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", "event-source-polyfill": "1.0.25", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/search/package.json b/plugins/search/package.json index 7d4dad7e2c..3631dbf073 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -66,7 +66,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index 99f63f83f6..9e2fc84e95 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -62,7 +62,7 @@ "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index 6f3971458e..bd24319681 100644 --- a/plugins/shortcuts/package.json +++ b/plugins/shortcuts/package.json @@ -50,7 +50,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/sonarqube-backend/package.json b/plugins/sonarqube-backend/package.json index 2f6dad8fd6..269b6cc761 100644 --- a/plugins/sonarqube-backend/package.json +++ b/plugins/sonarqube-backend/package.json @@ -36,7 +36,7 @@ "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "@types/supertest": "^2.0.12", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.2.4" }, "files": [ diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index a731150dd9..2d217ee57c 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -59,7 +59,7 @@ "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index fc415994d3..dfb4aef654 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -60,7 +60,7 @@ "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "configSchema": "config.d.ts", "files": [ diff --git a/plugins/stack-overflow/package.json b/plugins/stack-overflow/package.json index 185ed36ccd..d9748e41dd 100644 --- a/plugins/stack-overflow/package.json +++ b/plugins/stack-overflow/package.json @@ -48,7 +48,7 @@ "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index be79cb2c14..cf687a3763 100644 --- a/plugins/tech-insights/package.json +++ b/plugins/tech-insights/package.json @@ -56,7 +56,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index b04d50a7c8..ad4e84803b 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -59,7 +59,7 @@ "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index 425ece8faf..df41006048 100644 --- a/plugins/techdocs-addons-test-utils/package.json +++ b/plugins/techdocs-addons-test-utils/package.json @@ -63,7 +63,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 736c409af5..9c31f79c39 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -59,7 +59,7 @@ "@backstage/cli": "workspace:^", "@backstage/plugin-search-backend-node": "workspace:^", "@types/dockerode": "^3.3.0", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index c06425f27a..85255010be 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -61,7 +61,7 @@ "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index e36eeba8ef..a72b13ab6e 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -78,7 +78,7 @@ "@types/node": "^16.11.26", "canvas": "^2.10.2", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index 9318e10d0a..10762a501b 100644 --- a/plugins/todo-backend/package.json +++ b/plugins/todo-backend/package.json @@ -45,7 +45,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/todo/package.json b/plugins/todo/package.json index 04aec7ea7c..4e8fd21657 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -54,7 +54,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 56b9601091..b70002c177 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -58,7 +58,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/vault-backend/package.json b/plugins/vault-backend/package.json index 219ccbb319..7eeb568cf9 100644 --- a/plugins/vault-backend/package.json +++ b/plugins/vault-backend/package.json @@ -53,7 +53,7 @@ "@backstage/cli": "workspace:^", "@types/compression": "^1.7.2", "@types/supertest": "^2.0.8", - "msw": "^0.47.0", + "msw": "^0.48.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/vault/package.json b/plugins/vault/package.json index 37a8bd6805..04607f21a7 100644 --- a/plugins/vault/package.json +++ b/plugins/vault/package.json @@ -57,7 +57,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index b4d575535c..529917ee61 100644 --- a/plugins/xcmetrics/package.json +++ b/plugins/xcmetrics/package.json @@ -49,7 +49,7 @@ "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.47.0" + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/yarn.lock b/yarn.lock index 5750b9cf44..3c1ec50ab9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3198,7 +3198,7 @@ __metadata: minimist: ^1.2.5 mock-fs: ^5.1.0 morgan: ^1.10.0 - msw: ^0.47.0 + msw: ^0.48.0 mysql2: ^2.2.5 node-abort-controller: ^3.0.1 node-fetch: ^2.6.7 @@ -3283,7 +3283,7 @@ __metadata: "@backstage/config": "workspace:^" better-sqlite3: ^7.5.0 knex: ^2.0.0 - msw: ^0.47.0 + msw: ^0.48.0 mysql2: ^2.2.5 pg: ^8.3.0 testcontainers: ^8.1.2 @@ -3310,7 +3310,7 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/errors": "workspace:^" cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 languageName: unknown linkType: soft @@ -3452,7 +3452,7 @@ __metadata: mini-css-extract-plugin: ^2.4.2 minimatch: 5.1.0 mock-fs: ^5.1.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 node-libs-browser: ^2.2.1 nodemon: ^2.0.2 @@ -3535,7 +3535,7 @@ __metadata: json-schema-merge-allof: ^0.8.1 json-schema-traverse: ^1.0.0 mock-fs: ^5.1.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 typescript-json-schema: ^0.54.0 yaml: ^2.0.0 @@ -3583,7 +3583,7 @@ __metadata: "@types/prop-types": ^15.7.3 "@types/zen-observable": ^0.8.0 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 prop-types: ^15.7.2 react-router-beta: "npm:react-router@6.0.0-beta.0" react-router-dom-beta: "npm:react-router-dom@6.0.0-beta.0" @@ -3696,7 +3696,7 @@ __metadata: history: ^5.0.0 immer: ^9.0.1 lodash: ^4.17.21 - msw: ^0.47.0 + msw: ^0.48.0 pluralize: ^8.0.0 prop-types: ^15.7.2 qs: ^6.9.4 @@ -3759,7 +3759,7 @@ __metadata: "@types/zen-observable": ^0.8.0 cross-fetch: ^3.1.5 history: ^5.0.0 - msw: ^0.47.0 + msw: ^0.48.0 prop-types: ^15.7.2 zen-observable: ^0.8.15 peerDependencies: @@ -3887,7 +3887,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -3926,7 +3926,7 @@ __metadata: git-url-parse: ^13.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 languageName: unknown linkType: soft @@ -3947,7 +3947,7 @@ __metadata: "@types/supertest": ^2.0.8 luxon: ^3.0.0 marked: ^4.0.14 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.5 supertest: ^6.1.3 winston: ^3.2.1 @@ -3993,7 +3993,7 @@ __metadata: "@types/node": "*" cross-fetch: ^3.1.5 git-url-parse: ^13.0.0 - msw: ^0.47.0 + msw: ^0.48.0 octokit: ^2.0.0 react-markdown: ^8.0.0 react-use: ^17.2.4 @@ -4017,7 +4017,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 http-proxy-middleware: ^2.0.0 - msw: ^0.47.0 + msw: ^0.48.0 supertest: ^6.1.6 winston: ^3.2.1 yn: ^4.0.0 @@ -4046,7 +4046,7 @@ __metadata: "@types/node": ^16.11.26 "@types/object-hash": ^2.2.1 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 object-hash: ^3.0.0 react-use: ^17.2.4 peerDependencies: @@ -4076,7 +4076,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -4104,7 +4104,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-ga: ^3.3.0 react-use: ^17.2.4 peerDependencies: @@ -4130,7 +4130,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 qs: ^6.10.1 react-use: ^17.2.4 peerDependencies: @@ -4179,7 +4179,7 @@ __metadata: graphql: ^16.0.0 graphql-ws: ^5.4.1 isomorphic-form-data: ^2.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 swagger-ui-react: ^4.11.1 peerDependencies: @@ -4210,7 +4210,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": "*" cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 use-deep-compare-effect: ^1.8.1 peerDependencies: @@ -4242,7 +4242,7 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 mock-fs: ^5.1.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 supertest: ^6.1.3 winston: ^3.2.1 @@ -4293,7 +4293,7 @@ __metadata: luxon: ^3.0.0 minimatch: ^5.0.0 morgan: ^1.10.0 - msw: ^0.47.0 + msw: ^0.48.0 node-cache: ^5.1.2 node-fetch: ^2.6.7 openid-client: ^5.2.1 @@ -4327,7 +4327,7 @@ __metadata: express: ^4.17.1 jose: ^4.6.0 lodash: ^4.17.21 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 uuid: ^8.0.0 winston: ^3.2.1 @@ -4348,7 +4348,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 mime-types: ^2.1.27 - msw: ^0.47.0 + msw: ^0.48.0 p-limit: ^3.1.0 supertest: ^6.1.6 winston: ^3.2.1 @@ -4389,7 +4389,7 @@ __metadata: cross-fetch: ^3.1.5 humanize-duration: ^3.27.0 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -4412,7 +4412,7 @@ __metadata: "@types/supertest": ^2.0.8 express: ^4.17.1 express-promise-router: ^4.1.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 winston: ^3.2.1 yn: ^4.0.0 @@ -4450,7 +4450,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -4501,7 +4501,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -4565,7 +4565,7 @@ __metadata: "@backstage/integration": "workspace:^" "@openapitools/openapi-generator-cli": ^2.4.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 ts-morph: ^15.0.0 languageName: unknown linkType: soft @@ -4594,7 +4594,7 @@ __metadata: cross-fetch: ^3.1.5 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 qs: ^6.9.6 react-use: ^17.2.4 recharts: ^2.0.0 @@ -4650,7 +4650,7 @@ __metadata: "@types/lodash": ^4.14.151 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 uuid: ^8.0.0 winston: ^3.2.1 @@ -4672,7 +4672,7 @@ __metadata: "@backstage/plugin-catalog-backend": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 uuid: ^8.0.0 winston: ^3.2.1 languageName: unknown @@ -4695,7 +4695,7 @@ __metadata: "@backstage/plugin-catalog-node": "workspace:^" "@types/node-fetch": ^2.5.12 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 uuid: ^8.0.0 winston: ^3.2.1 @@ -4718,7 +4718,7 @@ __metadata: "@backstage/types": "workspace:^" "@types/lodash": ^4.14.151 lodash: ^4.17.21 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 winston: ^3.2.1 languageName: unknown @@ -4742,7 +4742,7 @@ __metadata: "@types/fs-extra": ^9.0.1 fs-extra: 10.1.0 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 uuid: ^8.0.0 winston: ^3.2.1 @@ -4772,7 +4772,7 @@ __metadata: git-url-parse: ^13.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 uuid: ^8.0.0 winston: ^3.2.1 @@ -4799,7 +4799,7 @@ __metadata: "@types/uuid": ^8.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 uuid: ^8.0.0 winston: ^3.2.1 @@ -4845,7 +4845,7 @@ __metadata: "@types/node-fetch": ^2.5.12 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 p-limit: ^3.0.2 qs: ^6.9.4 @@ -4913,7 +4913,7 @@ __metadata: knex: ^2.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 p-limit: ^3.0.2 prom-client: ^14.0.1 @@ -5003,7 +5003,7 @@ __metadata: graphql-modules: ^2.0.0 graphql-tag: ^2.11.0 graphql-type-json: ^0.3.2 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 winston: ^3.2.1 languageName: unknown @@ -5039,7 +5039,7 @@ __metadata: git-url-parse: ^13.0.0 js-base64: ^3.6.0 lodash: ^4.17.21 - msw: ^0.47.0 + msw: ^0.48.0 react-hook-form: ^7.12.2 react-use: ^17.2.4 yaml: ^2.0.0 @@ -5252,7 +5252,7 @@ __metadata: humanize-duration: ^3.27.0 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -5283,7 +5283,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 qs: ^6.9.4 react-use: ^17.2.4 peerDependencies: @@ -5317,7 +5317,7 @@ __metadata: cross-fetch: ^3.1.5 humanize-duration: ^3.27.1 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -5343,7 +5343,7 @@ __metadata: express-promise-router: ^4.1.0 express-xml-bodyparser: ^0.3.0 knex: ^2.0.0 - msw: ^0.47.0 + msw: ^0.48.0 supertest: ^6.1.6 uuid: ^8.3.2 winston: ^3.2.1 @@ -5380,7 +5380,7 @@ __metadata: cross-fetch: ^3.1.5 highlight.js: ^10.6.0 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 recharts: ^2.0.0 peerDependencies: @@ -5411,7 +5411,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": "*" cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 rc-progress: 3.4.0 react-use: ^17.2.4 peerDependencies: @@ -5443,7 +5443,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 jsonschema: ^1.2.6 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 zen-observable: ^0.8.15 peerDependencies: @@ -5490,7 +5490,7 @@ __metadata: cross-fetch: ^3.1.5 history: ^5.0.0 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 pluralize: ^8.0.0 qs: ^6.9.4 react-use: ^17.2.4 @@ -5524,7 +5524,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": "*" express: ^4.18.1 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: "@backstage/plugin-catalog-react": "workspace:^" @@ -5545,7 +5545,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 languageName: unknown linkType: soft @@ -5573,7 +5573,7 @@ __metadata: "@types/node": ^16.11.26 classnames: ^2.2.6 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 @@ -5604,7 +5604,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -5634,7 +5634,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 p-limit: ^3.0.2 react-use: ^17.2.4 peerDependencies: @@ -5671,7 +5671,7 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 material-ui-popup-state: ^1.9.3 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -5698,7 +5698,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 peerDependencies: react: ^16.13.1 || ^17.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 @@ -5729,7 +5729,7 @@ __metadata: "@types/recharts": ^1.8.15 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 qs: ^6.10.1 react-use: ^17.2.4 recharts: ^2.0.0 @@ -5764,7 +5764,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -5799,7 +5799,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -5832,7 +5832,7 @@ __metadata: "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 octokit: ^2.0.4 react-use: ^17.4.0 peerDependencies: @@ -5864,7 +5864,7 @@ __metadata: "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 p-limit: ^4.0.0 react-use: ^17.2.4 peerDependencies: @@ -5892,7 +5892,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -5926,7 +5926,7 @@ __metadata: cross-fetch: ^3.1.5 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 qs: ^6.10.1 react-use: ^17.2.4 peerDependencies: @@ -5957,7 +5957,7 @@ __metadata: graphiql: ^1.5.12 graphql: ^16.0.0 graphql-ws: ^5.4.1 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -5983,7 +5983,7 @@ __metadata: graphql: ^16.0.0 graphql-modules: ^2.0.0 helmet: ^6.0.0 - msw: ^0.47.0 + msw: ^0.48.0 reflect-metadata: ^0.1.13 supertest: ^6.1.3 winston: ^3.2.1 @@ -6039,7 +6039,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 lodash: ^4.17.21 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 @@ -6074,7 +6074,7 @@ __metadata: cross-fetch: ^3.1.5 humanize-duration: ^3.26.0 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6100,7 +6100,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 jenkins: ^1.0.0 - msw: ^0.47.0 + msw: ^0.48.0 promise-any-polyfill: ^1.0.1 supertest: ^6.1.6 winston: ^3.2.1 @@ -6143,7 +6143,7 @@ __metadata: "@types/testing-library__jest-dom": ^5.9.1 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6198,7 +6198,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 jest-when: ^3.1.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6283,7 +6283,7 @@ __metadata: js-yaml: ^4.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6315,7 +6315,7 @@ __metadata: "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6365,7 +6365,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6394,7 +6394,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": "*" cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6423,7 +6423,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 p-limit: ^3.1.0 pluralize: ^8.0.0 qs: ^6.10.1 @@ -6459,7 +6459,7 @@ __metadata: classnames: ^2.2.6 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 @@ -6479,7 +6479,7 @@ __metadata: "@types/supertest": ^2.0.8 express: ^4.17.1 express-promise-router: ^4.1.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 supertest: ^6.1.6 winston: ^3.2.1 @@ -6511,7 +6511,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6537,7 +6537,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 lodash: ^4.17.21 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 supertest: ^6.1.6 winston: ^3.2.1 @@ -6569,7 +6569,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/types": "workspace:^" cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 uuid: ^8.0.0 zod: ^3.11.6 languageName: unknown @@ -6590,7 +6590,7 @@ __metadata: "@types/supertest": ^2.0.8 express: ^4.17.1 express-promise-router: ^4.1.0 - msw: ^0.47.0 + msw: ^0.48.0 supertest: ^6.1.3 zod: ^3.11.6 zod-to-json-schema: ^3.18.1 @@ -6656,7 +6656,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 knex: ^2.0.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 supertest: ^6.1.3 uuid: ^8.2.0 @@ -6704,7 +6704,7 @@ __metadata: "@types/node": "*" cross-fetch: ^3.1.5 lodash: ^4.17.21 - msw: ^0.47.0 + msw: ^0.48.0 qs: ^6.9.4 react-hook-form: ^7.13.0 react-use: ^17.2.4 @@ -6732,7 +6732,7 @@ __metadata: express-promise-router: ^4.1.0 http-proxy-middleware: ^2.0.0 morgan: ^1.10.0 - msw: ^0.47.0 + msw: ^0.48.0 supertest: ^6.1.3 uuid: ^8.0.0 winston: ^3.2.1 @@ -6760,7 +6760,7 @@ __metadata: fs-extra: 10.1.0 lodash: ^4.17.21 morgan: ^1.10.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 supertest: ^6.1.3 winston: ^3.2.1 @@ -6792,7 +6792,7 @@ __metadata: "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 lodash: ^4.17.21 - msw: ^0.47.0 + msw: ^0.48.0 react-sparklines: ^1.7.0 react-use: ^17.2.4 peerDependencies: @@ -6819,7 +6819,7 @@ __metadata: command-exists: ^1.2.9 fs-extra: 10.1.0 mock-fs: ^5.1.0 - msw: ^0.47.0 + msw: ^0.48.0 winston: ^3.2.1 yn: ^4.0.0 languageName: unknown @@ -6910,7 +6910,7 @@ __metadata: luxon: ^3.0.0 mock-fs: ^5.1.0 morgan: ^1.10.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 nunjucks: ^3.2.3 octokit: ^2.0.0 @@ -6991,7 +6991,7 @@ __metadata: json-schema-library: ^7.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 qs: ^6.9.4 react-use: ^17.2.4 use-immer: ^0.7.0 @@ -7171,7 +7171,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 qs: ^6.9.4 react-use: ^17.2.4 peerDependencies: @@ -7207,7 +7207,7 @@ __metadata: "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-sparklines: ^1.7.0 react-use: ^17.2.4 peerDependencies: @@ -7237,7 +7237,7 @@ __metadata: "@types/node": ^16.11.26 "@types/zen-observable": ^0.8.2 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-hook-form: ^7.12.2 react-use: ^17.2.4 uuid: ^8.3.2 @@ -7261,7 +7261,7 @@ __metadata: "@types/supertest": ^2.0.12 express: ^4.18.1 express-promise-router: ^4.1.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 supertest: ^6.2.4 winston: ^3.2.1 @@ -7291,7 +7291,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 rc-progress: 3.4.0 react-use: ^17.2.4 peerDependencies: @@ -7323,7 +7323,7 @@ __metadata: classnames: ^2.2.6 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -7390,7 +7390,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 lodash: ^4.17.21 - msw: ^0.47.0 + msw: ^0.48.0 qs: ^6.9.4 react-use: ^17.2.4 peerDependencies: @@ -7501,7 +7501,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 qs: ^6.9.4 react-use: ^17.2.4 peerDependencies: @@ -7535,7 +7535,7 @@ __metadata: color: ^4.0.1 cross-fetch: ^3.1.5 d3-force: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 prop-types: ^15.7.2 react-use: ^17.2.4 peerDependencies: @@ -7567,7 +7567,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 testing-library__dom: ^7.29.4-beta.1 peerDependencies: @@ -7603,7 +7603,7 @@ __metadata: fs-extra: 10.1.0 knex: ^2.0.0 lodash: ^4.17.21 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 p-limit: ^3.1.0 supertest: ^6.1.3 @@ -7637,7 +7637,7 @@ __metadata: "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 git-url-parse: ^13.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -7748,7 +7748,7 @@ __metadata: git-url-parse: ^13.0.0 jss: ~10.8.2 lodash: ^4.17.21 - msw: ^0.47.0 + msw: ^0.48.0 react-helmet: 6.1.0 react-use: ^17.2.4 peerDependencies: @@ -7776,7 +7776,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 leasot: ^12.0.0 - msw: ^0.47.0 + msw: ^0.48.0 supertest: ^6.1.3 winston: ^3.2.1 yn: ^4.0.0 @@ -7805,7 +7805,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -7857,7 +7857,7 @@ __metadata: "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 zen-observable: ^0.8.15 peerDependencies: @@ -7884,7 +7884,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 helmet: ^6.0.0 - msw: ^0.47.0 + msw: ^0.48.0 node-fetch: ^2.6.7 p-limit: ^3.1.0 supertest: ^6.1.6 @@ -7915,7 +7915,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": "*" cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -7945,7 +7945,7 @@ __metadata: cross-fetch: ^3.1.5 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 recharts: ^2.0.0 peerDependencies: @@ -7961,7 +7961,7 @@ __metadata: "@backstage/test-utils": "workspace:^" "@types/node": ^16.0.0 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 languageName: unknown linkType: soft @@ -7984,7 +7984,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 zen-observable: ^0.8.15 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 @@ -9758,7 +9758,7 @@ __metadata: "@types/uuid": ^8.0.0 express: ^4.17.1 express-promise-router: ^4.1.0 - msw: ^0.47.0 + msw: ^0.48.0 supertest: ^6.1.6 uuid: ^8.3.2 winston: ^3.2.1 @@ -9777,7 +9777,7 @@ __metadata: "@backstage/test-utils": "workspace:^" "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.47.0 + msw: ^0.48.0 languageName: unknown linkType: soft @@ -9799,7 +9799,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - msw: ^0.47.0 + msw: ^0.48.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -29797,9 +29797,9 @@ __metadata: languageName: node linkType: hard -"msw@npm:^0.47.0": - version: 0.47.4 - resolution: "msw@npm:0.47.4" +"msw@npm:^0.48.0": + version: 0.48.0 + resolution: "msw@npm:0.48.0" dependencies: "@mswjs/cookies": ^0.2.2 "@mswjs/interceptors": ^0.17.5 @@ -29828,7 +29828,7 @@ __metadata: optional: true bin: msw: cli/index.js - checksum: 10ff632641d40384d6622abf4df6399e4ae649db0f676b5d1ee2d0a515ec96f33abe9d4fecba08cdba4b2e43255af419da9eefc020d40a7e10669d0906457197 + checksum: a931232d18ad02c8b98ffb5db507824d619860743eab6ecf2c228a403b5a20e2b167d4e0ef6cdd7ca2c0d1e4cc913dce1a690e80d7ef3ec6724d3ee060abc477 languageName: node linkType: hard From 4c9f7847e4c8b2138af3c1a1613879de8c949816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 9 Nov 2022 12:12:10 +0100 Subject: [PATCH 255/434] fixup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/renovate-9097e77-extras.md | 9 ++ .changeset/renovate-9097e77.md | 108 ------------------ .../catalog-backend-module-azure/package.json | 4 +- .../package.json | 4 +- .../package.json | 4 +- .../package.json | 4 +- .../package.json | 4 +- 7 files changed, 19 insertions(+), 118 deletions(-) create mode 100644 .changeset/renovate-9097e77-extras.md diff --git a/.changeset/renovate-9097e77-extras.md b/.changeset/renovate-9097e77-extras.md new file mode 100644 index 0000000000..082a6921a0 --- /dev/null +++ b/.changeset/renovate-9097e77-extras.md @@ -0,0 +1,9 @@ +--- +'@backstage/plugin-catalog-backend-module-azure': patch +'@backstage/plugin-catalog-backend-module-bitbucket': patch +'@backstage/plugin-catalog-backend-module-gerrit': patch +'@backstage/plugin-catalog-backend-module-github': patch +'@backstage/plugin-catalog-backend-module-gitlab': patch +--- + +Updated dependency `msw` to `^0.48.0` while moving it to be a dev dependency. diff --git a/.changeset/renovate-9097e77.md b/.changeset/renovate-9097e77.md index 5981a320d0..4e7f767a45 100644 --- a/.changeset/renovate-9097e77.md +++ b/.changeset/renovate-9097e77.md @@ -1,113 +1,5 @@ --- -'@backstage/backend-common': patch '@backstage/backend-test-utils': patch -'@backstage/catalog-client': patch -'@backstage/cli': patch -'@backstage/config-loader': patch -'@backstage/core-app-api': patch -'@backstage/core-components': patch -'@backstage/core-plugin-api': patch -'@backstage/integration-react': patch -'@backstage/integration': patch -'@backstage/release-manifests': patch -'@backstage/test-utils': patch -'@backstage/plugin-adr-backend': patch -'@backstage/plugin-adr': patch -'@backstage/plugin-airbrake-backend': patch -'@backstage/plugin-airbrake': patch -'@backstage/plugin-allure': patch -'@backstage/plugin-analytics-module-ga': patch -'@backstage/plugin-apache-airflow': patch -'@backstage/plugin-api-docs': patch -'@backstage/plugin-apollo-explorer': patch -'@backstage/plugin-app-backend': patch -'@backstage/plugin-auth-backend': patch -'@backstage/plugin-auth-node': patch -'@backstage/plugin-azure-devops-backend': patch -'@backstage/plugin-azure-devops': patch -'@backstage/plugin-azure-sites-backend': patch -'@backstage/plugin-azure-sites': patch -'@backstage/plugin-badges': patch -'@backstage/plugin-bitbucket-cloud-common': patch -'@backstage/plugin-bitrise': patch -'@backstage/plugin-catalog-backend-module-azure': patch -'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch -'@backstage/plugin-catalog-backend-module-bitbucket-server': patch -'@backstage/plugin-catalog-backend-module-bitbucket': patch -'@backstage/plugin-catalog-backend-module-gerrit': patch -'@backstage/plugin-catalog-backend-module-github': patch -'@backstage/plugin-catalog-backend-module-gitlab': patch -'@backstage/plugin-catalog-backend-module-msgraph': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-catalog-graphql': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-circleci': patch -'@backstage/plugin-cloudbuild': patch -'@backstage/plugin-code-climate': patch -'@backstage/plugin-code-coverage-backend': patch -'@backstage/plugin-code-coverage': patch -'@backstage/plugin-codescene': patch -'@backstage/plugin-config-schema': patch -'@backstage/plugin-cost-insights': patch -'@backstage/plugin-dynatrace': patch -'@backstage/plugin-explore-react': patch -'@backstage/plugin-explore': patch -'@backstage/plugin-firehydrant': patch -'@backstage/plugin-fossa': patch -'@backstage/plugin-gcalendar': patch -'@backstage/plugin-gcp-projects': patch -'@backstage/plugin-git-release-manager': patch -'@backstage/plugin-github-actions': patch -'@backstage/plugin-github-deployments': patch -'@backstage/plugin-github-issues': patch -'@backstage/plugin-github-pull-requests-board': patch -'@backstage/plugin-gitops-profiles': patch -'@backstage/plugin-gocd': patch -'@backstage/plugin-graphiql': patch -'@backstage/plugin-graphql-backend': patch -'@backstage/plugin-home': patch -'@backstage/plugin-ilert': patch -'@backstage/plugin-jenkins-backend': patch -'@backstage/plugin-jenkins': patch -'@backstage/plugin-kafka': patch -'@backstage/plugin-kubernetes': patch -'@backstage/plugin-lighthouse': patch -'@backstage/plugin-newrelic': patch -'@backstage/plugin-org-react': patch -'@backstage/plugin-org': patch -'@backstage/plugin-pagerduty': patch -'@backstage/plugin-periskop-backend': patch -'@backstage/plugin-periskop': patch -'@backstage/plugin-permission-backend': patch -'@backstage/plugin-permission-common': patch -'@backstage/plugin-permission-node': patch -'@backstage/plugin-playlist-backend': patch -'@backstage/plugin-playlist': patch -'@backstage/plugin-proxy-backend': patch -'@backstage/plugin-rollbar-backend': patch -'@backstage/plugin-rollbar': patch -'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-search': patch -'@backstage/plugin-sentry': patch -'@backstage/plugin-shortcuts': patch -'@backstage/plugin-sonarqube-backend': patch -'@backstage/plugin-sonarqube': patch -'@backstage/plugin-splunk-on-call': patch -'@backstage/plugin-stack-overflow': patch -'@backstage/plugin-tech-insights': patch -'@backstage/plugin-tech-radar': patch -'@backstage/plugin-techdocs-addons-test-utils': patch -'@backstage/plugin-techdocs-backend': patch -'@backstage/plugin-techdocs-module-addons-contrib': patch -'@backstage/plugin-techdocs': patch -'@backstage/plugin-todo-backend': patch -'@backstage/plugin-todo': patch -'@backstage/plugin-user-settings': patch -'@backstage/plugin-vault-backend': patch -'@backstage/plugin-vault': patch -'@backstage/plugin-xcmetrics': patch --- Updated dependency `msw` to `^0.48.0`. diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index ae8f7e5bfe..5490425527 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -44,7 +44,6 @@ "@backstage/plugin-catalog-node": "workspace:^", "@backstage/types": "workspace:^", "lodash": "^4.17.21", - "msw": "^0.48.0", "node-fetch": "^2.6.7", "uuid": "^8.0.0", "winston": "^3.2.1" @@ -53,7 +52,8 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/lodash": "^4.14.151", - "luxon": "^3.0.0" + "luxon": "^3.0.0", + "msw": "^0.48.0" }, "files": [ "alpha", diff --git a/plugins/catalog-backend-module-bitbucket/package.json b/plugins/catalog-backend-module-bitbucket/package.json index 2d36eaf5a6..c3e7b21a27 100644 --- a/plugins/catalog-backend-module-bitbucket/package.json +++ b/plugins/catalog-backend-module-bitbucket/package.json @@ -42,14 +42,14 @@ "@backstage/plugin-catalog-backend": "workspace:^", "@backstage/types": "workspace:^", "lodash": "^4.17.21", - "msw": "^0.48.0", "node-fetch": "^2.6.7", "winston": "^3.2.1" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", - "@types/lodash": "^4.14.151" + "@types/lodash": "^4.14.151", + "msw": "^0.48.0" }, "files": [ "dist" diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 9cfe9d111e..8f0ef8e735 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -39,7 +39,6 @@ "@backstage/plugin-catalog-backend": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", "fs-extra": "10.1.0", - "msw": "^0.48.0", "node-fetch": "^2.6.7", "uuid": "^8.0.0", "winston": "^3.2.1" @@ -48,7 +47,8 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/fs-extra": "^9.0.1", - "luxon": "^3.0.0" + "luxon": "^3.0.0", + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index 3189384c7e..68b5bad5cc 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -48,7 +48,6 @@ "@octokit/rest": "^19.0.3", "git-url-parse": "^13.0.0", "lodash": "^4.17.21", - "msw": "^0.48.0", "node-fetch": "^2.6.7", "uuid": "^8.0.0", "winston": "^3.2.1" @@ -57,7 +56,8 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/lodash": "^4.14.151", - "luxon": "^3.0.0" + "luxon": "^3.0.0", + "msw": "^0.48.0" }, "files": [ "dist", diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index 71f14ba57f..9ac4f39d86 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -44,7 +44,6 @@ "@backstage/plugin-catalog-node": "workspace:^", "@backstage/types": "workspace:^", "lodash": "^4.17.21", - "msw": "^0.48.0", "node-fetch": "^2.6.7", "uuid": "^8.0.0", "winston": "^3.2.1" @@ -54,7 +53,8 @@ "@backstage/cli": "workspace:^", "@types/lodash": "^4.14.151", "@types/uuid": "^8.0.0", - "luxon": "^3.0.0" + "luxon": "^3.0.0", + "msw": "^0.48.0" }, "files": [ "alpha", From 745e0e2228991729556ff76fe0285f11ce014dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= Date: Tue, 8 Nov 2022 23:39:39 +0100 Subject: [PATCH 256/434] Add changeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez --- .changeset/shaggy-moles-jump.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/shaggy-moles-jump.md diff --git a/.changeset/shaggy-moles-jump.md b/.changeset/shaggy-moles-jump.md new file mode 100644 index 0000000000..b2417beb9e --- /dev/null +++ b/.changeset/shaggy-moles-jump.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cost-insights': patch +--- + +Added support for displaying entity cost insights by implementing the new `getCatalogEntityDailyCost` that's part of the `CostInsightsApi`. From 0512bf08f9c5a0c8380730915983e34945c91873 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 12:14:08 +0000 Subject: [PATCH 257/434] Update dependency selfsigned to v2.1.1 Signed-off-by: Renovate Bot --- yarn.lock | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 0802bef2c2..97b575251b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35172,7 +35172,16 @@ __metadata: languageName: node linkType: hard -"selfsigned@npm:^2.0.0, selfsigned@npm:^2.0.1": +"selfsigned@npm:^2.0.0": + version: 2.1.1 + resolution: "selfsigned@npm:2.1.1" + dependencies: + node-forge: ^1 + checksum: aa9ce2150a54838978d5c0aee54d7ebe77649a32e4e690eb91775f71fdff773874a4fbafd0ac73d8ec3b702ff8a395c604df4f8e8868528f36fd6c15076fb43a + languageName: node + linkType: hard + +"selfsigned@npm:^2.0.1": version: 2.0.1 resolution: "selfsigned@npm:2.0.1" dependencies: From 3a351505526132f2469ed1a228d6d6eeb21d46e0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 17:50:20 +0000 Subject: [PATCH 258/434] Update dependency @rjsf/validator-ajv8 to v5.0.0-beta.12 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0802bef2c2..83a8a9fac1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12361,8 +12361,8 @@ __metadata: linkType: hard "@rjsf/validator-ajv8@npm:^5.0.0-beta.10": - version: 5.0.0-beta.11 - resolution: "@rjsf/validator-ajv8@npm:5.0.0-beta.11" + version: 5.0.0-beta.12 + resolution: "@rjsf/validator-ajv8@npm:5.0.0-beta.12" dependencies: ajv: ^8.11.0 ajv-formats: ^2.1.1 @@ -12370,7 +12370,7 @@ __metadata: lodash-es: ^4.17.15 peerDependencies: "@rjsf/utils": ^5.0.0-beta.1 - checksum: e9aec2e77c69ee55fd35cc82b2c3fe0c78cf021145500bc86f7e0a5bae794163dfae198df0543ce635e22cd4235880dcbb7c73487ae0baae6b03e1bdea2955c4 + checksum: 2acd420fdd099b35e534c4086ce5d3759574a8b4dc4b4a21ca35e85b023e6d9688aab1dbfca9381bdbf4aecbe3eb195e27453e8dd9cc70712fe2652e1496840c languageName: node linkType: hard From 94b7ca9c6df322c16c3e0fb2615fb0fb36f63a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 9 Nov 2022 13:12:33 +0100 Subject: [PATCH 259/434] fixup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/clever-colts-roll.md | 5 +++++ plugins/scaffolder/package.json | 8 ++++---- yarn.lock | 28 ++++++++++++++-------------- 3 files changed, 23 insertions(+), 18 deletions(-) create mode 100644 .changeset/clever-colts-roll.md diff --git a/.changeset/clever-colts-roll.md b/.changeset/clever-colts-roll.md new file mode 100644 index 0000000000..b0aed88dae --- /dev/null +++ b/.changeset/clever-colts-roll.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Updated to use `@rjsf` packages of version `^5.0.0-beta.12` diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index c2d4bdd334..214351e2b7 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -55,11 +55,11 @@ "@material-ui/lab": "4.0.0-alpha.57", "@react-hookz/web": "^15.0.0", "@rjsf/core": "^3.2.1", - "@rjsf/core-v5": "npm:@rjsf/core@^5.0.0-beta.10", + "@rjsf/core-v5": "npm:@rjsf/core@^5.0.0-beta.12", "@rjsf/material-ui": "^3.2.1", - "@rjsf/material-ui-v5": "npm:@rjsf/material-ui@^5.0.0-beta.10", - "@rjsf/utils": "^5.0.0-beta.10", - "@rjsf/validator-ajv8": "^5.0.0-beta.10", + "@rjsf/material-ui-v5": "npm:@rjsf/material-ui@^5.0.0-beta.12", + "@rjsf/utils": "^5.0.0-beta.12", + "@rjsf/validator-ajv8": "^5.0.0-beta.12", "@types/json-schema": "^7.0.9", "@uiw/react-codemirror": "^4.9.3", "classnames": "^2.2.6", diff --git a/yarn.lock b/yarn.lock index 83a8a9fac1..c08690bd76 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6968,11 +6968,11 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.57 "@react-hookz/web": ^15.0.0 "@rjsf/core": ^3.2.1 - "@rjsf/core-v5": "npm:@rjsf/core@^5.0.0-beta.10" + "@rjsf/core-v5": "npm:@rjsf/core@^5.0.0-beta.12" "@rjsf/material-ui": ^3.2.1 - "@rjsf/material-ui-v5": "npm:@rjsf/material-ui@^5.0.0-beta.10" - "@rjsf/utils": ^5.0.0-beta.10 - "@rjsf/validator-ajv8": ^5.0.0-beta.10 + "@rjsf/material-ui-v5": "npm:@rjsf/material-ui@^5.0.0-beta.12" + "@rjsf/utils": ^5.0.0-beta.12 + "@rjsf/validator-ajv8": ^5.0.0-beta.12 "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 @@ -12286,9 +12286,9 @@ __metadata: languageName: node linkType: hard -"@rjsf/core-v5@npm:@rjsf/core@^5.0.0-beta.10": - version: 5.0.0-beta.10 - resolution: "@rjsf/core@npm:5.0.0-beta.10" +"@rjsf/core-v5@npm:@rjsf/core@^5.0.0-beta.12": + version: 5.0.0-beta.12 + resolution: "@rjsf/core@npm:5.0.0-beta.12" dependencies: lodash: ^4.17.15 lodash-es: ^4.17.15 @@ -12297,7 +12297,7 @@ __metadata: peerDependencies: "@rjsf/utils": ^5.0.0-beta.1 react: ^16.14.0 || >=17 - checksum: c3e8852c8fedc6ae23da610033e0bded1bd198cebf7f54a5cdcf3b42d22a3b3864da9c735300cadc7d756f26055a7e62408d51a5ebdb906be9b1bf85bf3712ed + checksum: 6c3fe058a29716cb8d31d436e284aa7ab51ec3c272dc34d49275ea0033c3350a2486249767d454bca20a4ccd00ed910f7ed518d2ebe30693b0218db1b3c990ac languageName: node linkType: hard @@ -12320,16 +12320,16 @@ __metadata: languageName: node linkType: hard -"@rjsf/material-ui-v5@npm:@rjsf/material-ui@^5.0.0-beta.10": - version: 5.0.0-beta.10 - resolution: "@rjsf/material-ui@npm:5.0.0-beta.10" +"@rjsf/material-ui-v5@npm:@rjsf/material-ui@^5.0.0-beta.12": + version: 5.0.0-beta.12 + resolution: "@rjsf/material-ui@npm:5.0.0-beta.12" peerDependencies: "@material-ui/core": ^4.12.3 "@material-ui/icons": ^4.11.2 "@rjsf/core": ^5.0.0-beta.1 "@rjsf/utils": ^5.0.0-beta.1 react: ^16.14.0 || >=17 - checksum: c6e602fc331ec37524837123f42e605389c8ea1a9207ed3e9052de380b91fb90365aa962b0020197f0fb2bcbd87baac34bef7dbbb31ea4b57b6587d0fcd81a09 + checksum: 9b67c64956e74af6230d722fe9510fc50e6133c6913642f5bcbcb8da38b7ff5d912bc90a6b6692eb3df315ba9b330136556fb41854fb351e432433d584c1a969 languageName: node linkType: hard @@ -12345,7 +12345,7 @@ __metadata: languageName: node linkType: hard -"@rjsf/utils@npm:^5.0.0-beta.10": +"@rjsf/utils@npm:^5.0.0-beta.12": version: 5.0.0-beta.12 resolution: "@rjsf/utils@npm:5.0.0-beta.12" dependencies: @@ -12360,7 +12360,7 @@ __metadata: languageName: node linkType: hard -"@rjsf/validator-ajv8@npm:^5.0.0-beta.10": +"@rjsf/validator-ajv8@npm:^5.0.0-beta.12": version: 5.0.0-beta.12 resolution: "@rjsf/validator-ajv8@npm:5.0.0-beta.12" dependencies: From 9740a44613de6d6894e0b943b9c69f2bb311f83a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 13:10:44 +0000 Subject: [PATCH 260/434] Update dependency sucrase to v3.28.0 Signed-off-by: Renovate Bot --- yarn.lock | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 97b575251b..9965fb0d95 100644 --- a/yarn.lock +++ b/yarn.lock @@ -36632,7 +36632,7 @@ __metadata: languageName: node linkType: hard -"sucrase@npm:^3.18.0, sucrase@npm:^3.20.2": +"sucrase@npm:^3.18.0": version: 3.25.0 resolution: "sucrase@npm:3.25.0" dependencies: @@ -36649,6 +36649,23 @@ __metadata: languageName: node linkType: hard +"sucrase@npm:^3.20.2": + version: 3.28.0 + resolution: "sucrase@npm:3.28.0" + dependencies: + commander: ^4.0.0 + glob: 7.1.6 + lines-and-columns: ^1.1.6 + mz: ^2.7.0 + pirates: ^4.0.1 + ts-interface-checker: ^0.1.9 + bin: + sucrase: bin/sucrase + sucrase-node: bin/sucrase-node + checksum: 6a2369c140cee674988ebcf83538f38b11270e47ebaffc811baabe1db3fc586f1a357d4bbc66388a6b99054ba06a08f31b44b764e777abbd457b9e29332b12d0 + languageName: node + linkType: hard + "superagent@npm:^8.0.0": version: 8.0.0 resolution: "superagent@npm:8.0.0" From 7887b72fc6635df5790de536e0a2a8319bfd0709 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 14:43:19 +0000 Subject: [PATCH 261/434] Update dependency swagger-ui-react to v4.15.5 Signed-off-by: Renovate Bot --- yarn.lock | 177 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 121 insertions(+), 56 deletions(-) diff --git a/yarn.lock b/yarn.lock index 22d86509f0..025d31f618 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18129,6 +18129,13 @@ __metadata: languageName: node linkType: hard +"ci-info@npm:^2.0.0": + version: 2.0.0 + resolution: "ci-info@npm:2.0.0" + checksum: 3b374666a85ea3ca43fa49aa3a048d21c9b475c96eb13c133505d2324e7ae5efd6a454f41efe46a152269e9b6a00c9edbe63ec7fa1921957165aae16625acd67 + languageName: node + linkType: hard + "ci-info@npm:^3.1.0, ci-info@npm:^3.2.0": version: 3.3.2 resolution: "ci-info@npm:3.3.2" @@ -18999,7 +19006,7 @@ __metadata: languageName: node linkType: hard -"copy-to-clipboard@npm:^3, copy-to-clipboard@npm:^3.2.0, copy-to-clipboard@npm:^3.3.1": +"copy-to-clipboard@npm:^3.2.0, copy-to-clipboard@npm:^3.3.1": version: 3.3.1 resolution: "copy-to-clipboard@npm:3.3.1" dependencies: @@ -19267,6 +19274,19 @@ __metadata: languageName: node linkType: hard +"cross-spawn@npm:^6.0.5": + version: 6.0.5 + resolution: "cross-spawn@npm:6.0.5" + dependencies: + nice-try: ^1.0.4 + path-key: ^2.0.1 + semver: ^5.5.0 + shebang-command: ^1.2.0 + which: ^1.2.9 + checksum: f893bb0d96cd3d5751d04e67145bdddf25f99449531a72e82dcbbd42796bbc8268c1076c6b3ea51d4d455839902804b94bc45dfb37ecbb32ea8e54a6741c3ab9 + languageName: node + linkType: hard + "cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" @@ -22977,6 +22997,15 @@ __metadata: languageName: node linkType: hard +"find-yarn-workspace-root@npm:^2.0.0": + version: 2.0.0 + resolution: "find-yarn-workspace-root@npm:2.0.0" + dependencies: + micromatch: ^4.0.2 + checksum: fa5ca8f9d08fe7a54ce7c0a5931ff9b7e36f9ee7b9475fb13752bcea80ec6b5f180fa5102d60b376d5526ce924ea3fc6b19301262efa0a5d248dd710f3644242 + languageName: node + linkType: hard + "first-chunk-stream@npm:^2.0.0": version: 2.0.0 resolution: "first-chunk-stream@npm:2.0.0" @@ -25427,6 +25456,17 @@ __metadata: languageName: node linkType: hard +"is-ci@npm:^2.0.0": + version: 2.0.0 + resolution: "is-ci@npm:2.0.0" + dependencies: + ci-info: ^2.0.0 + bin: + is-ci: bin.js + checksum: 77b869057510f3efa439bbb36e9be429d53b3f51abd4776eeea79ab3b221337fe1753d1e50058a9e2c650d38246108beffb15ccfd443929d77748d8c0cc90144 + languageName: node + linkType: hard + "is-ci@npm:^3.0.0, is-ci@npm:^3.0.1": version: 3.0.1 resolution: "is-ci@npm:3.0.1" @@ -25497,16 +25537,6 @@ __metadata: languageName: node linkType: hard -"is-dom@npm:^1.0.0": - version: 1.1.0 - resolution: "is-dom@npm:1.1.0" - dependencies: - is-object: ^1.0.1 - is-window: ^1.0.2 - checksum: 72aff0a7366b801c9d598d49452ec06544b52c3da92a0c6c3cacace33bb0c3df5ba1b4e422ac39224773316a553699d5920a1eb136919319f57d00e6384eb41b - languageName: node - linkType: hard - "is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" @@ -25658,13 +25688,6 @@ __metadata: languageName: node linkType: hard -"is-object@npm:^1.0.1": - version: 1.0.1 - resolution: "is-object@npm:1.0.1" - checksum: 845eea5ecea9723c04809c9c502a19f318b486f796b128a7b8e5a228c7256c3db8c8201043577542075632e292cd4dfeb04627f12f53817d7bd9f30485cf4c34 - languageName: node - linkType: hard - "is-path-cwd@npm:^2.2.0": version: 2.2.0 resolution: "is-path-cwd@npm:2.2.0" @@ -25929,13 +25952,6 @@ __metadata: languageName: node linkType: hard -"is-window@npm:^1.0.2": - version: 1.0.2 - resolution: "is-window@npm:1.0.2" - checksum: aeaacd2ca816d38d4e2fba4670158fba2190061f28a61c5d84df7c479abf8897b8cb634d22cb76cdf7805035e95bebd430faaab6231ac2ebc814eae02d2c8fd4 - languageName: node - linkType: hard - "is-windows@npm:^1.0.0, is-windows@npm:^1.0.1": version: 1.0.2 resolution: "is-windows@npm:1.0.2" @@ -25943,7 +25959,7 @@ __metadata: languageName: node linkType: hard -"is-wsl@npm:^2.2.0": +"is-wsl@npm:^2.1.1, is-wsl@npm:^2.2.0": version: 2.2.0 resolution: "is-wsl@npm:2.2.0" dependencies: @@ -27599,6 +27615,15 @@ __metadata: languageName: node linkType: hard +"klaw-sync@npm:^6.0.0": + version: 6.0.0 + resolution: "klaw-sync@npm:6.0.0" + dependencies: + graceful-fs: ^4.1.11 + checksum: 0da397f8961313c3ef8f79fb63af9002cde5a8fb2aeb1a37351feff0dd6006129c790400c3f5c3b4e757bedcabb13d21ec0a5eaef5a593d59515d4f2c291e475 + languageName: node + linkType: hard + "klaw@npm:^3.0.0": version: 3.0.0 resolution: "klaw@npm:3.0.0" @@ -30003,6 +30028,13 @@ __metadata: languageName: node linkType: hard +"nice-try@npm:^1.0.4": + version: 1.0.5 + resolution: "nice-try@npm:1.0.5" + checksum: 0b4af3b5bb5d86c289f7a026303d192a7eb4417231fe47245c460baeabae7277bcd8fd9c728fb6bd62c30b3e15cd6620373e2cf33353b095d8b403d3e8a15aff + languageName: node + linkType: hard + "nise@npm:^5.1.1": version: 5.1.1 resolution: "nise@npm:5.1.1" @@ -30726,6 +30758,16 @@ __metadata: languageName: node linkType: hard +"open@npm:^7.4.2": + version: 7.4.2 + resolution: "open@npm:7.4.2" + dependencies: + is-docker: ^2.0.0 + is-wsl: ^2.1.1 + checksum: 3333900ec0e420d64c23b831bc3467e57031461d843c801f569b2204a1acc3cd7b3ec3c7897afc9dde86491dfa289708eb92bba164093d8bd88fb2c231843c91 + languageName: node + linkType: hard + "open@npm:^8.0.0, open@npm:^8.0.9, open@npm:^8.4.0": version: 8.4.0 resolution: "open@npm:8.4.0" @@ -31438,6 +31480,30 @@ __metadata: languageName: node linkType: hard +"patch-package@npm:^6.5.0": + version: 6.5.0 + resolution: "patch-package@npm:6.5.0" + dependencies: + "@yarnpkg/lockfile": ^1.1.0 + chalk: ^4.1.2 + cross-spawn: ^6.0.5 + find-yarn-workspace-root: ^2.0.0 + fs-extra: ^7.0.1 + is-ci: ^2.0.0 + klaw-sync: ^6.0.0 + minimist: ^1.2.6 + open: ^7.4.2 + rimraf: ^2.6.3 + semver: ^5.6.0 + slash: ^2.0.0 + tmp: ^0.0.33 + yaml: ^1.10.2 + bin: + patch-package: index.js + checksum: d300e87617e3fb990d1f78fd5be205b5a5e65dfdf197b1e7f76f3b3dfe1551a03d276cb5ee6b82ab4d57e78f54ddc22bde803eec1b0896560262b276d0b2c4ab + languageName: node + linkType: hard + "path-browserify@npm:0.0.1": version: 0.0.1 resolution: "path-browserify@npm:0.0.1" @@ -31506,6 +31572,13 @@ __metadata: languageName: node linkType: hard +"path-key@npm:^2.0.1": + version: 2.0.1 + resolution: "path-key@npm:2.0.1" + checksum: f7ab0ad42fe3fb8c7f11d0c4f849871e28fbd8e1add65c370e422512fc5887097b9cf34d09c1747d45c942a8c1e26468d6356e2df3f740bf177ab8ca7301ebfd + languageName: node + linkType: hard + "path-key@npm:^3.0.0, path-key@npm:^3.1.0": version: 3.1.1 resolution: "path-key@npm:3.1.1" @@ -33210,19 +33283,7 @@ __metadata: languageName: node linkType: hard -"react-copy-to-clipboard@npm:5.0.4": - version: 5.0.4 - resolution: "react-copy-to-clipboard@npm:5.0.4" - dependencies: - copy-to-clipboard: ^3 - prop-types: ^15.5.8 - peerDependencies: - react: ^15.3.0 || ^16.0.0 || ^17.0.0 - checksum: dae8caae192d4937a151ec3ddad540fe4846d28646aee6d90774abcc6a077761926c99f2bcd9506a76a65524ec2c32b5ec1341e8096fcd3f6335365eaf065137 - languageName: node - linkType: hard - -"react-copy-to-clipboard@npm:^5.0.4": +"react-copy-to-clipboard@npm:5.1.0, react-copy-to-clipboard@npm:^5.0.4": version: 5.1.0 resolution: "react-copy-to-clipboard@npm:5.1.0" dependencies: @@ -33403,16 +33464,12 @@ __metadata: languageName: node linkType: hard -"react-inspector@npm:^5.1.1": - version: 5.1.1 - resolution: "react-inspector@npm:5.1.1" - dependencies: - "@babel/runtime": ^7.0.0 - is-dom: ^1.0.0 - prop-types: ^15.0.0 +"react-inspector@npm:^6.0.1": + version: 6.0.1 + resolution: "react-inspector@npm:6.0.1" peerDependencies: - react: ^16.8.4 || ^17.0.0 - checksum: ca9e4c1fedb94e4e956dd3142838c5a25a9d61375aee5e8a74dd623bae09a263098a93f220e8d84c7fd39e569e1fa4297d363ddbc91b15bca91baeb7281d7f4f + react: ^16.8.4 || ^17.0.0 || ^18.0.0 + checksum: 877cbccf36fdc6213abb9611fb9279c4bb76ef7ecb4ec554b3935419a99d55e6d30a80799a054d468d43cc59a9777f21d22d6219a4597bfbd27f3f08a4cdfdc6 languageName: node linkType: hard @@ -33631,7 +33688,7 @@ __metadata: languageName: node linkType: hard -"react-syntax-highlighter@npm:^15.4.5": +"react-syntax-highlighter@npm:^15.4.5, react-syntax-highlighter@npm:^15.5.0": version: 15.5.0 resolution: "react-syntax-highlighter@npm:15.5.0" dependencies: @@ -35204,7 +35261,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.4.1, semver@npm:^5.6.0, semver@npm:^5.7.1": +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.6.0, semver@npm:^5.7.1": version: 5.7.1 resolution: "semver@npm:5.7.1" bin: @@ -35595,6 +35652,13 @@ __metadata: languageName: node linkType: hard +"slash@npm:^2.0.0": + version: 2.0.0 + resolution: "slash@npm:2.0.0" + checksum: 512d4350735375bd11647233cb0e2f93beca6f53441015eea241fe784d8068281c3987fbaa93e7ef1c38df68d9c60013045c92837423c69115297d6169aa85e6 + languageName: node + linkType: hard + "slash@npm:^3.0.0": version: 3.0.0 resolution: "slash@npm:3.0.0" @@ -36785,8 +36849,8 @@ __metadata: linkType: hard "swagger-ui-react@npm:^4.11.1": - version: 4.14.3 - resolution: "swagger-ui-react@npm:4.14.3" + version: 4.15.5 + resolution: "swagger-ui-react@npm:4.15.5" dependencies: "@babel/runtime-corejs3": ^7.18.9 "@braintree/sanitize-url": =6.0.0 @@ -36800,16 +36864,17 @@ __metadata: js-file-download: ^0.4.12 js-yaml: =4.1.0 lodash: ^4.17.21 + patch-package: ^6.5.0 prop-types: ^15.8.1 randexp: ^0.5.3 randombytes: ^2.1.0 - react-copy-to-clipboard: 5.0.4 + react-copy-to-clipboard: 5.1.0 react-debounce-input: =3.3.0 react-immutable-proptypes: 2.2.0 react-immutable-pure-component: ^2.2.0 - react-inspector: ^5.1.1 + react-inspector: ^6.0.1 react-redux: ^7.2.4 - react-syntax-highlighter: ^15.4.5 + react-syntax-highlighter: ^15.5.0 redux: ^4.1.2 redux-immutable: ^4.0.0 remarkable: ^2.0.1 @@ -36824,7 +36889,7 @@ __metadata: peerDependencies: react: ">=17.0.0" react-dom: ">=17.0.0" - checksum: ae8e932ff7eb0b4be71fd1ad7f00ef3eb461636a83985bd36ea28647f60769e6234a9921ff2f84aa33c370f30b8fa1c30a6ca7cf3c4a6ded963aaf9a337aa197 + checksum: 22a72947da865ebfa9269f66b42c2b50105b6285bcb6546f8f356cf73961f76e397b7d79003641c9569bfb2163ea98e2f3f73a27b5b66843d308786c37362e1c languageName: node linkType: hard From da781676aef3ddcb5fbe0f485c2728f80ea0851d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 14:44:11 +0000 Subject: [PATCH 262/434] Update dependency testcontainers to v8.16.0 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 22d86509f0..572dd98ecd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -37112,8 +37112,8 @@ __metadata: linkType: hard "testcontainers@npm:^8.1.2": - version: 8.13.1 - resolution: "testcontainers@npm:8.13.1" + version: 8.16.0 + resolution: "testcontainers@npm:8.16.0" dependencies: "@balena/dockerignore": ^1.0.2 "@types/archiver": ^5.3.1 @@ -37127,7 +37127,7 @@ __metadata: properties-reader: ^2.2.0 ssh-remote-port-forward: ^1.0.4 tar-fs: ^2.1.1 - checksum: a15345bed5a7e28cf521a01348ca5c0a9de67e274b628345ac91e6db69793c0f2044fb7634166d849eac1d9ea592c79319bdc7e1ec6c5a0208e2e74548c57a5a + checksum: 2fb8250591691a4bd86640b53e13236ad507ba9e03ac3043683de5e9dd632bc29d52827c22ccfe2b0d28dec6896cbaa56dcb153ce65f7f74212ddefc204e8d6a languageName: node linkType: hard From 4cdd935b99b8c026298bf94032c5c8ea9e02f784 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 15:28:54 +0000 Subject: [PATCH 263/434] Update dependency openid-client to v5.3.0 Signed-off-by: Renovate Bot --- yarn.lock | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 025d31f618..5708a57cc1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -30796,7 +30796,7 @@ __metadata: languageName: node linkType: hard -"openid-client@npm:^5.1.6, openid-client@npm:^5.2.1": +"openid-client@npm:^5.1.6": version: 5.2.1 resolution: "openid-client@npm:5.2.1" dependencies: @@ -30808,6 +30808,18 @@ __metadata: languageName: node linkType: hard +"openid-client@npm:^5.2.1": + version: 5.3.0 + resolution: "openid-client@npm:5.3.0" + dependencies: + jose: ^4.10.0 + lru-cache: ^6.0.0 + object-hash: ^2.0.1 + oidc-token-hash: ^5.0.1 + checksum: 27faa298e083daae2a2a99629b25cc89f648302f4845dd1acd04ec6e7105a6edf13a5c38ab1159bcb7b88c5bc54be08e021c911e22f0b8bfcca1b2d686ae3d95 + languageName: node + linkType: hard + "optionator@npm:^0.8.1": version: 0.8.3 resolution: "optionator@npm:0.8.3" From c1a4addda3006202cd4b704e126b9cb2b72932ec Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Tue, 8 Nov 2022 09:18:56 +0100 Subject: [PATCH 264/434] feat(catalog): add location to processing error logs Signed-off-by: Patrick Jungermann --- .changeset/cuddly-coats-try.md | 7 +++++++ .../src/processing/DefaultCatalogProcessingEngine.ts | 11 ++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 .changeset/cuddly-coats-try.md diff --git a/.changeset/cuddly-coats-try.md b/.changeset/cuddly-coats-try.md new file mode 100644 index 0000000000..3b8bb654b2 --- /dev/null +++ b/.changeset/cuddly-coats-try.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Improve processing error logging. + +Adds `location` and `owner` to the logging meta if they are available. diff --git a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts index 2cc0e2dc40..bef2878099 100644 --- a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts @@ -14,7 +14,11 @@ * limitations under the License. */ -import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; +import { + ANNOTATION_LOCATION, + Entity, + stringifyEntityRef, +} from '@backstage/catalog-model'; import { assertError, serializeError, stringifyError } from '@backstage/errors'; import { Hash } from 'crypto'; import stableStringify from 'fast-json-stable-stringify'; @@ -116,11 +120,12 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { }); } + const location = + unprocessedEntity?.metadata?.annotations?.[ANNOTATION_LOCATION]; for (const error of result.errors) { - // TODO(freben): Try to extract the location out of the unprocessed - // entity and add as meta to the log lines this.logger.warn(error.message, { entity: entityRef, + location, }); } const errorsString = JSON.stringify( From ece8c70bb221726f353e0c0d830e58cd6a273473 Mon Sep 17 00:00:00 2001 From: manusant Date: Wed, 9 Nov 2022 16:25:10 +0000 Subject: [PATCH 265/434] API report cleanup Signed-off-by: manusant --- plugins/sonarqube/api-report.md | 24 ++++--------------- plugins/sonarqube/package.json | 3 +-- .../SonarQubeContentPage.tsx | 13 ++++------ plugins/sonarqube/src/index.ts | 8 ++++++- yarn.lock | 1 - 5 files changed, 17 insertions(+), 32 deletions(-) diff --git a/plugins/sonarqube/api-report.md b/plugins/sonarqube/api-report.md index 3248dbbbed..48cd38e97c 100644 --- a/plugins/sonarqube/api-report.md +++ b/plugins/sonarqube/api-report.md @@ -8,7 +8,6 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { InfoCardVariants } from '@backstage/core-components'; -import { default as React_2 } from 'react'; // @public (undocumented) export type DuplicationRating = { @@ -23,11 +22,9 @@ export const EntitySonarQubeCard: (props: { }) => JSX.Element; // @public (undocumented) -export const EntitySonarQubeContentPage: ({ - title, - supportTitle, - ...otherProps -}: SonarQubeContentPageProps) => JSX.Element; +export const EntitySonarQubeContentPage: ( + props: SonarQubeContentPageProps, +) => JSX.Element; // @public (undocumented) export const isSonarQubeAvailable: (entity: Entity) => boolean; @@ -35,24 +32,11 @@ export const isSonarQubeAvailable: (entity: Entity) => boolean; // @public (undocumented) export const SONARQUBE_PROJECT_KEY_ANNOTATION = 'sonarqube.org/project-key'; -// @public (undocumented) -export const SonarQubeCard: (props: { - variant?: InfoCardVariants; - duplicationRatings?: DuplicationRating[]; -}) => JSX.Element; - -// @public (undocumented) -export const SonarQubeContentPage: ({ - title, - supportTitle, - ...otherProps -}: SonarQubeContentPageProps) => JSX.Element; - // @public (undocumented) export type SonarQubeContentPageProps = { title?: string; supportTitle?: string; -} & React_2.ComponentPropsWithoutRef<'div'>; +}; // @public (undocumented) const sonarQubePlugin: BackstagePlugin<{}, {}, {}>; diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 89cbb0c049..b46cb5c0b1 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -45,8 +45,7 @@ "@material-ui/styles": "^4.10.0", "cross-fetch": "^3.1.5", "rc-progress": "3.4.0", - "react-use": "^17.2.4", - "@types/react": "^16.13.1 || ^17.0.0" + "react-use": "^17.2.4" }, "peerDependencies": { "react": "^16.13.1 || ^17.0.0" diff --git a/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx b/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx index 124906bb12..c11fff7237 100644 --- a/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx +++ b/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx @@ -32,19 +32,16 @@ import { SonarQubeCard } from '../SonarQubeCard'; export type SonarQubeContentPageProps = { title?: string; supportTitle?: string; -} & React.ComponentPropsWithoutRef<'div'>; +}; /** @public */ -export const SonarQubeContentPage = ({ - title = 'SonarQube Dashboard', - supportTitle, - ...otherProps -}: SonarQubeContentPageProps) => { +export const SonarQubeContentPage = (props: SonarQubeContentPageProps) => { const { entity } = useEntity(); + const { title, supportTitle } = props; return isSonarQubeAvailable(entity) ? ( - - + + {supportTitle && {supportTitle}} diff --git a/plugins/sonarqube/src/index.ts b/plugins/sonarqube/src/index.ts index 8b2a4b86b8..9936cc04e9 100644 --- a/plugins/sonarqube/src/index.ts +++ b/plugins/sonarqube/src/index.ts @@ -21,7 +21,13 @@ * @packageDocumentation */ -export * from './components'; +export type { + DuplicationRating, + SonarQubeContentPageProps, + SONARQUBE_PROJECT_KEY_ANNOTATION, + isSonarQubeAvailable, +} from './components'; + export { sonarQubePlugin, sonarQubePlugin as plugin, diff --git a/yarn.lock b/yarn.lock index 6ab3c2300a..c42aac2eec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7261,7 +7261,6 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 rc-progress: 3.4.0 From df21bbd4ad56f413ab0190128b613997e9e50b76 Mon Sep 17 00:00:00 2001 From: Elizabeth Hobbs Date: Thu, 3 Nov 2022 14:02:15 -0700 Subject: [PATCH 266/434] Remove app.googleAnalyticsTrackingId and related scripts The analytics plugin removed the need for app.googleAnalyticsTrackingId and the script tags in packages/app/public/index.html. More context: https://discord.com/channels/687207715902193673/1007303347914690610/1014108244664401952 Signed-off-by: Elizabeth Hobbs --- .changeset/four-snails-raise.md | 5 +++ .changeset/lucky-falcons-dress.md | 38 +++++++++++++++++++ app-config.yaml | 1 - .../templates/backstage-app-config.yaml | 1 - contrib/chart/backstage/values.yaml | 1 - packages/app/public/index.html | 19 +--------- packages/cli/package.json | 8 ---- .../packages/app/public/index.html | 18 --------- plugins/config-schema/dev/example-schema.json | 6 --- 9 files changed, 44 insertions(+), 53 deletions(-) create mode 100644 .changeset/four-snails-raise.md create mode 100644 .changeset/lucky-falcons-dress.md diff --git a/.changeset/four-snails-raise.md b/.changeset/four-snails-raise.md new file mode 100644 index 0000000000..1484a454e1 --- /dev/null +++ b/.changeset/four-snails-raise.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Removed googleAnalyticsTrackingId configSchema. diff --git a/.changeset/lucky-falcons-dress.md b/.changeset/lucky-falcons-dress.md new file mode 100644 index 0000000000..16e5c8a015 --- /dev/null +++ b/.changeset/lucky-falcons-dress.md @@ -0,0 +1,38 @@ +--- +'@backstage/create-app': patch +--- + +The [Analytics API](https://backstage.io/docs/plugins/analytics) is the recommended way to track usage in Backstage; an optionally installable [Google Analytics module](https://github.com/backstage/backstage/tree/master/plugins/analytics-module-ga#installation) has superseded the old app.googleAnalyticsTrackingId config and its corresponding script tags in packages/app/public/index.html. + +For an existing installation where you want to remove the redundant app.googleAnalyticsTrackingId, you should make the following adjustment to `packages/app/public/index.html`: + +```diff + <%= config.getString('app.title') %> +- <% if (config.has('app.googleAnalyticsTrackingId')) { %> +- +- +- <% } %> + +``` + +Additionally, you should make the following adjustment to `app-config.yaml`: + +```diff +app: + title: Backstage Example App + baseUrl: http://localhost:3000 +- googleAnalyticsTrackingId: # UA-000000-0 +``` diff --git a/app-config.yaml b/app-config.yaml index 69a1207365..ef133491af 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -1,7 +1,6 @@ app: title: Backstage Example App baseUrl: http://localhost:3000 - googleAnalyticsTrackingId: # UA-000000-0 #datadogRum: # clientToken: '123456789' # applicationId: qwerty diff --git a/contrib/chart/backstage/templates/backstage-app-config.yaml b/contrib/chart/backstage/templates/backstage-app-config.yaml index f06e47feab..061fc3285b 100644 --- a/contrib/chart/backstage/templates/backstage-app-config.yaml +++ b/contrib/chart/backstage/templates/backstage-app-config.yaml @@ -13,7 +13,6 @@ metadata: data: APP_CONFIG_app_baseUrl: {{ .Values.appConfig.app.baseUrl | quote | quote }} APP_CONFIG_app_title: {{ .Values.appConfig.app.title | quote | quote }} - APP_CONFIG_app_googleAnalyticsTrackingId: {{ .Values.appConfig.app.googleAnalyticsTrackingId | quote | quote }} APP_CONFIG_backend_baseUrl: {{ .Values.appConfig.backend.baseUrl | quote | quote }} APP_CONFIG_backend_cors_origin: {{ .Values.appConfig.backend.cors.origin | quote | quote }} APP_CONFIG_techdocs_storageUrl: {{ .Values.appConfig.techdocs.storageUrl | quote | quote }} diff --git a/contrib/chart/backstage/values.yaml b/contrib/chart/backstage/values.yaml index 6ffe076e57..cd80fd954b 100644 --- a/contrib/chart/backstage/values.yaml +++ b/contrib/chart/backstage/values.yaml @@ -92,7 +92,6 @@ appConfig: app: baseUrl: https://demo.example.com title: Backstage - googleAnalyticsTrackingId: backend: baseUrl: https://demo.example.com listen: diff --git a/packages/app/public/index.html b/packages/app/public/index.html index 885fb6c228..863566e776 100644 --- a/packages/app/public/index.html +++ b/packages/app/public/index.html @@ -44,24 +44,7 @@ /> <%= config.getString('app.title') %> - <% if (config.has('app.googleAnalyticsTrackingId')) { %> - - - <% } %> <% if (config.has('app.datadogRum')) { %> + <% if (config.has('app.datadogRum')) { %> - - <% } %> diff --git a/plugins/config-schema/dev/example-schema.json b/plugins/config-schema/dev/example-schema.json index bb90595340..9c16e8c316 100644 --- a/plugins/config-schema/dev/example-schema.json +++ b/plugins/config-schema/dev/example-schema.json @@ -19,12 +19,6 @@ "visibility": "frontend", "description": "The title of the app." }, - "googleAnalyticsTrackingId": { - "type": "string", - "visibility": "frontend", - "description": "Tracking ID for Google Analytics", - "examples": ["UA-000000-0"] - }, "listen": { "type": "object", "description": "Listening configuration for local development", From 0611f266c6fe1dce4ca268b38d6365a7925955fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Nov 2022 02:38:08 +0000 Subject: [PATCH 267/434] build(deps): bump socket.io-parser from 3.3.2 to 3.3.3 Bumps [socket.io-parser](https://github.com/socketio/socket.io-parser) from 3.3.2 to 3.3.3. - [Release notes](https://github.com/socketio/socket.io-parser/releases) - [Changelog](https://github.com/socketio/socket.io-parser/blob/main/CHANGELOG.md) - [Commits](https://github.com/socketio/socket.io-parser/compare/3.3.2...3.3.3) --- updated-dependencies: - dependency-name: socket.io-parser dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 025d31f618..3d2635bae8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35758,13 +35758,13 @@ __metadata: linkType: hard "socket.io-parser@npm:~3.3.0": - version: 3.3.2 - resolution: "socket.io-parser@npm:3.3.2" + version: 3.3.3 + resolution: "socket.io-parser@npm:3.3.3" dependencies: component-emitter: ~1.3.0 debug: ~3.1.0 isarray: 2.0.1 - checksum: 794b3f374faff583a74e2b4fdf55a01761622022d763a0261e3e13889f3088b288caa0f42f092451f7bcc088a4bbad1c48d86871388ff7d5cc5dfc1b15a928b5 + checksum: 6cf464e324e4207811dbf994822c0aa18ba01d615fbed8e3f069927e0e402fdc9b3ac3d2657f18d481fb8c584b1fd40152ced15b3686982a51ec843c6a76dbc2 languageName: node linkType: hard From 6132afe4a336c48209e25938bb625560c386f9f6 Mon Sep 17 00:00:00 2001 From: Kyle Smith Date: Wed, 9 Nov 2022 22:23:32 -0600 Subject: [PATCH 268/434] docs: fix /frame/handler => /handler/frame typo Signed-off-by: Kyle Smith --- docs/auth/add-auth-provider.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/auth/add-auth-provider.md b/docs/auth/add-auth-provider.md index 01c18f04cd..a43e2307e6 100644 --- a/docs/auth/add-auth-provider.md +++ b/docs/auth/add-auth-provider.md @@ -49,7 +49,7 @@ the user to initiate a login. This login request is done to the `/start` endpoint which is handled by the `start` method. The `start` method re-directs to the external auth provider who authenticates -the request and re-directs the request to the `/frame/handler` endpoint, which +the request and re-directs the request to the `/handler/frame` endpoint, which is handled by the `frameHandler` method. The `frameHandler` returns an HTML response, containing a script that does a From f316f8b4d801cf1843b71cce1d10938ee4400e7f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Nov 2022 09:12:36 +0000 Subject: [PATCH 269/434] Update dependency google-auth-library to v8.7.0 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3d2635bae8..fa77a9ffe4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23868,8 +23868,8 @@ __metadata: linkType: hard "google-auth-library@npm:^8.0.0": - version: 8.6.0 - resolution: "google-auth-library@npm:8.6.0" + version: 8.7.0 + resolution: "google-auth-library@npm:8.7.0" dependencies: arrify: ^2.0.0 base64-js: ^1.3.0 @@ -23880,7 +23880,7 @@ __metadata: gtoken: ^6.1.0 jws: ^4.0.0 lru-cache: ^6.0.0 - checksum: ba2eed30dc495393cbaa4159e85504944c88c751f780fdff03a98e065c72f160e0918f5ddeb2af3631867f5018d1812ea8c75067d4be051cafdbdcc7b9cc0247 + checksum: 978d1c5f763aceddbc0218cd76fa578c8ba54a0653cefffaf61847bb8d246ebf26e7fcd276d8885b8a3354c17eef0a11cfae9e60e4df62c01cae4378d4eb78e4 languageName: node linkType: hard From a4a7166fd0ccb66addb80792f8c926b56050488e Mon Sep 17 00:00:00 2001 From: manusant Date: Thu, 10 Nov 2022 10:13:57 +0000 Subject: [PATCH 270/434] Cleanup exports Signed-off-by: manusant --- plugins/sonarqube/api-report.md | 15 ++++++++++++--- .../src/components/SonarQubeContentPage/index.ts | 3 ++- plugins/sonarqube/src/components/index.ts | 6 ++++-- plugins/sonarqube/src/index.ts | 15 ++------------- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/plugins/sonarqube/api-report.md b/plugins/sonarqube/api-report.md index 48cd38e97c..df9601ea8f 100644 --- a/plugins/sonarqube/api-report.md +++ b/plugins/sonarqube/api-report.md @@ -32,6 +32,17 @@ export const isSonarQubeAvailable: (entity: Entity) => boolean; // @public (undocumented) export const SONARQUBE_PROJECT_KEY_ANNOTATION = 'sonarqube.org/project-key'; +// @public (undocumented) +export const SonarQubeCard: (props: { + variant?: InfoCardVariants; + duplicationRatings?: DuplicationRating[]; +}) => JSX.Element; + +// @public (undocumented) +export const SonarQubeContentPage: ( + props: SonarQubeContentPageProps, +) => JSX.Element; + // @public (undocumented) export type SonarQubeContentPageProps = { title?: string; @@ -39,7 +50,5 @@ export type SonarQubeContentPageProps = { }; // @public (undocumented) -const sonarQubePlugin: BackstagePlugin<{}, {}, {}>; -export { sonarQubePlugin as plugin }; -export { sonarQubePlugin }; +export const sonarQubePlugin: BackstagePlugin<{}, {}, {}>; ``` diff --git a/plugins/sonarqube/src/components/SonarQubeContentPage/index.ts b/plugins/sonarqube/src/components/SonarQubeContentPage/index.ts index 27c0c59365..59327e9a88 100644 --- a/plugins/sonarqube/src/components/SonarQubeContentPage/index.ts +++ b/plugins/sonarqube/src/components/SonarQubeContentPage/index.ts @@ -13,4 +13,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export * from './SonarQubeContentPage'; +export { SonarQubeContentPage } from './SonarQubeContentPage'; +export type { SonarQubeContentPageProps } from './SonarQubeContentPage'; diff --git a/plugins/sonarqube/src/components/index.ts b/plugins/sonarqube/src/components/index.ts index 3edce60f37..3cb54da601 100644 --- a/plugins/sonarqube/src/components/index.ts +++ b/plugins/sonarqube/src/components/index.ts @@ -14,8 +14,10 @@ * limitations under the License. */ -export * from './SonarQubeCard'; -export * from './SonarQubeContentPage'; +export { SonarQubeCard } from './SonarQubeCard'; +export type { DuplicationRating } from './SonarQubeCard'; +export { SonarQubeContentPage } from './SonarQubeContentPage'; +export type { SonarQubeContentPageProps } from './SonarQubeContentPage'; export { isSonarQubeAvailable, SONARQUBE_PROJECT_KEY_ANNOTATION, diff --git a/plugins/sonarqube/src/index.ts b/plugins/sonarqube/src/index.ts index 9936cc04e9..30f6351d4d 100644 --- a/plugins/sonarqube/src/index.ts +++ b/plugins/sonarqube/src/index.ts @@ -21,16 +21,5 @@ * @packageDocumentation */ -export type { - DuplicationRating, - SonarQubeContentPageProps, - SONARQUBE_PROJECT_KEY_ANNOTATION, - isSonarQubeAvailable, -} from './components'; - -export { - sonarQubePlugin, - sonarQubePlugin as plugin, - EntitySonarQubeCard, - EntitySonarQubeContentPage, -} from './plugin'; +export * from './components'; +export * from './plugin'; From 0e37858f22bf28e42b292d86305d1b571410d7e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 10 Nov 2022 11:56:29 +0100 Subject: [PATCH 271/434] richer errors in the msgraph import steps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/clean-socks-call.md | 5 +++++ .../src/microsoftGraph/read.ts | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/clean-socks-call.md diff --git a/.changeset/clean-socks-call.md b/.changeset/clean-socks-call.md new file mode 100644 index 0000000000..9b802618f6 --- /dev/null +++ b/.changeset/clean-socks-call.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-msgraph': patch +--- + +Added cause information to logged warnings diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts index 8e1d9a3776..0ed411bfea 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts @@ -122,7 +122,7 @@ export async function readMicrosoftGraphUsers( 120, ); } catch (e) { - options.logger.warn(`Unable to load photo for ${user.id}`); + options.logger.warn(`Unable to load photo for ${user.id}, ${e}`); } const entity = await transformer(user, userPhoto); @@ -206,7 +206,7 @@ export async function readMicrosoftGraphUsersInGroups( expand: options.userExpand, }); } catch (e) { - options.logger.warn(`Unable to load user for ${userId}`); + options.logger.warn(`Unable to load user for ${userId}, ${e}`); } if (user) { try { @@ -217,7 +217,7 @@ export async function readMicrosoftGraphUsersInGroups( 120, ); } catch (e) { - options.logger.warn(`Unable to load userphoto for ${userId}`); + options.logger.warn(`Unable to load userphoto for ${userId}, ${e}`); } const entity = await transformer(user, userPhoto); From 4db78c2296b10c224163313550d4ee9125014c94 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Nov 2022 12:33:11 +0000 Subject: [PATCH 272/434] Update dependency @asyncapi/react-component to v1.0.0-next.44 Signed-off-by: Renovate Bot --- .changeset/renovate-e920c22.md | 5 +++++ plugins/api-docs/package.json | 2 +- yarn.lock | 10 +++++----- 3 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 .changeset/renovate-e920c22.md diff --git a/.changeset/renovate-e920c22.md b/.changeset/renovate-e920c22.md new file mode 100644 index 0000000000..29a66fba59 --- /dev/null +++ b/.changeset/renovate-e920c22.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-api-docs': patch +--- + +Updated dependency `@asyncapi/react-component` to `1.0.0-next.44`. diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 9041176057..8b6f4a638d 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -32,7 +32,7 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@asyncapi/react-component": "1.0.0-next.43", + "@asyncapi/react-component": "1.0.0-next.44", "@backstage/catalog-model": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", diff --git a/yarn.lock b/yarn.lock index 8a3477a715..f75571e221 100644 --- a/yarn.lock +++ b/yarn.lock @@ -303,9 +303,9 @@ __metadata: languageName: node linkType: hard -"@asyncapi/react-component@npm:1.0.0-next.43": - version: 1.0.0-next.43 - resolution: "@asyncapi/react-component@npm:1.0.0-next.43" +"@asyncapi/react-component@npm:1.0.0-next.44": + version: 1.0.0-next.44 + resolution: "@asyncapi/react-component@npm:1.0.0-next.44" dependencies: "@asyncapi/avro-schema-parser": ^0.3.0 "@asyncapi/openapi-schema-parser": ^2.0.0 @@ -319,7 +319,7 @@ __metadata: peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: d19adc2b6e674633457da28d38636df4cf9891f4038827b52f2737699d064bcf0d3be707e9f3284852d1bb507f3f36df9ec3bb02fd6f901cfda7a1f49ea9c5da + checksum: 1d96db3bc6a4655884969a7639467836376c028df1a00f8930adf4e1b6ecb43e6a2d61df5c68e63d6c105d319fecb3f2ac0e4146274a81a874fbde17f4dbac1c languageName: node linkType: hard @@ -4155,7 +4155,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-api-docs@workspace:plugins/api-docs" dependencies: - "@asyncapi/react-component": 1.0.0-next.43 + "@asyncapi/react-component": 1.0.0-next.44 "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/core-app-api": "workspace:^" From 4a41ce86b599710945ee5a75d033f0194f903abf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Nov 2022 12:34:07 +0000 Subject: [PATCH 273/434] Update dependency @pmmmwh/react-refresh-webpack-plugin to v0.5.9 Signed-off-by: Renovate Bot --- yarn.lock | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8a3477a715..dbcfe18059 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12152,8 +12152,8 @@ __metadata: linkType: hard "@pmmmwh/react-refresh-webpack-plugin@npm:^0.5.7": - version: 0.5.8 - resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.5.8" + version: 0.5.9 + resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.5.9" dependencies: ansi-html-community: ^0.0.8 common-path-prefix: ^3.0.0 @@ -12161,7 +12161,7 @@ __metadata: error-stack-parser: ^2.0.6 find-up: ^5.0.0 html-entities: ^2.1.0 - loader-utils: ^2.0.0 + loader-utils: ^2.0.3 schema-utils: ^3.0.0 source-map: ^0.7.3 peerDependencies: @@ -12186,7 +12186,7 @@ __metadata: optional: true webpack-plugin-serve: optional: true - checksum: 48d8b2813dfba7d482e58a2b0161b79e3a5d608603f1a3c34d709ecc2e6e08f8b14f79934c57849d06f153eb327f18e3d8e1539f978e40ca91539c342f27b8ae + checksum: 446c0add9ecf17ed9911bf310bf22ab64f4b3d0ce334e68a3fcac5efee782ef4d7b6260997efaf720c7a2ea39086db89629e4aa07fb18558387d8dc8f0f31da2 languageName: node linkType: hard @@ -28013,6 +28013,17 @@ __metadata: languageName: node linkType: hard +"loader-utils@npm:^2.0.3": + version: 2.0.3 + resolution: "loader-utils@npm:2.0.3" + dependencies: + big.js: ^5.2.2 + emojis-list: ^3.0.0 + json5: ^2.1.2 + checksum: d055c61ce5927b64cb4af40218606603a7d3a39adb7b6eec116bb31d19203875950e478152dea056de404eced8e87e9bfd336ec636591ded040ea451f63c7d88 + languageName: node + linkType: hard + "loader-utils@npm:^3.2.0": version: 3.2.0 resolution: "loader-utils@npm:3.2.0" From 4e8a483112b52065b2f956a8c780d362a4105e7d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Nov 2022 13:23:49 +0000 Subject: [PATCH 274/434] Update dependency @roadiehq/backstage-plugin-github-insights to v2.1.1 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index dbcfe18059..bd769b7fd2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12399,8 +12399,8 @@ __metadata: linkType: hard "@roadiehq/backstage-plugin-github-insights@npm:^2.0.5": - version: 2.1.0 - resolution: "@roadiehq/backstage-plugin-github-insights@npm:2.1.0" + version: 2.1.1 + resolution: "@roadiehq/backstage-plugin-github-insights@npm:2.1.1" dependencies: "@backstage/catalog-model": ^1.1.2 "@backstage/core-components": ^0.11.2 @@ -12422,7 +12422,7 @@ __metadata: react: ^16.13.1 || ^17.0.0 react-dom: ^16.13.1 || ^17.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 - checksum: 33ba1f1cf2370bd0af8cd3b9ed117f432de13be7b7a17dc23d427195826a66f696d0dcf916e6105c02b595d6c1eb151e4d280c8f248f75e8cfff05e8480c7cd8 + checksum: 95f02d4e51e88c7e3acf04b4fa54e68bf20800f0c21a22c4231bc6400cfae0cc11e7f0779f6d82e4d76eb6e97c25e7bd4ca869ada14e668d42741fd9b89f7351 languageName: node linkType: hard From 63705e73d98dfa9013a582c92cfde01b4f33098b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20Do=C4=9Fan?= <8117265+omerfarukdogan@users.noreply.github.com> Date: Thu, 10 Nov 2022 16:58:21 +0300 Subject: [PATCH 275/434] feat(docs): hide document description if not provided MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ömer Faruk Doğan <8117265+omerfarukdogan@users.noreply.github.com> --- .changeset/silly-snails-fail.md | 5 +++++ .../TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/silly-snails-fail.md diff --git a/.changeset/silly-snails-fail.md b/.changeset/silly-snails-fail.md new file mode 100644 index 0000000000..10376e5ece --- /dev/null +++ b/.changeset/silly-snails-fail.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': minor +--- + +Hide document description if not provided diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx index e76cb1d173..b7b297591d 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx @@ -81,7 +81,7 @@ export const TechDocsReaderPageHeader = ( setSubtitle(() => { let { site_description } = metadata; if (!site_description || site_description === 'None') { - site_description = 'Home'; + site_description = ''; } return site_description; }); @@ -155,7 +155,7 @@ export const TechDocsReaderPageHeader = ( type="Documentation" typeLink={docsRootLink} title={title || skeleton} - subtitle={subtitle || skeleton} + subtitle={subtitle === '' ? undefined : subtitle || skeleton} > {tabTitle} From 8a737b0ed7988bccfc9c716dab1b4f6d01802088 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Nov 2022 15:42:14 +0000 Subject: [PATCH 276/434] Update dependency @codemirror/view to v6.4.2 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8f2f8a41b9..88830b576b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8386,13 +8386,13 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0": - version: 6.4.1 - resolution: "@codemirror/view@npm:6.4.1" + version: 6.4.2 + resolution: "@codemirror/view@npm:6.4.2" dependencies: "@codemirror/state": ^6.0.0 style-mod: ^4.0.0 w3c-keyname: ^2.2.4 - checksum: 51f8e9bf1701cd490708784fd42a90dd9b2ad84aaebfacdbcfa9093e7f99ded38093ac49bc9eb037924b7734a58ed854a19621d931cce3f7962c2a0b30fecc23 + checksum: c79982563ad90adf1d7504b28bb1304a73f669c69634a1630b51521e4023b3630c15601daf2857683b34a86cac4ca24dc5b538a9d944616617f99c1a7da7faa6 languageName: node linkType: hard From 4acce9e5cc1d14d8d97991d5eb86ffbaf8911b10 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Nov 2022 15:43:12 +0000 Subject: [PATCH 277/434] Update dependency @uiw/react-codemirror to v4.13.2 Signed-off-by: Renovate Bot --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8f2f8a41b9..b22003e0ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15456,9 +15456,9 @@ __metadata: languageName: node linkType: hard -"@uiw/codemirror-extensions-basic-setup@npm:4.13.0": - version: 4.13.0 - resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.13.0" +"@uiw/codemirror-extensions-basic-setup@npm:4.13.2": + version: 4.13.2 + resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.13.2" dependencies: "@codemirror/autocomplete": ^6.0.0 "@codemirror/commands": ^6.0.0 @@ -15475,19 +15475,19 @@ __metadata: "@codemirror/search": ">=6.0.0" "@codemirror/state": ">=6.0.0" "@codemirror/view": ">=6.0.0" - checksum: bdff9fc4e32ecd9a31be75a1e003793ead1e7164748542307c92d50ffae1d66c5b1b2dbe9cbd6b4df1e31cac5fa8c27b8d5de4afb59373abae30b2cee96964d5 + checksum: 5597d6bd7ea0304aa15f77c4bec4a071d95ae9b706a2abd6486f5fc51dba4a89101fa1e6faeb8f4fc27f4698993b008c3fd751a864618eef6baef56434d1fafd languageName: node linkType: hard "@uiw/react-codemirror@npm:^4.9.3": - version: 4.13.0 - resolution: "@uiw/react-codemirror@npm:4.13.0" + version: 4.13.2 + resolution: "@uiw/react-codemirror@npm:4.13.2" dependencies: "@babel/runtime": ^7.18.6 "@codemirror/commands": ^6.1.0 "@codemirror/state": ^6.1.1 "@codemirror/theme-one-dark": ^6.0.0 - "@uiw/codemirror-extensions-basic-setup": 4.13.0 + "@uiw/codemirror-extensions-basic-setup": 4.13.2 codemirror: ^6.0.0 peerDependencies: "@babel/runtime": ">=7.11.0" @@ -15497,7 +15497,7 @@ __metadata: codemirror: ">=6.0.0" react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: ff5d4166dadf1ce14b8368fb1f98a6044410ebf315aa57ffc3c7721cea7b5eafd02e205230fc8be98700959d3732e435953495fbc8343af4be5f402b3444eb34 + checksum: 8f35aa2f54beabc440027584ccd6244f4d2e52e0792f700fb8612f1a5c8d0d705203ddddd202b3d6b82a3b1426bd4bdb230f76a5ec1ae41ec3806e9b2c955900 languageName: node linkType: hard From b94af16ac85cc9626e2051a0d19018c6d10d012a Mon Sep 17 00:00:00 2001 From: manusant Date: Thu, 10 Nov 2022 16:08:42 +0000 Subject: [PATCH 278/434] Updates according PR commentas Signed-off-by: manusant --- .changeset/unlucky-pigs-end.md | 1 + plugins/sonarqube/api-report.md | 5 ----- .../components/SonarQubeContentPage/SonarQubeContentPage.tsx | 1 - plugins/sonarqube/src/components/index.ts | 1 - 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.changeset/unlucky-pigs-end.md b/.changeset/unlucky-pigs-end.md index 9a33827087..7088a92c48 100644 --- a/.changeset/unlucky-pigs-end.md +++ b/.changeset/unlucky-pigs-end.md @@ -3,3 +3,4 @@ --- Fix sonarqube annotation parsing. Add content page for Sonarqube. +Removed the deprecated `plugin` export; please use `sonarQubePlugin` instead. diff --git a/plugins/sonarqube/api-report.md b/plugins/sonarqube/api-report.md index df9601ea8f..2edf80618e 100644 --- a/plugins/sonarqube/api-report.md +++ b/plugins/sonarqube/api-report.md @@ -38,11 +38,6 @@ export const SonarQubeCard: (props: { duplicationRatings?: DuplicationRating[]; }) => JSX.Element; -// @public (undocumented) -export const SonarQubeContentPage: ( - props: SonarQubeContentPageProps, -) => JSX.Element; - // @public (undocumented) export type SonarQubeContentPageProps = { title?: string; diff --git a/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx b/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx index c11fff7237..33a145b746 100644 --- a/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx +++ b/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx @@ -34,7 +34,6 @@ export type SonarQubeContentPageProps = { supportTitle?: string; }; -/** @public */ export const SonarQubeContentPage = (props: SonarQubeContentPageProps) => { const { entity } = useEntity(); const { title, supportTitle } = props; diff --git a/plugins/sonarqube/src/components/index.ts b/plugins/sonarqube/src/components/index.ts index 3cb54da601..8e1d93f85b 100644 --- a/plugins/sonarqube/src/components/index.ts +++ b/plugins/sonarqube/src/components/index.ts @@ -16,7 +16,6 @@ export { SonarQubeCard } from './SonarQubeCard'; export type { DuplicationRating } from './SonarQubeCard'; -export { SonarQubeContentPage } from './SonarQubeContentPage'; export type { SonarQubeContentPageProps } from './SonarQubeContentPage'; export { isSonarQubeAvailable, From fde99df4c736fe14fe5125402b1488d56bfb6c7f Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Thu, 10 Nov 2022 17:19:57 +0100 Subject: [PATCH 279/434] Rename SubRoute to SettingsLayoutRouteProps Signed-off-by: Nikita Karpukhin --- plugins/user-settings/api-report.md | 4 ++-- .../src/components/SettingsLayout/SettingsLayout.tsx | 6 +++--- .../user-settings/src/components/SettingsLayout/index.ts | 5 ++++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/plugins/user-settings/api-report.md b/plugins/user-settings/api-report.md index 1323bb8d7f..6167e343d6 100644 --- a/plugins/user-settings/api-report.md +++ b/plugins/user-settings/api-report.md @@ -47,7 +47,7 @@ export const Settings: (props: { icon?: IconComponent }) => JSX.Element; // @public (undocumented) export const SettingsLayout: { (props: SettingsLayoutProps): JSX.Element; - Route: (props: SubRoute) => null; + Route: (props: SettingsLayoutRouteProps) => null; }; // @public (undocumented) @@ -58,7 +58,7 @@ export type SettingsLayoutProps = { }; // @public (undocumented) -export type SubRoute = { +export type SettingsLayoutRouteProps = { path: string; title: string; children: JSX.Element; diff --git a/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx b/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx index 23394819d6..c120c87122 100644 --- a/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx +++ b/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx @@ -28,7 +28,7 @@ import { } from '@backstage/core-plugin-api'; /** @public */ -export type SubRoute = { +export type SettingsLayoutRouteProps = { path: string; title: string; children: JSX.Element; @@ -37,7 +37,7 @@ export type SubRoute = { const dataKey = 'plugin.user-settings.settingsLayoutRoute'; -const Route: (props: SubRoute) => null = () => null; +const Route: (props: SettingsLayoutRouteProps) => null = () => null; attachComponentData(Route, dataKey, true); // This causes all mount points that are discovered within this route to use the path of the route itself @@ -64,7 +64,7 @@ export const SettingsLayout = (props: SettingsLayoutProps) => { withStrictError: 'Child of SettingsLayout must be an SettingsLayout.Route', }) - .getElements() + .getElements() .map(child => child.props), ); diff --git a/plugins/user-settings/src/components/SettingsLayout/index.ts b/plugins/user-settings/src/components/SettingsLayout/index.ts index 36a5633c94..6e610f8078 100644 --- a/plugins/user-settings/src/components/SettingsLayout/index.ts +++ b/plugins/user-settings/src/components/SettingsLayout/index.ts @@ -14,5 +14,8 @@ * limitations under the License. */ -export type { SettingsLayoutProps, SubRoute } from './SettingsLayout'; +export type { + SettingsLayoutProps, + SettingsLayoutRouteProps, +} from './SettingsLayout'; export { SettingsLayout } from './SettingsLayout'; From c9bbb32e0b67fa80d86ce3154050532398d099dd Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Thu, 10 Nov 2022 17:25:00 +0100 Subject: [PATCH 280/434] Update README Signed-off-by: Nikita Karpukhin --- plugins/user-settings/README.md | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/plugins/user-settings/README.md b/plugins/user-settings/README.md index 09e095a8e0..1549b8de65 100644 --- a/plugins/user-settings/README.md +++ b/plugins/user-settings/README.md @@ -104,20 +104,16 @@ import { } from '@backstage/plugin-user-settings'; import { AdvancedSettings } from './advancedSettings'; -export const SettingsPage = () => { - return ( - - - - - - - - - ); -}; - -export const settingsPage = ; +export const settingsPage = () => ( + + + + + + + + +); ``` Now register the new settings page in `packages/app/src/App.tsx`: From f36127f5fe044d6ed2a6211c6777199ddd39ae5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arn=C3=BE=C3=B3r=20J=C3=B3nsson?= Date: Wed, 9 Nov 2022 18:42:19 +0100 Subject: [PATCH 281/434] Add optional step to SimpleStepper Signed-off-by: Arnthor Jonsson --- .changeset/cyan-seahorses-itch.md | 5 ++++ .../SimpleStepper/SimpleStepper.stories.tsx | 20 +++++++++++++ .../SimpleStepper/SimpleStepper.test.tsx | 28 +++++++++++++++++++ .../SimpleStepper/SimpleStepperFooter.tsx | 27 ++++++++++++++++++ .../src/components/SimpleStepper/types.ts | 5 ++++ 5 files changed, 85 insertions(+) create mode 100644 .changeset/cyan-seahorses-itch.md diff --git a/.changeset/cyan-seahorses-itch.md b/.changeset/cyan-seahorses-itch.md new file mode 100644 index 0000000000..c3ced5ceb7 --- /dev/null +++ b/.changeset/cyan-seahorses-itch.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': minor +--- + +Add optional step to SimpleStepper diff --git a/packages/core-components/src/components/SimpleStepper/SimpleStepper.stories.tsx b/packages/core-components/src/components/SimpleStepper/SimpleStepper.stories.tsx index 2f3f26f23e..aedd5e6b80 100644 --- a/packages/core-components/src/components/SimpleStepper/SimpleStepper.stories.tsx +++ b/packages/core-components/src/components/SimpleStepper/SimpleStepper.stories.tsx @@ -91,3 +91,23 @@ export const CompletionStep = (args: StepperProps) => { }; CompletionStep.args = defaultArgs; + +export const OptionalStep = (args: StepperProps) => { + return ( + + +
This is the content for step 1
+
+ +
This is the content for step 2
+
+
+ ); +}; + +ConditionalButtons.args = defaultArgs; diff --git a/packages/core-components/src/components/SimpleStepper/SimpleStepper.test.tsx b/packages/core-components/src/components/SimpleStepper/SimpleStepper.test.tsx index 5897054ed5..73baff8db2 100644 --- a/packages/core-components/src/components/SimpleStepper/SimpleStepper.test.tsx +++ b/packages/core-components/src/components/SimpleStepper/SimpleStepper.test.tsx @@ -145,4 +145,32 @@ describe('Stepper', () => { expect(rendered.getByText('FinalStepNext')).toBeInTheDocument(); }); + + it('Handles skipStep property', async () => { + const rendered = await renderInTestApp( + + +
step0
+
+ +
step1
+
+ +
step2
+
+ +
step3
+
+
, + ); + + fireEvent.click(getTextInSlide(rendered, 0)('Next') as Node); + expect(rendered.getByText('step1')).toBeInTheDocument(); + + fireEvent.click(getTextInSlide(rendered, 1)('Skip') as Node); + expect(rendered.getByText('step2')).toBeInTheDocument(); + + fireEvent.click(getTextInSlide(rendered, 2)('Back') as Node); + expect(rendered.getByText('step1')).toBeInTheDocument(); + }); }); diff --git a/packages/core-components/src/components/SimpleStepper/SimpleStepperFooter.tsx b/packages/core-components/src/components/SimpleStepper/SimpleStepperFooter.tsx index 5f4bdbf0c6..0f7d604eb0 100644 --- a/packages/core-components/src/components/SimpleStepper/SimpleStepperFooter.tsx +++ b/packages/core-components/src/components/SimpleStepper/SimpleStepperFooter.tsx @@ -45,6 +45,10 @@ interface NextBtnProps extends CommonBtnProps { last?: boolean; stepIndex: number; } +interface SkipBtnProps extends CommonBtnProps { + disabled?: boolean; + stepIndex: number; +} interface BackBtnProps extends CommonBtnProps { disabled?: boolean; stepIndex: number; @@ -71,6 +75,18 @@ const NextBtn = ({ ); +const SkipBtn = ({ text, handleClick, disabled, stepIndex }: SkipBtnProps) => ( + +); + const BackBtn = ({ text, handleClick, disabled, stepIndex }: BackBtnProps) => ( + + + + +
+ + + + + + + null} + /> +
+ + ); +}; diff --git a/plugins/scaffolder/src/components/TemplateEditorPage/TemplateEditorIntro.tsx b/plugins/scaffolder/src/components/TemplateEditorPage/TemplateEditorIntro.tsx index dc411ee965..61e6c46964 100644 --- a/plugins/scaffolder/src/components/TemplateEditorPage/TemplateEditorIntro.tsx +++ b/plugins/scaffolder/src/components/TemplateEditorPage/TemplateEditorIntro.tsx @@ -44,7 +44,7 @@ const useStyles = makeStyles(theme => ({ interface EditorIntroProps { style?: JSX.IntrinsicElements['div']['style']; - onSelect?: (option: 'local' | 'form') => void; + onSelect?: (option: 'local' | 'form' | 'field-explorer') => void; } export function TemplateEditorIntro(props: EditorIntroProps) { @@ -104,6 +104,22 @@ export function TemplateEditorIntro(props: EditorIntroProps) { ); + const cardFieldExplorer = ( + + props.onSelect?.('field-explorer')}> + + + Custom Field Explorer + + + View and play around with available installed custom field + extensions. + + + + + ); + return (
@@ -121,6 +137,7 @@ export function TemplateEditorIntro(props: EditorIntroProps) { {supportsLoad && cardLoadLocal} {cardFormEditor} {!supportsLoad && cardLoadLocal} + {cardFieldExplorer}
); diff --git a/plugins/scaffolder/src/components/TemplateEditorPage/TemplateEditorPage.tsx b/plugins/scaffolder/src/components/TemplateEditorPage/TemplateEditorPage.tsx index b539b6403b..8847b85373 100644 --- a/plugins/scaffolder/src/components/TemplateEditorPage/TemplateEditorPage.tsx +++ b/plugins/scaffolder/src/components/TemplateEditorPage/TemplateEditorPage.tsx @@ -19,6 +19,7 @@ import { TemplateDirectoryAccess, WebFileSystemAccess, } from '../../lib/filesystem'; +import { CustomFieldExplorer } from './CustomFieldExplorer'; import { TemplateEditorIntro } from './TemplateEditorIntro'; import { TemplateEditor } from './TemplateEditor'; import { TemplateFormPreviewer } from './TemplateFormPreviewer'; @@ -32,6 +33,9 @@ type Selection = } | { type: 'form'; + } + | { + type: 'field-explorer'; }; interface TemplateEditorPageProps { @@ -62,6 +66,13 @@ export function TemplateEditorPage(props: TemplateEditorPageProps) { layouts={props.layouts} /> ); + } else if (selection?.type === 'field-explorer') { + content = ( + setSelection(undefined)} + /> + ); } else { content = ( @@ -73,6 +84,8 @@ export function TemplateEditorPage(props: TemplateEditorPageProps) { .catch(() => {}); } else if (option === 'form') { setSelection({ type: 'form' }); + } else if (option === 'field-explorer') { + setSelection({ type: 'field-explorer' }); } }} /> diff --git a/plugins/scaffolder/src/components/fields/EntityNamePicker/EntityNamePicker.tsx b/plugins/scaffolder/src/components/fields/EntityNamePicker/EntityNamePicker.tsx index 802135a863..eba05cfb92 100644 --- a/plugins/scaffolder/src/components/fields/EntityNamePicker/EntityNamePicker.tsx +++ b/plugins/scaffolder/src/components/fields/EntityNamePicker/EntityNamePicker.tsx @@ -15,13 +15,16 @@ */ import React from 'react'; import { FieldExtensionComponentProps } from '../../../extensions'; +import { EntityNamePickerReturnValue } from './schema'; import { TextField } from '@material-ui/core'; +export { EntityNamePickerSchema } from './schema'; + /** * EntityName Picker */ export const EntityNamePicker = ( - props: FieldExtensionComponentProps, + props: FieldExtensionComponentProps, ) => { const { onChange, diff --git a/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts b/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts new file mode 100644 index 0000000000..45aa4502ce --- /dev/null +++ b/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { JSONSchema7 } from 'json-schema'; +import { z } from 'zod'; +import zodToJsonSchema from 'zod-to-json-schema'; + +const EntityNamePickerReturnValueSchema = z.string(); + +export type EntityNamePickerReturnValue = z.infer< + typeof EntityNamePickerReturnValueSchema +>; + +export const EntityNamePickerSchema = { + returnValue: zodToJsonSchema( + EntityNamePickerReturnValueSchema, + ) as JSONSchema7, +}; diff --git a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx index e7883a4721..8fcc412d0a 100644 --- a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx @@ -24,19 +24,9 @@ import Autocomplete from '@material-ui/lab/Autocomplete'; import React, { useCallback, useEffect } from 'react'; import useAsync from 'react-use/lib/useAsync'; import { FieldExtensionComponentProps } from '../../../extensions'; +import { EntityPickerReturnValue, EntityPickerUiOptions } from './schema'; -/** - * The input props that can be specified under `ui:options` for the - * `EntityPicker` field extension. - * - * @public - */ -export interface EntityPickerUiOptions { - allowedKinds?: string[]; - defaultKind?: string; - allowArbitraryValues?: boolean; - defaultNamespace?: string | false; -} +export { EntityPickerSchema } from './schema'; /** * The underlying component that is rendered in the form for the `EntityPicker` @@ -45,7 +35,10 @@ export interface EntityPickerUiOptions { * @public */ export const EntityPicker = ( - props: FieldExtensionComponentProps, + props: FieldExtensionComponentProps< + EntityPickerReturnValue, + EntityPickerUiOptions + >, ) => { const { onChange, diff --git a/plugins/scaffolder/src/components/fields/EntityPicker/index.ts b/plugins/scaffolder/src/components/fields/EntityPicker/index.ts index 891b5bef16..d1044e4e67 100644 --- a/plugins/scaffolder/src/components/fields/EntityPicker/index.ts +++ b/plugins/scaffolder/src/components/fields/EntityPicker/index.ts @@ -13,4 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export type { EntityPickerUiOptions } from './EntityPicker'; +export { + type EntityPickerUiOptions, + EntityPickerUiOptionsSchema, +} from './schema'; diff --git a/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts b/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts new file mode 100644 index 0000000000..5f7d66fc4f --- /dev/null +++ b/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts @@ -0,0 +1,63 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { JSONSchema7 } from 'json-schema'; +import { z } from 'zod'; +import zodToJsonSchema from 'zod-to-json-schema'; + +/** + * @public + */ +export const EntityPickerUiOptionsSchema = z.object({ + allowedKinds: z + .array(z.string()) + .optional() + .describe('List of kinds of entities to derive options from'), + defaultKind: z + .string() + .optional() + .describe( + 'The default entity kind. Options of this kind will not be prefixed.', + ), + allowArbitraryValues: z + .boolean() + .optional() + .describe('Whether to allow arbitrary user input. Defaults to true'), + defaultNamespace: z + .union([z.string(), z.literal(false)]) + .optional() + .describe( + 'The default namespace. Options with this namespace will not be prefixed.', + ), +}); + +const EntityPickerReturnValueSchema = z.string(); + +/** + * The input props that can be specified under `ui:options` for the + * `EntityPicker` field extension. + * + * @public + */ +export type EntityPickerUiOptions = z.infer; + +export type EntityPickerReturnValue = z.infer< + typeof EntityPickerReturnValueSchema +>; + +export const EntityPickerSchema = { + uiOptions: zodToJsonSchema(EntityPickerUiOptionsSchema) as JSONSchema7, + returnValue: zodToJsonSchema(EntityPickerReturnValueSchema) as JSONSchema7, +}; diff --git a/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx b/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx index c0e3aab436..6d5404cee1 100644 --- a/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx +++ b/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx @@ -23,18 +23,12 @@ import { catalogApiRef } from '@backstage/plugin-catalog-react'; import { FormControl, TextField } from '@material-ui/core'; import { Autocomplete } from '@material-ui/lab'; import { FieldExtensionComponentProps } from '../../../extensions'; +import { + EntityTagsPickerReturnValue, + EntityTagsPickerUiOptions, +} from './schema'; -/** - * The input props that can be specified under `ui:options` for the - * `EntityTagsPicker` field extension. - * - * @public - */ -export interface EntityTagsPickerUiOptions { - kinds?: string[]; - showCounts?: boolean; - helperText?: string; -} +export { EntityTagsPickerSchema } from './schema'; /** * The underlying component that is rendered in the form for the `EntityTagsPicker` @@ -43,7 +37,10 @@ export interface EntityTagsPickerUiOptions { * @public */ export const EntityTagsPicker = ( - props: FieldExtensionComponentProps, + props: FieldExtensionComponentProps< + EntityTagsPickerReturnValue, + EntityTagsPickerUiOptions + >, ) => { const { formData, onChange, uiSchema } = props; const catalogApi = useApi(catalogApiRef); diff --git a/plugins/scaffolder/src/components/fields/EntityTagsPicker/index.ts b/plugins/scaffolder/src/components/fields/EntityTagsPicker/index.ts index 9ff6e553a6..850fc17c8e 100644 --- a/plugins/scaffolder/src/components/fields/EntityTagsPicker/index.ts +++ b/plugins/scaffolder/src/components/fields/EntityTagsPicker/index.ts @@ -13,4 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export type { EntityTagsPickerUiOptions } from './EntityTagsPicker'; +export { + type EntityTagsPickerUiOptions, + EntityTagsPickerUiOptionsSchema, +} from './schema'; diff --git a/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts b/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts new file mode 100644 index 0000000000..ff477903d7 --- /dev/null +++ b/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { JSONSchema7 } from 'json-schema'; +import { z } from 'zod'; +import zodToJsonSchema from 'zod-to-json-schema'; + +/** + * @public + */ +export const EntityTagsPickerUiOptionsSchema = z.object({ + kinds: z + .array(z.string()) + .optional() + .describe('List of kinds of entities to derive tags from'), + showCounts: z + .boolean() + .optional() + .describe('Whether to show usage counts per tag'), + helperText: z.string().optional().describe('Helper text to display'), +}); + +const EntityTagsPickerReturnValueSchema = z.array(z.string()); + +/** + * The input props that can be specified under `ui:options` for the + * `EntityTagsPicker` field extension. + * + * @public + */ +export type EntityTagsPickerUiOptions = z.infer< + typeof EntityTagsPickerUiOptionsSchema +>; + +export type EntityTagsPickerReturnValue = z.infer< + typeof EntityTagsPickerReturnValueSchema +>; + +export const EntityTagsPickerSchema = { + uiOptions: zodToJsonSchema(EntityTagsPickerUiOptionsSchema) as JSONSchema7, + returnValue: zodToJsonSchema( + EntityTagsPickerReturnValueSchema, + ) as JSONSchema7, +}; diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx index 2446883a86..47bcb6c9b8 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx @@ -27,20 +27,12 @@ import React, { useMemo } from 'react'; import useAsync from 'react-use/lib/useAsync'; import { FieldExtensionComponentProps } from '../../../extensions'; +import { + OwnedEntityPickerReturnValue, + OwnedEntityPickerUiOptions, +} from './schema'; -/** - * The input props that can be specified under `ui:options` for the - * `OwnedEntityPicker` field extension. - * - * @public - */ -export interface OwnedEntityPickerUiOptions { - allowedKinds?: string[]; - defaultKind?: string; - allowArbitraryValues?: boolean; - defaultNamespace?: string | false; -} - +export { OwnedEntityPickerSchema } from './schema'; /** * The underlying component that is rendered in the form for the `OwnedEntityPicker` * field extension. @@ -48,7 +40,10 @@ export interface OwnedEntityPickerUiOptions { * @public */ export const OwnedEntityPicker = ( - props: FieldExtensionComponentProps, + props: FieldExtensionComponentProps< + OwnedEntityPickerReturnValue, + OwnedEntityPickerUiOptions + >, ) => { const { onChange, diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/index.ts b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/index.ts index 2988ba8cdc..0101eb8845 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/index.ts +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/index.ts @@ -13,4 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export type { OwnedEntityPickerUiOptions } from './OwnedEntityPicker'; +export { + type OwnedEntityPickerUiOptions, + OwnedEntityPickerUiOptionsSchema, +} from './schema'; diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts new file mode 100644 index 0000000000..c260fae3cd --- /dev/null +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts @@ -0,0 +1,67 @@ +/* + * 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 { JSONSchema7 } from 'json-schema'; +import { z } from 'zod'; +import zodToJsonSchema from 'zod-to-json-schema'; + +/** + * @public + */ +export const OwnedEntityPickerUiOptionsSchema = z.object({ + allowedKinds: z + .array(z.string()) + .optional() + .describe('List of kinds of entities to derive options from'), + defaultKind: z + .string() + .optional() + .describe( + 'The default entity kind. Options of this kind will not be prefixed.', + ), + allowArbitraryValues: z + .boolean() + .optional() + .describe('Whether to allow arbitrary user input. Defaults to true'), + defaultNamespace: z + .union([z.string(), z.literal(false)]) + .optional() + .describe( + 'The default namespace. Options with this namespace will not be prefixed.', + ), +}); + +const OwnedEntityPickerReturnValueSchema = z.string(); + +/** + * The input props that can be specified under `ui:options` for the + * `OwnedEntityPicker` field extension. + * + * @public + */ +export type OwnedEntityPickerUiOptions = z.infer< + typeof OwnedEntityPickerUiOptionsSchema +>; + +export type OwnedEntityPickerReturnValue = z.infer< + typeof OwnedEntityPickerReturnValueSchema +>; + +export const OwnedEntityPickerSchema = { + uiOptions: zodToJsonSchema(OwnedEntityPickerUiOptionsSchema) as JSONSchema7, + returnValue: zodToJsonSchema( + OwnedEntityPickerReturnValueSchema, + ) as JSONSchema7, +}; diff --git a/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.tsx b/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.tsx index 3de2b12bd0..10333684d0 100644 --- a/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.tsx +++ b/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.tsx @@ -16,18 +16,9 @@ import React from 'react'; import { EntityPicker } from '../EntityPicker/EntityPicker'; import { FieldExtensionComponentProps } from '../../../extensions'; +import { OwnerPickerReturnValue, OwnerPickerUiOptions } from './schema'; -/** - * The input props that can be specified under `ui:options` for the - * `OwnerPicker` field extension. - * - * @public - */ -export interface OwnerPickerUiOptions { - allowedKinds?: string[]; - allowArbitraryValues?: boolean; - defaultNamespace?: string | false; -} +export { OwnerPickerSchema } from './schema'; /** * The underlying component that is rendered in the form for the `OwnerPicker` @@ -36,7 +27,10 @@ export interface OwnerPickerUiOptions { * @public */ export const OwnerPicker = ( - props: FieldExtensionComponentProps, + props: FieldExtensionComponentProps< + OwnerPickerReturnValue, + OwnerPickerUiOptions + >, ) => { const { schema: { title = 'Owner', description = 'The owner of the component' }, diff --git a/plugins/scaffolder/src/components/fields/OwnerPicker/index.ts b/plugins/scaffolder/src/components/fields/OwnerPicker/index.ts index aa26024b5b..5d436358b3 100644 --- a/plugins/scaffolder/src/components/fields/OwnerPicker/index.ts +++ b/plugins/scaffolder/src/components/fields/OwnerPicker/index.ts @@ -13,4 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export type { OwnerPickerUiOptions } from './OwnerPicker'; +export { + type OwnerPickerUiOptions, + OwnerPickerUiOptionsSchema, +} from './schema'; diff --git a/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts b/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts new file mode 100644 index 0000000000..634a39ddee --- /dev/null +++ b/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts @@ -0,0 +1,60 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { JSONSchema7 } from 'json-schema'; +import { z } from 'zod'; +import zodToJsonSchema from 'zod-to-json-schema'; + +/** + * @public + */ +export const OwnerPickerUiOptionsSchema = z.object({ + allowedKinds: z + .array(z.string()) + .default(['Group', 'User']) + .optional() + .describe( + 'List of kinds of entities to derive options from. Defaults to Group and User', + ), + allowArbitraryValues: z + .boolean() + .optional() + .describe('Whether to allow arbitrary user input. Defaults to true'), + defaultNamespace: z + .union([z.string(), z.literal(false)]) + .optional() + .describe( + 'The default namespace. Options with this namespace will not be prefixed.', + ), +}); + +const OwnerPickerReturnValueSchema = z.string(); + +/** + * The input props that can be specified under `ui:options` for the + * `OwnerPicker` field extension. + * + * @public + */ +export type OwnerPickerUiOptions = z.infer; + +export type OwnerPickerReturnValue = z.infer< + typeof OwnerPickerReturnValueSchema +>; + +export const OwnerPickerSchema = { + uiOptions: zodToJsonSchema(OwnerPickerUiOptionsSchema) as JSONSchema7, + returnValue: zodToJsonSchema(OwnerPickerReturnValueSchema) as JSONSchema7, +}; diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx index 451df857e5..8aca07e995 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx @@ -28,32 +28,12 @@ import { FieldExtensionComponentProps } from '../../../extensions'; import { RepoUrlPickerHost } from './RepoUrlPickerHost'; import { RepoUrlPickerRepoName } from './RepoUrlPickerRepoName'; import { parseRepoPickerUrl, serializeRepoPickerUrl } from './utils'; +import { RepoUrlPickerReturnValue, RepoUrlPickerUiOptions } from './schema'; import { RepoUrlPickerState } from './types'; import useDebounce from 'react-use/lib/useDebounce'; import { useTemplateSecrets } from '../../secrets'; -/** - * The input props that can be specified under `ui:options` for the - * `RepoUrlPicker` field extension. - * - * @public - */ -export interface RepoUrlPickerUiOptions { - allowedHosts?: string[]; - allowedOrganizations?: string[]; - allowedOwners?: string[]; - allowedRepos?: string[]; - requestUserCredentials?: { - secretsKey: string; - additionalScopes?: { - gerrit?: string[]; - github?: string[]; - gitlab?: string[]; - bitbucket?: string[]; - azure?: string[]; - }; - }; -} +export { RepoUrlPickerSchema } from './schema'; /** * The underlying component that is rendered in the form for the `RepoUrlPicker` @@ -62,7 +42,10 @@ export interface RepoUrlPickerUiOptions { * @public */ export const RepoUrlPicker = ( - props: FieldExtensionComponentProps, + props: FieldExtensionComponentProps< + RepoUrlPickerReturnValue, + RepoUrlPickerUiOptions + >, ) => { const { uiSchema, onChange, rawErrors, formData } = props; const [state, setState] = useState( diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.ts b/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.ts index c5f596a786..34124d0ccd 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.ts +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.ts @@ -13,5 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export type { RepoUrlPickerUiOptions } from './RepoUrlPicker'; +export { + type RepoUrlPickerUiOptions, + RepoUrlPickerUiOptionsSchema, +} from './schema'; export { repoPickerValidation } from './validation'; diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts b/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts new file mode 100644 index 0000000000..b870747fd4 --- /dev/null +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts @@ -0,0 +1,101 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { JSONSchema7 } from 'json-schema'; +import { z } from 'zod'; +import zodToJsonSchema from 'zod-to-json-schema'; + +/** + * @public + */ +export const RepoUrlPickerUiOptionsSchema = z.object({ + allowedHosts: z + .array(z.string()) + .optional() + .describe('List of allowed SCM platform hosts'), + allowedOrganizations: z + .array(z.string()) + .optional() + .describe('List of allowed organizations in the given SCM platform'), + allowedOwners: z + .array(z.string()) + .optional() + .describe('List of allowed owners in the given SCM platform'), + allowedRepos: z + .array(z.string()) + .optional() + .describe('List of allowed repos in the given SCM platform'), + requestUserCredentials: z + .object({ + secretsKey: z + .string() + .describe( + 'Key used within the template secrets context to store the credential', + ), + additionalScopes: z + .object({ + gerrit: z + .array(z.string()) + .optional() + .describe('Additional Gerrit scopes to request'), + github: z + .array(z.string()) + .optional() + .describe('Additional GitHub scopes to request'), + gitlab: z + .array(z.string()) + .optional() + .describe('Additional GitLab scopes to request'), + bitbucket: z + .array(z.string()) + .optional() + .describe('Additional BitBucket scopes to request'), + azure: z + .array(z.string()) + .optional() + .describe('Additional Azure scopes to request'), + }) + .optional() + .describe('Additional permission scopes to request'), + }) + .optional() + .describe( + 'If defined will request user credentials to auth against the given SCM platform', + ), +}); + +const RepoUrlPickerReturnValueSchema = z.string(); + +/** + * The input props that can be specified under `ui:options` for the + * `RepoUrlPicker` field extension. + * + * @public + */ +export type RepoUrlPickerUiOptions = z.infer< + typeof RepoUrlPickerUiOptionsSchema +>; + +export type RepoUrlPickerReturnValue = z.infer< + typeof RepoUrlPickerReturnValueSchema +>; + +// NOTE: There is a bug with this failing validation in the custom field explorer due +// to https://github.com/rjsf-team/react-jsonschema-form/issues/675 even if +// requestUserCredentials is not defined +export const RepoUrlPickerSchema = { + uiOptions: zodToJsonSchema(RepoUrlPickerUiOptionsSchema) as JSONSchema7, + returnValue: zodToJsonSchema(RepoUrlPickerReturnValueSchema) as JSONSchema7, +}; diff --git a/plugins/scaffolder/src/extensions/default.ts b/plugins/scaffolder/src/extensions/default.ts index 8081dcb0ca..c6ab5276d0 100644 --- a/plugins/scaffolder/src/extensions/default.ts +++ b/plugins/scaffolder/src/extensions/default.ts @@ -13,40 +13,64 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { EntityPicker } from '../components/fields/EntityPicker/EntityPicker'; -import { EntityNamePicker } from '../components/fields/EntityNamePicker/EntityNamePicker'; +import { + EntityPicker, + EntityPickerSchema, +} from '../components/fields/EntityPicker/EntityPicker'; +import { + EntityNamePicker, + EntityNamePickerSchema, +} from '../components/fields/EntityNamePicker/EntityNamePicker'; import { entityNamePickerValidation } from '../components/fields/EntityNamePicker/validation'; -import { EntityTagsPicker } from '../components/fields/EntityTagsPicker/EntityTagsPicker'; -import { OwnerPicker } from '../components/fields/OwnerPicker/OwnerPicker'; -import { RepoUrlPicker } from '../components/fields/RepoUrlPicker/RepoUrlPicker'; +import { + EntityTagsPicker, + EntityTagsPickerSchema, +} from '../components/fields/EntityTagsPicker/EntityTagsPicker'; +import { + OwnerPicker, + OwnerPickerSchema, +} from '../components/fields/OwnerPicker/OwnerPicker'; +import { + RepoUrlPicker, + RepoUrlPickerSchema, +} from '../components/fields/RepoUrlPicker/RepoUrlPicker'; import { repoPickerValidation } from '../components/fields/RepoUrlPicker/validation'; -import { OwnedEntityPicker } from '../components/fields/OwnedEntityPicker/OwnedEntityPicker'; +import { + OwnedEntityPicker, + OwnedEntityPickerSchema, +} from '../components/fields/OwnedEntityPicker/OwnedEntityPicker'; export const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS = [ { component: EntityPicker, name: 'EntityPicker', + schema: EntityPickerSchema, }, { component: EntityNamePicker, name: 'EntityNamePicker', validation: entityNamePickerValidation, + schema: EntityNamePickerSchema, }, { component: EntityTagsPicker, name: 'EntityTagsPicker', + schema: EntityTagsPickerSchema, }, { component: RepoUrlPicker, name: 'RepoUrlPicker', validation: repoPickerValidation, + schema: RepoUrlPickerSchema, }, { component: OwnerPicker, name: 'OwnerPicker', + schema: OwnerPickerSchema, }, { component: OwnedEntityPicker, name: 'OwnedEntityPicker', + schema: OwnedEntityPickerSchema, }, ]; diff --git a/plugins/scaffolder/src/extensions/index.tsx b/plugins/scaffolder/src/extensions/index.tsx index 08075b5b9d..72f17edc20 100644 --- a/plugins/scaffolder/src/extensions/index.tsx +++ b/plugins/scaffolder/src/extensions/index.tsx @@ -16,6 +16,7 @@ import React from 'react'; import { + CustomFieldExtensionSchema, CustomFieldValidator, FieldExtensionOptions, FieldExtensionComponentProps, @@ -103,6 +104,7 @@ attachComponentData( ); export type { + CustomFieldExtensionSchema, CustomFieldValidator, FieldExtensionOptions, FieldExtensionComponentProps, diff --git a/plugins/scaffolder/src/extensions/types.ts b/plugins/scaffolder/src/extensions/types.ts index 62f17dff15..b15de56fc1 100644 --- a/plugins/scaffolder/src/extensions/types.ts +++ b/plugins/scaffolder/src/extensions/types.ts @@ -15,14 +15,14 @@ */ import { ApiHolder } from '@backstage/core-plugin-api'; import { FieldValidation, FieldProps } from '@rjsf/core'; -import { PropsWithChildren } from 'react'; - import { UIOptionsType, FieldProps as FieldPropsV5, UiSchema as UiSchemaV5, FieldValidation as FieldValidationV5, } from '@rjsf/utils'; +import { PropsWithChildren } from 'react'; +import { JSONSchema7 } from 'json-schema'; /** * Field validation type for Custom Field Extensions. @@ -35,6 +35,16 @@ export type CustomFieldValidator = ( context: { apiHolder: ApiHolder }, ) => void | Promise; +/** + * Type for the Custom Field Extension schema. + * + * @public + */ +export type CustomFieldExtensionSchema = { + uiOptions?: JSONSchema7; + returnValue?: JSONSchema7; +}; + /** * Type for the Custom Field Extension with the * name and components and validation function. @@ -50,6 +60,7 @@ export type FieldExtensionOptions< props: FieldExtensionComponentProps, ) => JSX.Element | null; validation?: CustomFieldValidator; + schema?: CustomFieldExtensionSchema; }; /** @@ -107,4 +118,5 @@ export type NextFieldExtensionOptions< props: NextFieldExtensionComponentProps, ) => JSX.Element | null; validation?: NextCustomFieldValidator; + schema?: CustomFieldExtensionSchema; }; diff --git a/plugins/scaffolder/src/index.ts b/plugins/scaffolder/src/index.ts index 7853667101..0e5e2630ac 100644 --- a/plugins/scaffolder/src/index.ts +++ b/plugins/scaffolder/src/index.ts @@ -43,6 +43,7 @@ export { ScaffolderFieldExtensions, } from './extensions'; export type { + CustomFieldExtensionSchema, CustomFieldValidator, FieldExtensionOptions, FieldExtensionComponentProps, diff --git a/plugins/scaffolder/src/plugin.ts b/plugins/scaffolder/src/plugin.ts index f9b359d93a..a34105745f 100644 --- a/plugins/scaffolder/src/plugin.ts +++ b/plugins/scaffolder/src/plugin.ts @@ -16,12 +16,24 @@ import { scmIntegrationsApiRef } from '@backstage/integration-react'; import { scaffolderApiRef, ScaffolderClient } from './api'; -import { EntityPicker } from './components/fields/EntityPicker/EntityPicker'; +import { + EntityPicker, + EntityPickerSchema, +} from './components/fields/EntityPicker/EntityPicker'; import { entityNamePickerValidation } from './components/fields/EntityNamePicker'; -import { EntityNamePicker } from './components/fields/EntityNamePicker/EntityNamePicker'; -import { OwnerPicker } from './components/fields/OwnerPicker/OwnerPicker'; +import { + EntityNamePicker, + EntityNamePickerSchema, +} from './components/fields/EntityNamePicker/EntityNamePicker'; +import { + OwnerPicker, + OwnerPickerSchema, +} from './components/fields/OwnerPicker/OwnerPicker'; import { repoPickerValidation } from './components/fields/RepoUrlPicker'; -import { RepoUrlPicker } from './components/fields/RepoUrlPicker/RepoUrlPicker'; +import { + RepoUrlPicker, + RepoUrlPickerSchema, +} from './components/fields/RepoUrlPicker/RepoUrlPicker'; import { createScaffolderFieldExtension } from './extensions'; import { nextRouteRef, @@ -37,8 +49,14 @@ import { fetchApiRef, identityApiRef, } from '@backstage/core-plugin-api'; -import { OwnedEntityPicker } from './components/fields/OwnedEntityPicker/OwnedEntityPicker'; -import { EntityTagsPicker } from './components/fields/EntityTagsPicker/EntityTagsPicker'; +import { + OwnedEntityPicker, + OwnedEntityPickerSchema, +} from './components/fields/OwnedEntityPicker/OwnedEntityPicker'; +import { + EntityTagsPicker, + EntityTagsPickerSchema, +} from './components/fields/EntityTagsPicker/EntityTagsPicker'; /** * The main plugin export for the scaffolder. @@ -82,6 +100,7 @@ export const EntityPickerFieldExtension = scaffolderPlugin.provide( createScaffolderFieldExtension({ component: EntityPicker, name: 'EntityPicker', + schema: EntityPickerSchema, }), ); @@ -95,6 +114,7 @@ export const EntityNamePickerFieldExtension = scaffolderPlugin.provide( component: EntityNamePicker, name: 'EntityNamePicker', validation: entityNamePickerValidation, + schema: EntityNamePickerSchema, }), ); @@ -109,6 +129,7 @@ export const RepoUrlPickerFieldExtension = scaffolderPlugin.provide( component: RepoUrlPicker, name: 'RepoUrlPicker', validation: repoPickerValidation, + schema: RepoUrlPickerSchema, }), ); @@ -121,6 +142,7 @@ export const OwnerPickerFieldExtension = scaffolderPlugin.provide( createScaffolderFieldExtension({ component: OwnerPicker, name: 'OwnerPicker', + schema: OwnerPickerSchema, }), ); @@ -146,6 +168,7 @@ export const OwnedEntityPickerFieldExtension = scaffolderPlugin.provide( createScaffolderFieldExtension({ component: OwnedEntityPicker, name: 'OwnedEntityPicker', + schema: OwnedEntityPickerSchema, }), ); @@ -157,6 +180,7 @@ export const EntityTagsPickerFieldExtension = scaffolderPlugin.provide( createScaffolderFieldExtension({ component: EntityTagsPicker, name: 'EntityTagsPicker', + schema: EntityTagsPickerSchema, }), ); diff --git a/yarn.lock b/yarn.lock index acc503697d..eb5d0ffe16 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6998,6 +6998,8 @@ __metadata: use-immer: ^0.7.0 yaml: ^2.0.0 zen-observable: ^0.8.15 + zod: ^3.11.6 + zod-to-json-schema: ^3.18.1 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 react: ^16.13.1 || ^17.0.0 From aa4438e3415b16c595b2c4ab032956dd1b032284 Mon Sep 17 00:00:00 2001 From: Phil Kuang Date: Wed, 9 Nov 2022 14:43:13 -0500 Subject: [PATCH 298/434] refactor(scaffolder): abstract away zod schema types Signed-off-by: Phil Kuang --- plugins/scaffolder/api-report.md | 212 +++--------------- .../fields/EntityNamePicker/schema.ts | 14 +- .../components/fields/EntityPicker/schema.ts | 63 +++--- .../fields/EntityTagsPicker/schema.ts | 47 ++-- .../fields/OwnedEntityPicker/schema.ts | 67 +++--- .../components/fields/OwnerPicker/schema.ts | 56 ++--- .../components/fields/RepoUrlPicker/schema.ts | 131 ++++++----- .../scaffolder/src/components/fields/utils.ts | 34 +++ 8 files changed, 253 insertions(+), 371 deletions(-) create mode 100644 plugins/scaffolder/src/components/fields/utils.ts diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index 69512e7af0..e56b280c05 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -35,7 +35,6 @@ import { TaskStep } from '@backstage/plugin-scaffolder-common'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { UIOptionsType } from '@rjsf/utils'; import { UiSchema } from '@rjsf/utils'; -import { z } from 'zod'; // @alpha export function createNextScaffolderFieldExtension< @@ -91,33 +90,19 @@ export const EntityPickerFieldExtension: FieldExtensionComponent< >; // @public -export type EntityPickerUiOptions = z.infer; +export type EntityPickerUiOptions = + typeof EntityPickerUiOptionsSchema.schemaType; // @public (undocumented) -export const EntityPickerUiOptionsSchema: z.ZodObject< - { - allowedKinds: z.ZodOptional>; - defaultKind: z.ZodOptional; - allowArbitraryValues: z.ZodOptional; - defaultNamespace: z.ZodOptional< - z.ZodUnion<[z.ZodString, z.ZodLiteral]> - >; - }, - 'strip', - z.ZodTypeAny, - { +export const EntityPickerUiOptionsSchema: { + jsonSchema: JSONSchema7; + schemaType: { defaultKind?: string | undefined; defaultNamespace?: string | false | undefined; allowedKinds?: string[] | undefined; allowArbitraryValues?: boolean | undefined; - }, - { - defaultKind?: string | undefined; - defaultNamespace?: string | false | undefined; - allowedKinds?: string[] | undefined; - allowArbitraryValues?: boolean | undefined; - } ->; + }; +}; // @public export const EntityTagsPickerFieldExtension: FieldExtensionComponent< @@ -130,30 +115,18 @@ export const EntityTagsPickerFieldExtension: FieldExtensionComponent< >; // @public -export type EntityTagsPickerUiOptions = z.infer< - typeof EntityTagsPickerUiOptionsSchema ->; +export type EntityTagsPickerUiOptions = + typeof EntityTagsPickerUiOptionsSchema.schemaType; // @public (undocumented) -export const EntityTagsPickerUiOptionsSchema: z.ZodObject< - { - kinds: z.ZodOptional>; - showCounts: z.ZodOptional; - helperText: z.ZodOptional; - }, - 'strip', - z.ZodTypeAny, - { +export const EntityTagsPickerUiOptionsSchema: { + jsonSchema: JSONSchema7; + schemaType: { showCounts?: boolean | undefined; kinds?: string[] | undefined; helperText?: string | undefined; - }, - { - showCounts?: boolean | undefined; - kinds?: string[] | undefined; - helperText?: string | undefined; - } ->; + }; +}; // @public export type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null; @@ -288,35 +261,19 @@ export const OwnedEntityPickerFieldExtension: FieldExtensionComponent< >; // @public -export type OwnedEntityPickerUiOptions = z.infer< - typeof OwnedEntityPickerUiOptionsSchema ->; +export type OwnedEntityPickerUiOptions = + typeof OwnedEntityPickerUiOptionsSchema.schemaType; // @public (undocumented) -export const OwnedEntityPickerUiOptionsSchema: z.ZodObject< - { - allowedKinds: z.ZodOptional>; - defaultKind: z.ZodOptional; - allowArbitraryValues: z.ZodOptional; - defaultNamespace: z.ZodOptional< - z.ZodUnion<[z.ZodString, z.ZodLiteral]> - >; - }, - 'strip', - z.ZodTypeAny, - { +export const OwnedEntityPickerUiOptionsSchema: { + jsonSchema: JSONSchema7; + schemaType: { defaultKind?: string | undefined; defaultNamespace?: string | false | undefined; allowedKinds?: string[] | undefined; allowArbitraryValues?: boolean | undefined; - }, - { - defaultKind?: string | undefined; - defaultNamespace?: string | false | undefined; - allowedKinds?: string[] | undefined; - allowArbitraryValues?: boolean | undefined; - } ->; + }; +}; // @public export const OwnerPickerFieldExtension: FieldExtensionComponent< @@ -329,30 +286,17 @@ export const OwnerPickerFieldExtension: FieldExtensionComponent< >; // @public -export type OwnerPickerUiOptions = z.infer; +export type OwnerPickerUiOptions = typeof OwnerPickerUiOptionsSchema.schemaType; // @public (undocumented) -export const OwnerPickerUiOptionsSchema: z.ZodObject< - { - allowedKinds: z.ZodOptional>>; - allowArbitraryValues: z.ZodOptional; - defaultNamespace: z.ZodOptional< - z.ZodUnion<[z.ZodString, z.ZodLiteral]> - >; - }, - 'strip', - z.ZodTypeAny, - { +export const OwnerPickerUiOptionsSchema: { + jsonSchema: JSONSchema7; + schemaType: { defaultNamespace?: string | false | undefined; allowedKinds?: string[] | undefined; allowArbitraryValues?: boolean | undefined; - }, - { - defaultNamespace?: string | false | undefined; - allowedKinds?: string[] | undefined; - allowArbitraryValues?: boolean | undefined; - } ->; + }; +}; // @public export const repoPickerValidation: ( @@ -389,81 +333,13 @@ export const RepoUrlPickerFieldExtension: FieldExtensionComponent< >; // @public -export type RepoUrlPickerUiOptions = z.infer< - typeof RepoUrlPickerUiOptionsSchema ->; +export type RepoUrlPickerUiOptions = + typeof RepoUrlPickerUiOptionsSchema.schemaType; // @public (undocumented) -export const RepoUrlPickerUiOptionsSchema: z.ZodObject< - { - allowedHosts: z.ZodOptional>; - allowedOrganizations: z.ZodOptional>; - allowedOwners: z.ZodOptional>; - allowedRepos: z.ZodOptional>; - requestUserCredentials: z.ZodOptional< - z.ZodObject< - { - secretsKey: z.ZodString; - additionalScopes: z.ZodOptional< - z.ZodObject< - { - gerrit: z.ZodOptional>; - github: z.ZodOptional>; - gitlab: z.ZodOptional>; - bitbucket: z.ZodOptional>; - azure: z.ZodOptional>; - }, - 'strip', - z.ZodTypeAny, - { - azure?: string[] | undefined; - github?: string[] | undefined; - gitlab?: string[] | undefined; - bitbucket?: string[] | undefined; - gerrit?: string[] | undefined; - }, - { - azure?: string[] | undefined; - github?: string[] | undefined; - gitlab?: string[] | undefined; - bitbucket?: string[] | undefined; - gerrit?: string[] | undefined; - } - > - >; - }, - 'strip', - z.ZodTypeAny, - { - additionalScopes?: - | { - azure?: string[] | undefined; - github?: string[] | undefined; - gitlab?: string[] | undefined; - bitbucket?: string[] | undefined; - gerrit?: string[] | undefined; - } - | undefined; - secretsKey: string; - }, - { - additionalScopes?: - | { - azure?: string[] | undefined; - github?: string[] | undefined; - gitlab?: string[] | undefined; - bitbucket?: string[] | undefined; - gerrit?: string[] | undefined; - } - | undefined; - secretsKey: string; - } - > - >; - }, - 'strip', - z.ZodTypeAny, - { +export const RepoUrlPickerUiOptionsSchema: { + jsonSchema: JSONSchema7; + schemaType: { allowedOwners?: string[] | undefined; allowedOrganizations?: string[] | undefined; allowedRepos?: string[] | undefined; @@ -482,28 +358,8 @@ export const RepoUrlPickerUiOptionsSchema: z.ZodObject< secretsKey: string; } | undefined; - }, - { - allowedOwners?: string[] | undefined; - allowedOrganizations?: string[] | undefined; - allowedRepos?: string[] | undefined; - allowedHosts?: string[] | undefined; - requestUserCredentials?: - | { - additionalScopes?: - | { - azure?: string[] | undefined; - github?: string[] | undefined; - gitlab?: string[] | undefined; - bitbucket?: string[] | undefined; - gerrit?: string[] | undefined; - } - | undefined; - secretsKey: string; - } - | undefined; - } ->; + }; +}; // @public (undocumented) export const rootRouteRef: RouteRef; diff --git a/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts b/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts index 45aa4502ce..83e477b6aa 100644 --- a/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts @@ -13,18 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { JSONSchema7 } from 'json-schema'; import { z } from 'zod'; -import zodToJsonSchema from 'zod-to-json-schema'; +import { makeJsonSchemaFromZod } from '../utils'; -const EntityNamePickerReturnValueSchema = z.string(); +const EntityNamePickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); -export type EntityNamePickerReturnValue = z.infer< - typeof EntityNamePickerReturnValueSchema ->; +export type EntityNamePickerReturnValue = + typeof EntityNamePickerReturnValueSchema.schemaType; export const EntityNamePickerSchema = { - returnValue: zodToJsonSchema( - EntityNamePickerReturnValueSchema, - ) as JSONSchema7, + returnValue: EntityNamePickerReturnValueSchema.jsonSchema, }; diff --git a/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts b/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts index 5f7d66fc4f..3e05264a14 100644 --- a/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts @@ -13,37 +13,38 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { JSONSchema7 } from 'json-schema'; import { z } from 'zod'; -import zodToJsonSchema from 'zod-to-json-schema'; +import { makeJsonSchemaFromZod } from '../utils'; /** * @public */ -export const EntityPickerUiOptionsSchema = z.object({ - allowedKinds: z - .array(z.string()) - .optional() - .describe('List of kinds of entities to derive options from'), - defaultKind: z - .string() - .optional() - .describe( - 'The default entity kind. Options of this kind will not be prefixed.', - ), - allowArbitraryValues: z - .boolean() - .optional() - .describe('Whether to allow arbitrary user input. Defaults to true'), - defaultNamespace: z - .union([z.string(), z.literal(false)]) - .optional() - .describe( - 'The default namespace. Options with this namespace will not be prefixed.', - ), -}); +export const EntityPickerUiOptionsSchema = makeJsonSchemaFromZod( + z.object({ + allowedKinds: z + .array(z.string()) + .optional() + .describe('List of kinds of entities to derive options from'), + defaultKind: z + .string() + .optional() + .describe( + 'The default entity kind. Options of this kind will not be prefixed.', + ), + allowArbitraryValues: z + .boolean() + .optional() + .describe('Whether to allow arbitrary user input. Defaults to true'), + defaultNamespace: z + .union([z.string(), z.literal(false)]) + .optional() + .describe( + 'The default namespace. Options with this namespace will not be prefixed.', + ), + }), +); -const EntityPickerReturnValueSchema = z.string(); +const EntityPickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); /** * The input props that can be specified under `ui:options` for the @@ -51,13 +52,13 @@ const EntityPickerReturnValueSchema = z.string(); * * @public */ -export type EntityPickerUiOptions = z.infer; +export type EntityPickerUiOptions = + typeof EntityPickerUiOptionsSchema.schemaType; -export type EntityPickerReturnValue = z.infer< - typeof EntityPickerReturnValueSchema ->; +export type EntityPickerReturnValue = + typeof EntityPickerReturnValueSchema.schemaType; export const EntityPickerSchema = { - uiOptions: zodToJsonSchema(EntityPickerUiOptionsSchema) as JSONSchema7, - returnValue: zodToJsonSchema(EntityPickerReturnValueSchema) as JSONSchema7, + uiOptions: EntityPickerUiOptionsSchema.jsonSchema, + returnValue: EntityPickerReturnValueSchema.jsonSchema, }; diff --git a/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts b/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts index ff477903d7..e08918f838 100644 --- a/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts @@ -13,26 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { JSONSchema7 } from 'json-schema'; import { z } from 'zod'; -import zodToJsonSchema from 'zod-to-json-schema'; +import { makeJsonSchemaFromZod } from '../utils'; /** * @public */ -export const EntityTagsPickerUiOptionsSchema = z.object({ - kinds: z - .array(z.string()) - .optional() - .describe('List of kinds of entities to derive tags from'), - showCounts: z - .boolean() - .optional() - .describe('Whether to show usage counts per tag'), - helperText: z.string().optional().describe('Helper text to display'), -}); +export const EntityTagsPickerUiOptionsSchema = makeJsonSchemaFromZod( + z.object({ + kinds: z + .array(z.string()) + .optional() + .describe('List of kinds of entities to derive tags from'), + showCounts: z + .boolean() + .optional() + .describe('Whether to show usage counts per tag'), + helperText: z.string().optional().describe('Helper text to display'), + }), +); -const EntityTagsPickerReturnValueSchema = z.array(z.string()); +const EntityTagsPickerReturnValueSchema = makeJsonSchemaFromZod( + z.array(z.string()), +); /** * The input props that can be specified under `ui:options` for the @@ -40,17 +43,13 @@ const EntityTagsPickerReturnValueSchema = z.array(z.string()); * * @public */ -export type EntityTagsPickerUiOptions = z.infer< - typeof EntityTagsPickerUiOptionsSchema ->; +export type EntityTagsPickerUiOptions = + typeof EntityTagsPickerUiOptionsSchema.schemaType; -export type EntityTagsPickerReturnValue = z.infer< - typeof EntityTagsPickerReturnValueSchema ->; +export type EntityTagsPickerReturnValue = + typeof EntityTagsPickerReturnValueSchema.schemaType; export const EntityTagsPickerSchema = { - uiOptions: zodToJsonSchema(EntityTagsPickerUiOptionsSchema) as JSONSchema7, - returnValue: zodToJsonSchema( - EntityTagsPickerReturnValueSchema, - ) as JSONSchema7, + uiOptions: EntityTagsPickerUiOptionsSchema.jsonSchema, + returnValue: EntityTagsPickerReturnValueSchema.jsonSchema, }; diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts index c260fae3cd..e5bfcd9709 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts @@ -13,37 +13,38 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { JSONSchema7 } from 'json-schema'; import { z } from 'zod'; -import zodToJsonSchema from 'zod-to-json-schema'; +import { makeJsonSchemaFromZod } from '../utils'; /** * @public */ -export const OwnedEntityPickerUiOptionsSchema = z.object({ - allowedKinds: z - .array(z.string()) - .optional() - .describe('List of kinds of entities to derive options from'), - defaultKind: z - .string() - .optional() - .describe( - 'The default entity kind. Options of this kind will not be prefixed.', - ), - allowArbitraryValues: z - .boolean() - .optional() - .describe('Whether to allow arbitrary user input. Defaults to true'), - defaultNamespace: z - .union([z.string(), z.literal(false)]) - .optional() - .describe( - 'The default namespace. Options with this namespace will not be prefixed.', - ), -}); +export const OwnedEntityPickerUiOptionsSchema = makeJsonSchemaFromZod( + z.object({ + allowedKinds: z + .array(z.string()) + .optional() + .describe('List of kinds of entities to derive options from'), + defaultKind: z + .string() + .optional() + .describe( + 'The default entity kind. Options of this kind will not be prefixed.', + ), + allowArbitraryValues: z + .boolean() + .optional() + .describe('Whether to allow arbitrary user input. Defaults to true'), + defaultNamespace: z + .union([z.string(), z.literal(false)]) + .optional() + .describe( + 'The default namespace. Options with this namespace will not be prefixed.', + ), + }), +); -const OwnedEntityPickerReturnValueSchema = z.string(); +const OwnedEntityPickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); /** * The input props that can be specified under `ui:options` for the @@ -51,17 +52,13 @@ const OwnedEntityPickerReturnValueSchema = z.string(); * * @public */ -export type OwnedEntityPickerUiOptions = z.infer< - typeof OwnedEntityPickerUiOptionsSchema ->; +export type OwnedEntityPickerUiOptions = + typeof OwnedEntityPickerUiOptionsSchema.schemaType; -export type OwnedEntityPickerReturnValue = z.infer< - typeof OwnedEntityPickerReturnValueSchema ->; +export type OwnedEntityPickerReturnValue = + typeof OwnedEntityPickerReturnValueSchema.schemaType; export const OwnedEntityPickerSchema = { - uiOptions: zodToJsonSchema(OwnedEntityPickerUiOptionsSchema) as JSONSchema7, - returnValue: zodToJsonSchema( - OwnedEntityPickerReturnValueSchema, - ) as JSONSchema7, + uiOptions: OwnedEntityPickerUiOptionsSchema.jsonSchema, + returnValue: OwnedEntityPickerReturnValueSchema.jsonSchema, }; diff --git a/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts b/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts index 634a39ddee..ccfe453651 100644 --- a/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts @@ -13,34 +13,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { JSONSchema7 } from 'json-schema'; import { z } from 'zod'; -import zodToJsonSchema from 'zod-to-json-schema'; +import { makeJsonSchemaFromZod } from '../utils'; /** * @public */ -export const OwnerPickerUiOptionsSchema = z.object({ - allowedKinds: z - .array(z.string()) - .default(['Group', 'User']) - .optional() - .describe( - 'List of kinds of entities to derive options from. Defaults to Group and User', - ), - allowArbitraryValues: z - .boolean() - .optional() - .describe('Whether to allow arbitrary user input. Defaults to true'), - defaultNamespace: z - .union([z.string(), z.literal(false)]) - .optional() - .describe( - 'The default namespace. Options with this namespace will not be prefixed.', - ), -}); +export const OwnerPickerUiOptionsSchema = makeJsonSchemaFromZod( + z.object({ + allowedKinds: z + .array(z.string()) + .default(['Group', 'User']) + .optional() + .describe( + 'List of kinds of entities to derive options from. Defaults to Group and User', + ), + allowArbitraryValues: z + .boolean() + .optional() + .describe('Whether to allow arbitrary user input. Defaults to true'), + defaultNamespace: z + .union([z.string(), z.literal(false)]) + .optional() + .describe( + 'The default namespace. Options with this namespace will not be prefixed.', + ), + }), +); -const OwnerPickerReturnValueSchema = z.string(); +const OwnerPickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); /** * The input props that can be specified under `ui:options` for the @@ -48,13 +49,12 @@ const OwnerPickerReturnValueSchema = z.string(); * * @public */ -export type OwnerPickerUiOptions = z.infer; +export type OwnerPickerUiOptions = typeof OwnerPickerUiOptionsSchema.schemaType; -export type OwnerPickerReturnValue = z.infer< - typeof OwnerPickerReturnValueSchema ->; +export type OwnerPickerReturnValue = + typeof OwnerPickerReturnValueSchema.schemaType; export const OwnerPickerSchema = { - uiOptions: zodToJsonSchema(OwnerPickerUiOptionsSchema) as JSONSchema7, - returnValue: zodToJsonSchema(OwnerPickerReturnValueSchema) as JSONSchema7, + uiOptions: OwnerPickerUiOptionsSchema.jsonSchema, + returnValue: OwnerPickerReturnValueSchema.jsonSchema, }; diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts b/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts index b870747fd4..98d9f76a9c 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts @@ -13,70 +13,71 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { JSONSchema7 } from 'json-schema'; import { z } from 'zod'; -import zodToJsonSchema from 'zod-to-json-schema'; +import { makeJsonSchemaFromZod } from '../utils'; /** * @public */ -export const RepoUrlPickerUiOptionsSchema = z.object({ - allowedHosts: z - .array(z.string()) - .optional() - .describe('List of allowed SCM platform hosts'), - allowedOrganizations: z - .array(z.string()) - .optional() - .describe('List of allowed organizations in the given SCM platform'), - allowedOwners: z - .array(z.string()) - .optional() - .describe('List of allowed owners in the given SCM platform'), - allowedRepos: z - .array(z.string()) - .optional() - .describe('List of allowed repos in the given SCM platform'), - requestUserCredentials: z - .object({ - secretsKey: z - .string() - .describe( - 'Key used within the template secrets context to store the credential', - ), - additionalScopes: z - .object({ - gerrit: z - .array(z.string()) - .optional() - .describe('Additional Gerrit scopes to request'), - github: z - .array(z.string()) - .optional() - .describe('Additional GitHub scopes to request'), - gitlab: z - .array(z.string()) - .optional() - .describe('Additional GitLab scopes to request'), - bitbucket: z - .array(z.string()) - .optional() - .describe('Additional BitBucket scopes to request'), - azure: z - .array(z.string()) - .optional() - .describe('Additional Azure scopes to request'), - }) - .optional() - .describe('Additional permission scopes to request'), - }) - .optional() - .describe( - 'If defined will request user credentials to auth against the given SCM platform', - ), -}); +export const RepoUrlPickerUiOptionsSchema = makeJsonSchemaFromZod( + z.object({ + allowedHosts: z + .array(z.string()) + .optional() + .describe('List of allowed SCM platform hosts'), + allowedOrganizations: z + .array(z.string()) + .optional() + .describe('List of allowed organizations in the given SCM platform'), + allowedOwners: z + .array(z.string()) + .optional() + .describe('List of allowed owners in the given SCM platform'), + allowedRepos: z + .array(z.string()) + .optional() + .describe('List of allowed repos in the given SCM platform'), + requestUserCredentials: z + .object({ + secretsKey: z + .string() + .describe( + 'Key used within the template secrets context to store the credential', + ), + additionalScopes: z + .object({ + gerrit: z + .array(z.string()) + .optional() + .describe('Additional Gerrit scopes to request'), + github: z + .array(z.string()) + .optional() + .describe('Additional GitHub scopes to request'), + gitlab: z + .array(z.string()) + .optional() + .describe('Additional GitLab scopes to request'), + bitbucket: z + .array(z.string()) + .optional() + .describe('Additional BitBucket scopes to request'), + azure: z + .array(z.string()) + .optional() + .describe('Additional Azure scopes to request'), + }) + .optional() + .describe('Additional permission scopes to request'), + }) + .optional() + .describe( + 'If defined will request user credentials to auth against the given SCM platform', + ), + }), +); -const RepoUrlPickerReturnValueSchema = z.string(); +const RepoUrlPickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); /** * The input props that can be specified under `ui:options` for the @@ -84,18 +85,16 @@ const RepoUrlPickerReturnValueSchema = z.string(); * * @public */ -export type RepoUrlPickerUiOptions = z.infer< - typeof RepoUrlPickerUiOptionsSchema ->; +export type RepoUrlPickerUiOptions = + typeof RepoUrlPickerUiOptionsSchema.schemaType; -export type RepoUrlPickerReturnValue = z.infer< - typeof RepoUrlPickerReturnValueSchema ->; +export type RepoUrlPickerReturnValue = + typeof RepoUrlPickerReturnValueSchema.schemaType; // NOTE: There is a bug with this failing validation in the custom field explorer due // to https://github.com/rjsf-team/react-jsonschema-form/issues/675 even if // requestUserCredentials is not defined export const RepoUrlPickerSchema = { - uiOptions: zodToJsonSchema(RepoUrlPickerUiOptionsSchema) as JSONSchema7, - returnValue: zodToJsonSchema(RepoUrlPickerReturnValueSchema) as JSONSchema7, + uiOptions: RepoUrlPickerUiOptionsSchema.jsonSchema, + returnValue: RepoUrlPickerReturnValueSchema.jsonSchema, }; diff --git a/plugins/scaffolder/src/components/fields/utils.ts b/plugins/scaffolder/src/components/fields/utils.ts new file mode 100644 index 0000000000..b3ebf1e1b4 --- /dev/null +++ b/plugins/scaffolder/src/components/fields/utils.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { JSONSchema7 } from 'json-schema'; +import { z } from 'zod'; +import zodToJsonSchema from 'zod-to-json-schema'; + +/** + * Utility function to convert zod schemas to JSON schemas with + * type inference extraction that abstracts away zod typings + */ +export function makeJsonSchemaFromZod( + schema: T, +): { + jsonSchema: JSONSchema7; + schemaType: T extends z.ZodType ? I : never; +} { + return { + jsonSchema: zodToJsonSchema(schema) as JSONSchema7, + schemaType: null as any, + }; +} From 3e4a2ee77979919564e7f6bfd9a770966e995d5a Mon Sep 17 00:00:00 2001 From: Phil Kuang Date: Thu, 10 Nov 2022 13:11:03 -0500 Subject: [PATCH 299/434] docs(scaffolder): add info about custom field explorer Signed-off-by: Phil Kuang --- .../custom-field-explorer.png | Bin 0 -> 151063 bytes .../writing-custom-field-extensions.md | 106 ++++++++++++++++++ plugins/scaffolder/api-report.md | 41 ++++--- .../fields/EntityNamePicker/schema.ts | 4 +- .../components/fields/EntityPicker/schema.ts | 10 +- .../fields/EntityTagsPicker/schema.ts | 8 +- .../fields/OwnedEntityPicker/schema.ts | 8 +- .../components/fields/OwnerPicker/schema.ts | 9 +- .../components/fields/RepoUrlPicker/schema.ts | 9 +- .../scaffolder/src/components/fields/index.ts | 1 + .../scaffolder/src/components/fields/utils.ts | 9 +- 11 files changed, 158 insertions(+), 47 deletions(-) create mode 100644 docs/assets/software-templates/custom-field-explorer.png diff --git a/docs/assets/software-templates/custom-field-explorer.png b/docs/assets/software-templates/custom-field-explorer.png new file mode 100644 index 0000000000000000000000000000000000000000..1af897ac8c4c693f23a679527d41bf9917604bb8 GIT binary patch literal 151063 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 + + +
This is the content for step 2
+
+ + ); +}; + +ConditionalButtons.args = defaultArgs; diff --git a/packages/core-components/src/components/SimpleStepper/SimpleStepper.test.tsx b/packages/core-components/src/components/SimpleStepper/SimpleStepper.test.tsx index 5897054ed5..73baff8db2 100644 --- a/packages/core-components/src/components/SimpleStepper/SimpleStepper.test.tsx +++ b/packages/core-components/src/components/SimpleStepper/SimpleStepper.test.tsx @@ -145,4 +145,32 @@ describe('Stepper', () => { expect(rendered.getByText('FinalStepNext')).toBeInTheDocument(); }); + + it('Handles skipStep property', async () => { + const rendered = await renderInTestApp( + + +
step0
+
+ +
step1
+
+ +
step2
+
+ +
step3
+
+
, + ); + + fireEvent.click(getTextInSlide(rendered, 0)('Next') as Node); + expect(rendered.getByText('step1')).toBeInTheDocument(); + + fireEvent.click(getTextInSlide(rendered, 1)('Skip') as Node); + expect(rendered.getByText('step2')).toBeInTheDocument(); + + fireEvent.click(getTextInSlide(rendered, 2)('Back') as Node); + expect(rendered.getByText('step1')).toBeInTheDocument(); + }); }); diff --git a/packages/core-components/src/components/SimpleStepper/SimpleStepperFooter.tsx b/packages/core-components/src/components/SimpleStepper/SimpleStepperFooter.tsx index 5f4bdbf0c6..0f7d604eb0 100644 --- a/packages/core-components/src/components/SimpleStepper/SimpleStepperFooter.tsx +++ b/packages/core-components/src/components/SimpleStepper/SimpleStepperFooter.tsx @@ -45,6 +45,10 @@ interface NextBtnProps extends CommonBtnProps { last?: boolean; stepIndex: number; } +interface SkipBtnProps extends CommonBtnProps { + disabled?: boolean; + stepIndex: number; +} interface BackBtnProps extends CommonBtnProps { disabled?: boolean; stepIndex: number; @@ -71,6 +75,18 @@ const NextBtn = ({ ); +const SkipBtn = ({ text, handleClick, disabled, stepIndex }: SkipBtnProps) => ( + +); + const BackBtn = ({ text, handleClick, disabled, stepIndex }: BackBtnProps) => (

y)iSUXrP?ZG`Sk7BbS+)!D8YhJ>47T|85pz6i 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 z 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Νu$ULnuIF2KsUoE%*sM+(Q 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 => { + return ( + 0 && !formData} + onChange={onChange} + focused={focused} + /> + ); +}; +``` + +```tsx +// packages/app/src/scaffolder/MyCustomExtensionWithOptions/extensions.ts +... +import { MyCustomExtensionWithOptions, MyCustomExtensionWithOptionsSchema } from './MyCustomExtensionWithOptions'; + +export const MyCustomFieldWithOptionsExtension = scaffolderPlugin.provide( + createScaffolderFieldExtension({ + name: 'MyCustomExtensionWithOptions', + component: MyCustomExtensionWithOptions, + schema: MyCustomExtensionWithOptionsSchema, + }), +); +``` + +We recommend using a library like [zod](https://github.com/colinhacks/zod) to define your schema +and the provided `makeJsonSchemaFromZod` helper utility function to generate both the JSON schema +and types for your field input/output to preventing having to duplicate the definitions: + +```tsx +//packages/app/src/scaffolder/MyCustomExtensionWithOptions/MyCustomExtensionWithOptions.tsx +... +import { z } from 'zod'; +import { makeJsonSchemaFromZod } from '@backstage/plugin-scaffolder'; + +const MyCustomExtensionWithOptionsUiOptionsSchema = makeJsonSchemaFromZod( + z.object({ + focused: z + .boolean() + .optional() + .describe('Whether to focus this field'), + }), +); + +const MyCustomExtensionWithOptionsReturnValueSchema = makeJsonSchemaFromZod( + z.string(), +); + +export const MyCustomExtensionWithOptionsSchema = { + uiOptions: MyCustomExtensionWithOptionsUiOptionsSchema.schema, + returnValue: MyCustomExtensionWithOptionsReturnValueSchema.schema, +}; + +export const MyCustomExtensionWithOptions = ({ + onChange, + rawErrors, + required, + formData, +}: FieldProps< + typeof MyCustomExtensionWithOptionsReturnValueSchema.type, + typeof MyCustomExtensionWithOptionsUiOptionsSchema.type +>) => { + return ( + 0 && !formData} + onChange={onChange} + focused={focused} + /> + ); +}; +``` diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index e56b280c05..1ef699f462 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -35,6 +35,7 @@ import { TaskStep } from '@backstage/plugin-scaffolder-common'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { UIOptionsType } from '@rjsf/utils'; import { UiSchema } from '@rjsf/utils'; +import { z } from 'zod'; // @alpha export function createNextScaffolderFieldExtension< @@ -90,13 +91,12 @@ export const EntityPickerFieldExtension: FieldExtensionComponent< >; // @public -export type EntityPickerUiOptions = - typeof EntityPickerUiOptionsSchema.schemaType; +export type EntityPickerUiOptions = typeof EntityPickerUiOptionsSchema.type; // @public (undocumented) export const EntityPickerUiOptionsSchema: { - jsonSchema: JSONSchema7; - schemaType: { + schema: JSONSchema7; + type: { defaultKind?: string | undefined; defaultNamespace?: string | false | undefined; allowedKinds?: string[] | undefined; @@ -116,12 +116,12 @@ export const EntityTagsPickerFieldExtension: FieldExtensionComponent< // @public export type EntityTagsPickerUiOptions = - typeof EntityTagsPickerUiOptionsSchema.schemaType; + typeof EntityTagsPickerUiOptionsSchema.type; // @public (undocumented) export const EntityTagsPickerUiOptionsSchema: { - jsonSchema: JSONSchema7; - schemaType: { + schema: JSONSchema7; + type: { showCounts?: boolean | undefined; kinds?: string[] | undefined; helperText?: string | undefined; @@ -192,6 +192,14 @@ export type LogEvent = { taskId: string; }; +// @public +export function makeJsonSchemaFromZod( + schema: T, +): { + schema: JSONSchema7; + type: T extends z.ZodType ? I : never; +}; + // @alpha export type NextCustomFieldValidator = ( data: TFieldReturnValue, @@ -262,12 +270,12 @@ export const OwnedEntityPickerFieldExtension: FieldExtensionComponent< // @public export type OwnedEntityPickerUiOptions = - typeof OwnedEntityPickerUiOptionsSchema.schemaType; + typeof OwnedEntityPickerUiOptionsSchema.type; // @public (undocumented) export const OwnedEntityPickerUiOptionsSchema: { - jsonSchema: JSONSchema7; - schemaType: { + schema: JSONSchema7; + type: { defaultKind?: string | undefined; defaultNamespace?: string | false | undefined; allowedKinds?: string[] | undefined; @@ -286,12 +294,12 @@ export const OwnerPickerFieldExtension: FieldExtensionComponent< >; // @public -export type OwnerPickerUiOptions = typeof OwnerPickerUiOptionsSchema.schemaType; +export type OwnerPickerUiOptions = typeof OwnerPickerUiOptionsSchema.type; // @public (undocumented) export const OwnerPickerUiOptionsSchema: { - jsonSchema: JSONSchema7; - schemaType: { + schema: JSONSchema7; + type: { defaultNamespace?: string | false | undefined; allowedKinds?: string[] | undefined; allowArbitraryValues?: boolean | undefined; @@ -333,13 +341,12 @@ export const RepoUrlPickerFieldExtension: FieldExtensionComponent< >; // @public -export type RepoUrlPickerUiOptions = - typeof RepoUrlPickerUiOptionsSchema.schemaType; +export type RepoUrlPickerUiOptions = typeof RepoUrlPickerUiOptionsSchema.type; // @public (undocumented) export const RepoUrlPickerUiOptionsSchema: { - jsonSchema: JSONSchema7; - schemaType: { + schema: JSONSchema7; + type: { allowedOwners?: string[] | undefined; allowedOrganizations?: string[] | undefined; allowedRepos?: string[] | undefined; diff --git a/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts b/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts index 83e477b6aa..3139839bf4 100644 --- a/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts @@ -19,8 +19,8 @@ import { makeJsonSchemaFromZod } from '../utils'; const EntityNamePickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); export type EntityNamePickerReturnValue = - typeof EntityNamePickerReturnValueSchema.schemaType; + typeof EntityNamePickerReturnValueSchema.type; export const EntityNamePickerSchema = { - returnValue: EntityNamePickerReturnValueSchema.jsonSchema, + returnValue: EntityNamePickerReturnValueSchema.schema, }; diff --git a/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts b/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts index 3e05264a14..3d14a2bf3e 100644 --- a/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts @@ -52,13 +52,11 @@ const EntityPickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); * * @public */ -export type EntityPickerUiOptions = - typeof EntityPickerUiOptionsSchema.schemaType; +export type EntityPickerUiOptions = typeof EntityPickerUiOptionsSchema.type; -export type EntityPickerReturnValue = - typeof EntityPickerReturnValueSchema.schemaType; +export type EntityPickerReturnValue = typeof EntityPickerReturnValueSchema.type; export const EntityPickerSchema = { - uiOptions: EntityPickerUiOptionsSchema.jsonSchema, - returnValue: EntityPickerReturnValueSchema.jsonSchema, + uiOptions: EntityPickerUiOptionsSchema.schema, + returnValue: EntityPickerReturnValueSchema.schema, }; diff --git a/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts b/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts index e08918f838..d3a5391385 100644 --- a/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts @@ -44,12 +44,12 @@ const EntityTagsPickerReturnValueSchema = makeJsonSchemaFromZod( * @public */ export type EntityTagsPickerUiOptions = - typeof EntityTagsPickerUiOptionsSchema.schemaType; + typeof EntityTagsPickerUiOptionsSchema.type; export type EntityTagsPickerReturnValue = - typeof EntityTagsPickerReturnValueSchema.schemaType; + typeof EntityTagsPickerReturnValueSchema.type; export const EntityTagsPickerSchema = { - uiOptions: EntityTagsPickerUiOptionsSchema.jsonSchema, - returnValue: EntityTagsPickerReturnValueSchema.jsonSchema, + uiOptions: EntityTagsPickerUiOptionsSchema.schema, + returnValue: EntityTagsPickerReturnValueSchema.schema, }; diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts index e5bfcd9709..c967448729 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts @@ -53,12 +53,12 @@ const OwnedEntityPickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); * @public */ export type OwnedEntityPickerUiOptions = - typeof OwnedEntityPickerUiOptionsSchema.schemaType; + typeof OwnedEntityPickerUiOptionsSchema.type; export type OwnedEntityPickerReturnValue = - typeof OwnedEntityPickerReturnValueSchema.schemaType; + typeof OwnedEntityPickerReturnValueSchema.type; export const OwnedEntityPickerSchema = { - uiOptions: OwnedEntityPickerUiOptionsSchema.jsonSchema, - returnValue: OwnedEntityPickerReturnValueSchema.jsonSchema, + uiOptions: OwnedEntityPickerUiOptionsSchema.schema, + returnValue: OwnedEntityPickerReturnValueSchema.schema, }; diff --git a/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts b/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts index ccfe453651..accc8f80fc 100644 --- a/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts @@ -49,12 +49,11 @@ const OwnerPickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); * * @public */ -export type OwnerPickerUiOptions = typeof OwnerPickerUiOptionsSchema.schemaType; +export type OwnerPickerUiOptions = typeof OwnerPickerUiOptionsSchema.type; -export type OwnerPickerReturnValue = - typeof OwnerPickerReturnValueSchema.schemaType; +export type OwnerPickerReturnValue = typeof OwnerPickerReturnValueSchema.type; export const OwnerPickerSchema = { - uiOptions: OwnerPickerUiOptionsSchema.jsonSchema, - returnValue: OwnerPickerReturnValueSchema.jsonSchema, + uiOptions: OwnerPickerUiOptionsSchema.schema, + returnValue: OwnerPickerReturnValueSchema.schema, }; diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts b/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts index 98d9f76a9c..bf8fa3cf5c 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts @@ -85,16 +85,15 @@ const RepoUrlPickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); * * @public */ -export type RepoUrlPickerUiOptions = - typeof RepoUrlPickerUiOptionsSchema.schemaType; +export type RepoUrlPickerUiOptions = typeof RepoUrlPickerUiOptionsSchema.type; export type RepoUrlPickerReturnValue = - typeof RepoUrlPickerReturnValueSchema.schemaType; + typeof RepoUrlPickerReturnValueSchema.type; // NOTE: There is a bug with this failing validation in the custom field explorer due // to https://github.com/rjsf-team/react-jsonschema-form/issues/675 even if // requestUserCredentials is not defined export const RepoUrlPickerSchema = { - uiOptions: RepoUrlPickerUiOptionsSchema.jsonSchema, - returnValue: RepoUrlPickerReturnValueSchema.jsonSchema, + uiOptions: RepoUrlPickerUiOptionsSchema.schema, + returnValue: RepoUrlPickerReturnValueSchema.schema, }; diff --git a/plugins/scaffolder/src/components/fields/index.ts b/plugins/scaffolder/src/components/fields/index.ts index 6358934025..e78b92da00 100644 --- a/plugins/scaffolder/src/components/fields/index.ts +++ b/plugins/scaffolder/src/components/fields/index.ts @@ -18,3 +18,4 @@ export * from './OwnerPicker'; export * from './RepoUrlPicker'; export * from './OwnedEntityPicker'; export * from './EntityTagsPicker'; +export { makeJsonSchemaFromZod } from './utils'; diff --git a/plugins/scaffolder/src/components/fields/utils.ts b/plugins/scaffolder/src/components/fields/utils.ts index b3ebf1e1b4..2f56e31db5 100644 --- a/plugins/scaffolder/src/components/fields/utils.ts +++ b/plugins/scaffolder/src/components/fields/utils.ts @@ -18,17 +18,18 @@ import { z } from 'zod'; import zodToJsonSchema from 'zod-to-json-schema'; /** + * @public * Utility function to convert zod schemas to JSON schemas with * type inference extraction that abstracts away zod typings */ export function makeJsonSchemaFromZod( schema: T, ): { - jsonSchema: JSONSchema7; - schemaType: T extends z.ZodType ? I : never; + schema: JSONSchema7; + type: T extends z.ZodType ? I : never; } { return { - jsonSchema: zodToJsonSchema(schema) as JSONSchema7, - schemaType: null as any, + schema: zodToJsonSchema(schema) as JSONSchema7, + type: null as any, }; } From 4d23a5c7b240c474e02ea6e60d74941439589815 Mon Sep 17 00:00:00 2001 From: Alex Crome Date: Fri, 28 Oct 2022 08:51:52 +0100 Subject: [PATCH 300/434] Fix casing of EntityNamePicker validation error message The error message for `EntityNamePicker` has two sentences. The first word of the second sentence is capitalised, but the first sentence was not. This fixes the capitalisation of the first sentence. Signed-off-by: Alex Crome --- .../src/components/fields/EntityNamePicker/validation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder/src/components/fields/EntityNamePicker/validation.ts b/plugins/scaffolder/src/components/fields/EntityNamePicker/validation.ts index 7a40a460ba..d116bef228 100644 --- a/plugins/scaffolder/src/components/fields/EntityNamePicker/validation.ts +++ b/plugins/scaffolder/src/components/fields/EntityNamePicker/validation.ts @@ -23,7 +23,7 @@ export const entityNamePickerValidation = ( ) => { if (!KubernetesValidatorFunctions.isValidObjectName(value)) { validation.addError( - 'must start and end with an alphanumeric character, and contain only alphanumeric characters, hyphens, underscores, and periods. Maximum length is 63 characters.', + 'Must start and end with an alphanumeric character, and contain only alphanumeric characters, hyphens, underscores, and periods. Maximum length is 63 characters.', ); } }; From f93f263eff7b05547a357db03b9b422d5c586b79 Mon Sep 17 00:00:00 2001 From: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Date: Fri, 11 Nov 2022 14:51:37 -0600 Subject: [PATCH 301/434] Added custom provider annotation details Signed-off-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> --- docs/features/software-catalog/external-integrations.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index 65f97fb8da..f3387d31f0 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -159,7 +159,12 @@ Check out the numbered markings - let's go through them one by one. the outcome of that. This example issues a `fetch` to the right service and issues a full refresh of its entity bucket based on that. 5. The method translates the foreign data model to the native `Entity` form, as - expected by the catalog. + expected by the catalog. Make sure that in this method you include the + `backstage.io/managed-by-location` and `backstage.io/managed-by-origin-location` + annotations on your `Entity`. If these are not present they will not show up + in the Catalog and you will see warnings in your logs. The + [Well-known Annotations](./well-known-annotations.md#backstageiomanaged-by-location) + documentation has guidance on what values to use for these. 6. Finally, we issue a "mutation" to the catalog. This persists the entities in our own bucket, along with an optional `locationKey` that's used for conflict checks. But this is a bigger topic - mutations warrant their own explanatory From 7e4ba8de90adb0aed42fe3a17d0f144fee718c46 Mon Sep 17 00:00:00 2001 From: Alex Crome Date: Fri, 11 Nov 2022 21:10:48 +0000 Subject: [PATCH 302/434] Improve MS Graph docs Signed-off-by: Alex Crome --- docs/integrations/azure/org.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/integrations/azure/org.md b/docs/integrations/azure/org.md index 99c517b568..acb43db182 100644 --- a/docs/integrations/azure/org.md +++ b/docs/integrations/azure/org.md @@ -101,7 +101,7 @@ To grant the managed identity the same permissions as mentioned in _App Registra ## Filtering imported Users and Groups By default, the plugin will import all users and groups from your directory. -This can be customized through filters and search queries. +This can be customized through [filters](https://learn.microsoft.com/en-us/graph/filter-query-parameter) and [search](https://learn.microsoft.com/en-us/graph/search-query-parameter) queries. ### Groups @@ -228,6 +228,17 @@ export async function myOrganizationTransformer( ## Troubleshooting +### No data + +First check your logs for the message `Reading msgraph users and groups`. +If you don't see this, check you've registered the provider, and that the schedule is valid + +If you see a log entry `Read 0 msgraph users and 0 msgraph groups`, check your search and filter arguments. + +If you see the start message (`Reading msgraph users and groups`) but no end message (`Read X msgraph users and Y msgraph groups`), then it is likely the job is taking a long time due to a large volume of data. +The default behavior is to import all users and groups, which is often more data than needed. +Try importing a smaller set of data (e.g. `filter: displayName eq 'John Smith'`). + ### Authentication / Token Errors See [Troubleshooting Azure Identity Authentication Issues](https://aka.ms/azsdk/js/identity/troubleshoot) From 87840c8c6c019d79a96b4b8023c8a38f134d846c Mon Sep 17 00:00:00 2001 From: Alex Crome Date: Fri, 11 Nov 2022 21:14:21 +0000 Subject: [PATCH 303/434] Add missing changeset Signed-off-by: Alex Crome --- .changeset/good-doors-attend.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/good-doors-attend.md diff --git a/.changeset/good-doors-attend.md b/.changeset/good-doors-attend.md new file mode 100644 index 0000000000..43294b252a --- /dev/null +++ b/.changeset/good-doors-attend.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Fixed tiny grammar error in EntityNamePicker. The first letter of the description is now capatalised. From 7bbd2403a1fc2907938ba71f01ba75f6a7010fe5 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Tue, 4 Oct 2022 16:35:26 +0200 Subject: [PATCH 304/434] feat(events): add events management capabilities This change introduces some new plugins which provide the basics for managing events inside of backstage. Hereby, it offers extension points to add event publishers and subscribers as well as to exchange the event broker implementation. - `@backstage/plugin-events-backend`: backend for the events management which connects all parts and provides a simple in-memory event broker - `@backstage/plugin-events-node`: interfaces and API for `@backstage/plugin-events-backend` - `@backstage/plugin-events-test-utils`: test utilities like implementations useful for writing tests at modules All plugins support the new backend-plugin-api. Relates-to: #11082 Signed-off-by: Patrick Jungermann --- .changeset/rotten-readers-yell.md | 14 ++ .github/CODEOWNERS | 3 + .../events-backend-test-utils/.eslintrc.js | 1 + plugins/events-backend-test-utils/README.md | 4 + .../events-backend-test-utils/api-report.md | 47 +++++++ .../events-backend-test-utils/package.json | 34 +++++ .../events-backend-test-utils/src/index.ts | 23 ++++ .../src/testUtils/TestEventBroker.ts | 37 ++++++ .../src/testUtils/TestEventPublisher.ts | 30 +++++ .../src/testUtils/TestEventSubscriber.ts | 39 ++++++ .../src/testUtils/index.ts | 19 +++ plugins/events-backend/.eslintrc.js | 1 + plugins/events-backend/README.md | 124 ++++++++++++++++++ plugins/events-backend/api-report.md | 30 +++++ plugins/events-backend/package.json | 40 ++++++ plugins/events-backend/src/index.ts | 24 ++++ .../src/service/EventsBackend.test.ts | 60 +++++++++ .../src/service/EventsBackend.ts | 67 ++++++++++ .../src/service/EventsPlugin.test.ts | 64 +++++++++ .../src/service/EventsPlugin.ts | 93 +++++++++++++ .../src/service/InMemoryEventBroker.test.ts | 66 ++++++++++ .../src/service/InMemoryEventBroker.ts | 58 ++++++++ plugins/events-backend/src/setupTests.ts | 17 +++ plugins/events-node/.eslintrc.js | 1 + plugins/events-node/README.md | 3 + plugins/events-node/api-report.md | 76 +++++++++++ plugins/events-node/package.json | 38 ++++++ plugins/events-node/src/api/EventBroker.ts | 43 ++++++ plugins/events-node/src/api/EventParams.ts | 33 +++++ plugins/events-node/src/api/EventPublisher.ts | 29 ++++ .../events-node/src/api/EventRouter.test.ts | 81 ++++++++++++ plugins/events-node/src/api/EventRouter.ts | 55 ++++++++ .../events-node/src/api/EventSubscriber.ts | 38 ++++++ .../src/api/SubTopicEventRouter.test.ts | 67 ++++++++++ .../src/api/SubTopicEventRouter.ts | 44 +++++++ plugins/events-node/src/api/index.ts | 22 ++++ plugins/events-node/src/extensions.ts | 40 ++++++ plugins/events-node/src/index.ts | 25 ++++ plugins/events-node/src/setupTests.ts | 17 +++ yarn.lock | 34 +++++ 40 files changed, 1541 insertions(+) create mode 100644 .changeset/rotten-readers-yell.md create mode 100644 plugins/events-backend-test-utils/.eslintrc.js create mode 100644 plugins/events-backend-test-utils/README.md create mode 100644 plugins/events-backend-test-utils/api-report.md create mode 100644 plugins/events-backend-test-utils/package.json create mode 100644 plugins/events-backend-test-utils/src/index.ts create mode 100644 plugins/events-backend-test-utils/src/testUtils/TestEventBroker.ts create mode 100644 plugins/events-backend-test-utils/src/testUtils/TestEventPublisher.ts create mode 100644 plugins/events-backend-test-utils/src/testUtils/TestEventSubscriber.ts create mode 100644 plugins/events-backend-test-utils/src/testUtils/index.ts create mode 100644 plugins/events-backend/.eslintrc.js create mode 100644 plugins/events-backend/README.md create mode 100644 plugins/events-backend/api-report.md create mode 100644 plugins/events-backend/package.json create mode 100644 plugins/events-backend/src/index.ts create mode 100644 plugins/events-backend/src/service/EventsBackend.test.ts create mode 100644 plugins/events-backend/src/service/EventsBackend.ts create mode 100644 plugins/events-backend/src/service/EventsPlugin.test.ts create mode 100644 plugins/events-backend/src/service/EventsPlugin.ts create mode 100644 plugins/events-backend/src/service/InMemoryEventBroker.test.ts create mode 100644 plugins/events-backend/src/service/InMemoryEventBroker.ts create mode 100644 plugins/events-backend/src/setupTests.ts create mode 100644 plugins/events-node/.eslintrc.js create mode 100644 plugins/events-node/README.md create mode 100644 plugins/events-node/api-report.md create mode 100644 plugins/events-node/package.json create mode 100644 plugins/events-node/src/api/EventBroker.ts create mode 100644 plugins/events-node/src/api/EventParams.ts create mode 100644 plugins/events-node/src/api/EventPublisher.ts create mode 100644 plugins/events-node/src/api/EventRouter.test.ts create mode 100644 plugins/events-node/src/api/EventRouter.ts create mode 100644 plugins/events-node/src/api/EventSubscriber.ts create mode 100644 plugins/events-node/src/api/SubTopicEventRouter.test.ts create mode 100644 plugins/events-node/src/api/SubTopicEventRouter.ts create mode 100644 plugins/events-node/src/api/index.ts create mode 100644 plugins/events-node/src/extensions.ts create mode 100644 plugins/events-node/src/index.ts create mode 100644 plugins/events-node/src/setupTests.ts diff --git a/.changeset/rotten-readers-yell.md b/.changeset/rotten-readers-yell.md new file mode 100644 index 0000000000..29be4102dc --- /dev/null +++ b/.changeset/rotten-readers-yell.md @@ -0,0 +1,14 @@ +--- +'@backstage/plugin-events-backend': minor +'@backstage/plugin-events-node': minor +'@backstage/plugin-events-backend-test-utils': minor +--- + +Adds a new backend plugin plugin-events-backend for managing events. + +plugin-events-node exposes interfaces which can be used by modules. + +plugin-events-backend-test-utils provides utilities which can be used while writing tests e.g. for modules. + +Please find more information at +https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2dd8f4b55b..dea361606a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -36,6 +36,9 @@ yarn.lock @backstage/reviewers @backst /plugins/code-coverage-backend @backstage/reviewers @alde @nissayeva /plugins/cost-insights @backstage/reviewers @backstage/silver-lining /plugins/cost-insights-* @backstage/reviewers @backstage/silver-lining +/plugins/events-backend @backstage/reviewers @pjungermann +/plugins/events-backend-test-utils @backstage/reviewers @pjungermann +/plugins/events-node @backstage/reviewers @pjungermann /plugins/explore @backstage/reviewers @backstage/sda-se-reviewers /plugins/explore-react @backstage/reviewers @backstage/sda-se-reviewers /plugins/fossa @backstage/reviewers @backstage/sda-se-reviewers diff --git a/plugins/events-backend-test-utils/.eslintrc.js b/plugins/events-backend-test-utils/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/events-backend-test-utils/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/events-backend-test-utils/README.md b/plugins/events-backend-test-utils/README.md new file mode 100644 index 0000000000..c8727b536b --- /dev/null +++ b/plugins/events-backend-test-utils/README.md @@ -0,0 +1,4 @@ +# plugin-events-backend-test-utils + +Houses implementations of plugin-events-node interfaces +which can be useful for test for events-backend and its modules. diff --git a/plugins/events-backend-test-utils/api-report.md b/plugins/events-backend-test-utils/api-report.md new file mode 100644 index 0000000000..46131c4244 --- /dev/null +++ b/plugins/events-backend-test-utils/api-report.md @@ -0,0 +1,47 @@ +## API Report File for "@backstage/plugin-events-backend-test-utils" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { EventBroker } from '@backstage/plugin-events-node'; +import { EventParams } from '@backstage/plugin-events-node'; +import { EventPublisher } from '@backstage/plugin-events-node'; +import { EventSubscriber } from '@backstage/plugin-events-node'; + +// @public (undocumented) +export class TestEventBroker implements EventBroker { + // (undocumented) + publish(params: EventParams): Promise; + // (undocumented) + readonly published: EventParams[]; + // (undocumented) + subscribe( + ...subscribers: Array> + ): void; + // (undocumented) + readonly subscribed: EventSubscriber[]; +} + +// @public (undocumented) +export class TestEventPublisher implements EventPublisher { + // (undocumented) + get eventBroker(): EventBroker | undefined; + // (undocumented) + setEventBroker(eventBroker: EventBroker): Promise; +} + +// @public (undocumented) +export class TestEventSubscriber implements EventSubscriber { + constructor(name: string, topics: string[]); + // (undocumented) + readonly name: string; + // (undocumented) + onEvent(params: EventParams): Promise; + // (undocumented) + readonly receivedEvents: Record; + // (undocumented) + supportsEventTopics(): string[]; + // (undocumented) + readonly topics: string[]; +} +``` diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json new file mode 100644 index 0000000000..c834ee39cf --- /dev/null +++ b/plugins/events-backend-test-utils/package.json @@ -0,0 +1,34 @@ +{ + "name": "@backstage/plugin-events-backend-test-utils", + "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", + "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" + }, + "backstage": { + "role": "node-library" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/plugin-events-node": "workspace:^" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/events-backend-test-utils/src/index.ts b/plugins/events-backend-test-utils/src/index.ts new file mode 100644 index 0000000000..efba5be0d0 --- /dev/null +++ b/plugins/events-backend-test-utils/src/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The events-test-utils module for `@backstage/plugin-events-node`. + * + * @packageDocumentation + */ + +export * from './testUtils'; diff --git a/plugins/events-backend-test-utils/src/testUtils/TestEventBroker.ts b/plugins/events-backend-test-utils/src/testUtils/TestEventBroker.ts new file mode 100644 index 0000000000..c697a6506f --- /dev/null +++ b/plugins/events-backend-test-utils/src/testUtils/TestEventBroker.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + EventBroker, + EventParams, + EventSubscriber, +} from '@backstage/plugin-events-node'; + +/** @public */ +export class TestEventBroker implements EventBroker { + readonly published: EventParams[] = []; + readonly subscribed: EventSubscriber[] = []; + + async publish(params: EventParams): Promise { + this.published.push(params); + } + + subscribe( + ...subscribers: Array> + ): void { + this.subscribed.push(...subscribers.flat()); + } +} diff --git a/plugins/events-backend-test-utils/src/testUtils/TestEventPublisher.ts b/plugins/events-backend-test-utils/src/testUtils/TestEventPublisher.ts new file mode 100644 index 0000000000..c1b2038afb --- /dev/null +++ b/plugins/events-backend-test-utils/src/testUtils/TestEventPublisher.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EventBroker, EventPublisher } from '@backstage/plugin-events-node'; + +/** @public */ +export class TestEventPublisher implements EventPublisher { + #eventBroker?: EventBroker; + + async setEventBroker(eventBroker: EventBroker): Promise { + this.#eventBroker = eventBroker; + } + + get eventBroker() { + return this.#eventBroker; + } +} diff --git a/plugins/events-backend-test-utils/src/testUtils/TestEventSubscriber.ts b/plugins/events-backend-test-utils/src/testUtils/TestEventSubscriber.ts new file mode 100644 index 0000000000..ef5758b804 --- /dev/null +++ b/plugins/events-backend-test-utils/src/testUtils/TestEventSubscriber.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EventParams, EventSubscriber } from '@backstage/plugin-events-node'; + +/** @public */ +export class TestEventSubscriber implements EventSubscriber { + readonly name: string; + readonly topics: string[]; + + readonly receivedEvents: Record = {}; + + constructor(name: string, topics: string[]) { + this.name = name; + this.topics = topics; + } + + supportsEventTopics(): string[] { + return this.topics; + } + + async onEvent(params: EventParams): Promise { + this.receivedEvents[params.topic] = this.receivedEvents[params.topic] ?? []; + this.receivedEvents[params.topic].push(params); + } +} diff --git a/plugins/events-backend-test-utils/src/testUtils/index.ts b/plugins/events-backend-test-utils/src/testUtils/index.ts new file mode 100644 index 0000000000..a571ba3075 --- /dev/null +++ b/plugins/events-backend-test-utils/src/testUtils/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { TestEventBroker } from './TestEventBroker'; +export { TestEventPublisher } from './TestEventPublisher'; +export { TestEventSubscriber } from './TestEventSubscriber'; diff --git a/plugins/events-backend/.eslintrc.js b/plugins/events-backend/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/events-backend/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/events-backend/README.md b/plugins/events-backend/README.md new file mode 100644 index 0000000000..1a71a68944 --- /dev/null +++ b/plugins/events-backend/README.md @@ -0,0 +1,124 @@ +# events-backend + +Welcome to the events-backend backend plugin! + +This plugin provides the wiring of all extension points +for managing events as defined by [plugin-events-node](../events-node) +including backend plugin `EventsPlugin` and `EventsBackend`. + +Additionally, it uses a simple in-memory implementation for +the `EventBroker` by default which you can replace with a more sophisticated +implementation of your choice as you need (e.g., via module). + +Some of these (non-exhaustive) may provide added persistence, +or use external systems like AWS EventBridge, AWS SNS, Kafka, etc. + +## Installation + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-events-backend +``` + +Add a file [`packages/backend/src/plugins/events.ts`](../../packages/backend/src/plugins/events.ts) +to your Backstage project. + +There, you can add all publishers, subscribers, etc. you want. + +Additionally, add the events plugin to your backend. + +```diff +// packages/backend/src/index.ts +// [...] ++import events from './plugins/events'; +// [...] ++ const eventsEnv = useHotMemoize(module, () => createEnv('events')); +// [...] ++ apiRouter.use('/events', await events(eventsEnv, [])); +// [...] +``` + +### With Event-based Entity Providers + +In case you use event-based `EntityProviders`, +you may need something like the following: + +```diff +// packages/backend/src/index.ts +- apiRouter.use('/events', await events(eventsEnv, [])); ++ apiRouter.use('/events', await events(eventsEnv, eventBasedEntityProviders)); +``` + +as well as a file +[`packages/backend/src/plugins/catalogEventBasedProviders.ts`](../../packages/backend/src/plugins/catalogEventBasedProviders.ts) +which contains event-based entity providers. + +In case you don't have this dependency added yet: + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-events-backend +``` + +```diff +// packages/backend/src/plugins/catalog.ts + import { CatalogBuilder } from '@backstage/plugin-catalog-backend'; ++import { EntityProvider } from '@backstage/plugin-catalog-node'; + import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend'; + import { Router } from 'express'; + import { PluginEnvironment } from '../types'; + + export default async function createPlugin( + env: PluginEnvironment, ++ providers?: Array, + ): Promise { + const builder = await CatalogBuilder.create(env); + builder.addProcessor(new ScaffolderEntitiesProcessor()); ++ builder.addEntityProvider(providers ?? []); + const { processingEngine, router } = await builder.build(); + await processingEngine.start(); + return router; + } +``` + +## Use Cases + +### Custom Event Broker + +Example using the `EventsBackend`: + +```ts +new EventsBackend(env.logger) + .setEventBroker(yourEventBroker) + // [...] + .start(); +``` + +Example using a module: + +```ts +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; + +// [...] + +export const yourModuleEventsModule = createBackendModule({ + pluginId: 'events', + moduleId: 'yourModule', + register(env) { + // [...] + env.registerInit({ + deps: { + // [...] + events: eventsExtensionPoint, + // [...] + }, + async init({ /* ... */ events /*, ... */ }) { + // [...] + const yourEventBroker = new YourEventBroker(); + // [...] + events.setEventBroker(yourEventBroker); + }, + }); + }, +}); +``` diff --git a/plugins/events-backend/api-report.md b/plugins/events-backend/api-report.md new file mode 100644 index 0000000000..e61664b428 --- /dev/null +++ b/plugins/events-backend/api-report.md @@ -0,0 +1,30 @@ +## API Report File for "@backstage/plugin-events-backend" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { EventBroker } from '@backstage/plugin-events-node'; +import { EventPublisher } from '@backstage/plugin-events-node'; +import { EventSubscriber } from '@backstage/plugin-events-node'; +import { Logger } from 'winston'; + +// @public +export class EventsBackend { + constructor(logger: Logger); + // (undocumented) + addPublishers( + ...publishers: Array> + ): EventsBackend; + // (undocumented) + addSubscribers( + ...subscribers: Array> + ): EventsBackend; + // (undocumented) + setEventBroker(eventBroker: EventBroker): EventsBackend; + start(): Promise; +} + +// @alpha +export const eventsPlugin: (options?: undefined) => BackendFeature; +``` diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json new file mode 100644 index 0000000000..3c93ef48c1 --- /dev/null +++ b/plugins/events-backend/package.json @@ -0,0 +1,40 @@ +{ + "name": "@backstage/plugin-events-backend", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "alphaTypes": "dist/index.alpha.d.ts", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build --experimental-type-build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-plugin-api": "workspace:^", + "@backstage/plugin-events-node": "workspace:^", + "winston": "^3.2.1" + }, + "devDependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "@backstage/plugin-events-backend-test-utils": "workspace:^" + }, + "files": [ + "alpha", + "dist" + ] +} diff --git a/plugins/events-backend/src/index.ts b/plugins/events-backend/src/index.ts new file mode 100644 index 0000000000..121d9cdc46 --- /dev/null +++ b/plugins/events-backend/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The Backstage backend plugin "events" that provides the event management. + * + * @packageDocumentation + */ + +export { EventsBackend } from './service/EventsBackend'; +export { eventsPlugin } from './service/EventsPlugin'; diff --git a/plugins/events-backend/src/service/EventsBackend.test.ts b/plugins/events-backend/src/service/EventsBackend.test.ts new file mode 100644 index 0000000000..c2041b57ac --- /dev/null +++ b/plugins/events-backend/src/service/EventsBackend.test.ts @@ -0,0 +1,60 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { + TestEventBroker, + TestEventPublisher, + TestEventSubscriber, +} from '@backstage/plugin-events-backend-test-utils'; +import { EventsBackend } from './EventsBackend'; + +const logger = getVoidLogger(); + +describe('EventsBackend', () => { + it('wires up all components', async () => { + const eventBroker = new TestEventBroker(); + const publisher1 = new TestEventPublisher(); + const publisher2 = new TestEventPublisher(); + + await new EventsBackend(logger) + .setEventBroker(eventBroker) + .addPublishers(publisher1, [publisher2]) + .addSubscribers(new TestEventSubscriber('one', ['topicA']), [ + new TestEventSubscriber('two', ['topicA', 'topicB']), + ]) + .start(); + + await eventBroker.publish({ + topic: 'topicA', + eventPayload: { test: 'payload' }, + }); + + expect(eventBroker.published.length).toEqual(1); + expect(eventBroker.published[0].topic).toEqual('topicA'); + expect(eventBroker.published[0].eventPayload).toEqual({ test: 'payload' }); + + expect(eventBroker.subscribed.length).toEqual(2); + expect( + eventBroker.subscribed.map( + sub => (sub as unknown as TestEventSubscriber).name, + ), + ).toEqual(['one', 'two']); + + expect(publisher1.eventBroker).toBe(eventBroker); + expect(publisher2.eventBroker).toBe(eventBroker); + }); +}); diff --git a/plugins/events-backend/src/service/EventsBackend.ts b/plugins/events-backend/src/service/EventsBackend.ts new file mode 100644 index 0000000000..77b1b538f7 --- /dev/null +++ b/plugins/events-backend/src/service/EventsBackend.ts @@ -0,0 +1,67 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + EventBroker, + EventPublisher, + EventSubscriber, +} from '@backstage/plugin-events-node'; +import { Logger } from 'winston'; +import { InMemoryEventBroker } from './InMemoryEventBroker'; + +/** + * A builder that helps wire up all component parts of the event management. + * + * @public + */ +export class EventsBackend { + private eventBroker: EventBroker; + private publishers: EventPublisher[] = []; + private subscribers: EventSubscriber[] = []; + + constructor(logger: Logger) { + this.eventBroker = new InMemoryEventBroker(logger); + } + + setEventBroker(eventBroker: EventBroker): EventsBackend { + this.eventBroker = eventBroker; + return this; + } + + addPublishers( + ...publishers: Array> + ): EventsBackend { + this.publishers.push(...publishers.flat()); + return this; + } + + addSubscribers( + ...subscribers: Array> + ): EventsBackend { + this.subscribers.push(...subscribers.flat()); + return this; + } + + /** + * Wires up and returns all component parts of the event management. + */ + async start(): Promise { + this.eventBroker.subscribe(this.subscribers); + this.publishers.forEach(publisher => + publisher.setEventBroker(this.eventBroker), + ); + } +} diff --git a/plugins/events-backend/src/service/EventsPlugin.test.ts b/plugins/events-backend/src/service/EventsPlugin.test.ts new file mode 100644 index 0000000000..e6c7c75264 --- /dev/null +++ b/plugins/events-backend/src/service/EventsPlugin.test.ts @@ -0,0 +1,64 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { + createBackendModule, + loggerServiceRef, +} from '@backstage/backend-plugin-api'; +import { startTestBackend } from '@backstage/backend-test-utils'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { + TestEventBroker, + TestEventPublisher, + TestEventSubscriber, +} from '@backstage/plugin-events-backend-test-utils'; +import { eventsPlugin } from './EventsPlugin'; + +describe('eventPlugin', () => { + it('should be initialized properly', async () => { + const eventBroker = new TestEventBroker(); + const publisher = new TestEventPublisher(); + const subscriber = new TestEventSubscriber('sub', ['topicA']); + + const testModule = createBackendModule({ + pluginId: 'events', + moduleId: 'test', + register(env) { + env.registerInit({ + deps: { + events: eventsExtensionPoint, + }, + async init({ events }) { + events.setEventBroker(eventBroker); + events.addPublishers(publisher); + events.addSubscribers(subscriber); + }, + }); + }, + }); + + await startTestBackend({ + extensionPoints: [], + services: [[loggerServiceRef, getVoidLogger()]], + features: [eventsPlugin(), testModule()], + }); + + expect(publisher.eventBroker).toBe(eventBroker); + expect(eventBroker.subscribed.length).toEqual(1); + expect(eventBroker.subscribed[0]).toBe(subscriber); + }); +}); diff --git a/plugins/events-backend/src/service/EventsPlugin.ts b/plugins/events-backend/src/service/EventsPlugin.ts new file mode 100644 index 0000000000..d2cac331f9 --- /dev/null +++ b/plugins/events-backend/src/service/EventsPlugin.ts @@ -0,0 +1,93 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createBackendPlugin, + loggerServiceRef, + loggerToWinstonLogger, +} from '@backstage/backend-plugin-api'; +import { + EventBroker, + EventPublisher, + EventSubscriber, + eventsExtensionPoint, + EventsExtensionPoint, +} from '@backstage/plugin-events-node'; +import { InMemoryEventBroker } from './InMemoryEventBroker'; + +class EventsExtensionPointImpl implements EventsExtensionPoint { + #eventBroker: EventBroker | undefined; + #publishers: EventPublisher[] = []; + #subscribers: EventSubscriber[] = []; + + setEventBroker(eventBroker: EventBroker): void { + this.#eventBroker = eventBroker; + } + + addPublishers( + ...publishers: Array> + ): void { + this.#publishers.push(...publishers.flat()); + } + + addSubscribers( + ...subscribers: Array> + ): void { + this.#subscribers.push(...subscribers.flat()); + } + + get eventBroker() { + return this.#eventBroker; + } + + get publishers() { + return this.#publishers; + } + + get subscribers() { + return this.#subscribers; + } +} + +/** + * Events plugin + * + * @alpha + */ +export const eventsPlugin = createBackendPlugin({ + id: 'events', + register(env) { + const extensionPoint = new EventsExtensionPointImpl(); + env.registerExtensionPoint(eventsExtensionPoint, extensionPoint); + + env.registerInit({ + deps: { + logger: loggerServiceRef, + }, + async init({ logger }) { + if (!extensionPoint.eventBroker) { + const winstonLogger = loggerToWinstonLogger(logger); + extensionPoint.setEventBroker(new InMemoryEventBroker(winstonLogger)); + } + + extensionPoint.eventBroker!.subscribe(extensionPoint.subscribers); + extensionPoint.publishers.forEach(publisher => + publisher.setEventBroker(extensionPoint.eventBroker!), + ); + }, + }); + }, +}); diff --git a/plugins/events-backend/src/service/InMemoryEventBroker.test.ts b/plugins/events-backend/src/service/InMemoryEventBroker.test.ts new file mode 100644 index 0000000000..68a6f63a72 --- /dev/null +++ b/plugins/events-backend/src/service/InMemoryEventBroker.test.ts @@ -0,0 +1,66 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { TestEventSubscriber } from '@backstage/plugin-events-backend-test-utils'; +import { InMemoryEventBroker } from './InMemoryEventBroker'; + +const logger = getVoidLogger(); + +describe('InMemoryEventBroker', () => { + it('passes events to interested subscribers', () => { + const subscriber1 = new TestEventSubscriber('test1', ['topicA', 'topicB']); + const subscriber2 = new TestEventSubscriber('test2', ['topicB', 'topicC']); + const eventBroker = new InMemoryEventBroker(logger); + + eventBroker.subscribe(subscriber1); + eventBroker.subscribe(subscriber2); + eventBroker.publish({ topic: 'topicA', eventPayload: { test: 'topicA' } }); + eventBroker.publish({ topic: 'topicB', eventPayload: { test: 'topicB' } }); + eventBroker.publish({ topic: 'topicC', eventPayload: { test: 'topicC' } }); + eventBroker.publish({ topic: 'topicD', eventPayload: { test: 'topicD' } }); + + expect(Object.keys(subscriber1.receivedEvents)).toEqual([ + 'topicA', + 'topicB', + ]); + expect(subscriber1.receivedEvents.topicA.length).toEqual(1); + expect(subscriber1.receivedEvents.topicA[0]).toEqual({ + topic: 'topicA', + eventPayload: { test: 'topicA' }, + }); + expect(subscriber1.receivedEvents.topicB.length).toEqual(1); + expect(subscriber1.receivedEvents.topicB[0]).toEqual({ + topic: 'topicB', + eventPayload: { test: 'topicB' }, + }); + + expect(Object.keys(subscriber2.receivedEvents)).toEqual([ + 'topicB', + 'topicC', + ]); + expect(subscriber2.receivedEvents.topicB.length).toEqual(1); + expect(subscriber2.receivedEvents.topicB[0]).toEqual({ + topic: 'topicB', + eventPayload: { test: 'topicB' }, + }); + expect(subscriber2.receivedEvents.topicC.length).toEqual(1); + expect(subscriber2.receivedEvents.topicC[0]).toEqual({ + topic: 'topicC', + eventPayload: { test: 'topicC' }, + }); + }); +}); diff --git a/plugins/events-backend/src/service/InMemoryEventBroker.ts b/plugins/events-backend/src/service/InMemoryEventBroker.ts new file mode 100644 index 0000000000..90c7d912fe --- /dev/null +++ b/plugins/events-backend/src/service/InMemoryEventBroker.ts @@ -0,0 +1,58 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + EventBroker, + EventParams, + EventSubscriber, +} from '@backstage/plugin-events-node'; +import { Logger } from 'winston'; + +/** + * In-memory event broker which will pass the event to all registered subscribers + * interested in it. + * Events will not be persisted in any form. + */ +// TODO(pjungermann): add prom metrics? (see plugins/catalog-backend/src/util/metrics.ts, etc.) +export class InMemoryEventBroker implements EventBroker { + constructor(private readonly logger: Logger) {} + + private readonly subscribers: { + [topic: string]: EventSubscriber[]; + } = {}; + + async publish(params: EventParams): Promise { + this.logger.debug( + `Event received: topic=${params.topic}, metadata=${JSON.stringify( + params.metadata, + )}, payload=${JSON.stringify(params.eventPayload)}`, + ); + + const subscribed = this.subscribers[params.topic] ?? []; + subscribed.forEach(subscriber => subscriber.onEvent(params)); + } + + subscribe( + ...subscribers: Array> + ): void { + subscribers.flat().forEach(subscriber => { + subscriber.supportsEventTopics().forEach(topic => { + this.subscribers[topic] = this.subscribers[topic] ?? []; + this.subscribers[topic].push(subscriber); + }); + }); + } +} diff --git a/plugins/events-backend/src/setupTests.ts b/plugins/events-backend/src/setupTests.ts new file mode 100644 index 0000000000..d3232290a7 --- /dev/null +++ b/plugins/events-backend/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 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/events-node/.eslintrc.js b/plugins/events-node/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/events-node/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/events-node/README.md b/plugins/events-node/README.md new file mode 100644 index 0000000000..44738222bc --- /dev/null +++ b/plugins/events-node/README.md @@ -0,0 +1,3 @@ +# plugin-events-node + +Houses types and utilities for building events-related modules. diff --git a/plugins/events-node/api-report.md b/plugins/events-node/api-report.md new file mode 100644 index 0000000000..e0b34aa204 --- /dev/null +++ b/plugins/events-node/api-report.md @@ -0,0 +1,76 @@ +## API Report File for "@backstage/plugin-events-node" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ExtensionPoint } from '@backstage/backend-plugin-api'; + +// @public +export interface EventBroker { + publish(params: EventParams): Promise; + subscribe( + ...subscribers: Array> + ): void; +} + +// @public (undocumented) +export interface EventParams { + eventPayload: unknown; + metadata?: Record; + topic: string; +} + +// @public +export interface EventPublisher { + // (undocumented) + setEventBroker(eventBroker: EventBroker): Promise; +} + +// @public +export abstract class EventRouter implements EventPublisher, EventSubscriber { + // (undocumented) + protected abstract determineDestinationTopic( + params: EventParams, + ): string | undefined; + // (undocumented) + onEvent(params: EventParams): Promise; + // (undocumented) + setEventBroker(eventBroker: EventBroker): Promise; + // (undocumented) + abstract supportsEventTopics(): string[]; +} + +// @alpha (undocumented) +export interface EventsExtensionPoint { + // (undocumented) + addPublishers( + ...publishers: Array> + ): void; + // (undocumented) + addSubscribers( + ...subscribers: Array> + ): void; + // (undocumented) + setEventBroker(eventBroker: EventBroker): void; +} + +// @alpha (undocumented) +export const eventsExtensionPoint: ExtensionPoint; + +// @public +export interface EventSubscriber { + onEvent(params: EventParams): Promise; + supportsEventTopics(): string[]; +} + +// @public +export abstract class SubTopicEventRouter extends EventRouter { + protected constructor(topic: string); + // (undocumented) + protected determineDestinationTopic(params: EventParams): string | undefined; + // (undocumented) + protected abstract determineSubTopic(params: EventParams): string | undefined; + // (undocumented) + supportsEventTopics(): string[]; +} +``` diff --git a/plugins/events-node/package.json b/plugins/events-node/package.json new file mode 100644 index 0000000000..317af49c5c --- /dev/null +++ b/plugins/events-node/package.json @@ -0,0 +1,38 @@ +{ + "name": "@backstage/plugin-events-node", + "description": "The plugin-events-node module for @backstage/plugin-events-backend", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "alphaTypes": "dist/index.alpha.d.ts", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "node-library" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build --experimental-type-build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-plugin-api": "workspace:^", + "@types/express": "^4.17.6", + "express": "^4.17.1" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" + }, + "files": [ + "alpha", + "dist" + ] +} diff --git a/plugins/events-node/src/api/EventBroker.ts b/plugins/events-node/src/api/EventBroker.ts new file mode 100644 index 0000000000..736c2a2bf0 --- /dev/null +++ b/plugins/events-node/src/api/EventBroker.ts @@ -0,0 +1,43 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EventParams } from './EventParams'; +import { EventSubscriber } from './EventSubscriber'; + +/** + * Allows a decoupled and asynchronous communication between components. + * Components can publish events for a given topic and + * others can subscribe for future events for topics they are interested in. + * + * @public + */ +export interface EventBroker { + /** + * Publishes an event for the topic. + * + * @param params - parameters for the to be published event. + */ + publish(params: EventParams): Promise; + + /** + * Adds new subscribers for {@link EventSubscriber#supportsEventTopics | interested topics}. + * + * @param subscribers - interested in events of specified topics. + */ + subscribe( + ...subscribers: Array> + ): void; +} diff --git a/plugins/events-node/src/api/EventParams.ts b/plugins/events-node/src/api/EventParams.ts new file mode 100644 index 0000000000..6912827281 --- /dev/null +++ b/plugins/events-node/src/api/EventParams.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @public + */ +export interface EventParams { + /** + * Topic for which this event should be published. + */ + topic: string; + /** + * Event payload. + */ + eventPayload: unknown; + /** + * Metadata (e.g., HTTP headers and similar for events received from external). + */ + metadata?: Record; +} diff --git a/plugins/events-node/src/api/EventPublisher.ts b/plugins/events-node/src/api/EventPublisher.ts new file mode 100644 index 0000000000..285f427804 --- /dev/null +++ b/plugins/events-node/src/api/EventPublisher.ts @@ -0,0 +1,29 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EventBroker } from './EventBroker'; + +/** + * Publishes events to be consumed by subscribers for their topic. + * The events can come from different (external) sources + * like emitted themselves, received via HTTP endpoint (i.e. webhook) + * or from event brokers, queues, etc. + * + * @public + */ +export interface EventPublisher { + setEventBroker(eventBroker: EventBroker): Promise; +} diff --git a/plugins/events-node/src/api/EventRouter.test.ts b/plugins/events-node/src/api/EventRouter.test.ts new file mode 100644 index 0000000000..551c5ea67d --- /dev/null +++ b/plugins/events-node/src/api/EventRouter.test.ts @@ -0,0 +1,81 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EventBroker } from './EventBroker'; +import { EventParams } from './EventParams'; +import { EventRouter } from './EventRouter'; + +class TestEventRouter extends EventRouter { + protected determineDestinationTopic(params: EventParams): string | undefined { + const payload = params.eventPayload as { value?: number }; + if (payload.value === undefined) { + return undefined; + } + + return payload.value % 2 === 0 ? 'even' : 'odd'; + } + + supportsEventTopics(): string[] { + return ['my-topic']; + } +} + +describe('EventRouter', () => { + const eventRouter = new TestEventRouter(); + const topic = 'my-topic'; + const metadata = { random: 'metadata' }; + + it('no destination topic', async () => { + const published: EventParams[] = []; + const eventBroker = { + publish: (params: EventParams) => { + published.push(params); + }, + } as EventBroker; + await eventRouter.setEventBroker(eventBroker); + + await eventRouter.onEvent({ + topic, + eventPayload: { discarded: 'event' }, + metadata, + }); + + expect(published).toEqual([]); + }); + + it('with destination topic', async () => { + const published: EventParams[] = []; + const eventBroker = { + publish: (params: EventParams) => { + published.push(params); + }, + } as EventBroker; + await eventRouter.setEventBroker(eventBroker); + + const payloadEven = { value: 2 }; + const payloadOdd = { value: 3 }; + await eventRouter.onEvent({ topic, eventPayload: payloadEven, metadata }); + await eventRouter.onEvent({ topic, eventPayload: payloadOdd, metadata }); + + expect(published.length).toBe(2); + expect(published[0].topic).toEqual('even'); + expect(published[0].eventPayload).toEqual(payloadEven); + expect(published[0].metadata).toEqual(metadata); + expect(published[1].topic).toEqual('odd'); + expect(published[1].eventPayload).toEqual(payloadOdd); + expect(published[1].metadata).toEqual(metadata); + }); +}); diff --git a/plugins/events-node/src/api/EventRouter.ts b/plugins/events-node/src/api/EventRouter.ts new file mode 100644 index 0000000000..b435ef15f4 --- /dev/null +++ b/plugins/events-node/src/api/EventRouter.ts @@ -0,0 +1,55 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EventBroker } from './EventBroker'; +import { EventParams } from './EventParams'; +import { EventPublisher } from './EventPublisher'; +import { EventSubscriber } from './EventSubscriber'; + +/** + * Subscribes to a topic and - depending on a set of conditions - + * republishes the event to another topic. + * + * @see {@link https://www.enterpriseintegrationpatterns.com/MessageRouter.html | Message Router pattern}. + * @public + */ +export abstract class EventRouter implements EventPublisher, EventSubscriber { + private eventBroker?: EventBroker; + + protected abstract determineDestinationTopic( + params: EventParams, + ): string | undefined; + + async onEvent(params: EventParams): Promise { + const topic = this.determineDestinationTopic(params); + + if (!topic) { + return; + } + + // republish to different topic + this.eventBroker?.publish({ + ...params, + topic, + }); + } + + async setEventBroker(eventBroker: EventBroker): Promise { + this.eventBroker = eventBroker; + } + + abstract supportsEventTopics(): string[]; +} diff --git a/plugins/events-node/src/api/EventSubscriber.ts b/plugins/events-node/src/api/EventSubscriber.ts new file mode 100644 index 0000000000..439f49b890 --- /dev/null +++ b/plugins/events-node/src/api/EventSubscriber.ts @@ -0,0 +1,38 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EventParams } from './EventParams'; + +/** + * Handles received events. + * This may include triggering refreshes of catalog entities + * or other actions to react on events. + * + * @public + */ +export interface EventSubscriber { + /** + * Supported event topics like "github", "bitbucketCloud", etc. + */ + supportsEventTopics(): string[]; + + /** + * React on a received event. + * + * @param params - parameters for the to be received event. + */ + onEvent(params: EventParams): Promise; +} diff --git a/plugins/events-node/src/api/SubTopicEventRouter.test.ts b/plugins/events-node/src/api/SubTopicEventRouter.test.ts new file mode 100644 index 0000000000..d5c79895a5 --- /dev/null +++ b/plugins/events-node/src/api/SubTopicEventRouter.test.ts @@ -0,0 +1,67 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EventBroker } from './EventBroker'; +import { EventParams } from './EventParams'; +import { SubTopicEventRouter } from './SubTopicEventRouter'; + +class TestSubTopicEventRouter extends SubTopicEventRouter { + constructor() { + super('my-topic'); + } + + protected determineSubTopic(params: EventParams): string | undefined { + return params.metadata?.['x-my-event'] as string | undefined; + } +} + +describe('SubTopicEventRouter', () => { + const eventRouter = new TestSubTopicEventRouter(); + const topic = 'my-topic'; + const eventPayload = { test: 'payload' }; + const metadata = { 'x-my-event': 'test.type' }; + + it('no x-my-event', async () => { + const published: EventParams[] = []; + const eventBroker = { + publish: (params: EventParams) => { + published.push(params); + }, + } as EventBroker; + await eventRouter.setEventBroker(eventBroker); + + await eventRouter.onEvent({ topic, eventPayload }); + + expect(published).toEqual([]); + }); + + it('with x-my-event', async () => { + const published: EventParams[] = []; + const eventBroker = { + publish: (params: EventParams) => { + published.push(params); + }, + } as EventBroker; + await eventRouter.setEventBroker(eventBroker); + + await eventRouter.onEvent({ topic, eventPayload, metadata }); + + expect(published.length).toBe(1); + expect(published[0].topic).toEqual('my-topic.test.type'); + expect(published[0].eventPayload).toEqual(eventPayload); + expect(published[0].metadata).toEqual(metadata); + }); +}); diff --git a/plugins/events-node/src/api/SubTopicEventRouter.ts b/plugins/events-node/src/api/SubTopicEventRouter.ts new file mode 100644 index 0000000000..04abe14009 --- /dev/null +++ b/plugins/events-node/src/api/SubTopicEventRouter.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EventParams } from './EventParams'; +import { EventRouter } from './EventRouter'; + +/** + * Subscribes to the provided (generic) topic + * and publishes the events under the more concrete sub-topic + * depending on the implemented logic for determining it. + * Implementing classes might use information from `metadata` + * and/or properties within the payload. + * + * @public + */ +export abstract class SubTopicEventRouter extends EventRouter { + protected constructor(private readonly topic: string) { + super(); + } + + protected abstract determineSubTopic(params: EventParams): string | undefined; + + protected determineDestinationTopic(params: EventParams): string | undefined { + const subTopic = this.determineSubTopic(params); + return subTopic ? `${params.topic}.${subTopic}` : undefined; + } + + supportsEventTopics(): string[] { + return [this.topic]; + } +} diff --git a/plugins/events-node/src/api/index.ts b/plugins/events-node/src/api/index.ts new file mode 100644 index 0000000000..22b51c191d --- /dev/null +++ b/plugins/events-node/src/api/index.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export type { EventBroker } from './EventBroker'; +export type { EventParams } from './EventParams'; +export type { EventPublisher } from './EventPublisher'; +export { EventRouter } from './EventRouter'; +export type { EventSubscriber } from './EventSubscriber'; +export { SubTopicEventRouter } from './SubTopicEventRouter'; diff --git a/plugins/events-node/src/extensions.ts b/plugins/events-node/src/extensions.ts new file mode 100644 index 0000000000..f935e85be8 --- /dev/null +++ b/plugins/events-node/src/extensions.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createExtensionPoint } from '@backstage/backend-plugin-api'; +import { EventBroker, EventPublisher, EventSubscriber } from './api'; + +/** + * @alpha + */ +export interface EventsExtensionPoint { + setEventBroker(eventBroker: EventBroker): void; + + addPublishers( + ...publishers: Array> + ): void; + + addSubscribers( + ...subscribers: Array> + ): void; +} + +/** + * @alpha + */ +export const eventsExtensionPoint = createExtensionPoint({ + id: 'events', +}); diff --git a/plugins/events-node/src/index.ts b/plugins/events-node/src/index.ts new file mode 100644 index 0000000000..422eeb169e --- /dev/null +++ b/plugins/events-node/src/index.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The events-node module for `@backstage/plugin-events-backend`. + * + * @packageDocumentation + */ + +export * from './api'; +export type { EventsExtensionPoint } from './extensions'; +export { eventsExtensionPoint } from './extensions'; diff --git a/plugins/events-node/src/setupTests.ts b/plugins/events-node/src/setupTests.ts new file mode 100644 index 0000000000..d3232290a7 --- /dev/null +++ b/plugins/events-node/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 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/yarn.lock b/yarn.lock index 025d31f618..c96addfbcc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5532,6 +5532,40 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-events-backend-test-utils@workspace:^, @backstage/plugin-events-backend-test-utils@workspace:plugins/events-backend-test-utils": + version: 0.0.0-use.local + resolution: "@backstage/plugin-events-backend-test-utils@workspace:plugins/events-backend-test-utils" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" + languageName: unknown + linkType: soft + +"@backstage/plugin-events-backend@workspace:plugins/events-backend": + version: 0.0.0-use.local + resolution: "@backstage/plugin-events-backend@workspace:plugins/events-backend" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/plugin-events-backend-test-utils": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" + winston: ^3.2.1 + languageName: unknown + linkType: soft + +"@backstage/plugin-events-node@workspace:^, @backstage/plugin-events-node@workspace:plugins/events-node": + version: 0.0.0-use.local + resolution: "@backstage/plugin-events-node@workspace:plugins/events-node" + dependencies: + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/cli": "workspace:^" + "@types/express": ^4.17.6 + express: ^4.17.1 + languageName: unknown + linkType: soft + "@backstage/plugin-explore-react@workspace:^, @backstage/plugin-explore-react@workspace:plugins/explore-react": version: 0.0.0-use.local resolution: "@backstage/plugin-explore-react@workspace:plugins/explore-react" From dc9da28abd759b86df99d6aeab96a976c0fa5a88 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Tue, 4 Oct 2022 16:41:08 +0200 Subject: [PATCH 305/434] feat(events/http): add HTTP endpoint-based event publisher This plugin adds an event publisher which receives events via (an) HTTP endpoint(s) and can be used as destination at webhook subscriptions. Relates-to: #11082 Signed-off-by: Patrick Jungermann --- .changeset/poor-cheetahs-work.md | 17 ++ plugins/events-backend/README.md | 86 +++++++ plugins/events-backend/api-report.md | 18 ++ plugins/events-backend/config.d.ts | 28 +++ plugins/events-backend/package.json | 12 +- plugins/events-backend/src/index.ts | 1 + .../src/service/EventsPlugin.test.ts | 39 ++- .../src/service/EventsPlugin.ts | 48 +++- .../HttpPostIngressEventPublisher.test.ts | 225 ++++++++++++++++++ .../http/HttpPostIngressEventPublisher.ts | 118 +++++++++ .../events-backend/src/service/http/index.ts | 18 ++ .../RequestValidationContextImpl.test.ts | 64 +++++ .../RequestValidationContextImpl.ts | 39 +++ .../src/service/http/validation/index.ts | 17 ++ plugins/events-node/api-report.md | 30 +++ .../src/api/http/HttpPostIngressOptions.ts | 25 ++ plugins/events-node/src/api/http/index.ts | 18 ++ .../validation/RequestRejectionDetails.ts | 26 ++ .../validation/RequestValidationContext.ts | 32 +++ .../api/http/validation/RequestValidator.ts | 34 +++ .../src/api/http/validation/index.ts | 19 ++ plugins/events-node/src/api/index.ts | 1 + plugins/events-node/src/extensions.ts | 9 +- yarn.lock | 5 + 24 files changed, 918 insertions(+), 11 deletions(-) create mode 100644 .changeset/poor-cheetahs-work.md create mode 100644 plugins/events-backend/config.d.ts create mode 100644 plugins/events-backend/src/service/http/HttpPostIngressEventPublisher.test.ts create mode 100644 plugins/events-backend/src/service/http/HttpPostIngressEventPublisher.ts create mode 100644 plugins/events-backend/src/service/http/index.ts create mode 100644 plugins/events-backend/src/service/http/validation/RequestValidationContextImpl.test.ts create mode 100644 plugins/events-backend/src/service/http/validation/RequestValidationContextImpl.ts create mode 100644 plugins/events-backend/src/service/http/validation/index.ts create mode 100644 plugins/events-node/src/api/http/HttpPostIngressOptions.ts create mode 100644 plugins/events-node/src/api/http/index.ts create mode 100644 plugins/events-node/src/api/http/validation/RequestRejectionDetails.ts create mode 100644 plugins/events-node/src/api/http/validation/RequestValidationContext.ts create mode 100644 plugins/events-node/src/api/http/validation/RequestValidator.ts create mode 100644 plugins/events-node/src/api/http/validation/index.ts diff --git a/.changeset/poor-cheetahs-work.md b/.changeset/poor-cheetahs-work.md new file mode 100644 index 0000000000..0fa29949d2 --- /dev/null +++ b/.changeset/poor-cheetahs-work.md @@ -0,0 +1,17 @@ +--- +'@backstage/plugin-events-backend': minor +'@backstage/plugin-events-node': minor +--- + +Support events received via HTTP endpoints at plugin-events-backend. + +The plugin provides an event publisher `HttpPostIngressEventPublisher` +which will allow you to receive events via +HTTP endpoints `POST /api/events/http/{topic}` +and will publish these to the used event broker. + +Using a provided custom validator, you can participate in the decision +which events are accepted, e.g. by verifying the source of the request. + +Please find more information at +https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md. diff --git a/plugins/events-backend/README.md b/plugins/events-backend/README.md index 1a71a68944..f71df21517 100644 --- a/plugins/events-backend/README.md +++ b/plugins/events-backend/README.md @@ -13,6 +13,10 @@ implementation of your choice as you need (e.g., via module). Some of these (non-exhaustive) may provide added persistence, or use external systems like AWS EventBridge, AWS SNS, Kafka, etc. +By default, the plugin ships with support to receive events via HTTP endpoints +`POST /api/events/http/{topic}` and will publish these +to the used event broker. + ## Installation ```bash @@ -81,6 +85,36 @@ yarn add --cwd packages/backend @backstage/plugin-events-backend } ``` +## Configuration + +In order to create HTTP endpoints to receive events for a certain +topic, you need to add them at your configuration: + +```yaml +events: + http: + topics: + - bitbucketCloud + - github + - whatever +``` + +Only those topics added to the configuration will result in +available endpoints. + +The example above would result in the following endpoints: + +``` +POST /api/events/http/bitbucketCloud +POST /api/events/http/github +POST /api/events/http/whatever +``` + +You may want to use these for webhooks by SCM providers +in combination with suitable event subscribers. + +However, it is not limited to these use cases. + ## Use Cases ### Custom Event Broker @@ -122,3 +156,55 @@ export const yourModuleEventsModule = createBackendModule({ }, }); ``` + +### Request Validator + +Example using the `EventsBackend`: + +```ts +const http = HttpPostIngressEventPublisher.fromConfig({ + config: env.config, + ingresses: { + yourTopic: { + validator: yourValidator, + }, + }, + logger: env.logger, + router: httpRouter, +}); + +await new EventsBackend(env.logger) + .addPublishers(http) + // [...] + .start(); +``` + +Example using a module: + +```ts +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; + +// [...] + +export const yourModuleEventsModule = createBackendModule({ + pluginId: 'events', + moduleId: 'yourModule', + register(env) { + // [...] + env.registerInit({ + deps: { + // [...] + events: eventsExtensionPoint, + // [...] + }, + async init({ /* ... */ events /*, ... */ }) { + // [...] + events.addHttpPostIngress({ + topic: 'your-topic', + validator: yourValidator, + }); + }, + }); + }, +}); +``` diff --git a/plugins/events-backend/api-report.md b/plugins/events-backend/api-report.md index e61664b428..4154168fa1 100644 --- a/plugins/events-backend/api-report.md +++ b/plugins/events-backend/api-report.md @@ -4,9 +4,12 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; +import { Config } from '@backstage/config'; import { EventBroker } from '@backstage/plugin-events-node'; import { EventPublisher } from '@backstage/plugin-events-node'; import { EventSubscriber } from '@backstage/plugin-events-node'; +import express from 'express'; +import { HttpPostIngressOptions } from '@backstage/plugin-events-node'; import { Logger } from 'winston'; // @public @@ -27,4 +30,19 @@ export class EventsBackend { // @alpha export const eventsPlugin: (options?: undefined) => BackendFeature; + +// @public +export class HttpPostIngressEventPublisher implements EventPublisher { + // (undocumented) + static fromConfig(env: { + config: Config; + ingresses?: { + [topic: string]: Omit; + }; + logger: Logger; + router: express.Router; + }): HttpPostIngressEventPublisher; + // (undocumented) + setEventBroker(eventBroker: EventBroker): Promise; +} ``` diff --git a/plugins/events-backend/config.d.ts b/plugins/events-backend/config.d.ts new file mode 100644 index 0000000000..3d26661855 --- /dev/null +++ b/plugins/events-backend/config.d.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface Config { + events?: { + http?: { + /** + * Topics for which a route has to be registered + * at which we can receive events via HTTP POST requests + * (i.e. received from webhooks). + */ + topics?: string[]; + }; + }; +} diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index 3c93ef48c1..2d82953e71 100644 --- a/plugins/events-backend/package.json +++ b/plugins/events-backend/package.json @@ -23,18 +23,26 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { + "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", + "@backstage/config": "workspace:^", "@backstage/plugin-events-node": "workspace:^", + "@types/express": "^4.17.6", + "express": "^4.17.1", + "express-promise-router": "^4.1.0", "winston": "^3.2.1" }, "devDependencies": { "@backstage/backend-common": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", - "@backstage/plugin-events-backend-test-utils": "workspace:^" + "@backstage/plugin-events-backend-test-utils": "workspace:^", + "supertest": "^6.1.3" }, "files": [ "alpha", + "config.d.ts", "dist" - ] + ], + "configSchema": "config.d.ts" } diff --git a/plugins/events-backend/src/index.ts b/plugins/events-backend/src/index.ts index 121d9cdc46..5026729015 100644 --- a/plugins/events-backend/src/index.ts +++ b/plugins/events-backend/src/index.ts @@ -22,3 +22,4 @@ export { EventsBackend } from './service/EventsBackend'; export { eventsPlugin } from './service/EventsPlugin'; +export { HttpPostIngressEventPublisher } from './service/http'; diff --git a/plugins/events-backend/src/service/EventsPlugin.test.ts b/plugins/events-backend/src/service/EventsPlugin.test.ts index e6c7c75264..f58f081742 100644 --- a/plugins/events-backend/src/service/EventsPlugin.test.ts +++ b/plugins/events-backend/src/service/EventsPlugin.test.ts @@ -14,9 +14,12 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; +import { errorHandler, getVoidLogger } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; import { + configServiceRef, createBackendModule, + httpRouterServiceRef, loggerServiceRef, } from '@backstage/backend-plugin-api'; import { startTestBackend } from '@backstage/backend-test-utils'; @@ -26,13 +29,29 @@ import { TestEventPublisher, TestEventSubscriber, } from '@backstage/plugin-events-backend-test-utils'; +import express from 'express'; +import Router from 'express-promise-router'; +import request from 'supertest'; import { eventsPlugin } from './EventsPlugin'; describe('eventPlugin', () => { it('should be initialized properly', async () => { const eventBroker = new TestEventBroker(); const publisher = new TestEventPublisher(); - const subscriber = new TestEventSubscriber('sub', ['topicA']); + const subscriber = new TestEventSubscriber('sub', ['fake']); + + const config = new ConfigReader({ + events: { + http: { + topics: ['fake'], + }, + }, + }); + + const httpRouter = Router(); + httpRouter.use(express.json()); + httpRouter.use(errorHandler()); + const app = express().use(httpRouter); const testModule = createBackendModule({ pluginId: 'events', @@ -53,12 +72,26 @@ describe('eventPlugin', () => { await startTestBackend({ extensionPoints: [], - services: [[loggerServiceRef, getVoidLogger()]], + services: [ + [configServiceRef, config], + [httpRouterServiceRef, httpRouter], + [loggerServiceRef, getVoidLogger()], + ], features: [eventsPlugin(), testModule()], }); expect(publisher.eventBroker).toBe(eventBroker); expect(eventBroker.subscribed.length).toEqual(1); expect(eventBroker.subscribed[0]).toBe(subscriber); + + const response = await request(app) + .post('/http/fake') + .timeout(100) + .send({ test: 'fake' }); + expect(response.status).toBe(202); + + expect(eventBroker.published.length).toEqual(1); + expect(eventBroker.published[0].topic).toEqual('fake'); + expect(eventBroker.published[0].eventPayload).toEqual({ test: 'fake' }); }); }); diff --git a/plugins/events-backend/src/service/EventsPlugin.ts b/plugins/events-backend/src/service/EventsPlugin.ts index d2cac331f9..d5a38a7fd7 100644 --- a/plugins/events-backend/src/service/EventsPlugin.ts +++ b/plugins/events-backend/src/service/EventsPlugin.ts @@ -15,7 +15,9 @@ */ import { + configServiceRef, createBackendPlugin, + httpRouterServiceRef, loggerServiceRef, loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; @@ -25,11 +27,15 @@ import { EventSubscriber, eventsExtensionPoint, EventsExtensionPoint, + HttpPostIngressOptions, } from '@backstage/plugin-events-node'; import { InMemoryEventBroker } from './InMemoryEventBroker'; +import Router from 'express-promise-router'; +import { HttpPostIngressEventPublisher } from './http'; class EventsExtensionPointImpl implements EventsExtensionPoint { #eventBroker: EventBroker | undefined; + #httpPostIngresses: HttpPostIngressOptions[] = []; #publishers: EventPublisher[] = []; #subscribers: EventSubscriber[] = []; @@ -49,6 +55,10 @@ class EventsExtensionPointImpl implements EventsExtensionPoint { this.#subscribers.push(...subscribers.flat()); } + addHttpPostIngress(options: HttpPostIngressOptions) { + this.#httpPostIngresses.push(options); + } + get eventBroker() { return this.#eventBroker; } @@ -60,6 +70,10 @@ class EventsExtensionPointImpl implements EventsExtensionPoint { get subscribers() { return this.#subscribers; } + + get httpPostIngresses() { + return this.#httpPostIngresses; + } } /** @@ -75,18 +89,42 @@ export const eventsPlugin = createBackendPlugin({ env.registerInit({ deps: { + config: configServiceRef, + httpRouter: httpRouterServiceRef, logger: loggerServiceRef, }, - async init({ logger }) { + async init({ config, httpRouter, logger }) { + const winstonLogger = loggerToWinstonLogger(logger); + const eventsRouter = Router(); + const router = Router(); + eventsRouter.use('/http', router); + + const ingresses = Object.fromEntries( + extensionPoint.httpPostIngresses.map(ingress => [ + ingress.topic, + ingress as Omit, + ]), + ); + + const http = HttpPostIngressEventPublisher.fromConfig({ + config, + logger: winstonLogger, + router, + ingresses, + }); + if (!extensionPoint.eventBroker) { - const winstonLogger = loggerToWinstonLogger(logger); extensionPoint.setEventBroker(new InMemoryEventBroker(winstonLogger)); } extensionPoint.eventBroker!.subscribe(extensionPoint.subscribers); - extensionPoint.publishers.forEach(publisher => - publisher.setEventBroker(extensionPoint.eventBroker!), - ); + [extensionPoint.publishers, http] + .flat() + .forEach(publisher => + publisher.setEventBroker(extensionPoint.eventBroker!), + ); + + httpRouter.use(eventsRouter); }, }); }, diff --git a/plugins/events-backend/src/service/http/HttpPostIngressEventPublisher.test.ts b/plugins/events-backend/src/service/http/HttpPostIngressEventPublisher.test.ts new file mode 100644 index 0000000000..3d93e347b3 --- /dev/null +++ b/plugins/events-backend/src/service/http/HttpPostIngressEventPublisher.test.ts @@ -0,0 +1,225 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { errorHandler, getVoidLogger } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils'; +import express from 'express'; +import Router from 'express-promise-router'; +import request from 'supertest'; +import { HttpPostIngressEventPublisher } from './HttpPostIngressEventPublisher'; + +describe('HttpPostIngressEventPublisher', () => { + const logger = getVoidLogger(); + + it('should set up routes correctly', async () => { + const config = new ConfigReader({ + events: { + http: { + topics: ['testA'], + }, + }, + }); + + const router = Router(); + router.use(express.json()); + router.use(errorHandler()); + const app = express().use(router); + + const publisher = HttpPostIngressEventPublisher.fromConfig({ + config, + logger, + router, + ingresses: { + testB: {}, + }, + }); + + const eventBroker = new TestEventBroker(); + await publisher.setEventBroker(eventBroker); + + const notFoundResponse = await request(app) + .post('/unknown') + .timeout(100) + .send({ test: 'data' }); + expect(notFoundResponse.status).toBe(404); + + const response1 = await request(app) + .post('/testA') + .set('X-Custom-Header', 'test-value') + .timeout(100) + .send({ testA: 'data' }); + expect(response1.status).toBe(202); + + const response2 = await request(app) + .post('/testB') + .set('X-Custom-Header', 'test-value') + .timeout(100) + .send({ testB: 'data' }); + expect(response2.status).toBe(202); + + expect(eventBroker.published.length).toEqual(2); + expect(eventBroker.published[0].topic).toEqual('testA'); + expect(eventBroker.published[0].eventPayload).toEqual({ testA: 'data' }); + expect(eventBroker.published[0].metadata).toEqual( + expect.objectContaining({ + 'content-type': 'application/json', + 'x-custom-header': 'test-value', + }), + ); + expect(eventBroker.published[1].topic).toEqual('testB'); + expect(eventBroker.published[1].eventPayload).toEqual({ testB: 'data' }); + expect(eventBroker.published[1].metadata).toEqual( + expect.objectContaining({ + 'content-type': 'application/json', + 'x-custom-header': 'test-value', + }), + ); + }); + + it('with validator', async () => { + const config = new ConfigReader({ + events: { + http: { + topics: ['testA'], + }, + }, + }); + + const router = Router(); + router.use(express.json()); + router.use(errorHandler()); + const app = express().use(router); + + const publisher = HttpPostIngressEventPublisher.fromConfig({ + config, + logger, + router, + ingresses: { + testB: { + validator: async (req, context) => { + if (req.headers['x-test-signature'] === 'testB-signature') { + return; + } + + context.reject({ + status: 400, + payload: { + message: 'wrong signature', + }, + }); + }, + }, + testC: { + validator: async (req, context) => { + if (req.headers['x-test-signature'] === 'testC-signature') { + return; + } + + context.reject({ + status: 404, + // payload: {}, + }); + }, + }, + testD: { + validator: async (req, context) => { + if (req.headers['x-test-signature'] === 'testD-signature') { + return; + } + + context.reject({ + // status: 403, + // payload: {}, + }); + }, + }, + }, + }); + + const eventBroker = new TestEventBroker(); + await publisher.setEventBroker(eventBroker); + + const response1 = await request(app) + .post('/testA') + .timeout(100) + .send({ test: 'data' }); + expect(response1.status).toBe(202); + + const response2 = await request(app) + .post('/testB') + .timeout(100) + .send({ test: 'data' }); + expect(response2.status).toBe(400); + expect(response2.body).toEqual({ message: 'wrong signature' }); + + const response3 = await request(app) + .post('/testB') + .set('X-Test-Signature', 'wrong') + .timeout(100) + .send({ test: 'data' }); + expect(response3.status).toBe(400); + expect(response3.body).toEqual({ message: 'wrong signature' }); + + const response4 = await request(app) + .post('/testB') + .set('X-Test-Signature', 'testB-signature') + .timeout(100) + .send({ test: 'data' }); + expect(response4.status).toBe(202); + + const response5 = await request(app) + .post('/testC') + .timeout(100) + .send({ test: 'data' }); + expect(response5.status).toBe(404); + expect(response5.body).toEqual({}); + + const response6 = await request(app) + .post('/testD') + .timeout(100) + .send({ test: 'data' }); + expect(response6.status).toBe(403); + expect(response6.body).toEqual({}); + + expect(eventBroker.published.length).toEqual(2); + expect(eventBroker.published[0].topic).toEqual('testA'); + expect(eventBroker.published[0].eventPayload).toEqual({ test: 'data' }); + expect(eventBroker.published[1].topic).toEqual('testB'); + expect(eventBroker.published[1].eventPayload).toEqual({ test: 'data' }); + expect(eventBroker.published[1].metadata).toEqual( + expect.objectContaining({ + 'x-test-signature': 'testB-signature', + }), + ); + }); + + it('without configuration', async () => { + const config = new ConfigReader({}); + + const router = Router(); + router.use(express.json()); + router.use(errorHandler()); + + expect(() => + HttpPostIngressEventPublisher.fromConfig({ + config, + logger, + router, + }), + ).not.toThrow(); + }); +}); diff --git a/plugins/events-backend/src/service/http/HttpPostIngressEventPublisher.ts b/plugins/events-backend/src/service/http/HttpPostIngressEventPublisher.ts new file mode 100644 index 0000000000..64b7140b54 --- /dev/null +++ b/plugins/events-backend/src/service/http/HttpPostIngressEventPublisher.ts @@ -0,0 +1,118 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { errorHandler } from '@backstage/backend-common'; +import { Config } from '@backstage/config'; +import { + EventBroker, + EventPublisher, + HttpPostIngressOptions, + RequestValidator, +} from '@backstage/plugin-events-node'; +import express from 'express'; +import Router from 'express-promise-router'; +import { Logger } from 'winston'; +import { RequestValidationContextImpl } from './validation'; + +/** + * Publishes events received from their origin (e.g., webhook events from an SCM system) + * via HTTP POST endpoint and passes the request body as event payload to the registered subscribers. + * + * @public + */ +// TODO(pjungermann): add prom metrics? (see plugins/catalog-backend/src/util/metrics.ts, etc.) +export class HttpPostIngressEventPublisher implements EventPublisher { + private eventBroker?: EventBroker; + + static fromConfig(env: { + config: Config; + ingresses?: { [topic: string]: Omit }; + logger: Logger; + router: express.Router; + }): HttpPostIngressEventPublisher { + const topics = + env.config.getOptionalStringArray('events.http.topics') ?? []; + + const ingresses = env.ingresses ?? {}; + topics.forEach(topic => { + // don't overwrite topic settings + // (e.g., added at the config as well as argument) + if (!ingresses[topic]) { + ingresses[topic] = {}; + } + }); + + return new HttpPostIngressEventPublisher(env.logger, env.router, ingresses); + } + + private constructor( + private logger: Logger, + router: express.Router, + ingresses: { [topic: string]: Omit }, + ) { + router.use(this.createRouter(ingresses)); + } + + async setEventBroker(eventBroker: EventBroker): Promise { + this.eventBroker = eventBroker; + } + + private createRouter(ingresses: { + [topic: string]: Omit; + }): express.Router { + const router = Router(); + router.use(express.json()); + + Object.keys(ingresses).forEach(topic => + this.addRouteForTopic(router, topic, ingresses[topic].validator), + ); + + router.use(errorHandler()); + return router; + } + + private addRouteForTopic( + router: express.Router, + topic: string, + validator?: RequestValidator, + ): void { + const path = `/${topic}`; + + router.post(path, async (request, response) => { + const context = new RequestValidationContextImpl(); + await validator?.(request, context); + if (context.wasRejected()) { + response + .status(context.rejectionDetails!.status) + .json(context.rejectionDetails!.payload); + return; + } + + const eventPayload = request.body; + await this.eventBroker!.publish({ + topic, + eventPayload, + metadata: request.headers, + }); + + response.status(202).json({ status: 'accepted' }); + }); + + // TODO(pjungermann): We don't really know the externally defined path prefix here, + // however it is more useful for users to have it. Is there a better way? + this.logger.info(`Registered /api/events/http${path} to receive events`); + } +} diff --git a/plugins/events-backend/src/service/http/index.ts b/plugins/events-backend/src/service/http/index.ts new file mode 100644 index 0000000000..fe71e49dfa --- /dev/null +++ b/plugins/events-backend/src/service/http/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2020 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 { HttpPostIngressEventPublisher } from './HttpPostIngressEventPublisher'; +export * from './validation'; diff --git a/plugins/events-backend/src/service/http/validation/RequestValidationContextImpl.test.ts b/plugins/events-backend/src/service/http/validation/RequestValidationContextImpl.test.ts new file mode 100644 index 0000000000..b2f1485f65 --- /dev/null +++ b/plugins/events-backend/src/service/http/validation/RequestValidationContextImpl.test.ts @@ -0,0 +1,64 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { RequestValidationContextImpl } from './RequestValidationContextImpl'; + +describe('RequestValidationContextImpl', () => { + it('not rejected', () => { + const context = new RequestValidationContextImpl(); + + expect(context.wasRejected()).toBe(false); + expect(context.rejectionDetails).toBeUndefined(); + }); + + it('reject without details', () => { + const context = new RequestValidationContextImpl(); + + context.reject(); + + expect(context.wasRejected()).toBe(true); + expect(context.rejectionDetails).not.toBeUndefined(); + expect(context.rejectionDetails!.status).toBe(403); + expect(context.rejectionDetails!.payload).toEqual({}); + }); + + it('reject with partial details', () => { + const context = new RequestValidationContextImpl(); + + context.reject({ status: 404 }); + + expect(context.wasRejected()).toBe(true); + expect(context.rejectionDetails).not.toBeUndefined(); + expect(context.rejectionDetails!.status).toBe(404); + expect(context.rejectionDetails!.payload).toEqual({}); + }); + + it('reject with details', () => { + const context = new RequestValidationContextImpl(); + + context.reject({ + status: 403, + payload: { message: 'invalid signature' }, + }); + + expect(context.wasRejected()).toBe(true); + expect(context.rejectionDetails).not.toBeUndefined(); + expect(context.rejectionDetails!.status).toBe(403); + expect(context.rejectionDetails!.payload).toEqual({ + message: 'invalid signature', + }); + }); +}); diff --git a/plugins/events-backend/src/service/http/validation/RequestValidationContextImpl.ts b/plugins/events-backend/src/service/http/validation/RequestValidationContextImpl.ts new file mode 100644 index 0000000000..3dc607a683 --- /dev/null +++ b/plugins/events-backend/src/service/http/validation/RequestValidationContextImpl.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + RequestRejectionDetails, + RequestValidationContext, +} from '@backstage/plugin-events-node'; + +export class RequestValidationContextImpl implements RequestValidationContext { + #rejectionDetails: RequestRejectionDetails | undefined; + + reject(details?: Partial): void { + this.#rejectionDetails = { + status: details?.status ?? 403, + payload: details?.payload ?? {}, + }; + } + + wasRejected(): boolean { + return this.#rejectionDetails !== undefined; + } + + get rejectionDetails() { + return this.#rejectionDetails; + } +} diff --git a/plugins/events-backend/src/service/http/validation/index.ts b/plugins/events-backend/src/service/http/validation/index.ts new file mode 100644 index 0000000000..7513014906 --- /dev/null +++ b/plugins/events-backend/src/service/http/validation/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 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 { RequestValidationContextImpl } from './RequestValidationContextImpl'; diff --git a/plugins/events-node/api-report.md b/plugins/events-node/api-report.md index e0b34aa204..1054211cbc 100644 --- a/plugins/events-node/api-report.md +++ b/plugins/events-node/api-report.md @@ -4,6 +4,7 @@ ```ts import { ExtensionPoint } from '@backstage/backend-plugin-api'; +import { Request as Request_2 } from 'express'; // @public export interface EventBroker { @@ -42,6 +43,8 @@ export abstract class EventRouter implements EventPublisher, EventSubscriber { // @alpha (undocumented) export interface EventsExtensionPoint { + // (undocumented) + addHttpPostIngress(options: HttpPostIngressOptions): void; // (undocumented) addPublishers( ...publishers: Array> @@ -63,6 +66,33 @@ export interface EventSubscriber { supportsEventTopics(): string[]; } +// @public (undocumented) +export interface HttpPostIngressOptions { + // (undocumented) + topic: string; + // (undocumented) + validator?: RequestValidator; +} + +// @public +export interface RequestRejectionDetails { + // (undocumented) + payload: unknown; + // (undocumented) + status: number; +} + +// @public +export interface RequestValidationContext { + reject(details?: Partial): void; +} + +// @public +export type RequestValidator = ( + request: Request_2, + context: RequestValidationContext, +) => Promise; + // @public export abstract class SubTopicEventRouter extends EventRouter { protected constructor(topic: string); diff --git a/plugins/events-node/src/api/http/HttpPostIngressOptions.ts b/plugins/events-node/src/api/http/HttpPostIngressOptions.ts new file mode 100644 index 0000000000..d9f005d84d --- /dev/null +++ b/plugins/events-node/src/api/http/HttpPostIngressOptions.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { RequestValidator } from './validation'; + +/** + * @public + */ +export interface HttpPostIngressOptions { + topic: string; + validator?: RequestValidator; +} diff --git a/plugins/events-node/src/api/http/index.ts b/plugins/events-node/src/api/http/index.ts new file mode 100644 index 0000000000..9206819a4a --- /dev/null +++ b/plugins/events-node/src/api/http/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export type { HttpPostIngressOptions } from './HttpPostIngressOptions'; +export * from './validation'; diff --git a/plugins/events-node/src/api/http/validation/RequestRejectionDetails.ts b/plugins/events-node/src/api/http/validation/RequestRejectionDetails.ts new file mode 100644 index 0000000000..1eca094367 --- /dev/null +++ b/plugins/events-node/src/api/http/validation/RequestRejectionDetails.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Details for how to respond to the rejection + * of the received HTTP request transmitting an event payload. + * + * @public + */ +export interface RequestRejectionDetails { + status: number; + payload: unknown; +} diff --git a/plugins/events-node/src/api/http/validation/RequestValidationContext.ts b/plugins/events-node/src/api/http/validation/RequestValidationContext.ts new file mode 100644 index 0000000000..eedb6f1f96 --- /dev/null +++ b/plugins/events-node/src/api/http/validation/RequestValidationContext.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { RequestRejectionDetails } from './RequestRejectionDetails'; + +/** + * Passed context for the validation + * at which rejections can be expressed. + * + * @public + */ +export interface RequestValidationContext { + /** + * Rejects the validated request + * + * @param details - Optional details about the rejection which will be provided to the sender. + */ + reject(details?: Partial): void; +} diff --git a/plugins/events-node/src/api/http/validation/RequestValidator.ts b/plugins/events-node/src/api/http/validation/RequestValidator.ts new file mode 100644 index 0000000000..b419b855cf --- /dev/null +++ b/plugins/events-node/src/api/http/validation/RequestValidator.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Request } from 'express'; +import { RequestValidationContext } from './RequestValidationContext'; + +/** + * Validator used to check the received HTTP request + * transmitting an event payload. + * + * E.g., it can be used for signature verification like + * for GitHub webhook events + * (https://docs.github.com/en/developers/webhooks-and-events/webhooks/creating-webhooks#secret) + * or other kinds of checks. + * + * @public + */ +export type RequestValidator = ( + request: Request, + context: RequestValidationContext, +) => Promise; diff --git a/plugins/events-node/src/api/http/validation/index.ts b/plugins/events-node/src/api/http/validation/index.ts new file mode 100644 index 0000000000..95f2d474eb --- /dev/null +++ b/plugins/events-node/src/api/http/validation/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export type { RequestRejectionDetails } from './RequestRejectionDetails'; +export type { RequestValidationContext } from './RequestValidationContext'; +export type { RequestValidator } from './RequestValidator'; diff --git a/plugins/events-node/src/api/index.ts b/plugins/events-node/src/api/index.ts index 22b51c191d..91711c0e38 100644 --- a/plugins/events-node/src/api/index.ts +++ b/plugins/events-node/src/api/index.ts @@ -19,4 +19,5 @@ export type { EventParams } from './EventParams'; export type { EventPublisher } from './EventPublisher'; export { EventRouter } from './EventRouter'; export type { EventSubscriber } from './EventSubscriber'; +export * from './http'; export { SubTopicEventRouter } from './SubTopicEventRouter'; diff --git a/plugins/events-node/src/extensions.ts b/plugins/events-node/src/extensions.ts index f935e85be8..945d86b49c 100644 --- a/plugins/events-node/src/extensions.ts +++ b/plugins/events-node/src/extensions.ts @@ -15,7 +15,12 @@ */ import { createExtensionPoint } from '@backstage/backend-plugin-api'; -import { EventBroker, EventPublisher, EventSubscriber } from './api'; +import { + EventBroker, + EventPublisher, + EventSubscriber, + HttpPostIngressOptions, +} from './api'; /** * @alpha @@ -30,6 +35,8 @@ export interface EventsExtensionPoint { addSubscribers( ...subscribers: Array> ): void; + + addHttpPostIngress(options: HttpPostIngressOptions): void; } /** diff --git a/yarn.lock b/yarn.lock index c96addfbcc..198ab4acb7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5549,8 +5549,13 @@ __metadata: "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" "@backstage/plugin-events-backend-test-utils": "workspace:^" "@backstage/plugin-events-node": "workspace:^" + "@types/express": ^4.17.6 + express: ^4.17.1 + express-promise-router: ^4.1.0 + supertest: ^6.1.3 winston: ^3.2.1 languageName: unknown linkType: soft From e703ad022cc4fc9eef23639830bea07cdf46c7c0 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Tue, 4 Oct 2022 16:44:17 +0200 Subject: [PATCH 306/434] feat(events,example): integrate at example backend Integrate plugins-events-backend with plugins-events-backend-module-http at the example backend. Relates-to: #11082 Signed-off-by: Patrick Jungermann --- packages/backend/package.json | 2 ++ packages/backend/src/index.ts | 3 ++ packages/backend/src/plugins/events.ts | 45 ++++++++++++++++++++++++++ yarn.lock | 4 ++- 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 packages/backend/src/plugins/events.ts diff --git a/packages/backend/package.json b/packages/backend/package.json index 260af8c137..083779951f 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -40,6 +40,8 @@ "@backstage/plugin-badges-backend": "workspace:^", "@backstage/plugin-catalog-backend": "workspace:^", "@backstage/plugin-code-coverage-backend": "workspace:^", + "@backstage/plugin-events-backend": "workspace:^", + "@backstage/plugin-events-node": "workspace:^", "@backstage/plugin-graphql-backend": "workspace:^", "@backstage/plugin-jenkins-backend": "workspace:^", "@backstage/plugin-kafka-backend": "workspace:^", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index cb9c9bf580..856b7e8595 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -43,6 +43,7 @@ import auth from './plugins/auth'; import azureDevOps from './plugins/azure-devops'; import catalog from './plugins/catalog'; import codeCoverage from './plugins/codecoverage'; +import events from './plugins/events'; import kubernetes from './plugins/kubernetes'; import kafka from './plugins/kafka'; import rollbar from './plugins/rollbar'; @@ -141,10 +142,12 @@ async function main() { ); const permissionEnv = useHotMemoize(module, () => createEnv('permission')); const playlistEnv = useHotMemoize(module, () => createEnv('playlist')); + const eventsEnv = useHotMemoize(module, () => createEnv('events')); const apiRouter = Router(); apiRouter.use('/catalog', await catalog(catalogEnv)); apiRouter.use('/code-coverage', await codeCoverage(codeCoverageEnv)); + apiRouter.use('/events', await events(eventsEnv, [])); apiRouter.use('/rollbar', await rollbar(rollbarEnv)); apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv)); apiRouter.use('/tech-insights', await techInsights(techInsightsEnv)); diff --git a/packages/backend/src/plugins/events.ts b/packages/backend/src/plugins/events.ts new file mode 100644 index 0000000000..2ada92a5b6 --- /dev/null +++ b/packages/backend/src/plugins/events.ts @@ -0,0 +1,45 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + EventsBackend, + HttpPostIngressEventPublisher, +} from '@backstage/plugin-events-backend'; +import { EventSubscriber } from '@backstage/plugin-events-node'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin( + env: PluginEnvironment, + subscribers: EventSubscriber[], +): Promise { + const eventsRouter = Router(); + const httpRouter = Router(); + eventsRouter.use('/http', httpRouter); + + const http = HttpPostIngressEventPublisher.fromConfig({ + config: env.config, + logger: env.logger, + router: httpRouter, + }); + + await new EventsBackend(env.logger) + .addPublishers(http) + .addSubscribers(subscribers) + .start(); + + return eventsRouter; +} diff --git a/yarn.lock b/yarn.lock index 198ab4acb7..d5c72dbb57 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5541,7 +5541,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-events-backend@workspace:plugins/events-backend": +"@backstage/plugin-events-backend@workspace:^, @backstage/plugin-events-backend@workspace:plugins/events-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-events-backend@workspace:plugins/events-backend" dependencies: @@ -22341,6 +22341,8 @@ __metadata: "@backstage/plugin-badges-backend": "workspace:^" "@backstage/plugin-catalog-backend": "workspace:^" "@backstage/plugin-code-coverage-backend": "workspace:^" + "@backstage/plugin-events-backend": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" "@backstage/plugin-graphql-backend": "workspace:^" "@backstage/plugin-jenkins-backend": "workspace:^" "@backstage/plugin-kafka-backend": "workspace:^" From 53bfad8576c9f626a1fdf4ba1158180642b3b6c1 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Thu, 6 Oct 2022 00:24:20 +0200 Subject: [PATCH 307/434] feat(events,example): add simple way to add event-based entity providers Add `DemoEventBasedEntityProvider` as example implementation. Signed-off-by: Patrick Jungermann --- packages/backend/package.json | 1 + packages/backend/src/index.ts | 12 +++- packages/backend/src/plugins/catalog.ts | 3 + .../src/plugins/catalogEventBasedProviders.ts | 61 +++++++++++++++++++ yarn.lock | 1 + 5 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 packages/backend/src/plugins/catalogEventBasedProviders.ts diff --git a/packages/backend/package.json b/packages/backend/package.json index 083779951f..3285e309e1 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -39,6 +39,7 @@ "@backstage/plugin-azure-sites-backend": "workspace:^", "@backstage/plugin-badges-backend": "workspace:^", "@backstage/plugin-catalog-backend": "workspace:^", + "@backstage/plugin-catalog-node": "workspace:^", "@backstage/plugin-code-coverage-backend": "workspace:^", "@backstage/plugin-events-backend": "workspace:^", "@backstage/plugin-events-node": "workspace:^", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 856b7e8595..bacae07917 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -42,6 +42,7 @@ import { metricsInit, metricsHandler } from './metrics'; import auth from './plugins/auth'; import azureDevOps from './plugins/azure-devops'; import catalog from './plugins/catalog'; +import catalogEventBasedProviders from './plugins/catalogEventBasedProviders'; import codeCoverage from './plugins/codecoverage'; import events from './plugins/events'; import kubernetes from './plugins/kubernetes'; @@ -144,10 +145,17 @@ async function main() { const playlistEnv = useHotMemoize(module, () => createEnv('playlist')); const eventsEnv = useHotMemoize(module, () => createEnv('events')); + const eventBasedEntityProviders = await catalogEventBasedProviders( + catalogEnv, + ); + const apiRouter = Router(); - apiRouter.use('/catalog', await catalog(catalogEnv)); + apiRouter.use( + '/catalog', + await catalog(catalogEnv, eventBasedEntityProviders), + ); apiRouter.use('/code-coverage', await codeCoverage(codeCoverageEnv)); - apiRouter.use('/events', await events(eventsEnv, [])); + apiRouter.use('/events', await events(eventsEnv, eventBasedEntityProviders)); apiRouter.use('/rollbar', await rollbar(rollbarEnv)); apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv)); apiRouter.use('/tech-insights', await techInsights(techInsightsEnv)); diff --git a/packages/backend/src/plugins/catalog.ts b/packages/backend/src/plugins/catalog.ts index 7beeb4f35e..f6fe25f86a 100644 --- a/packages/backend/src/plugins/catalog.ts +++ b/packages/backend/src/plugins/catalog.ts @@ -15,15 +15,18 @@ */ import { CatalogBuilder } from '@backstage/plugin-catalog-backend'; +import { EntityProvider } from '@backstage/plugin-catalog-node'; import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; export default async function createPlugin( env: PluginEnvironment, + providers?: Array, ): Promise { const builder = await CatalogBuilder.create(env); builder.addProcessor(new ScaffolderEntitiesProcessor()); + builder.addEntityProvider(providers ?? []); const { processingEngine, router } = await builder.build(); await processingEngine.start(); return router; diff --git a/packages/backend/src/plugins/catalogEventBasedProviders.ts b/packages/backend/src/plugins/catalogEventBasedProviders.ts new file mode 100644 index 0000000000..346ed40fa6 --- /dev/null +++ b/packages/backend/src/plugins/catalogEventBasedProviders.ts @@ -0,0 +1,61 @@ +/* + * Copyright 2020 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 { + EntityProvider, + EntityProviderConnection, +} from '@backstage/plugin-catalog-node'; +import { EventParams, EventSubscriber } from '@backstage/plugin-events-node'; +import { Logger } from 'winston'; +import { PluginEnvironment } from '../types'; + +class DemoEventBasedEntityProvider implements EntityProvider, EventSubscriber { + constructor( + private readonly logger: Logger, + private readonly topics: string[], + ) {} + + async onEvent(params: EventParams): Promise { + this.logger.info( + `onEvent: topic=${params.topic}, metadata=${JSON.stringify( + params.metadata, + )}, payload=${JSON.stringify(params.eventPayload)}`, + ); + } + + supportsEventTopics(): string[] { + return this.topics; + } + + async connect(_: EntityProviderConnection): Promise { + // not doing anything here + } + + getProviderName(): string { + return DemoEventBasedEntityProvider.name; + } +} + +export default async function createCatalogEventBasedProviders( + env: PluginEnvironment, +): Promise> { + const providers: Array< + (EntityProvider & EventSubscriber) | Array + > = []; + providers.push(new DemoEventBasedEntityProvider(env.logger, ['example'])); + // add your event-based entity providers here + return providers.flat(); +} diff --git a/yarn.lock b/yarn.lock index d5c72dbb57..535a0c483e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22340,6 +22340,7 @@ __metadata: "@backstage/plugin-azure-sites-backend": "workspace:^" "@backstage/plugin-badges-backend": "workspace:^" "@backstage/plugin-catalog-backend": "workspace:^" + "@backstage/plugin-catalog-node": "workspace:^" "@backstage/plugin-code-coverage-backend": "workspace:^" "@backstage/plugin-events-backend": "workspace:^" "@backstage/plugin-events-node": "workspace:^" From d3ecb2382debcfe384d958abfcdf929e00e8eb37 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Tue, 4 Oct 2022 16:50:24 +0200 Subject: [PATCH 308/434] feat(events/sqs): add a new AWS SQS event publisher This change introduces a new plugin `@backstage/plugin-events-backend-module-aws-sqs`. This plugin provides an event publisher which receives events from (an) AWS SQS queue(s) and publishes them to the event broker. The plugin supports the new backend-plugin-api and connects with the other plugins. Signed-off-by: Patrick Jungermann --- .changeset/modern-toys-yell.md | 12 + .github/CODEOWNERS | 1 + .../.eslintrc.js | 1 + .../events-backend-module-aws-sqs/README.md | 42 + .../api-report.md | 29 + .../events-backend-module-aws-sqs/config.d.ts | 78 ++ .../package.json | 48 + .../src/index.ts | 27 + .../AwsSqsConsumingEventPublisher.test.ts | 227 +++++ .../AwsSqsConsumingEventPublisher.ts | 191 ++++ .../src/publisher/config.test.ts | 222 +++++ .../src/publisher/config.ts | 117 +++ ...onsumingEventPublisherEventsModule.test.ts | 94 ++ ...sSqsConsumingEventPublisherEventsModule.ts | 55 ++ .../src/setupTests.ts | 17 + yarn.lock | 883 +++++++++++++++++- 16 files changed, 2041 insertions(+), 3 deletions(-) create mode 100644 .changeset/modern-toys-yell.md create mode 100644 plugins/events-backend-module-aws-sqs/.eslintrc.js create mode 100644 plugins/events-backend-module-aws-sqs/README.md create mode 100644 plugins/events-backend-module-aws-sqs/api-report.md create mode 100644 plugins/events-backend-module-aws-sqs/config.d.ts create mode 100644 plugins/events-backend-module-aws-sqs/package.json create mode 100644 plugins/events-backend-module-aws-sqs/src/index.ts create mode 100644 plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.test.ts create mode 100644 plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.ts create mode 100644 plugins/events-backend-module-aws-sqs/src/publisher/config.test.ts create mode 100644 plugins/events-backend-module-aws-sqs/src/publisher/config.ts create mode 100644 plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.test.ts create mode 100644 plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.ts create mode 100644 plugins/events-backend-module-aws-sqs/src/setupTests.ts diff --git a/.changeset/modern-toys-yell.md b/.changeset/modern-toys-yell.md new file mode 100644 index 0000000000..d867d2b3af --- /dev/null +++ b/.changeset/modern-toys-yell.md @@ -0,0 +1,12 @@ +--- +'@backstage/plugin-events-backend-module-aws-sqs': minor +--- + +Adds a new module `aws-sqs` for plugin-events-backend. + +The module provides an event publisher `AwsSqsConsumingEventPublisher` +which will allow you to receive events from +an AWS SQS queue and will publish these to the used event broker. + +Please find more information at +https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index dea361606a..84c8cd22d2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -37,6 +37,7 @@ yarn.lock @backstage/reviewers @backst /plugins/cost-insights @backstage/reviewers @backstage/silver-lining /plugins/cost-insights-* @backstage/reviewers @backstage/silver-lining /plugins/events-backend @backstage/reviewers @pjungermann +/plugins/events-backend-module-aws-sqs @backstage/reviewers @pjungermann /plugins/events-backend-test-utils @backstage/reviewers @pjungermann /plugins/events-node @backstage/reviewers @pjungermann /plugins/explore @backstage/reviewers @backstage/sda-se-reviewers diff --git a/plugins/events-backend-module-aws-sqs/.eslintrc.js b/plugins/events-backend-module-aws-sqs/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/events-backend-module-aws-sqs/README.md b/plugins/events-backend-module-aws-sqs/README.md new file mode 100644 index 0000000000..cb3a5045c0 --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/README.md @@ -0,0 +1,42 @@ +# events-backend-module-aws-sqs + +Welcome to the `events-backend-module-aws-sqs` backend plugin! + +This plugin is a module for the `events-backend` backend plugin +and extends it with an `AwsSqsConsumingEventPublisher`. + +This event publisher will allow you to receive events from +an AWS SQS queue and will publish these to the used event broker. + +## Configuration + +The polled AWS SQS queues depend on your configuration: + +```yaml +events: + modules: + awsSqs: + awsSqsConsumingEventPublisher: + topics: + topicName1: # replace with actual topic name as expected by subscribers + queue: + url: 'https://sqs.us-east-2.amazonaws.com/123456789012/MyQueue' + region: us-east-2 + # visibilityTimeout - as HumanDuration; defaults to queue-based config + # waitTime - as HumanDuration; defaults to max of 20 seconds (long polling) + # timeout - as HumanDuration; timeout for the task execution + # waitTimeAfterEmptyReceive - as HumanDuration; time to wait before a retry when there was no message. + topicName2: + # [...] +``` + +## Installation + +1. Install the [`events-backend` plugin](../events-backend/README.md). +2. Install this module +3. Add your configuration. + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-events-backend-module-aws-sqs +``` diff --git a/plugins/events-backend-module-aws-sqs/api-report.md b/plugins/events-backend-module-aws-sqs/api-report.md new file mode 100644 index 0000000000..79a422c9f3 --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/api-report.md @@ -0,0 +1,29 @@ +## API Report File for "@backstage/plugin-events-backend-module-aws-sqs" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { Config } from '@backstage/config'; +import { EventBroker } from '@backstage/plugin-events-node'; +import { EventPublisher } from '@backstage/plugin-events-node'; +import { Logger } from 'winston'; +import { PluginTaskScheduler } from '@backstage/backend-tasks'; + +// @public +export class AwsSqsConsumingEventPublisher implements EventPublisher { + // (undocumented) + static fromConfig(env: { + config: Config; + logger: Logger; + scheduler: PluginTaskScheduler; + }): AwsSqsConsumingEventPublisher[]; + // (undocumented) + setEventBroker(eventBroker: EventBroker): Promise; +} + +// @alpha +export const awsSqsConsumingEventPublisherEventsModule: ( + options?: undefined, +) => BackendFeature; +``` diff --git a/plugins/events-backend-module-aws-sqs/config.d.ts b/plugins/events-backend-module-aws-sqs/config.d.ts new file mode 100644 index 0000000000..dfef35bf22 --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/config.d.ts @@ -0,0 +1,78 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { HumanDuration } from '@backstage/types'; + +export interface Config { + events?: { + modules?: { + /** + * events-backend-module-aws-sqs plugin configuration. + */ + awsSqs?: { + /** + * Configuration for AwsSqsConsumingEventPublisher. + */ + awsSqsConsumingEventPublisher?: { + /** + * Contains a record per topic for which an AWS SQS queue + * should be used as source of events. + */ + topics: Record< + string, + { + /** + * (Required) Queue-related configuration. + */ + queue: { + /** + * (Required) The region of the AWS SQS queue. + */ + region: string; + /** + * (Required) The absolute URL for the AWS SQS queue to be used. + */ + url: string; + /** + * (Optional) Visibility timeout for messages in flight. + */ + visibilityTimeout: HumanDuration; + /** + * (Optional) Wait time when polling for available messages. + * Default: 20 seconds. + */ + waitTime: HumanDuration; + }; + /** + * (Optional) Timeout for the task execution which includes polling for messages + * and publishing the events to the event broker + * and the wait time after empty receives. + * + * Must be greater than `queue.waitTime` + `waitTimeAfterEmptyReceive`. + */ + timeout: HumanDuration; + /** + * (Optional) Wait time before polling again if no message was received. + * Default: 1 minute. + */ + waitTimeAfterEmptyReceive: HumanDuration; + } + >; + }; + }; + }; + }; +} diff --git a/plugins/events-backend-module-aws-sqs/package.json b/plugins/events-backend-module-aws-sqs/package.json new file mode 100644 index 0000000000..ecce75d9a3 --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/package.json @@ -0,0 +1,48 @@ +{ + "name": "@backstage/plugin-events-backend-module-aws-sqs", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "alphaTypes": "dist/index.alpha.d.ts", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build --experimental-type-build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@aws-sdk/client-sqs": "^3.0.0", + "@backstage/backend-plugin-api": "workspace:^", + "@backstage/backend-tasks": "workspace:^", + "@backstage/config": "workspace:^", + "@backstage/plugin-events-node": "workspace:^", + "@backstage/types": "workspace:^", + "luxon": "^3.0.0", + "winston": "^3.2.1" + }, + "devDependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "@backstage/plugin-events-backend-test-utils": "workspace:^", + "aws-sdk-client-mock": "^2.0.0" + }, + "files": [ + "alpha", + "config.d.ts", + "dist" + ], + "configSchema": "config.d.ts" +} diff --git a/plugins/events-backend-module-aws-sqs/src/index.ts b/plugins/events-backend-module-aws-sqs/src/index.ts new file mode 100644 index 0000000000..73b950856b --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/src/index.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2020 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. + */ + +/** + * The module "sqs" for the Backstage backend plugin "events" + * adding an AWS SQS-based publisher, + * receiving events from an AWS SQS queue and passing it to the + * internal event broker. + * + * @packageDocumentation + */ + +export { AwsSqsConsumingEventPublisher } from './publisher/AwsSqsConsumingEventPublisher'; +export { awsSqsConsumingEventPublisherEventsModule } from './service/AwsSqsConsumingEventPublisherEventsModule'; diff --git a/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.test.ts b/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.test.ts new file mode 100644 index 0000000000..e32245b483 --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.test.ts @@ -0,0 +1,227 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + DeleteMessageBatchCommand, + ReceiveMessageCommand, + SQSClient, +} from '@aws-sdk/client-sqs'; +import { getVoidLogger } from '@backstage/backend-common'; +import { PluginTaskScheduler } from '@backstage/backend-tasks'; +import { ConfigReader } from '@backstage/config'; +import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils'; +import { mockClient } from 'aws-sdk-client-mock'; +import { AwsSqsConsumingEventPublisher } from './AwsSqsConsumingEventPublisher'; + +describe('AwsSqsConsumingEventPublisher', () => { + it('creates one publisher instance per configured topic', async () => { + const config = new ConfigReader({ + events: { + modules: { + awsSqs: { + awsSqsConsumingEventPublisher: { + topics: { + fake1: { + queue: { + region: 'eu-west-1', + url: 'https://fake1.queue.url', + }, + }, + fake2: { + queue: { + region: 'us-east-1', + url: 'https://fake2.queue.url', + }, + }, + }, + }, + }, + }, + }, + }); + const logger = getVoidLogger(); + const scheduler = { + scheduleTask: jest.fn(), + } as unknown as PluginTaskScheduler; + + const publishers = AwsSqsConsumingEventPublisher.fromConfig({ + config, + logger, + scheduler, + }); + expect(publishers.length).toEqual(2); + }); + + it('polling will be scheduled after connecting to the EventBroker', async () => { + const config = new ConfigReader({ + events: { + modules: { + awsSqs: { + awsSqsConsumingEventPublisher: { + topics: { + fake1: { + queue: { + region: 'eu-west-1', + url: 'https://fake1.queue.url', + }, + }, + }, + }, + }, + }, + }, + }); + const logger = getVoidLogger(); + const scheduler = { + scheduleTask: jest.fn(), + } as unknown as PluginTaskScheduler; + + const publishers = AwsSqsConsumingEventPublisher.fromConfig({ + config, + logger, + scheduler, + }); + expect(publishers.length).toEqual(1); + + const publisher = publishers[0]; + + const eventBroker = new TestEventBroker(); + await publisher.setEventBroker(eventBroker); + + // publisher.connect(..) was causing the polling for events to be scheduled + expect(scheduler.scheduleTask).toHaveBeenCalledWith( + expect.objectContaining({ + id: 'events.awsSqs.publisher:fake1', + frequency: { seconds: 0 }, + timeout: { seconds: 260 }, + scope: 'local', + }), + ); + }); + + it('publishes events for received messages and deletes them in bulk', async () => { + const config = new ConfigReader({ + events: { + modules: { + awsSqs: { + awsSqsConsumingEventPublisher: { + topics: { + fake1: { + queue: { + region: 'eu-west-1', + url: 'https://fake1.queue.url', + }, + waitTimeAfterEmptyReceive: { seconds: 1 }, + }, + }, + }, + }, + }, + }, + }); + const logger = getVoidLogger(); + let taskFn: (() => Promise) | undefined = undefined; + const scheduler = { + scheduleTask: (spec: { fn: () => Promise }) => { + taskFn = spec.fn; + }, + } as unknown as PluginTaskScheduler; + + // on the first attempt, we will return 1 message and 0 messages afterwards + const sqsMock = mockClient(SQSClient); + sqsMock + .on(ReceiveMessageCommand, { + MaxNumberOfMessages: 10, + QueueUrl: 'https://fake1.queue.url', + WaitTimeSeconds: 20, + }) + .resolvesOnce({ + Messages: [], + }) + .resolvesOnce({ + Messages: [ + { + Body: '{"event":"payload1"}', + ReceiptHandle: 'fake-handle1', + MessageAttributes: { + 'X-Custom-Attr': { + DataType: 'String', + StringValue: 'value', + }, + }, + }, + { + Body: '{"event":"payload2"}', + ReceiptHandle: 'fake-handle2', + }, + ], + }) + .on(DeleteMessageBatchCommand, { + Entries: [ + { + Id: 'message-0', + ReceiptHandle: 'fake-handle1', + }, + { + Id: 'message-1', + ReceiptHandle: 'fake-handle2', + }, + ], + QueueUrl: 'https://fake1.queue.url', + }) + .resolvesOnce({ + Failed: [ + { + Id: 'message-1', + Message: 'test failure', + SenderFault: true, + Code: '400', + }, + ], + Successful: [{ Id: 'message-0' }], + }); + + const publishers = AwsSqsConsumingEventPublisher.fromConfig({ + config, + logger, + scheduler, + }); + expect(publishers.length).toEqual(1); + const publisher = publishers[0]; + + const eventBroker = new TestEventBroker(); + await publisher.setEventBroker(eventBroker); + + await taskFn!(); + await taskFn!(); + await taskFn!(); + + expect(eventBroker.published.length).toEqual(2); + expect(eventBroker.published[0].topic).toEqual('fake1'); + expect(eventBroker.published[0].eventPayload).toEqual({ + event: 'payload1', + }); + expect(eventBroker.published[0].metadata).toEqual({ + 'X-Custom-Attr': 'value', + }); + + expect(eventBroker.published[1].topic).toEqual('fake1'); + expect(eventBroker.published[1].eventPayload).toEqual({ + event: 'payload2', + }); + expect(eventBroker.published[1].metadata).toEqual({}); + }); +}); diff --git a/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.ts b/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.ts new file mode 100644 index 0000000000..4638769c45 --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.ts @@ -0,0 +1,191 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + DeleteMessageBatchCommand, + Message, + ReceiveMessageCommand, + ReceiveMessageCommandInput, + SQSClient, +} from '@aws-sdk/client-sqs'; +import { PluginTaskScheduler } from '@backstage/backend-tasks'; +import { Config } from '@backstage/config'; +import { EventBroker, EventPublisher } from '@backstage/plugin-events-node'; +import { Logger } from 'winston'; +import { AwsSqsEventSourceConfig, readConfig } from './config'; + +/** + * Publishes events received from an AWS SQS queue. + * The message payload will be used as event payload and passed to registered subscribers. + * + * @public + */ +// TODO(pjungermann): add prom metrics? (see plugins/catalog-backend/src/util/metrics.ts, etc.) +export class AwsSqsConsumingEventPublisher implements EventPublisher { + private readonly topic: string; + private readonly receiveParams: ReceiveMessageCommandInput; + private readonly sqs: SQSClient; + private readonly queueUrl: string; + private readonly taskTimeoutSeconds: number; + private readonly waitTimeAfterEmptyReceiveMs; + private eventBroker?: EventBroker; + + static fromConfig(env: { + config: Config; + logger: Logger; + scheduler: PluginTaskScheduler; + }): AwsSqsConsumingEventPublisher[] { + return readConfig(env.config).map( + config => + new AwsSqsConsumingEventPublisher(env.logger, env.scheduler, config), + ); + } + + private constructor( + private readonly logger: Logger, + private readonly scheduler: PluginTaskScheduler, + config: AwsSqsEventSourceConfig, + ) { + this.topic = config.topic; + + this.receiveParams = { + MaxNumberOfMessages: 10, + MessageAttributeNames: ['All'], + QueueUrl: config.queueUrl, + VisibilityTimeout: config.visibilityTimeout?.as('seconds'), + WaitTimeSeconds: config.pollingWaitTime.as('seconds'), + }; + this.sqs = new SQSClient({ region: config.region }); + this.queueUrl = config.queueUrl; + + this.taskTimeoutSeconds = config.timeout.as('seconds'); + this.waitTimeAfterEmptyReceiveMs = + config.waitTimeAfterEmptyReceive.as('milliseconds'); + } + + async setEventBroker(eventBroker: EventBroker): Promise { + this.eventBroker = eventBroker; + return this.start(); + } + + private async start(): Promise { + const id = `events.awsSqs.publisher:${this.topic}`; + const logger = this.logger.child({ + class: AwsSqsConsumingEventPublisher.prototype.constructor.name, + taskId: id, + }); + + await this.scheduler.scheduleTask({ + id: id, + frequency: { seconds: 0 }, + timeout: { seconds: this.taskTimeoutSeconds }, + scope: 'local', + fn: async () => { + try { + const numMessages = await this.consumeMessages(); + if (numMessages === 0) { + await this.sleep(this.waitTimeAfterEmptyReceiveMs); + } + } catch (error) { + logger.error(error); + } + }, + }); + } + + private async deleteMessages(messages?: Message[]): Promise { + if (!messages) { + return; + } + + const deleteParams = { + QueueUrl: this.queueUrl, + Entries: messages.map((message, index) => { + return { + Id: message.MessageId ?? `message-${index}`, + ReceiptHandle: message.ReceiptHandle, + }; + }), + }; + + try { + const result = await this.sqs.send( + new DeleteMessageBatchCommand(deleteParams), + ); + if (result.Failed) { + this.logger.error( + `Failed to delete ${result.Failed!.length} of ${ + messages.length + } messages from AWS SQS ${this.queueUrl}. First: ${ + result.Failed[0].Message + }`, + ); + } + } catch (error) { + this.logger.error( + `Failed to delete message from AWS SQS ${this.queueUrl}`, + error, + ); + } + } + + private async consumeMessages(): Promise { + try { + const data = await this.sqs.send( + new ReceiveMessageCommand(this.receiveParams), + ); + + data.Messages?.forEach(message => { + const eventPayload = JSON.parse(message.Body!); + + const metadata: Record = {}; + Object.keys(message.MessageAttributes ?? {}).forEach(key => { + const attrValue = message.MessageAttributes![key]; + if ( + !attrValue || + !attrValue.DataType || + !['String', 'Number'].includes(attrValue.DataType) + ) { + return; + } + + const value = attrValue.StringListValues ?? attrValue.StringValue; + if (value !== undefined) { + metadata[key] = value; + } + }); + + this.eventBroker!.publish({ + topic: this.topic, + eventPayload, + metadata, + }); + }); + await this.deleteMessages(data.Messages); + return data.Messages?.length ?? 0; + } catch (error) { + this.logger.error( + `Failed to receive events from AWS SQS ${this.queueUrl}`, + error, + ); + return 0; + } + } + + private sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); + } +} diff --git a/plugins/events-backend-module-aws-sqs/src/publisher/config.test.ts b/plugins/events-backend-module-aws-sqs/src/publisher/config.test.ts new file mode 100644 index 0000000000..1fa9df4ce3 --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/src/publisher/config.test.ts @@ -0,0 +1,222 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConfigReader } from '@backstage/config'; +import { readConfig } from './config'; + +describe('readConfig', () => { + it('not configured', () => { + const config = new ConfigReader({}); + + const publisherConfigs = readConfig(config); + + expect(publisherConfigs.length).toBe(0); + }); + + it('only required fields configured', () => { + const config = new ConfigReader({ + events: { + modules: { + awsSqs: { + awsSqsConsumingEventPublisher: { + topics: { + fake1: { + queue: { + region: 'eu-west-1', + url: 'https://fake1.queue.url', + }, + }, + fake2: { + queue: { + region: 'us-east-1', + url: 'https://fake2.queue.url', + }, + }, + }, + }, + }, + }, + }, + }); + + const publisherConfigs = readConfig(config); + + expect(publisherConfigs.length).toBe(2); + + expect(publisherConfigs[0].topic).toEqual('fake1'); + expect(publisherConfigs[0].region).toEqual('eu-west-1'); + expect(publisherConfigs[0].queueUrl).toEqual('https://fake1.queue.url'); + expect(publisherConfigs[0].pollingWaitTime.as('seconds')).toBe(20); + expect(publisherConfigs[0].timeout.as('seconds')).toBe(260); + expect(publisherConfigs[0].waitTimeAfterEmptyReceive.as('seconds')).toBe( + 60, + ); + }); + + it('all fields configured', () => { + const config = new ConfigReader({ + events: { + modules: { + awsSqs: { + awsSqsConsumingEventPublisher: { + topics: { + fake1: { + queue: { + region: 'eu-west-1', + url: 'https://fake1.queue.url', + visibilityTimeout: { minutes: 5 }, + waitTime: { seconds: 10 }, + }, + timeout: { minutes: 5 }, + waitTimeAfterEmptyReceive: { seconds: 30 }, + }, + }, + }, + }, + }, + }, + }); + + const publisherConfigs = readConfig(config); + + expect(publisherConfigs.length).toBe(1); + + expect(publisherConfigs[0].topic).toEqual('fake1'); + expect(publisherConfigs[0].region).toEqual('eu-west-1'); + expect(publisherConfigs[0].queueUrl).toEqual('https://fake1.queue.url'); + expect(publisherConfigs[0].pollingWaitTime.as('seconds')).toBe(10); + expect(publisherConfigs[0].timeout.as('seconds')).toBe(300); + expect(publisherConfigs[0].waitTimeAfterEmptyReceive.as('seconds')).toBe( + 30, + ); + }); + + it('fail on negative queue.waitTime', () => { + const config = new ConfigReader({ + events: { + modules: { + awsSqs: { + awsSqsConsumingEventPublisher: { + topics: { + fake1: { + queue: { + region: 'eu-west-1', + url: 'https://fake1.queue.url', + visibilityTimeout: { minutes: 5 }, + waitTime: { seconds: -10 }, + }, + timeout: { minutes: 5 }, + waitTimeAfterEmptyReceive: { seconds: 30 }, + }, + }, + }, + }, + }, + }, + }); + + expect(() => readConfig(config)).toThrow( + 'events.modules.awsSqs.awsSqsConsumingEventPublisher.topics.fake1.queue.waitTime must be within 0..20 seconds', + ); + }); + + it('fail on too high queue.waitTime', () => { + const config = new ConfigReader({ + events: { + modules: { + awsSqs: { + awsSqsConsumingEventPublisher: { + topics: { + fake1: { + queue: { + region: 'eu-west-1', + url: 'https://fake1.queue.url', + visibilityTimeout: { minutes: 5 }, + waitTime: { seconds: 30 }, + }, + timeout: { minutes: 5 }, + waitTimeAfterEmptyReceive: { seconds: 30 }, + }, + }, + }, + }, + }, + }, + }); + + expect(() => readConfig(config)).toThrow( + 'events.modules.awsSqs.awsSqsConsumingEventPublisher.topics.fake1.queue.waitTime must be within 0..20 seconds', + ); + }); + + it('fail on too low timeout', () => { + const config = new ConfigReader({ + events: { + modules: { + awsSqs: { + awsSqsConsumingEventPublisher: { + topics: { + fake1: { + queue: { + region: 'eu-west-1', + url: 'https://fake1.queue.url', + visibilityTimeout: { minutes: 5 }, + waitTime: { seconds: 10 }, + }, + timeout: { seconds: 10 }, + waitTimeAfterEmptyReceive: { seconds: 30 }, + }, + }, + }, + }, + }, + }, + }); + + expect(() => readConfig(config)).toThrow( + 'The events.modules.awsSqs.awsSqsConsumingEventPublisher.topics.fake1.timeout must be greater than events.modules.awsSqs.awsSqsConsumingEventPublisher.topics.fake1.queue.waitTime', + ); + }); + + it('fail on negative waitTimeAfterEmptyReceive', () => { + const config = new ConfigReader({ + events: { + modules: { + awsSqs: { + awsSqsConsumingEventPublisher: { + topics: { + fake1: { + queue: { + region: 'eu-west-1', + url: 'https://fake1.queue.url', + visibilityTimeout: { minutes: 5 }, + waitTime: { seconds: 10 }, + }, + timeout: { minutes: 5 }, + waitTimeAfterEmptyReceive: { seconds: -30 }, + }, + }, + }, + }, + }, + }, + }); + + expect(() => readConfig(config)).toThrow( + 'The events.modules.awsSqs.awsSqsConsumingEventPublisher.topics.fake1.waitTimeAfterEmptyReceive must not be negative', + ); + }); +}); diff --git a/plugins/events-backend-module-aws-sqs/src/publisher/config.ts b/plugins/events-backend-module-aws-sqs/src/publisher/config.ts new file mode 100644 index 0000000000..c6b74ea8d3 --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/src/publisher/config.ts @@ -0,0 +1,117 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Config } from '@backstage/config'; +import { HumanDuration, JsonObject } from '@backstage/types'; +import { Duration } from 'luxon'; + +const CONFIG_PREFIX_MODULE = 'events.modules.awsSqs.'; +const CONFIG_PREFIX_PUBLISHER = `${CONFIG_PREFIX_MODULE}awsSqsConsumingEventPublisher.`; +const DEFAULT_WAIT_TIME_AFTER_EMPTY_RECEIVE = { minutes: 1 }; +const MAX_WAIT_SECONDS = 20; + +export interface AwsSqsEventSourceConfig { + pollingWaitTime: Duration; + queueUrl: string; + region: string; + timeout: Duration; + topic: string; + visibilityTimeout?: Duration; + waitTimeAfterEmptyReceive: Duration; +} + +// TODO(pjungermann): validation could be improved similar to `convertToHumanDuration` at @backstage/backend-tasks +function readOptionalHumanDuration( + config: Config, + key: string, +): HumanDuration | undefined { + return config.getOptional(key) as HumanDuration; +} + +function readOptionalDuration( + config: Config, + key: string, +): Duration | undefined { + const duration = readOptionalHumanDuration(config, key); + return duration ? Duration.fromObject(duration) : undefined; +} + +export function readConfig(config: Config): AwsSqsEventSourceConfig[] { + const key = `${CONFIG_PREFIX_PUBLISHER}topics`; + const topics = config.getOptionalConfig(key); + + return ( + topics?.keys()?.map(topic => { + const topicConfig = topics.getConfig(topic); + const keyPrefix = `${key}.${topic}.`; + + // queue config: + const pollingWaitTime = Duration.fromObject( + readOptionalHumanDuration(topicConfig, 'queue.waitTime') ?? { + seconds: MAX_WAIT_SECONDS, + }, + ); + if ( + pollingWaitTime.valueOf() < 0 || + pollingWaitTime.as('seconds') > MAX_WAIT_SECONDS + ) { + throw new Error( + `${keyPrefix}queue.waitTime must be within 0..${MAX_WAIT_SECONDS} seconds.`, + ); + } + const queueUrl = topicConfig.getString('queue.url'); + const region = topicConfig.getString('queue.region'); + const visibilityTimeout = readOptionalDuration( + topicConfig, + 'queue.visibilityTimeout', + ); + + // task: + const waitTimeAfterEmptyReceive = Duration.fromObject( + readOptionalHumanDuration(topicConfig, 'waitTimeAfterEmptyReceive') ?? + DEFAULT_WAIT_TIME_AFTER_EMPTY_RECEIVE, + ); + if (waitTimeAfterEmptyReceive.valueOf() < 0) { + throw new Error( + `The ${keyPrefix}waitTimeAfterEmptyReceive must not be negative.`, + ); + } + const timeout = + readOptionalDuration(topicConfig, 'timeout') ?? + pollingWaitTime + .plus(waitTimeAfterEmptyReceive) + .plus(Duration.fromObject({ seconds: 180 })); + if ( + timeout.valueOf() <= + pollingWaitTime.valueOf() + waitTimeAfterEmptyReceive.valueOf() + ) { + throw new Error( + `The ${keyPrefix}timeout must be greater than ${keyPrefix}queue.waitTime + ${keyPrefix}waitTimeAfterEmptyReceive.`, + ); + } + + return { + pollingWaitTime, + queueUrl, + region, + timeout, + topic, + visibilityTimeout, + waitTimeAfterEmptyReceive, + }; + }) ?? [] + ); +} diff --git a/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.test.ts b/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.test.ts new file mode 100644 index 0000000000..584b62a2c6 --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.test.ts @@ -0,0 +1,94 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { + configServiceRef, + loggerServiceRef, + schedulerServiceRef, +} from '@backstage/backend-plugin-api'; +import { startTestBackend } from '@backstage/backend-test-utils'; +import { ConfigReader } from '@backstage/config'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils'; +import { awsSqsConsumingEventPublisherEventsModule } from './AwsSqsConsumingEventPublisherEventsModule'; +import { AwsSqsConsumingEventPublisher } from '../publisher/AwsSqsConsumingEventPublisher'; + +describe('awsSqsEventsModule', () => { + it('should be correctly wired and set up', async () => { + const config = new ConfigReader({ + events: { + modules: { + awsSqs: { + awsSqsConsumingEventPublisher: { + topics: { + fake1: { + queue: { + region: 'eu-west-1', + url: 'https://fake1.queue.url', + }, + }, + fake2: { + queue: { + region: 'us-east-1', + url: 'https://fake2.queue.url', + }, + }, + }, + }, + }, + }, + }, + }); + + let addedPublishers: AwsSqsConsumingEventPublisher[] | undefined; + const extensionPoint = { + addPublishers: (publishers: any) => { + addedPublishers = publishers; + }, + }; + + const scheduler = { + scheduleTask: jest.fn(), + }; + + await startTestBackend({ + extensionPoints: [[eventsExtensionPoint, extensionPoint]], + services: [ + [configServiceRef, config], + [loggerServiceRef, getVoidLogger()], + [schedulerServiceRef, scheduler], + ], + features: [awsSqsConsumingEventPublisherEventsModule()], + }); + + expect(addedPublishers).not.toBeUndefined(); + expect(addedPublishers!.length).toEqual(2); + + const eventBroker = new TestEventBroker(); + await Promise.all( + addedPublishers!.map(publisher => publisher.setEventBroker(eventBroker)), + ); + + // publisher.connect(..) was causing the polling for events to be scheduled + expect(scheduler.scheduleTask).toHaveBeenCalledWith( + expect.objectContaining({ id: 'events.awsSqs.publisher:fake1' }), + ); + expect(scheduler.scheduleTask).toHaveBeenCalledWith( + expect.objectContaining({ id: 'events.awsSqs.publisher:fake2' }), + ); + }); +}); diff --git a/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.ts b/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.ts new file mode 100644 index 0000000000..7c33d7baae --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.ts @@ -0,0 +1,55 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + configServiceRef, + createBackendModule, + loggerServiceRef, + loggerToWinstonLogger, + schedulerServiceRef, +} from '@backstage/backend-plugin-api'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { AwsSqsConsumingEventPublisher } from '../publisher/AwsSqsConsumingEventPublisher'; + +/** + * AWS SQS module for the Events plugin. + * + * @alpha + */ +export const awsSqsConsumingEventPublisherEventsModule = createBackendModule({ + pluginId: 'events', + moduleId: 'awsSqsConsumingEventPublisherEventsModule', + register(env) { + env.registerInit({ + deps: { + config: configServiceRef, + events: eventsExtensionPoint, + logger: loggerServiceRef, + scheduler: schedulerServiceRef, + }, + async init({ config, events, logger, scheduler }) { + const winstonLogger = loggerToWinstonLogger(logger); + const sqs = AwsSqsConsumingEventPublisher.fromConfig({ + config: config, + logger: winstonLogger, + scheduler: scheduler, + }); + + events.addPublishers(sqs); + }, + }); + }, +}); diff --git a/plugins/events-backend-module-aws-sqs/src/setupTests.ts b/plugins/events-backend-module-aws-sqs/src/setupTests.ts new file mode 100644 index 0000000000..d3232290a7 --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 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/yarn.lock b/yarn.lock index 535a0c483e..97ca3c01a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -330,6 +330,790 @@ __metadata: languageName: node linkType: hard +"@aws-crypto/ie11-detection@npm:^2.0.0": + version: 2.0.2 + resolution: "@aws-crypto/ie11-detection@npm:2.0.2" + dependencies: + tslib: ^1.11.1 + checksum: 713293deea8eefd3ab43dc05e62228571d27754e7293f8ec2fd8a0c693fbbfc55213e6599387776e3cdbc951965dc62e24e92b9c4a853e4a50d00ae6a9f6b2bd + languageName: node + linkType: hard + +"@aws-crypto/sha256-browser@npm:2.0.0": + version: 2.0.0 + resolution: "@aws-crypto/sha256-browser@npm:2.0.0" + dependencies: + "@aws-crypto/ie11-detection": ^2.0.0 + "@aws-crypto/sha256-js": ^2.0.0 + "@aws-crypto/supports-web-crypto": ^2.0.0 + "@aws-crypto/util": ^2.0.0 + "@aws-sdk/types": ^3.1.0 + "@aws-sdk/util-locate-window": ^3.0.0 + "@aws-sdk/util-utf8-browser": ^3.0.0 + tslib: ^1.11.1 + checksum: 7bc1ff042d0c53a46c0fc3824bd97fb3ed1df7dc030b8a995889471052860b8c8ade469c97866fafd8249a3144d0f48b0f1054f357e2b403606009381c4b8f0e + languageName: node + linkType: hard + +"@aws-crypto/sha256-js@npm:2.0.0": + version: 2.0.0 + resolution: "@aws-crypto/sha256-js@npm:2.0.0" + dependencies: + "@aws-crypto/util": ^2.0.0 + "@aws-sdk/types": ^3.1.0 + tslib: ^1.11.1 + checksum: e4abf9baec6bed19d380f92a999a41ac5bdd8890dfd45971d29054c298854c5b7087e7de633413f2e64618ef8238ccf4c0b75797c73063c74bbba3cb5d8b2581 + languageName: node + linkType: hard + +"@aws-crypto/sha256-js@npm:^2.0.0": + version: 2.0.2 + resolution: "@aws-crypto/sha256-js@npm:2.0.2" + dependencies: + "@aws-crypto/util": ^2.0.2 + "@aws-sdk/types": ^3.110.0 + tslib: ^1.11.1 + checksum: 9125ec65a2b05fce908ac2289ba97b995a299f2d717684804211df8e8bcffd8cd9b8861582240655b88f2255c46fcee34026f75c057ffb22f44b6a76cd43f65a + languageName: node + linkType: hard + +"@aws-crypto/supports-web-crypto@npm:^2.0.0": + version: 2.0.2 + resolution: "@aws-crypto/supports-web-crypto@npm:2.0.2" + dependencies: + tslib: ^1.11.1 + checksum: 03d04d29292dc1b76db9bc6becd05f52fa79adee0ec084f971b0767f7e73250dd0422bea57636015f8c27f38aefcd1d9c58800a4749cf35339296c8d670f3ccb + languageName: node + linkType: hard + +"@aws-crypto/util@npm:^2.0.0, @aws-crypto/util@npm:^2.0.2": + version: 2.0.2 + resolution: "@aws-crypto/util@npm:2.0.2" + dependencies: + "@aws-sdk/types": ^3.110.0 + "@aws-sdk/util-utf8-browser": ^3.0.0 + tslib: ^1.11.1 + checksum: 13cb33a39005b09c062398d361043c2224bc8ba42b1432bad52e15bc4bf9ffad4facdddc394b3cc71b3fb8d86a7ec325fd1afa107b5fde0dab84a7e32d311d7f + languageName: node + linkType: hard + +"@aws-sdk/abort-controller@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/abort-controller@npm:3.183.0" + dependencies: + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 28f5bc16b5aba414e354df603bc8becd010aa8c9b3c79e527130723a39f21d5a3df98c3bafb3cea733d415a5b042af90098ffa9dfa29d400114c2f6f5292524e + languageName: node + linkType: hard + +"@aws-sdk/client-sqs@npm:^3.0.0": + version: 3.183.0 + resolution: "@aws-sdk/client-sqs@npm:3.183.0" + dependencies: + "@aws-crypto/sha256-browser": 2.0.0 + "@aws-crypto/sha256-js": 2.0.0 + "@aws-sdk/client-sts": 3.183.0 + "@aws-sdk/config-resolver": 3.183.0 + "@aws-sdk/credential-provider-node": 3.183.0 + "@aws-sdk/fetch-http-handler": 3.183.0 + "@aws-sdk/hash-node": 3.183.0 + "@aws-sdk/invalid-dependency": 3.183.0 + "@aws-sdk/md5-js": 3.183.0 + "@aws-sdk/middleware-content-length": 3.183.0 + "@aws-sdk/middleware-host-header": 3.183.0 + "@aws-sdk/middleware-logger": 3.183.0 + "@aws-sdk/middleware-recursion-detection": 3.183.0 + "@aws-sdk/middleware-retry": 3.183.0 + "@aws-sdk/middleware-sdk-sqs": 3.183.0 + "@aws-sdk/middleware-serde": 3.183.0 + "@aws-sdk/middleware-signing": 3.183.0 + "@aws-sdk/middleware-stack": 3.183.0 + "@aws-sdk/middleware-user-agent": 3.183.0 + "@aws-sdk/node-config-provider": 3.183.0 + "@aws-sdk/node-http-handler": 3.183.0 + "@aws-sdk/protocol-http": 3.183.0 + "@aws-sdk/smithy-client": 3.183.0 + "@aws-sdk/types": 3.183.0 + "@aws-sdk/url-parser": 3.183.0 + "@aws-sdk/util-base64-browser": 3.183.0 + "@aws-sdk/util-base64-node": 3.183.0 + "@aws-sdk/util-body-length-browser": 3.183.0 + "@aws-sdk/util-body-length-node": 3.183.0 + "@aws-sdk/util-defaults-mode-browser": 3.183.0 + "@aws-sdk/util-defaults-mode-node": 3.183.0 + "@aws-sdk/util-user-agent-browser": 3.183.0 + "@aws-sdk/util-user-agent-node": 3.183.0 + "@aws-sdk/util-utf8-browser": 3.183.0 + "@aws-sdk/util-utf8-node": 3.183.0 + entities: 2.2.0 + fast-xml-parser: 3.19.0 + tslib: ^2.3.1 + checksum: fe0a7ba53cac4d52c25a4a4f1a1bb16438d5011347fcfec037df1d73379d750cd47b437f7a45aea2d4e29bc92587b51dd7631a06f5d6881e3b67b2d4c0dd2633 + languageName: node + linkType: hard + +"@aws-sdk/client-sso@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/client-sso@npm:3.183.0" + dependencies: + "@aws-crypto/sha256-browser": 2.0.0 + "@aws-crypto/sha256-js": 2.0.0 + "@aws-sdk/config-resolver": 3.183.0 + "@aws-sdk/fetch-http-handler": 3.183.0 + "@aws-sdk/hash-node": 3.183.0 + "@aws-sdk/invalid-dependency": 3.183.0 + "@aws-sdk/middleware-content-length": 3.183.0 + "@aws-sdk/middleware-host-header": 3.183.0 + "@aws-sdk/middleware-logger": 3.183.0 + "@aws-sdk/middleware-recursion-detection": 3.183.0 + "@aws-sdk/middleware-retry": 3.183.0 + "@aws-sdk/middleware-serde": 3.183.0 + "@aws-sdk/middleware-stack": 3.183.0 + "@aws-sdk/middleware-user-agent": 3.183.0 + "@aws-sdk/node-config-provider": 3.183.0 + "@aws-sdk/node-http-handler": 3.183.0 + "@aws-sdk/protocol-http": 3.183.0 + "@aws-sdk/smithy-client": 3.183.0 + "@aws-sdk/types": 3.183.0 + "@aws-sdk/url-parser": 3.183.0 + "@aws-sdk/util-base64-browser": 3.183.0 + "@aws-sdk/util-base64-node": 3.183.0 + "@aws-sdk/util-body-length-browser": 3.183.0 + "@aws-sdk/util-body-length-node": 3.183.0 + "@aws-sdk/util-defaults-mode-browser": 3.183.0 + "@aws-sdk/util-defaults-mode-node": 3.183.0 + "@aws-sdk/util-user-agent-browser": 3.183.0 + "@aws-sdk/util-user-agent-node": 3.183.0 + "@aws-sdk/util-utf8-browser": 3.183.0 + "@aws-sdk/util-utf8-node": 3.183.0 + tslib: ^2.3.1 + checksum: 6909329cf87c1a0c830fa9657e04c7e1ae496d7d79cc0a6813999503ae809f245f0b879af1d5564a5d97c2c69583c8a4df702d29ec7dc75934d98a0cdf017ad3 + languageName: node + linkType: hard + +"@aws-sdk/client-sts@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/client-sts@npm:3.183.0" + dependencies: + "@aws-crypto/sha256-browser": 2.0.0 + "@aws-crypto/sha256-js": 2.0.0 + "@aws-sdk/config-resolver": 3.183.0 + "@aws-sdk/credential-provider-node": 3.183.0 + "@aws-sdk/fetch-http-handler": 3.183.0 + "@aws-sdk/hash-node": 3.183.0 + "@aws-sdk/invalid-dependency": 3.183.0 + "@aws-sdk/middleware-content-length": 3.183.0 + "@aws-sdk/middleware-host-header": 3.183.0 + "@aws-sdk/middleware-logger": 3.183.0 + "@aws-sdk/middleware-recursion-detection": 3.183.0 + "@aws-sdk/middleware-retry": 3.183.0 + "@aws-sdk/middleware-sdk-sts": 3.183.0 + "@aws-sdk/middleware-serde": 3.183.0 + "@aws-sdk/middleware-signing": 3.183.0 + "@aws-sdk/middleware-stack": 3.183.0 + "@aws-sdk/middleware-user-agent": 3.183.0 + "@aws-sdk/node-config-provider": 3.183.0 + "@aws-sdk/node-http-handler": 3.183.0 + "@aws-sdk/protocol-http": 3.183.0 + "@aws-sdk/smithy-client": 3.183.0 + "@aws-sdk/types": 3.183.0 + "@aws-sdk/url-parser": 3.183.0 + "@aws-sdk/util-base64-browser": 3.183.0 + "@aws-sdk/util-base64-node": 3.183.0 + "@aws-sdk/util-body-length-browser": 3.183.0 + "@aws-sdk/util-body-length-node": 3.183.0 + "@aws-sdk/util-defaults-mode-browser": 3.183.0 + "@aws-sdk/util-defaults-mode-node": 3.183.0 + "@aws-sdk/util-user-agent-browser": 3.183.0 + "@aws-sdk/util-user-agent-node": 3.183.0 + "@aws-sdk/util-utf8-browser": 3.183.0 + "@aws-sdk/util-utf8-node": 3.183.0 + entities: 2.2.0 + fast-xml-parser: 3.19.0 + tslib: ^2.3.1 + checksum: d4492e537803d64e5fc0c5db8ac3a3788204aadc14b21e4fb407188feb58b35689c4a6878b4f13123a5f35f7e9fa01d95d427be168aeec9072aea881f2a92fb7 + languageName: node + linkType: hard + +"@aws-sdk/config-resolver@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/config-resolver@npm:3.183.0" + dependencies: + "@aws-sdk/signature-v4": 3.183.0 + "@aws-sdk/types": 3.183.0 + "@aws-sdk/util-config-provider": 3.183.0 + "@aws-sdk/util-middleware": 3.183.0 + tslib: ^2.3.1 + checksum: 1be0ab79d5019f7502a7aee8c740f4e381ab7501ed639569526a4a7e1c70ad6bb36d642a8a2b18afe58c34497c6f2f8244dbf05211a0f6bc9a57e5e379c70b2b + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-env@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.183.0" + dependencies: + "@aws-sdk/property-provider": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 4281e14c286cc5c57c69ba88c49fe1c1ff61f27923db5e8f852a84cce02b40fdc938f876ad08e72005deae9a28fab7400f747f63ca50f9c4d60e04e6c2705205 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-imds@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/credential-provider-imds@npm:3.183.0" + dependencies: + "@aws-sdk/node-config-provider": 3.183.0 + "@aws-sdk/property-provider": 3.183.0 + "@aws-sdk/types": 3.183.0 + "@aws-sdk/url-parser": 3.183.0 + tslib: ^2.3.1 + checksum: e9fe1007b22825dc0c033beb2057b9f759d8cafec6e65d08ba4915bccb9b7d737eeccb3d06e9768a084b6726d9ea10778172b1bec695353c60276c1a5c21370e + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-ini@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.183.0" + dependencies: + "@aws-sdk/credential-provider-env": 3.183.0 + "@aws-sdk/credential-provider-imds": 3.183.0 + "@aws-sdk/credential-provider-sso": 3.183.0 + "@aws-sdk/credential-provider-web-identity": 3.183.0 + "@aws-sdk/property-provider": 3.183.0 + "@aws-sdk/shared-ini-file-loader": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: c7784a3674c863dacc1305a08dd63cb16d1e7374250b0ceafa9feee8344de4228d7c32e84fbaa9d963adab69eb3938cd75b99554756da120cd9beae4693eded9 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-node@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.183.0" + dependencies: + "@aws-sdk/credential-provider-env": 3.183.0 + "@aws-sdk/credential-provider-imds": 3.183.0 + "@aws-sdk/credential-provider-ini": 3.183.0 + "@aws-sdk/credential-provider-process": 3.183.0 + "@aws-sdk/credential-provider-sso": 3.183.0 + "@aws-sdk/credential-provider-web-identity": 3.183.0 + "@aws-sdk/property-provider": 3.183.0 + "@aws-sdk/shared-ini-file-loader": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: f23e1148054a96d68632284501ba01c4285cce1a2f4562817ec4b7fa315ff56e2f6b97fae0d2ae26fd52fca8c9f000be5d72a3582cff6c32ba10010f02a30977 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-process@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.183.0" + dependencies: + "@aws-sdk/property-provider": 3.183.0 + "@aws-sdk/shared-ini-file-loader": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 3109e79ec2b4647f5e7f78c6dc2e10cd8a34a70147e7e90549153b7ff3ff12eda3499b3189d6fc1f3b99f461d5445e8017b44cd50029d30b0fc7437ad88a5f38 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-sso@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.183.0" + dependencies: + "@aws-sdk/client-sso": 3.183.0 + "@aws-sdk/property-provider": 3.183.0 + "@aws-sdk/shared-ini-file-loader": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 8775894ef50499361a4b49d846417c2c1e1ea90383730a32428154628358e7847f6f29dddd3cd04d3a4e15c1343fe10b051a92863055989ac3c4cb241e68f63a + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-web-identity@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.183.0" + dependencies: + "@aws-sdk/property-provider": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: c39576c8f35137284fc69db8d94adcf07fa89d51153ee9710481262e205d485ff089a796e8a253aa14a0434dde91eadb65602fc614167a4f14301201ee840c08 + languageName: node + linkType: hard + +"@aws-sdk/fetch-http-handler@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/fetch-http-handler@npm:3.183.0" + dependencies: + "@aws-sdk/protocol-http": 3.183.0 + "@aws-sdk/querystring-builder": 3.183.0 + "@aws-sdk/types": 3.183.0 + "@aws-sdk/util-base64-browser": 3.183.0 + tslib: ^2.3.1 + checksum: 87c51d1dad8c469e32b99f6ed3729e753097cd4a9f8f417ec8681cf01e18b9a5dc6571f3cd1220293216bd4527b8499bb2ea1f821a240fde6d9560817c120066 + languageName: node + linkType: hard + +"@aws-sdk/hash-node@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/hash-node@npm:3.183.0" + dependencies: + "@aws-sdk/types": 3.183.0 + "@aws-sdk/util-buffer-from": 3.183.0 + tslib: ^2.3.1 + checksum: fbed8757df633620807594535e3bb7d387576e0c2f89ad16dc7c98405a9d1d9743bea50148186de2f19cac67144b30f7f89e6c15317ddd7b8c0c8f61ca9556ef + languageName: node + linkType: hard + +"@aws-sdk/invalid-dependency@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/invalid-dependency@npm:3.183.0" + dependencies: + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: d928ca26d4390ad4f5e2c8198d16e14b675face6ad8c4a4eef699b54ce3f6cba584456659287b0e57e9f9019bc456b51dfa474671e11bf555fe04ed16174c10c + languageName: node + linkType: hard + +"@aws-sdk/is-array-buffer@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/is-array-buffer@npm:3.183.0" + dependencies: + tslib: ^2.3.1 + checksum: 717e508989821434a2ace4f690fc599f67b3f28ee9de5f06fce65a296fe11a68a5b97f30d66bfbf490d4a83259e4ffa1f0321231e4a54ce2440a9c6fdbacde24 + languageName: node + linkType: hard + +"@aws-sdk/md5-js@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/md5-js@npm:3.183.0" + dependencies: + "@aws-sdk/types": 3.183.0 + "@aws-sdk/util-utf8-browser": 3.183.0 + "@aws-sdk/util-utf8-node": 3.183.0 + tslib: ^2.3.1 + checksum: 5bd92465940ace6b3ca13342bd60eab42ffd5d74dfa65655c28e10bbf4aa0c32b2f9b4deb2050f3d092b8586e558bf248559af9c3cffb37810961169ad0797af + languageName: node + linkType: hard + +"@aws-sdk/middleware-content-length@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/middleware-content-length@npm:3.183.0" + dependencies: + "@aws-sdk/protocol-http": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: bf3ec6872a925dbafd91e57334b6264e8446ca59eba598ee4bc7b37113c466300ac6b77ab314c4aa2859221f1f4e98beabbd365346e0815d591f276e642d1849 + languageName: node + linkType: hard + +"@aws-sdk/middleware-host-header@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.183.0" + dependencies: + "@aws-sdk/protocol-http": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: b4c4886976cffec614ff368daa995a69c765e737c8d366daa0033d781cf8e7483565bb3627ecd752698edc23dcf578de6657c9e8cb41c0fcd92631d17b7749b8 + languageName: node + linkType: hard + +"@aws-sdk/middleware-logger@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/middleware-logger@npm:3.183.0" + dependencies: + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 10ffb6af0f81b0144fef91af2bbeaeb680df2beff838f2a6ebcc260971fd6252a166e3bf3501c1fc00f6f8f203117ff6e2b4baebb7a6d8cd8504b7e1f392bd6d + languageName: node + linkType: hard + +"@aws-sdk/middleware-recursion-detection@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.183.0" + dependencies: + "@aws-sdk/protocol-http": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 461117e0dc8c38750942035a07163817bc8e89f377211f5fb52d4314acae4e7e6cb49be04193c508112833535b33814c1609196cb65e38cff1122043398ad89e + languageName: node + linkType: hard + +"@aws-sdk/middleware-retry@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/middleware-retry@npm:3.183.0" + dependencies: + "@aws-sdk/protocol-http": 3.183.0 + "@aws-sdk/service-error-classification": 3.183.0 + "@aws-sdk/types": 3.183.0 + "@aws-sdk/util-middleware": 3.183.0 + tslib: ^2.3.1 + uuid: ^8.3.2 + checksum: 76fa3f9fe5f1c67bbfa792611289edf0afa2d0271073039931ac9ea46b3f432d74692d2db55443f40b7e97014898454f6d4bd8d2f2f5714a4281428b7464efac + languageName: node + linkType: hard + +"@aws-sdk/middleware-sdk-sqs@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.183.0" + dependencies: + "@aws-sdk/types": 3.183.0 + "@aws-sdk/util-hex-encoding": 3.183.0 + tslib: ^2.3.1 + checksum: 0bb914b2e7a5391f5b22a5262a5c299fa7e3eb22076d00c4cfffb449e97404b4830a77bb742e8f3110d66f15ae9aad81ea740238799cc35bb8d328eaf13f3fe2 + languageName: node + linkType: hard + +"@aws-sdk/middleware-sdk-sts@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/middleware-sdk-sts@npm:3.183.0" + dependencies: + "@aws-sdk/middleware-signing": 3.183.0 + "@aws-sdk/property-provider": 3.183.0 + "@aws-sdk/protocol-http": 3.183.0 + "@aws-sdk/signature-v4": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 1969d6128d24cc7d8ff199c2900d805281928668f4dc3ffd128065ccfe515f9f7467a265af276592009bd285847cb9298f8ba4b1dfbe33971c3e7de80986b422 + languageName: node + linkType: hard + +"@aws-sdk/middleware-serde@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/middleware-serde@npm:3.183.0" + dependencies: + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 7495bb2adceab2c686588697fd9dd50a859706a8d33d98d9907ffc8f9ef78af141f2654cdac8d7b28b1f0544dcf2e52f25d109f5da1348102234ab5b4e79b256 + languageName: node + linkType: hard + +"@aws-sdk/middleware-signing@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/middleware-signing@npm:3.183.0" + dependencies: + "@aws-sdk/property-provider": 3.183.0 + "@aws-sdk/protocol-http": 3.183.0 + "@aws-sdk/signature-v4": 3.183.0 + "@aws-sdk/types": 3.183.0 + "@aws-sdk/util-middleware": 3.183.0 + tslib: ^2.3.1 + checksum: 8025499acfefc072511adbc5084a1ed3cfe9cd9e514c58045425c87538af72ad3adfc134f7d0a059ff52832da392b4679b62d4ad28e477b866a20e78370f0758 + languageName: node + linkType: hard + +"@aws-sdk/middleware-stack@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/middleware-stack@npm:3.183.0" + dependencies: + tslib: ^2.3.1 + checksum: 03136847b96b0e4baba9b64f53a6c6b5738b1fa2c645edb3f47c1f85082791549b423ea791af33e9da3507cd56fbcbd052f1ba773a9f45ea42a3647277e85264 + languageName: node + linkType: hard + +"@aws-sdk/middleware-user-agent@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.183.0" + dependencies: + "@aws-sdk/protocol-http": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 8d1001d6d30f0f56aa440c541f6dcee9aad9190837e7a9653aef35448ff13e644cb7a441373192134ac86b5741fa64a120add07202cb97674018bd44612acdf7 + languageName: node + linkType: hard + +"@aws-sdk/node-config-provider@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/node-config-provider@npm:3.183.0" + dependencies: + "@aws-sdk/property-provider": 3.183.0 + "@aws-sdk/shared-ini-file-loader": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 673fb105de8d11ddd1c3e636c7ed01ef4fbe412a7d96543d9db69149dfad64d33adf5b96b106763c058190841ea497f220e1b75ca438dbda7b34729f00b9e823 + languageName: node + linkType: hard + +"@aws-sdk/node-http-handler@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/node-http-handler@npm:3.183.0" + dependencies: + "@aws-sdk/abort-controller": 3.183.0 + "@aws-sdk/protocol-http": 3.183.0 + "@aws-sdk/querystring-builder": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: a24ee8cc4e3b63fdec0ebb671caa1e634af488befa7c93a28bb733bb532934c221f6c47707db20264af91ca84336a50b98427b425329b89aeac2a6d2be9537ff + languageName: node + linkType: hard + +"@aws-sdk/property-provider@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/property-provider@npm:3.183.0" + dependencies: + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 6e8616e5f7efa9f46bdf62118dfc586e61dcdf0bc99f82305759020ce3d25fc1d2db71c62cfd4417a757a138b1a539cf305b584e6e7ade9bce9975fbe66fd326 + languageName: node + linkType: hard + +"@aws-sdk/protocol-http@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/protocol-http@npm:3.183.0" + dependencies: + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 13b255bcb37b70853d93374f972d743c80f33ac16188c41b512536c2dbec4d7beb55226bfac6d809981d63bbc87f6bf345334238f187da2faa9feaef5001e0a7 + languageName: node + linkType: hard + +"@aws-sdk/querystring-builder@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/querystring-builder@npm:3.183.0" + dependencies: + "@aws-sdk/types": 3.183.0 + "@aws-sdk/util-uri-escape": 3.183.0 + tslib: ^2.3.1 + checksum: a3de19863ccee4e8c9d5bbd719688ee1ffea02c3d90aad5e9c3eb04bed942ff8e5be0bfbc21ed03a968481abe2a2b1093e93b986b4111c468a9f3d3466b61f83 + languageName: node + linkType: hard + +"@aws-sdk/querystring-parser@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/querystring-parser@npm:3.183.0" + dependencies: + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: f05a03c46317c97f1b775f7c5be19365cf464396edc6b23c93efd5289ff1a8658883f7c9dde2cc7b74bb42b57f257bc212abae5d62100d23cdec5409fbffe468 + languageName: node + linkType: hard + +"@aws-sdk/service-error-classification@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/service-error-classification@npm:3.183.0" + checksum: 8c015163aee9ec4d789daa8605e5b9424dfda81d3f609a2c34d800cb36ee78f4a3af02d1738c7e75f9a62cd1ef8ec4307f77457eecba3de4c6565a981484bca4 + languageName: node + linkType: hard + +"@aws-sdk/shared-ini-file-loader@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/shared-ini-file-loader@npm:3.183.0" + dependencies: + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 317fd0d8012559754f82b88fb386d2a01c19be1d3a0b6da3a6436f71701ed8cd8fbe3f5aa869fd7bbfb8dfb148cd9de02aa68e93001200c76ba9e0691e135773 + languageName: node + linkType: hard + +"@aws-sdk/signature-v4@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/signature-v4@npm:3.183.0" + dependencies: + "@aws-sdk/is-array-buffer": 3.183.0 + "@aws-sdk/types": 3.183.0 + "@aws-sdk/util-hex-encoding": 3.183.0 + "@aws-sdk/util-middleware": 3.183.0 + "@aws-sdk/util-uri-escape": 3.183.0 + tslib: ^2.3.1 + checksum: 6639a4925b194171907fc1cf61101470836f5a8fa363f3fcd7b70bbaa4c756f43e13ad93b575885218a68192c375295d359a7e91db370816bd8f39f9c158ba36 + languageName: node + linkType: hard + +"@aws-sdk/smithy-client@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/smithy-client@npm:3.183.0" + dependencies: + "@aws-sdk/middleware-stack": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 70866adfd91fb35721bcd8667d9a4638e306de6ddc22be37a5b3ea19dfc2a1404a7325992f7f56d635a3bfd3b0ffa159d32f17df35c47ada4724ad8d5bb8d1ce + languageName: node + linkType: hard + +"@aws-sdk/types@npm:3.183.0, @aws-sdk/types@npm:^3.1.0, @aws-sdk/types@npm:^3.110.0": + version: 3.183.0 + resolution: "@aws-sdk/types@npm:3.183.0" + checksum: ab6e888ef8f6d5f5c047dbe0899ac94ad4aa83b9ae1b1fd7a3b88eacec61ab912f215fda65c71f783418d569d1088641806f6b98c9a28ddae04cc70d0eeccea7 + languageName: node + linkType: hard + +"@aws-sdk/url-parser@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/url-parser@npm:3.183.0" + dependencies: + "@aws-sdk/querystring-parser": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 54c99d47e927368db12b6aa1fe4331a27461502355e0c18e99d8e05d9a114529d0b15965ff885cae8e19e49692ad44bf3c323ffdc535d7129deac900f286d1d5 + languageName: node + linkType: hard + +"@aws-sdk/util-base64-browser@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-base64-browser@npm:3.183.0" + dependencies: + tslib: ^2.3.1 + checksum: 2c3a4dc7e285b146285ac23de155de5e885d96aa46b29f9c830b6f12541032c6a42be7fd412ec019ddb83e6f155f561d04065b99159515d26d28c0968965dcf2 + languageName: node + linkType: hard + +"@aws-sdk/util-base64-node@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-base64-node@npm:3.183.0" + dependencies: + "@aws-sdk/util-buffer-from": 3.183.0 + tslib: ^2.3.1 + checksum: d8d0330aa768f816411a7b2343c500728501775d2f8d7c121d52d8484cbdd938102f3049e69e28574c838416ead0cb742494140609287b8d462bfb041218600d + languageName: node + linkType: hard + +"@aws-sdk/util-body-length-browser@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-body-length-browser@npm:3.183.0" + dependencies: + tslib: ^2.3.1 + checksum: 294074e20e4eb46ea992fc9d50fac0b97875d1d09efa706d5298e34f4200226c90bb33bbe96c41c7e91a43fbe44e6cfc0654d09fcdb823fe579545ada65701d9 + languageName: node + linkType: hard + +"@aws-sdk/util-body-length-node@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-body-length-node@npm:3.183.0" + dependencies: + tslib: ^2.3.1 + checksum: 60697959c63731d6b4b334bed91d08c4e38e09c0ad95000509641370249c76c5df1ffa0a7cab7418d250a526f49e660f0c67cea28547e442ac47feb7623413b8 + languageName: node + linkType: hard + +"@aws-sdk/util-buffer-from@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-buffer-from@npm:3.183.0" + dependencies: + "@aws-sdk/is-array-buffer": 3.183.0 + tslib: ^2.3.1 + checksum: 5f16145cf68b0756f0930990cfba57ac343c83c6e9dc48bc8d4f488cd66548a9e186e702fa94ba33b69d852c2d019eedf4116ac676cf0dfb701081e39e0776dd + languageName: node + linkType: hard + +"@aws-sdk/util-config-provider@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-config-provider@npm:3.183.0" + dependencies: + tslib: ^2.3.1 + checksum: 8af6bf5ba31ec0a2fcf994f0a13bde5ff948bcdba02d153cdeea2105ea5eaf934368456bc92f35bfa42a7475cd4d2d2b9a644dfb8b4c2670ae2f103c045dc8b4 + languageName: node + linkType: hard + +"@aws-sdk/util-defaults-mode-browser@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-defaults-mode-browser@npm:3.183.0" + dependencies: + "@aws-sdk/property-provider": 3.183.0 + "@aws-sdk/types": 3.183.0 + bowser: ^2.11.0 + tslib: ^2.3.1 + checksum: 8ff54acf1684dd9d82ca13a522c5d2d7ee305511a2748f6e8ef7dc43e668798269e51455ac81b905a5b000a704fd5536f178c84425b8c431500e6a8dc1418135 + languageName: node + linkType: hard + +"@aws-sdk/util-defaults-mode-node@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-defaults-mode-node@npm:3.183.0" + dependencies: + "@aws-sdk/config-resolver": 3.183.0 + "@aws-sdk/credential-provider-imds": 3.183.0 + "@aws-sdk/node-config-provider": 3.183.0 + "@aws-sdk/property-provider": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + checksum: 40665d251844c4add23e358d9171add7180e0f1fcd4bd99601f4bdd03daa2259fed2567fa200152e14c4d7b1acc1126997f5b4e74c569ee1032f9fee16e6b582 + languageName: node + linkType: hard + +"@aws-sdk/util-hex-encoding@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-hex-encoding@npm:3.183.0" + dependencies: + tslib: ^2.3.1 + checksum: 1bf9577d96d01c13a3118e5d767c1e16b1f4f1c574168d78e128e0342edac30c87776340e9e14deb1e9adf539a6b2f953338adabc097fb143e870889698a6308 + languageName: node + linkType: hard + +"@aws-sdk/util-locate-window@npm:^3.0.0": + version: 3.183.0 + resolution: "@aws-sdk/util-locate-window@npm:3.183.0" + dependencies: + tslib: ^2.3.1 + checksum: c29899b440c148aa44a5d9322e06e4cf21644e47bee10555cf8db104d9d76b3985fa4da6e8ca92c137b0b739f7504a7d106e9da49e1d189b84f51f45c21b2204 + languageName: node + linkType: hard + +"@aws-sdk/util-middleware@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-middleware@npm:3.183.0" + dependencies: + tslib: ^2.3.1 + checksum: e1a433aebae5e74b365ecb4a57e3c583e7b89697f24b0c9edde93b8ba358e92256550329efb7c6924c0a5037e1bad2b7a1c8ed1b6d02e1aaaa35bca502923752 + languageName: node + linkType: hard + +"@aws-sdk/util-uri-escape@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-uri-escape@npm:3.183.0" + dependencies: + tslib: ^2.3.1 + checksum: 9d5f30821cdad15ed6912f7406f83b5b5a45358b208a9374ea944313d9853da8f4ec9881aefa5d6fe78caeaefbb0d103c8485a32f7c25e8b2cae193ea2233bb8 + languageName: node + linkType: hard + +"@aws-sdk/util-user-agent-browser@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.183.0" + dependencies: + "@aws-sdk/types": 3.183.0 + bowser: ^2.11.0 + tslib: ^2.3.1 + checksum: 21349881a4069a09fb0f8c0f5a6d69e6659255008861817c5d9dada61bf032f0bd7d5735f01dbddbc310d228ea843fbec6ada9f83a4197909efd6ebadb364f6b + languageName: node + linkType: hard + +"@aws-sdk/util-user-agent-node@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.183.0" + dependencies: + "@aws-sdk/node-config-provider": 3.183.0 + "@aws-sdk/types": 3.183.0 + tslib: ^2.3.1 + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + checksum: 727d46842053f8f19789fee1550e235adff399559ef6c9b8dd0fe9edd7ac629a9b5c5849377553bfff37deba1ba9889d0c313f059f27cfc40a33895990c1f894 + languageName: node + linkType: hard + +"@aws-sdk/util-utf8-browser@npm:3.183.0, @aws-sdk/util-utf8-browser@npm:^3.0.0": + version: 3.183.0 + resolution: "@aws-sdk/util-utf8-browser@npm:3.183.0" + dependencies: + tslib: ^2.3.1 + checksum: f1c9cbafc3dcf5b04264c3708509117d5e6f6b373fb30712a0cd9d09966a2cdead0a91067a8e9513abac9b082971fd40519e421a2e046b3653ce1ede136197c2 + languageName: node + linkType: hard + +"@aws-sdk/util-utf8-node@npm:3.183.0": + version: 3.183.0 + resolution: "@aws-sdk/util-utf8-node@npm:3.183.0" + dependencies: + "@aws-sdk/util-buffer-from": 3.183.0 + tslib: ^2.3.1 + checksum: c37f2bd388783c33c981afcd5a6a80481cc4e019f42bc5ab10ba2dfb039a4684acb4fa30df579cb3a5b509f61b1261870b30cd966c179029adb2a42672c0a871 + languageName: node + linkType: hard + "@azure/abort-controller@npm:^1.0.0": version: 1.0.2 resolution: "@azure/abort-controller@npm:1.0.2" @@ -5532,6 +6316,26 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-events-backend-module-aws-sqs@workspace:plugins/events-backend-module-aws-sqs": + version: 0.0.0-use.local + resolution: "@backstage/plugin-events-backend-module-aws-sqs@workspace:plugins/events-backend-module-aws-sqs" + dependencies: + "@aws-sdk/client-sqs": ^3.0.0 + "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-tasks": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/plugin-events-backend-test-utils": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" + "@backstage/types": "workspace:^" + aws-sdk-client-mock: ^2.0.0 + luxon: ^3.0.0 + winston: ^3.2.1 + languageName: unknown + linkType: soft + "@backstage/plugin-events-backend-test-utils@workspace:^, @backstage/plugin-events-backend-test-utils@workspace:plugins/events-backend-test-utils": version: 0.0.0-use.local resolution: "@backstage/plugin-events-backend-test-utils@workspace:plugins/events-backend-test-utils" @@ -12705,7 +13509,16 @@ __metadata: languageName: node linkType: hard -"@sinonjs/samsam@npm:^6.1.1": +"@sinonjs/fake-timers@npm:^7.1.2": + version: 7.1.2 + resolution: "@sinonjs/fake-timers@npm:7.1.2" + dependencies: + "@sinonjs/commons": ^1.7.0 + checksum: c84773d7973edad5511a31d2cc75023447b5cf714a84de9bb50eda45dda88a0d3bd2c30bf6e6e936da50a048d5352e2151c694e13e59b97d187ba1f329e9a00c + languageName: node + linkType: hard + +"@sinonjs/samsam@npm:^6.0.2, @sinonjs/samsam@npm:^6.1.1": version: 6.1.1 resolution: "@sinonjs/samsam@npm:6.1.1" dependencies: @@ -14916,6 +15729,22 @@ __metadata: languageName: node linkType: hard +"@types/sinon@npm:^10.0.10": + version: 10.0.13 + resolution: "@types/sinon@npm:10.0.13" + dependencies: + "@types/sinonjs__fake-timers": "*" + checksum: 46a14c888db50f0098ec53d451877e0111d878ec4a653b9e9ed7f8e54de386d6beb0e528ddc3e95cd3361a8ab9ad54e4cca33cd88d45b9227b83e9fc8fb6688a + languageName: node + linkType: hard + +"@types/sinonjs__fake-timers@npm:*": + version: 8.1.2 + resolution: "@types/sinonjs__fake-timers@npm:8.1.2" + checksum: bbc73a5ab6c0ec974929392f3d6e1e8db4ebad97ec506d785301e1c3d8a4f98a35b1aa95b97035daef02886fd8efd7788a2fa3ced2ec7105988bfd8dce61eedd + languageName: node + linkType: hard + "@types/sinonjs__fake-timers@npm:8.1.1": version: 8.1.1 resolution: "@types/sinonjs__fake-timers@npm:8.1.1" @@ -16755,6 +17584,17 @@ __metadata: languageName: node linkType: hard +"aws-sdk-client-mock@npm:^2.0.0": + version: 2.0.0 + resolution: "aws-sdk-client-mock@npm:2.0.0" + dependencies: + "@types/sinon": ^10.0.10 + sinon: ^11.1.1 + tslib: ^2.1.0 + checksum: e6081ca6bb72f5c082dfcd93155bbb7e1c9e8d3d346914ed05d736c495a5ef99ab3d0253507aff2e07b5b995fae63671e53e094437ddfaf8649d69725628ff8f + languageName: node + linkType: hard + "aws-sdk-mock@npm:^5.2.1": version: 5.7.0 resolution: "aws-sdk-mock@npm:5.7.0" @@ -17411,6 +18251,13 @@ __metadata: languageName: node linkType: hard +"bowser@npm:^2.11.0": + version: 2.11.0 + resolution: "bowser@npm:2.11.0" + checksum: 29c3f01f22e703fa6644fc3b684307442df4240b6e10f6cfe1b61c6ca5721073189ca97cdeedb376081148c8518e33b1d818a57f781d70b0b70e1f31fb48814f + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": version: 1.1.11 resolution: "brace-expansion@npm:1.1.11" @@ -21021,6 +21868,13 @@ __metadata: languageName: node linkType: hard +"entities@npm:2.2.0": + version: 2.2.0 + resolution: "entities@npm:2.2.0" + checksum: 19010dacaf0912c895ea262b4f6128574f9ccf8d4b3b65c7e8334ad0079b3706376360e28d8843ff50a78aabcb8f08f0a32dbfacdc77e47ed77ca08b713669b3 + languageName: node + linkType: hard + "entities@npm:^2.0.0, entities@npm:~2.1.0": version: 2.1.0 resolution: "entities@npm:2.1.0" @@ -22767,6 +23621,15 @@ __metadata: languageName: node linkType: hard +"fast-xml-parser@npm:3.19.0": + version: 3.19.0 + resolution: "fast-xml-parser@npm:3.19.0" + bin: + xml2js: cli.js + checksum: d9da9145f73d90c05ee2746d80c78eca4da0249dea8c81ea8f1a6e1245e62988ed4a040dbd1c7229b1e0bdcbf69d33c882e0ac337d10c7eedb159a4dc9779327 + languageName: node + linkType: hard + "fastest-stable-stringify@npm:^2.0.2": version: 2.0.2 resolution: "fastest-stable-stringify@npm:2.0.2" @@ -30077,7 +30940,7 @@ __metadata: languageName: node linkType: hard -"nise@npm:^5.1.1": +"nise@npm:^5.1.0, nise@npm:^5.1.1": version: 5.1.1 resolution: "nise@npm:5.1.1" dependencies: @@ -35666,6 +36529,20 @@ __metadata: languageName: node linkType: hard +"sinon@npm:^11.1.1": + version: 11.1.2 + resolution: "sinon@npm:11.1.2" + dependencies: + "@sinonjs/commons": ^1.8.3 + "@sinonjs/fake-timers": ^7.1.2 + "@sinonjs/samsam": ^6.0.2 + diff: ^5.0.0 + nise: ^5.1.0 + supports-color: ^7.2.0 + checksum: 1d01377e230c9ba976bf33f28b588bae7901b0b5a503d2f6b2a7914b0dbaa9f09823481926c6f2abed820123c7fa865519695af3ae2e9ba18d8b025616163501 + languageName: node + linkType: hard + "sinon@npm:^13.0.2": version: 13.0.2 resolution: "sinon@npm:13.0.2" @@ -37713,7 +38590,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.10.0, tslib@npm:^1.8.1, tslib@npm:^1.9.0, tslib@npm:^1.9.3": +"tslib@npm:^1.10.0, tslib@npm:^1.11.1, tslib@npm:^1.8.1, tslib@npm:^1.9.0, tslib@npm:^1.9.3": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd From 6bc121bf0d1cc4675b1d0bf865ab200e8bdd5b98 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Mon, 24 Oct 2022 04:03:37 +0200 Subject: [PATCH 309/434] feat(events/bitbucketCloud): add `BitbucketCloudEventRouter` Add an event router for Bitbucket Cloud which handles events from the topic `bitbucketCloud` and re-publishes events under their more specific topic based on the `x-event-key` metadata like e.g., `bitbucketCloud.repo:push`. Signed-off-by: Patrick Jungermann --- .changeset/blue-papayas-relax.md | 14 ++++++ .github/CODEOWNERS | 1 + .../.eslintrc.js | 1 + .../README.md | 43 +++++++++++++++++ .../api-report.md | 21 +++++++++ .../package.json | 40 ++++++++++++++++ .../src/index.ts | 25 ++++++++++ .../router/BitbucketCloudEventRouter.test.ts | 46 +++++++++++++++++++ .../src/router/BitbucketCloudEventRouter.ts | 37 +++++++++++++++ ...bucketCloudEventRouterEventsModule.test.ts | 46 +++++++++++++++++++ .../BitbucketCloudEventRouterEventsModule.ts | 44 ++++++++++++++++++ .../src/setupTests.ts | 17 +++++++ yarn.lock | 14 ++++++ 13 files changed, 349 insertions(+) create mode 100644 .changeset/blue-papayas-relax.md create mode 100644 plugins/events-backend-module-bitbucket-cloud/.eslintrc.js create mode 100644 plugins/events-backend-module-bitbucket-cloud/README.md create mode 100644 plugins/events-backend-module-bitbucket-cloud/api-report.md create mode 100644 plugins/events-backend-module-bitbucket-cloud/package.json create mode 100644 plugins/events-backend-module-bitbucket-cloud/src/index.ts create mode 100644 plugins/events-backend-module-bitbucket-cloud/src/router/BitbucketCloudEventRouter.test.ts create mode 100644 plugins/events-backend-module-bitbucket-cloud/src/router/BitbucketCloudEventRouter.ts create mode 100644 plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.test.ts create mode 100644 plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.ts create mode 100644 plugins/events-backend-module-bitbucket-cloud/src/setupTests.ts diff --git a/.changeset/blue-papayas-relax.md b/.changeset/blue-papayas-relax.md new file mode 100644 index 0000000000..002fd66a62 --- /dev/null +++ b/.changeset/blue-papayas-relax.md @@ -0,0 +1,14 @@ +--- +'@backstage/plugin-events-backend-module-bitbucket-cloud': minor +--- + +Adds a new module `bitbucket-cloud` to plugin-events-backend. + +The module adds a new event router `BitbucketCloudEventRouter`. + +The event router will re-publish events received at topic `bitbucketCloud` +under a more specific topic depending on their `x-event-key` value +(e.g., `bitbucketCloud.repo:push`). + +Please find more information at +https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-bitbucket-cloud/README.md. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 84c8cd22d2..235392c9bf 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -38,6 +38,7 @@ yarn.lock @backstage/reviewers @backst /plugins/cost-insights-* @backstage/reviewers @backstage/silver-lining /plugins/events-backend @backstage/reviewers @pjungermann /plugins/events-backend-module-aws-sqs @backstage/reviewers @pjungermann +/plugins/events-backend-module-bitbucket-cloud @backstage/reviewers @pjungermann /plugins/events-backend-test-utils @backstage/reviewers @pjungermann /plugins/events-node @backstage/reviewers @pjungermann /plugins/explore @backstage/reviewers @backstage/sda-se-reviewers diff --git a/plugins/events-backend-module-bitbucket-cloud/.eslintrc.js b/plugins/events-backend-module-bitbucket-cloud/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/events-backend-module-bitbucket-cloud/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/events-backend-module-bitbucket-cloud/README.md b/plugins/events-backend-module-bitbucket-cloud/README.md new file mode 100644 index 0000000000..c58529ed7a --- /dev/null +++ b/plugins/events-backend-module-bitbucket-cloud/README.md @@ -0,0 +1,43 @@ +# events-backend-module-bitbucket-cloud + +Welcome to the `events-backend-module-bitbucket-cloud` backend plugin! + +This plugin is a module for the `events-backend` backend plugin +and extends it with an `BitbucketCloudEventRouter`. + +The event router will subscribe to the topic `bitbucketCloud` +and route the events to more concrete topics based on the value +of the provided `x-event-key` metadata field. + +Examples: + +| x-event-key | topic | +| --------------------- | ------------------------------------ | +| `repo:push` | `bitbucketCloud.repo:push` | +| `repo:updated` | `bitbucketCloud.repo:updated` | +| `pullrequest:created` | `bitbucketCloud.pullrequest:created` | + +Please find all possible webhook event types at the +[official documentation](https://support.atlassian.com/bitbucket-cloud/docs/event-payloads/). + +## Installation + +Install the [`events-backend` plugin](../events-backend/README.md). + +Install this module: + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-events-backend-module-bitbucket-cloud +``` + +Add the event router to the `EventsBackend`: + +```diff ++const bitbucketCloudEventRouter = new BitbucketCloudEventRouter(); + + EventsBackend ++ .addPublishers(bitbucketCloudEventRouter) ++ .addSubscribers(bitbucketCloudEventRouter); +// [...] +``` diff --git a/plugins/events-backend-module-bitbucket-cloud/api-report.md b/plugins/events-backend-module-bitbucket-cloud/api-report.md new file mode 100644 index 0000000000..0e4acfac91 --- /dev/null +++ b/plugins/events-backend-module-bitbucket-cloud/api-report.md @@ -0,0 +1,21 @@ +## API Report File for "@backstage/plugin-events-backend-module-bitbucket-cloud" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { EventParams } from '@backstage/plugin-events-node'; +import { SubTopicEventRouter } from '@backstage/plugin-events-node'; + +// @public +export class BitbucketCloudEventRouter extends SubTopicEventRouter { + constructor(); + // (undocumented) + protected determineSubTopic(params: EventParams): string | undefined; +} + +// @alpha +export const bitbucketCloudEventRouterEventsModule: ( + options?: undefined, +) => BackendFeature; +``` diff --git a/plugins/events-backend-module-bitbucket-cloud/package.json b/plugins/events-backend-module-bitbucket-cloud/package.json new file mode 100644 index 0000000000..f43cd9c664 --- /dev/null +++ b/plugins/events-backend-module-bitbucket-cloud/package.json @@ -0,0 +1,40 @@ +{ + "name": "@backstage/plugin-events-backend-module-bitbucket-cloud", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "alphaTypes": "dist/index.alpha.d.ts", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build --experimental-type-build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-plugin-api": "workspace:^", + "@backstage/plugin-events-node": "workspace:^", + "winston": "^3.2.1" + }, + "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "@backstage/plugin-events-backend-test-utils": "workspace:^", + "supertest": "^6.1.3" + }, + "files": [ + "alpha", + "dist" + ] +} diff --git a/plugins/events-backend-module-bitbucket-cloud/src/index.ts b/plugins/events-backend-module-bitbucket-cloud/src/index.ts new file mode 100644 index 0000000000..0a58212de2 --- /dev/null +++ b/plugins/events-backend-module-bitbucket-cloud/src/index.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2020 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. + */ + +/** + * The module "bitbucket-cloud" for the Backstage backend plugin "events-backend" + * adding an event router for Bitbucket Cloud. + * + * @packageDocumentation + */ + +export { BitbucketCloudEventRouter } from './router/BitbucketCloudEventRouter'; +export { bitbucketCloudEventRouterEventsModule } from './service/BitbucketCloudEventRouterEventsModule'; diff --git a/plugins/events-backend-module-bitbucket-cloud/src/router/BitbucketCloudEventRouter.test.ts b/plugins/events-backend-module-bitbucket-cloud/src/router/BitbucketCloudEventRouter.test.ts new file mode 100644 index 0000000000..b7a47984e4 --- /dev/null +++ b/plugins/events-backend-module-bitbucket-cloud/src/router/BitbucketCloudEventRouter.test.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils'; +import { BitbucketCloudEventRouter } from './BitbucketCloudEventRouter'; + +describe('BitbucketCloudEventRouter', () => { + const eventRouter = new BitbucketCloudEventRouter(); + const topic = 'bitbucketCloud'; + const eventPayload = { test: 'payload' }; + const metadata = { 'x-event-key': 'test:type' }; + + it('no x-event-key', () => { + const eventBroker = new TestEventBroker(); + eventRouter.setEventBroker(eventBroker); + + eventRouter.onEvent({ topic, eventPayload }); + + expect(eventBroker.published).toEqual([]); + }); + + it('with x-event-key', () => { + const eventBroker = new TestEventBroker(); + eventRouter.setEventBroker(eventBroker); + + eventRouter.onEvent({ topic, eventPayload, metadata }); + + expect(eventBroker.published.length).toBe(1); + expect(eventBroker.published[0].topic).toEqual('bitbucketCloud.test:type'); + expect(eventBroker.published[0].eventPayload).toEqual(eventPayload); + expect(eventBroker.published[0].metadata).toEqual(metadata); + }); +}); diff --git a/plugins/events-backend-module-bitbucket-cloud/src/router/BitbucketCloudEventRouter.ts b/plugins/events-backend-module-bitbucket-cloud/src/router/BitbucketCloudEventRouter.ts new file mode 100644 index 0000000000..8350511d65 --- /dev/null +++ b/plugins/events-backend-module-bitbucket-cloud/src/router/BitbucketCloudEventRouter.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + EventParams, + SubTopicEventRouter, +} from '@backstage/plugin-events-node'; + +/** + * Subscribes to the generic `bitbucketCloud` topic + * and publishes the events under the more concrete sub-topic + * depending on the `x-event-key` provided. + * + * @public + */ +export class BitbucketCloudEventRouter extends SubTopicEventRouter { + constructor() { + super('bitbucketCloud'); + } + + protected determineSubTopic(params: EventParams): string | undefined { + return params.metadata?.['x-event-key'] as string | undefined; + } +} diff --git a/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.test.ts b/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.test.ts new file mode 100644 index 0000000000..e456607a2b --- /dev/null +++ b/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.test.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { startTestBackend } from '@backstage/backend-test-utils'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { bitbucketCloudEventRouterEventsModule } from './BitbucketCloudEventRouterEventsModule'; +import { BitbucketCloudEventRouter } from '../router/BitbucketCloudEventRouter'; + +describe('bitbucketCloudEventRouterEventsModule', () => { + it('should be correctly wired and set up', async () => { + let addedPublisher: BitbucketCloudEventRouter | undefined; + let addedSubscriber: BitbucketCloudEventRouter | undefined; + const extensionPoint = { + addPublishers: (publisher: any) => { + addedPublisher = publisher; + }, + addSubscribers: (subscriber: any) => { + addedSubscriber = subscriber; + }, + }; + + await startTestBackend({ + extensionPoints: [[eventsExtensionPoint, extensionPoint]], + services: [], + features: [bitbucketCloudEventRouterEventsModule()], + }); + + expect(addedPublisher).not.toBeUndefined(); + expect(addedPublisher).toBeInstanceOf(BitbucketCloudEventRouter); + expect(addedSubscriber).not.toBeUndefined(); + expect(addedSubscriber).toBeInstanceOf(BitbucketCloudEventRouter); + }); +}); diff --git a/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.ts b/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.ts new file mode 100644 index 0000000000..7f755a28f4 --- /dev/null +++ b/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { BitbucketCloudEventRouter } from '../router/BitbucketCloudEventRouter'; + +/** + * Module for the events-backend plugin, adding an event router for Bitbucket Cloud. + * + * Registers the {@link BitbucketCloudEventRouter}. + * + * @alpha + */ +export const bitbucketCloudEventRouterEventsModule = createBackendModule({ + pluginId: 'events', + moduleId: 'bitbucketCloudEventRouter', + register(env) { + env.registerInit({ + deps: { + events: eventsExtensionPoint, + }, + async init({ events }) { + const eventRouter = new BitbucketCloudEventRouter(); + + events.addPublishers(eventRouter); + events.addSubscribers(eventRouter); + }, + }); + }, +}); diff --git a/plugins/events-backend-module-bitbucket-cloud/src/setupTests.ts b/plugins/events-backend-module-bitbucket-cloud/src/setupTests.ts new file mode 100644 index 0000000000..d3232290a7 --- /dev/null +++ b/plugins/events-backend-module-bitbucket-cloud/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 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/yarn.lock b/yarn.lock index 97ca3c01a7..6d392e7561 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6336,6 +6336,20 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-events-backend-module-bitbucket-cloud@workspace:plugins/events-backend-module-bitbucket-cloud": + version: 0.0.0-use.local + resolution: "@backstage/plugin-events-backend-module-bitbucket-cloud@workspace:plugins/events-backend-module-bitbucket-cloud" + dependencies: + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/plugin-events-backend-test-utils": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" + supertest: ^6.1.3 + winston: ^3.2.1 + languageName: unknown + linkType: soft + "@backstage/plugin-events-backend-test-utils@workspace:^, @backstage/plugin-events-backend-test-utils@workspace:plugins/events-backend-test-utils": version: 0.0.0-use.local resolution: "@backstage/plugin-events-backend-test-utils@workspace:plugins/events-backend-test-utils" From b8f913096ccae7d1e614a1d2bd899d2ec4cb5b9d Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Thu, 6 Oct 2022 00:33:59 +0200 Subject: [PATCH 310/434] fix(catalog/bitbucketCloud): fix test file name The file was forgotten to be adjusted as part of PR #13859. Relates-to: PR #13859 Signed-off-by: Patrick Jungermann --- ...est.ts => BitbucketCloudEntityProviderCatalogModule.test.ts} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename plugins/catalog-backend-module-bitbucket-cloud/src/service/{BitbucketCloudCatalogModule.test.ts => BitbucketCloudEntityProviderCatalogModule.test.ts} (100%) diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudCatalogModule.test.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.test.ts similarity index 100% rename from plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudCatalogModule.test.ts rename to plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.test.ts index 6307bee282..7606f7c36a 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudCatalogModule.test.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.test.ts @@ -27,8 +27,8 @@ import { } from '@backstage/backend-tasks'; import { startTestBackend } from '@backstage/backend-test-utils'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; -import { bitbucketCloudEntityProviderCatalogModule } from './BitbucketCloudEntityProviderCatalogModule'; import { Duration } from 'luxon'; +import { bitbucketCloudEntityProviderCatalogModule } from './BitbucketCloudEntityProviderCatalogModule'; import { BitbucketCloudEntityProvider } from '../BitbucketCloudEntityProvider'; describe('bitbucketCloudEntityProviderCatalogModule', () => { From d089fbe7dc1352d2e27c83a2d07f70452960df95 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Sat, 17 Sep 2022 02:01:00 +0200 Subject: [PATCH 311/434] feat(events,catalog/bitbucketCloud): handle repo:push events Relates-to: #10866 Signed-off-by: Patrick Jungermann --- .changeset/angry-starfishes-confess.md | 41 ++++ .changeset/small-chefs-tell.md | 5 + docs/integrations/bitbucketCloud/discovery.md | 66 +++++- plugins/bitbucket-cloud-common/api-report.md | 82 +++++++ .../scripts/reduce-models.js | 14 +- .../src/events/index.ts | 56 +++++ plugins/bitbucket-cloud-common/src/index.ts | 1 + .../src/models/index.ts | 42 ++++ .../api-report.md | 17 +- .../package.json | 6 + .../src/BitbucketCloudEntityProvider.test.ts | 2 + .../src/BitbucketCloudEntityProvider.ts | 213 ++++++++++++++++-- ...etCloudEntityProviderCatalogModule.test.ts | 27 ++- ...tbucketCloudEntityProviderCatalogModule.ts | 25 +- yarn.lock | 5 + 15 files changed, 571 insertions(+), 31 deletions(-) create mode 100644 .changeset/angry-starfishes-confess.md create mode 100644 .changeset/small-chefs-tell.md create mode 100644 plugins/bitbucket-cloud-common/src/events/index.ts diff --git a/.changeset/angry-starfishes-confess.md b/.changeset/angry-starfishes-confess.md new file mode 100644 index 0000000000..5cb4395d9a --- /dev/null +++ b/.changeset/angry-starfishes-confess.md @@ -0,0 +1,41 @@ +--- +'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch +--- + +Handle Bitbucket Cloud `repo:push` events at the `BitbucketCloudEntityProvider` +by subscribing to the topic `bitbucketCloud.repo:push.` + +Implements `EventSubscriber` to receive events for the topic `bitbucketCloud.repo:push`. + +On `repo:push`, the affected repository will be refreshed. +This includes adding new Location entities, refreshing existing ones, +and removing obsolete ones. + +To support this, a new annotation `bitbucket.org/repo-url` was added +to Location entities. + +A full refresh will require 1 API call to Bitbucket Cloud to discover all catalog files. +When we handle one `repo:push` event, we also need 1 API call in order to know +which catalog files exist. +This may lead to more discovery-related API calls (code search). +The main cause for hitting the rate limits are Locations refresh-related operations. + +A reduction of total API calls to reduce the rate limit issues can only be achieved in +combination with + +1. reducing the full refresh frequency (e.g., to monthly) +2. reducing the frequency of general Location refresh operations by the processing loop + +For (2.), it is not possible to reduce the frequency only for Bitbucket Cloud-related +Locations though. + +Further optimizations might be required to resolve the rate limit issue. + +**Installation and Migration** + +Please find more information at +https://backstage.io/docs/integrations/bitbucketCloud/discovery, +in particular the section about "_Installation with Events Support_". + +In case of the new backend-plugin-api _(alpha)_ the module will take care of +registering itself at both. diff --git a/.changeset/small-chefs-tell.md b/.changeset/small-chefs-tell.md new file mode 100644 index 0000000000..46d8a33f3c --- /dev/null +++ b/.changeset/small-chefs-tell.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-bitbucket-cloud-common': patch +--- + +Add interfaces for Bitbucket Cloud (webhook) events. diff --git a/docs/integrations/bitbucketCloud/discovery.md b/docs/integrations/bitbucketCloud/discovery.md index 9b9bc4ecde..f6ceab9ff7 100644 --- a/docs/integrations/bitbucketCloud/discovery.md +++ b/docs/integrations/bitbucketCloud/discovery.md @@ -24,10 +24,12 @@ package. yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-bitbucket-cloud ``` +### Installation without Events Support + And then add the entity provider to your catalog builder: ```diff - // In packages/backend/src/plugins/catalog.ts +// packages/backend/src/plugins/catalog.ts + import { BitbucketCloudEntityProvider } from '@backstage/plugin-catalog-backend-module-bitbucket-cloud'; export default async function createPlugin( @@ -37,11 +39,7 @@ And then add the entity provider to your catalog builder: + builder.addEntityProvider( + BitbucketCloudEntityProvider.fromConfig(env.config, { + logger: env.logger, -+ // optional: alternatively, configure via app-config.yaml -+ schedule: env.scheduler.createScheduledTaskRunner({ -+ frequency: { minutes: 30 }, -+ timeout: { minutes: 3 }, -+ }), ++ scheduler: env.scheduler, + }), + ); @@ -49,6 +47,62 @@ And then add the entity provider to your catalog builder: } ``` +Alternatively to the config-based schedule, you can use + +```diff +- scheduler: env.scheduler, ++ schedule: env.scheduler.createScheduledTaskRunner({ ++ frequency: { minutes: 30 }, ++ timeout: { minutes: 3 }, ++ }), +``` + +### Installation with Events Support + +Please follow the installation instructions at + +- https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md +- https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-bitbucket-cloud/README.md + +Additionally, you need to decide how you want to receive events from external sources like + +- [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) +- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md) + +Set up your provider + +```diff +// packages/backend/src/plugins/catalogEventBasedProviders.ts ++import { CatalogClient } from '@backstage/catalog-client'; ++import { BitbucketCloudEntityProvider } from '@backstage/plugin-catalog-backend-module-bitbucket-cloud'; + import { EntityProvider } from '@backstage/plugin-catalog-node'; + import { EventSubscriber } from '@backstage/plugin-events-node'; + import { PluginEnvironment } from '../types'; + + export default async function createCatalogEventBasedProviders( +- _: PluginEnvironment, ++ env: PluginEnvironment, + ): Promise> { + const providers: Array< + (EntityProvider & EventSubscriber) | Array + > = []; +- // add your event-based entity providers here ++ providers.push( ++ BitbucketCloudEntityProvider.fromConfig(env.config, { ++ catalogApi: new CatalogClient({ discoveryApi: env.discovery }), ++ logger: env.logger, ++ scheduler: env.scheduler, ++ tokenManager: env.tokenManager, ++ }), ++ ); + return providers.flat(); + } +``` + +**Attention:** +`catalogApi` and `tokenManager` are required at this variant +compared to the one without events support. + ## Configuration To use the entity provider, you'll need a [Bitbucket Cloud integration set up](locations.md). diff --git a/plugins/bitbucket-cloud-common/api-report.md b/plugins/bitbucket-cloud-common/api-report.md index d66b8b9a70..5182579a4b 100644 --- a/plugins/bitbucket-cloud-common/api-report.md +++ b/plugins/bitbucket-cloud-common/api-report.md @@ -24,6 +24,57 @@ export class BitbucketCloudClient { ): WithPagination; } +// @public (undocumented) +export namespace Events { + // (undocumented) + export interface Change { + // (undocumented) + closed: boolean; + // (undocumented) + commits: Models.Commit[]; + // (undocumented) + created: boolean; + // (undocumented) + forced: boolean; + // (undocumented) + links: ChangeLinks; + // (undocumented) + new: Models.Branch; + // (undocumented) + old: Models.Branch; + // (undocumented) + truncated: boolean; + } + // (undocumented) + export interface ChangeLinks { + // (undocumented) + commits: Models.Link; + // (undocumented) + diff: Models.Link; + // (undocumented) + html: Models.Link; + } + // (undocumented) + export interface RepoEvent { + // (undocumented) + actor: Models.Account; + // (undocumented) + repository: Models.Repository & { + workspace: Models.Workspace; + }; + } + // (undocumented) + export interface RepoPush { + // (undocumented) + changes: Change[]; + } + // (undocumented) + export interface RepoPushEvent extends RepoEvent { + // (undocumented) + push: RepoPush; + } +} + // @public (undocumented) export type FilterAndSortOptions = { q?: string; @@ -340,6 +391,37 @@ export namespace Models { // (undocumented) self?: Link; } + export interface Workspace extends ModelObject { + // (undocumented) + created_on?: string; + is_private?: boolean; + // (undocumented) + links?: WorkspaceLinks; + name?: string; + slug?: string; + // (undocumented) + updated_on?: string; + uuid?: string; + } + // (undocumented) + export interface WorkspaceLinks { + // (undocumented) + avatar?: Link; + // (undocumented) + html?: Link; + // (undocumented) + members?: Link; + // (undocumented) + owners?: Link; + // (undocumented) + projects?: Link; + // (undocumented) + repositories?: Link; + // (undocumented) + self?: Link; + // (undocumented) + snippets?: Link; + } } // @public (undocumented) diff --git a/plugins/bitbucket-cloud-common/scripts/reduce-models.js b/plugins/bitbucket-cloud-common/scripts/reduce-models.js index 9d458f4e74..115020493c 100755 --- a/plugins/bitbucket-cloud-common/scripts/reduce-models.js +++ b/plugins/bitbucket-cloud-common/scripts/reduce-models.js @@ -30,6 +30,14 @@ const modelsModule = modelsFile.getModuleOrThrow('Models'); const clientFile = project.getSourceFile('src/BitbucketCloudClient.ts'); const clientClass = clientFile.getClassOrThrow('BitbucketCloudClient'); +const eventsFile = project.getSourceFile('src/events/index.ts'); +const eventsModule = eventsFile.getModuleOrThrow('Events'); +const eventsStmts = [ + ...eventsModule.getClasses(), + ...eventsModule.getInterfaces(), + ...eventsModule.getTypeAliases(), +]; + /** * Returns an array of the unique items of the provided array. * @@ -79,7 +87,11 @@ function referencedModelsIdentifiers(stmt, processed) { } // all directly or transitively referenced/used `Models.[...]` are allowed to stay -const allowed = referencedModelsIdentifiers(clientClass); +const processed = []; +const allowed = referencedModelsIdentifiers(clientClass, processed); +allowed.push( + ...eventsStmts.flatMap(stmt => referencedModelsIdentifiers(stmt, processed)), +); // remove everything not part of the "allow list" modelsModule diff --git a/plugins/bitbucket-cloud-common/src/events/index.ts b/plugins/bitbucket-cloud-common/src/events/index.ts new file mode 100644 index 0000000000..53658be032 --- /dev/null +++ b/plugins/bitbucket-cloud-common/src/events/index.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Models } from '../models'; + +// source: https://support.atlassian.com/bitbucket-cloud/docs/event-payloads + +/** @public */ +export namespace Events { + /** @public */ + export interface RepoEvent { + repository: Models.Repository & { workspace: Models.Workspace }; + actor: Models.Account; + } + + /** @public */ + export interface RepoPushEvent extends RepoEvent { + push: RepoPush; + } + + /** @public */ + export interface RepoPush { + changes: Change[]; + } + + /** @public */ + export interface Change { + old: Models.Branch; + new: Models.Branch; + truncated: boolean; + created: boolean; + forced: boolean; + closed: boolean; + links: ChangeLinks; + commits: Models.Commit[]; + } + + /** @public */ + export interface ChangeLinks { + commits: Models.Link; + diff: Models.Link; + html: Models.Link; + } +} diff --git a/plugins/bitbucket-cloud-common/src/index.ts b/plugins/bitbucket-cloud-common/src/index.ts index 4edf148240..4a9b00e89b 100644 --- a/plugins/bitbucket-cloud-common/src/index.ts +++ b/plugins/bitbucket-cloud-common/src/index.ts @@ -21,6 +21,7 @@ */ export * from './BitbucketCloudClient'; +export * from './events'; export * from './models'; export * from './pagination'; export * from './types'; diff --git a/plugins/bitbucket-cloud-common/src/models/index.ts b/plugins/bitbucket-cloud-common/src/models/index.ts index 580f23a13f..9d25bbb873 100644 --- a/plugins/bitbucket-cloud-common/src/models/index.ts +++ b/plugins/bitbucket-cloud-common/src/models/index.ts @@ -518,4 +518,46 @@ export namespace Models { repositories?: Link; self?: Link; } + + /** + * A Bitbucket workspace. + * Workspaces are used to organize repositories. + * @public + */ + export interface Workspace extends ModelObject { + created_on?: string; + /** + * Indicates whether the workspace is publicly accessible, or whether it is + * private to the members and consequently only visible to members. + */ + is_private?: boolean; + links?: WorkspaceLinks; + /** + * The name of the workspace. + */ + name?: string; + /** + * The short label that identifies this workspace. + */ + slug?: string; + updated_on?: string; + /** + * The workspace's immutable id. + */ + uuid?: string; + } + + /** + * @public + */ + export interface WorkspaceLinks { + avatar?: Link; + html?: Link; + members?: Link; + owners?: Link; + projects?: Link; + repositories?: Link; + self?: Link; + snippets?: Link; + } } diff --git a/plugins/catalog-backend-module-bitbucket-cloud/api-report.md b/plugins/catalog-backend-module-bitbucket-cloud/api-report.md index 162ff8f67e..480395e477 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/api-report.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/api-report.md @@ -4,24 +4,33 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; +import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { EntityProvider } from '@backstage/plugin-catalog-backend'; import { EntityProviderConnection } from '@backstage/plugin-catalog-backend'; +import { EventParams } from '@backstage/plugin-events-node'; +import { Events } from '@backstage/plugin-bitbucket-cloud-common'; +import { EventSubscriber } from '@backstage/plugin-events-node'; import { Logger } from 'winston'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { TaskRunner } from '@backstage/backend-tasks'; +import { TokenManager } from '@backstage/backend-common'; // @public -export class BitbucketCloudEntityProvider implements EntityProvider { +export class BitbucketCloudEntityProvider + implements EntityProvider, EventSubscriber +{ // (undocumented) connect(connection: EntityProviderConnection): Promise; // (undocumented) static fromConfig( config: Config, options: { + catalogApi?: CatalogApi; logger: Logger; schedule?: TaskRunner; scheduler?: PluginTaskScheduler; + tokenManager?: TokenManager; }, ): BitbucketCloudEntityProvider[]; // (undocumented) @@ -29,7 +38,13 @@ export class BitbucketCloudEntityProvider implements EntityProvider { // (undocumented) getTaskId(): string; // (undocumented) + onEvent(params: EventParams): Promise; + // (undocumented) + onRepoPush(event: Events.RepoPushEvent): Promise; + // (undocumented) refresh(logger: Logger): Promise; + // (undocumented) + supportsEventTopics(): string[]; } // @alpha (undocumented) diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index 45876470d4..e7cd57b560 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -33,13 +33,19 @@ "clean": "backstage-cli package clean" }, "dependencies": { + "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/backend-tasks": "workspace:^", + "@backstage/catalog-client": "workspace:^", + "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/plugin-bitbucket-cloud-common": "workspace:^", "@backstage/plugin-catalog-backend": "workspace:^", + "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", + "@backstage/plugin-events-node": "workspace:^", + "p-limit": "^3.1.0", "uuid": "^8.0.0", "winston": "^3.2.1" }, diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.test.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.test.ts index 7d780cd064..72974a1c94 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.test.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.test.ts @@ -333,6 +333,8 @@ describe('BitbucketCloudEntityProvider', () => { annotations: { 'backstage.io/managed-by-location': `url:${url}`, 'backstage.io/managed-by-origin-location': `url:${url}`, + 'bitbucket.org/repo-url': + 'https://bitbucket.org/test-ws/test-repo2', }, name: 'generated-7c2e6263b6cc2d14e69fd4d029afba601ad6dc3b', }, diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.ts index f3334a6574..37ad60426d 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.ts @@ -14,7 +14,14 @@ * limitations under the License. */ +import { TokenManager } from '@backstage/backend-common'; import { PluginTaskScheduler, TaskRunner } from '@backstage/backend-tasks'; +import { CatalogApi } from '@backstage/catalog-client'; +import { + Entity, + LocationEntity, + stringifyEntityRef, +} from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { BitbucketCloudIntegration, @@ -22,22 +29,35 @@ import { } from '@backstage/integration'; import { BitbucketCloudClient, + Events, Models, } from '@backstage/plugin-bitbucket-cloud-common'; import { + DeferredEntity, EntityProvider, EntityProviderConnection, - LocationSpec, locationSpecToLocationEntity, } from '@backstage/plugin-catalog-backend'; +import { LocationSpec } from '@backstage/plugin-catalog-common'; +import { EventParams, EventSubscriber } from '@backstage/plugin-events-node'; import { BitbucketCloudEntityProviderConfig, readProviderConfigs, } from './BitbucketCloudEntityProviderConfig'; +import limiterFactory from 'p-limit'; import * as uuid from 'uuid'; import { Logger } from 'winston'; const DEFAULT_BRANCH = 'master'; +const TOPIC_REPO_PUSH = 'bitbucketCloud/repo:push'; + +/** @public */ +export const ANNOTATION_BITBUCKET_CLOUD_REPO_URL = 'bitbucket.org/repo-url'; + +interface IngestionTarget { + fileUrl: string; + repoUrl: string; +} /** * Discovers catalog files located in [Bitbucket Cloud](https://bitbucket.org). @@ -47,19 +67,27 @@ const DEFAULT_BRANCH = 'master'; * * @public */ -export class BitbucketCloudEntityProvider implements EntityProvider { +export class BitbucketCloudEntityProvider + implements EntityProvider, EventSubscriber +{ private readonly client: BitbucketCloudClient; private readonly config: BitbucketCloudEntityProviderConfig; private readonly logger: Logger; private readonly scheduleFn: () => Promise; + private readonly catalogApi?: CatalogApi; + private readonly tokenManager?: TokenManager; private connection?: EntityProviderConnection; + private eventConfigErrorThrown = false; + static fromConfig( config: Config, options: { + catalogApi?: CatalogApi; logger: Logger; schedule?: TaskRunner; scheduler?: PluginTaskScheduler; + tokenManager?: TokenManager; }, ): BitbucketCloudEntityProvider[] { const integrations = ScmIntegrations.fromConfig(config); @@ -90,6 +118,8 @@ export class BitbucketCloudEntityProvider implements EntityProvider { integration, options.logger, taskRunner, + options.catalogApi, + options.tokenManager, ); }); } @@ -99,6 +129,8 @@ export class BitbucketCloudEntityProvider implements EntityProvider { integration: BitbucketCloudIntegration, logger: Logger, taskRunner: TaskRunner, + catalogApi?: CatalogApi, + tokenManager?: TokenManager, ) { this.client = BitbucketCloudClient.fromConfig(integration.config); this.config = config; @@ -106,6 +138,8 @@ export class BitbucketCloudEntityProvider implements EntityProvider { target: this.getProviderName(), }); this.scheduleFn = this.createScheduleFn(taskRunner); + this.catalogApi = catalogApi; + this.tokenManager = tokenManager; } private createScheduleFn(schedule: TaskRunner): () => Promise { @@ -154,15 +188,7 @@ export class BitbucketCloudEntityProvider implements EntityProvider { logger.info('Discovering catalog files in Bitbucket Cloud repositories'); const targets = await this.findCatalogFiles(); - const entities = targets - .map(BitbucketCloudEntityProvider.toLocationSpec) - .map(location => locationSpecToLocationEntity({ location })) - .map(entity => { - return { - locationKey: this.getProviderName(), - entity: entity, - }; - }); + const entities = this.toDeferredEntities(targets); await this.connection.applyMutation({ type: 'full', @@ -174,7 +200,135 @@ export class BitbucketCloudEntityProvider implements EntityProvider { ); } - private async findCatalogFiles(): Promise { + /** {@inheritdoc @backstage/plugin-events-node#EventSubscriber.supportsEventTopics} */ + supportsEventTopics(): string[] { + return [TOPIC_REPO_PUSH]; + } + + /** {@inheritdoc @backstage/plugin-events-node#EventSubscriber.onEvent} */ + async onEvent(params: EventParams): Promise { + if (params.topic !== TOPIC_REPO_PUSH) { + return; + } + + if (params.metadata?.['x-event-key'] === 'repo:push') { + await this.onRepoPush(params.eventPayload as Events.RepoPushEvent); + } + } + + private canHandleEvents(): boolean { + if (this.catalogApi && this.tokenManager) { + return true; + } + + // throw only once + if (!this.eventConfigErrorThrown) { + this.eventConfigErrorThrown = true; + throw new Error( + `${this.getProviderName()} not well configured to handle repo:push. Missing CatalogApi and/or TokenManager.`, + ); + } + + return false; + } + + async onRepoPush(event: Events.RepoPushEvent): Promise { + if (!this.canHandleEvents()) { + return; + } + + if (!this.connection) { + throw new Error('Not initialized'); + } + + if (event.repository.workspace.slug !== this.config.workspace) { + return; + } + + if (!this.matchesFilters(event.repository)) { + return; + } + + const repoName = event.repository.slug; + const repoUrl = event.repository.links!.html!.href!; + this.logger.info(`handle repo:push event for ${repoUrl}`); + + // The commit information at the webhook only contains some high level metadata. + // In order to understand whether relevant files have changed we would need to + // look up all commits which would cost additional API calls. + // The overall goal is to optimize the necessary amount of API calls. + // Hence, we will just trigger a refresh for catalog file(s) within the repository + // if we get notified about changes there. + + const targets = await this.findCatalogFiles(repoName); + + const { token } = await this.tokenManager!.getToken(); + const existing = await this.findExistingLocations(repoUrl, token); + + const added: DeferredEntity[] = this.toDeferredEntities( + targets.filter( + // All Locations are managed by this provider and only have `target`, never `targets`. + // All URLs (fileUrl, target) are created using `BitbucketCloudEntityProvider.toUrl`. + // Hence, we can keep the comparison simple and don't need to handle different + // casing or encoding, etc. + target => !existing.find(item => item.spec.target === target.fileUrl), + ), + ); + + const limiter = limiterFactory(10); + + const stillExisting: Entity[] = []; + const removed: DeferredEntity[] = []; + existing.forEach(item => { + if (targets.find(value => value.fileUrl === item.spec.target)) { + stillExisting.push(item); + } else { + removed.push({ + locationKey: this.getProviderName(), + entity: item, + }); + } + }); + + const promises: Promise[] = stillExisting.map(entity => + limiter(async () => + this.catalogApi!.refreshEntity(stringifyEntityRef(entity), { token }), + ), + ); + + if (added.length > 0 || removed.length > 0) { + const connection = this.connection; + promises.push( + limiter(async () => + connection.applyMutation({ + type: 'delta', + added: added, + removed: removed, + }), + ), + ); + } + + await Promise.all(promises); + } + + private async findExistingLocations( + repoUrl: string, + token: string, + ): Promise { + const filter: Record = {}; + filter.kind = 'Location'; + filter[`metadata.annotations.${ANNOTATION_BITBUCKET_CLOUD_REPO_URL}`] = + repoUrl; + + return this.catalogApi!.getEntities({ filter }, { token }).then( + result => result.items, + ) as Promise; + } + + private async findCatalogFiles( + repoName?: string, + ): Promise { const workspace = this.config.workspace; const catalogPath = this.config.catalogPath; @@ -197,12 +351,13 @@ export class BitbucketCloudEntityProvider implements EntityProvider { // ...except the one we need '+values.file.commit.repository.links.html.href', ].join(','); - const query = `"${catalogFilename}" path:${catalogPath}`; + const optRepoFilter = repoName ? ` repo:${repoName}` : ''; + const query = `"${catalogFilename}" path:${catalogPath}${optRepoFilter}`; const searchResults = this.client .searchCode(workspace, query, { fields }) .iterateResults(); - const result: string[] = []; + const result: IngestionTarget[] = []; for await (const searchResult of searchResults) { // not a file match, but a code match @@ -212,12 +367,13 @@ export class BitbucketCloudEntityProvider implements EntityProvider { const repository = searchResult.file!.commit!.repository!; if (this.matchesFilters(repository)) { - result.push( - BitbucketCloudEntityProvider.toUrl( + result.push({ + fileUrl: BitbucketCloudEntityProvider.toUrl( repository, searchResult.file!.path!, ), - ); + repoUrl: repository.links!.html!.href!, + }); } } @@ -234,11 +390,32 @@ export class BitbucketCloudEntityProvider implements EntityProvider { ); } + private toDeferredEntities(targets: IngestionTarget[]): DeferredEntity[] { + return targets + .map(target => { + const location = BitbucketCloudEntityProvider.toLocationSpec( + target.fileUrl, + ); + const entity = locationSpecToLocationEntity({ location }); + entity.metadata.annotations = { + ...entity.metadata.annotations, + [ANNOTATION_BITBUCKET_CLOUD_REPO_URL]: target.repoUrl, + }; + return entity; + }) + .map(entity => { + return { + locationKey: this.getProviderName(), + entity: entity, + }; + }); + } + private static toUrl( repository: Models.Repository, filePath: string, ): string { - const repoUrl = repository.links!.html!.href; + const repoUrl = repository.links!.html!.href!; const branch = repository.mainbranch?.name ?? DEFAULT_BRANCH; return `${repoUrl}/src/${branch}/${filePath}`; diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.test.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.test.ts index 7606f7c36a..3fcc39fdd0 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.test.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.test.ts @@ -15,11 +15,17 @@ */ import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; +import { + getVoidLogger, + PluginEndpointDiscovery, + TokenManager, +} from '@backstage/backend-common'; import { configServiceRef, + discoveryServiceRef, loggerServiceRef, schedulerServiceRef, + tokenManagerServiceRef, } from '@backstage/backend-plugin-api'; import { PluginTaskScheduler, @@ -27,6 +33,7 @@ import { } from '@backstage/backend-tasks'; import { startTestBackend } from '@backstage/backend-test-utils'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; import { Duration } from 'luxon'; import { bitbucketCloudEntityProviderCatalogModule } from './BitbucketCloudEntityProviderCatalogModule'; import { BitbucketCloudEntityProvider } from '../BitbucketCloudEntityProvider'; @@ -34,13 +41,19 @@ import { BitbucketCloudEntityProvider } from '../BitbucketCloudEntityProvider'; describe('bitbucketCloudEntityProviderCatalogModule', () => { it('should register provider at the catalog extension point', async () => { let addedProviders: Array | undefined; + let addedSubscribers: Array | undefined; let usedSchedule: TaskScheduleDefinition | undefined; - const extensionPoint = { + const catalogExtensionPointImpl = { addEntityProvider: (providers: any) => { addedProviders = providers; }, }; + const eventsExtensionPointImpl = { + addSubscribers: (subscribers: any) => { + addedSubscribers = subscribers; + }, + }; const runner = jest.fn(); const scheduler = { createScheduledTaskRunner: (schedule: TaskScheduleDefinition) => { @@ -48,6 +61,8 @@ describe('bitbucketCloudEntityProviderCatalogModule', () => { return runner; }, } as unknown as PluginTaskScheduler; + const discovery = jest.fn() as any as PluginEndpointDiscovery; + const tokenManager = jest.fn() as any as TokenManager; const config = new ConfigReader({ catalog: { @@ -64,11 +79,16 @@ describe('bitbucketCloudEntityProviderCatalogModule', () => { }); await startTestBackend({ - extensionPoints: [[catalogProcessingExtensionPoint, extensionPoint]], + extensionPoints: [ + [catalogProcessingExtensionPoint, catalogExtensionPointImpl], + [eventsExtensionPoint, eventsExtensionPointImpl], + ], services: [ [configServiceRef, config], + [discoveryServiceRef, discovery], [loggerServiceRef, getVoidLogger()], [schedulerServiceRef, scheduler], + [tokenManagerServiceRef, tokenManager], ], features: [bitbucketCloudEntityProviderCatalogModule()], }); @@ -79,6 +99,7 @@ describe('bitbucketCloudEntityProviderCatalogModule', () => { expect(addedProviders?.pop()?.getProviderName()).toEqual( 'bitbucketCloud-provider:default', ); + expect(addedSubscribers).toEqual(addedProviders); expect(runner).not.toHaveBeenCalled(); }); }); diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.ts index d137bd7166..1c005991a6 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.ts @@ -20,8 +20,13 @@ import { loggerServiceRef, loggerToWinstonLogger, schedulerServiceRef, + tokenManagerServiceRef, } from '@backstage/backend-plugin-api'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { + catalogProcessingExtensionPoint, + catalogServiceRef, +} from '@backstage/plugin-catalog-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; import { BitbucketCloudEntityProvider } from '../BitbucketCloudEntityProvider'; /** @@ -34,18 +39,34 @@ export const bitbucketCloudEntityProviderCatalogModule = createBackendModule({ env.registerInit({ deps: { catalog: catalogProcessingExtensionPoint, + catalogApi: catalogServiceRef, config: configServiceRef, + // TODO(pjungermann): How to make this optional for those which only want the provider without event support? + // Do we even want to support this? + events: eventsExtensionPoint, logger: loggerServiceRef, scheduler: schedulerServiceRef, + tokenManager: tokenManagerServiceRef, }, - async init({ catalog, config, logger, scheduler }) { + async init({ + catalog, + catalogApi, + config, + events, + logger, + scheduler, + tokenManager, + }) { const winstonLogger = loggerToWinstonLogger(logger); const providers = BitbucketCloudEntityProvider.fromConfig(config, { + catalogApi, logger: winstonLogger, scheduler, + tokenManager, }); catalog.addEntityProvider(providers); + events.addSubscribers(providers); }, }); }, diff --git a/yarn.lock b/yarn.lock index 6d392e7561..7bed901253 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5449,14 +5449,19 @@ __metadata: "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" "@backstage/backend-test-utils": "workspace:^" + "@backstage/catalog-client": "workspace:^" + "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-bitbucket-cloud-common": "workspace:^" "@backstage/plugin-catalog-backend": "workspace:^" + "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" luxon: ^3.0.0 msw: ^0.48.0 + p-limit: ^3.1.0 uuid: ^8.0.0 winston: ^3.2.1 languageName: unknown From b3a4edb885f2fee4ee90b1278d44efdeff754ef9 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Mon, 24 Oct 2022 04:39:26 +0200 Subject: [PATCH 312/434] feat(events/github): add `GithubEventRouter` Add an event router for GitHub which handles events from the topic `github` and re-publishes events under their more specific topic based on the `x-github-event` metadata like e.g., `github.push`. Signed-off-by: Patrick Jungermann --- .changeset/funny-countries-watch.md | 14 ++++++ .github/CODEOWNERS | 1 + .../events-backend-module-github/.eslintrc.js | 1 + .../events-backend-module-github/README.md | 43 +++++++++++++++++ .../api-report.md | 21 +++++++++ .../events-backend-module-github/package.json | 40 ++++++++++++++++ .../events-backend-module-github/src/index.ts | 25 ++++++++++ .../src/router/GithubEventRouter.test.ts | 46 +++++++++++++++++++ .../src/router/GithubEventRouter.ts | 37 +++++++++++++++ .../GithubEventRouterEventsModule.test.ts | 46 +++++++++++++++++++ .../service/GithubEventRouterEventsModule.ts | 44 ++++++++++++++++++ .../src/setupTests.ts | 17 +++++++ yarn.lock | 14 ++++++ 13 files changed, 349 insertions(+) create mode 100644 .changeset/funny-countries-watch.md create mode 100644 plugins/events-backend-module-github/.eslintrc.js create mode 100644 plugins/events-backend-module-github/README.md create mode 100644 plugins/events-backend-module-github/api-report.md create mode 100644 plugins/events-backend-module-github/package.json create mode 100644 plugins/events-backend-module-github/src/index.ts create mode 100644 plugins/events-backend-module-github/src/router/GithubEventRouter.test.ts create mode 100644 plugins/events-backend-module-github/src/router/GithubEventRouter.ts create mode 100644 plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.test.ts create mode 100644 plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.ts create mode 100644 plugins/events-backend-module-github/src/setupTests.ts diff --git a/.changeset/funny-countries-watch.md b/.changeset/funny-countries-watch.md new file mode 100644 index 0000000000..452146d762 --- /dev/null +++ b/.changeset/funny-countries-watch.md @@ -0,0 +1,14 @@ +--- +'@backstage/plugin-events-backend-module-github': minor +--- + +Adds a new module `github` to plugin-events-backend. + +The module adds a new event router `GithubEventRouter`. + +The event router will re-publish events received at topic `github` +under a more specific topic depending on their `x-github-event` value +(e.g., `github.push`). + +Please find more information at +https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-github/README.md. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 235392c9bf..4fc500cf35 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -39,6 +39,7 @@ yarn.lock @backstage/reviewers @backst /plugins/events-backend @backstage/reviewers @pjungermann /plugins/events-backend-module-aws-sqs @backstage/reviewers @pjungermann /plugins/events-backend-module-bitbucket-cloud @backstage/reviewers @pjungermann +/plugins/events-backend-module-github @backstage/reviewers @pjungermann /plugins/events-backend-test-utils @backstage/reviewers @pjungermann /plugins/events-node @backstage/reviewers @pjungermann /plugins/explore @backstage/reviewers @backstage/sda-se-reviewers diff --git a/plugins/events-backend-module-github/.eslintrc.js b/plugins/events-backend-module-github/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/events-backend-module-github/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/events-backend-module-github/README.md b/plugins/events-backend-module-github/README.md new file mode 100644 index 0000000000..b111b79dd0 --- /dev/null +++ b/plugins/events-backend-module-github/README.md @@ -0,0 +1,43 @@ +# events-backend-module-github + +Welcome to the `events-backend-module-github` backend plugin! + +This plugin is a module for the `events-backend` backend plugin +and extends it with an `GithubEventRouter`. + +The event router will subscribe to the topic `github` +and route the events to more concrete topics based on the value +of the provided `x-github-event` metadata field. + +Examples: + +| `x-github-event` | topic | +| ---------------- | --------------------- | +| `pull_request` | `github.pull_request` | +| `push` | `github.push` | +| `repository` | `github.repository` | + +Please find all possible webhook event types at the +[official documentation](https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads). + +## Installation + +Install the [`events-backend` plugin](../events-backend/README.md). + +Install this module: + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-events-backend-module-github +``` + +Add the event router to the `EventsBackend`: + +```diff ++const githubEventRouter = new GithubEventRouter(); + + EventsBackend ++ .addPublishers(githubEventRouter) ++ .addSubscribers(githubEventRouter); +// [...] +``` diff --git a/plugins/events-backend-module-github/api-report.md b/plugins/events-backend-module-github/api-report.md new file mode 100644 index 0000000000..25ce30523a --- /dev/null +++ b/plugins/events-backend-module-github/api-report.md @@ -0,0 +1,21 @@ +## API Report File for "@backstage/plugin-events-backend-module-github" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { EventParams } from '@backstage/plugin-events-node'; +import { SubTopicEventRouter } from '@backstage/plugin-events-node'; + +// @public +export class GithubEventRouter extends SubTopicEventRouter { + constructor(); + // (undocumented) + protected determineSubTopic(params: EventParams): string | undefined; +} + +// @alpha +export const githubEventRouterEventsModule: ( + options?: undefined, +) => BackendFeature; +``` diff --git a/plugins/events-backend-module-github/package.json b/plugins/events-backend-module-github/package.json new file mode 100644 index 0000000000..7307826297 --- /dev/null +++ b/plugins/events-backend-module-github/package.json @@ -0,0 +1,40 @@ +{ + "name": "@backstage/plugin-events-backend-module-github", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "alphaTypes": "dist/index.alpha.d.ts", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build --experimental-type-build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-plugin-api": "workspace:^", + "@backstage/plugin-events-node": "workspace:^", + "winston": "^3.2.1" + }, + "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "@backstage/plugin-events-backend-test-utils": "workspace:^", + "supertest": "^6.1.3" + }, + "files": [ + "alpha", + "dist" + ] +} diff --git a/plugins/events-backend-module-github/src/index.ts b/plugins/events-backend-module-github/src/index.ts new file mode 100644 index 0000000000..672d82e6dc --- /dev/null +++ b/plugins/events-backend-module-github/src/index.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2020 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. + */ + +/** + * The module `github` for the Backstage backend plugin "events-backend" + * adding an event router for GitHub. + * + * @packageDocumentation + */ + +export { GithubEventRouter } from './router/GithubEventRouter'; +export { githubEventRouterEventsModule } from './service/GithubEventRouterEventsModule'; diff --git a/plugins/events-backend-module-github/src/router/GithubEventRouter.test.ts b/plugins/events-backend-module-github/src/router/GithubEventRouter.test.ts new file mode 100644 index 0000000000..14cf6b9933 --- /dev/null +++ b/plugins/events-backend-module-github/src/router/GithubEventRouter.test.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils'; +import { GithubEventRouter } from './GithubEventRouter'; + +describe('GithubEventRouter', () => { + const eventRouter = new GithubEventRouter(); + const topic = 'github'; + const eventPayload = { test: 'payload' }; + const metadata = { 'x-github-event': 'test_type' }; + + it('no x-github-event', () => { + const eventBroker = new TestEventBroker(); + eventRouter.setEventBroker(eventBroker); + + eventRouter.onEvent({ topic, eventPayload }); + + expect(eventBroker.published).toEqual([]); + }); + + it('with x-github-event', () => { + const eventBroker = new TestEventBroker(); + eventRouter.setEventBroker(eventBroker); + + eventRouter.onEvent({ topic, eventPayload, metadata }); + + expect(eventBroker.published.length).toBe(1); + expect(eventBroker.published[0].topic).toEqual('github.test_type'); + expect(eventBroker.published[0].eventPayload).toEqual(eventPayload); + expect(eventBroker.published[0].metadata).toEqual(metadata); + }); +}); diff --git a/plugins/events-backend-module-github/src/router/GithubEventRouter.ts b/plugins/events-backend-module-github/src/router/GithubEventRouter.ts new file mode 100644 index 0000000000..10dd1c55c6 --- /dev/null +++ b/plugins/events-backend-module-github/src/router/GithubEventRouter.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + EventParams, + SubTopicEventRouter, +} from '@backstage/plugin-events-node'; + +/** + * Subscribes to the generic `github` topic + * and publishes the events under the more concrete sub-topic + * depending on the `x-github-event` provided. + * + * @public + */ +export class GithubEventRouter extends SubTopicEventRouter { + constructor() { + super('github'); + } + + protected determineSubTopic(params: EventParams): string | undefined { + return params.metadata?.['x-github-event'] as string | undefined; + } +} diff --git a/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.test.ts b/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.test.ts new file mode 100644 index 0000000000..694f5e1dbe --- /dev/null +++ b/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.test.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { startTestBackend } from '@backstage/backend-test-utils'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { githubEventRouterEventsModule } from './GithubEventRouterEventsModule'; +import { GithubEventRouter } from '../router/GithubEventRouter'; + +describe('githubEventRouterEventsModule', () => { + it('should be correctly wired and set up', async () => { + let addedPublisher: GithubEventRouter | undefined; + let addedSubscriber: GithubEventRouter | undefined; + const extensionPoint = { + addPublishers: (publisher: any) => { + addedPublisher = publisher; + }, + addSubscribers: (subscriber: any) => { + addedSubscriber = subscriber; + }, + }; + + await startTestBackend({ + extensionPoints: [[eventsExtensionPoint, extensionPoint]], + services: [], + features: [githubEventRouterEventsModule()], + }); + + expect(addedPublisher).not.toBeUndefined(); + expect(addedPublisher).toBeInstanceOf(GithubEventRouter); + expect(addedSubscriber).not.toBeUndefined(); + expect(addedSubscriber).toBeInstanceOf(GithubEventRouter); + }); +}); diff --git a/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.ts b/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.ts new file mode 100644 index 0000000000..8914d07e71 --- /dev/null +++ b/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { GithubEventRouter } from '../router/GithubEventRouter'; + +/** + * Module for the events-backend plugin, adding an event router for GitHub. + * + * Registers the {@link GithubEventRouter}. + * + * @alpha + */ +export const githubEventRouterEventsModule = createBackendModule({ + pluginId: 'events', + moduleId: 'githubEventRouter', + register(env) { + env.registerInit({ + deps: { + events: eventsExtensionPoint, + }, + async init({ events }) { + const eventRouter = new GithubEventRouter(); + + events.addPublishers(eventRouter); + events.addSubscribers(eventRouter); + }, + }); + }, +}); diff --git a/plugins/events-backend-module-github/src/setupTests.ts b/plugins/events-backend-module-github/src/setupTests.ts new file mode 100644 index 0000000000..d3232290a7 --- /dev/null +++ b/plugins/events-backend-module-github/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 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/yarn.lock b/yarn.lock index 7bed901253..c0810933bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6355,6 +6355,20 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-events-backend-module-github@workspace:plugins/events-backend-module-github": + version: 0.0.0-use.local + resolution: "@backstage/plugin-events-backend-module-github@workspace:plugins/events-backend-module-github" + dependencies: + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/plugin-events-backend-test-utils": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" + supertest: ^6.1.3 + winston: ^3.2.1 + languageName: unknown + linkType: soft + "@backstage/plugin-events-backend-test-utils@workspace:^, @backstage/plugin-events-backend-test-utils@workspace:plugins/events-backend-test-utils": version: 0.0.0-use.local resolution: "@backstage/plugin-events-backend-test-utils@workspace:plugins/events-backend-test-utils" From 63f79833989b09269102eb4444176361620b4f35 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Mon, 24 Oct 2022 12:59:27 +0200 Subject: [PATCH 313/434] feat(events/gitlab): add `GitLabEventRouter` Add an event router for GitLab which handles events from the topic `gitlab` and re-publishes events under their more specific topic based on the `$.event_name` payload field like e.g., `gitlab.push`. Signed-off-by: Patrick Jungermann --- .changeset/small-months-call.md | 14 ++++++ .github/CODEOWNERS | 1 + .../events-backend-module-gitlab/.eslintrc.js | 1 + .../events-backend-module-gitlab/README.md | 42 ++++++++++++++++ .../api-report.md | 21 ++++++++ .../events-backend-module-gitlab/package.json | 40 +++++++++++++++ .../events-backend-module-gitlab/src/index.ts | 25 ++++++++++ .../src/router/GitlabEventRouter.test.ts | 50 +++++++++++++++++++ .../src/router/GitlabEventRouter.ts | 42 ++++++++++++++++ .../GitlabEventRouterEventsModule.test.ts | 46 +++++++++++++++++ .../service/GitlabEventRouterEventsModule.ts | 44 ++++++++++++++++ .../src/setupTests.ts | 17 +++++++ yarn.lock | 14 ++++++ 13 files changed, 357 insertions(+) create mode 100644 .changeset/small-months-call.md create mode 100644 plugins/events-backend-module-gitlab/.eslintrc.js create mode 100644 plugins/events-backend-module-gitlab/README.md create mode 100644 plugins/events-backend-module-gitlab/api-report.md create mode 100644 plugins/events-backend-module-gitlab/package.json create mode 100644 plugins/events-backend-module-gitlab/src/index.ts create mode 100644 plugins/events-backend-module-gitlab/src/router/GitlabEventRouter.test.ts create mode 100644 plugins/events-backend-module-gitlab/src/router/GitlabEventRouter.ts create mode 100644 plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.test.ts create mode 100644 plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.ts create mode 100644 plugins/events-backend-module-gitlab/src/setupTests.ts diff --git a/.changeset/small-months-call.md b/.changeset/small-months-call.md new file mode 100644 index 0000000000..de926ee219 --- /dev/null +++ b/.changeset/small-months-call.md @@ -0,0 +1,14 @@ +--- +'@backstage/plugin-events-backend-module-gitlab': minor +--- + +Adds a new module `gitlab` to plugin-events-backend. + +The module adds a new event router `GitlabEventRouter`. + +The event router will re-publish events received at topic `gitlab` +under a more specific topic depending on their `$.event_name` value +(e.g., `gitlab.push`). + +Please find more information at +https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-gitlab/README.md. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4fc500cf35..747b7816b3 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -40,6 +40,7 @@ yarn.lock @backstage/reviewers @backst /plugins/events-backend-module-aws-sqs @backstage/reviewers @pjungermann /plugins/events-backend-module-bitbucket-cloud @backstage/reviewers @pjungermann /plugins/events-backend-module-github @backstage/reviewers @pjungermann +/plugins/events-backend-module-gitlab @backstage/reviewers @pjungermann /plugins/events-backend-test-utils @backstage/reviewers @pjungermann /plugins/events-node @backstage/reviewers @pjungermann /plugins/explore @backstage/reviewers @backstage/sda-se-reviewers diff --git a/plugins/events-backend-module-gitlab/.eslintrc.js b/plugins/events-backend-module-gitlab/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/events-backend-module-gitlab/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/events-backend-module-gitlab/README.md b/plugins/events-backend-module-gitlab/README.md new file mode 100644 index 0000000000..dfbfcd9f4a --- /dev/null +++ b/plugins/events-backend-module-gitlab/README.md @@ -0,0 +1,42 @@ +# events-backend-module-gitlab + +Welcome to the `events-backend-module-gitlab` backend plugin! + +This plugin is a module for the `events-backend` backend plugin +and extends it with an `GitlabEventRouter`. + +The event router will subscribe to the topic `gitlab` +and route the events to more concrete topics based on the value +of the provided `$.event_name` payload field. + +Examples: + +| `$.event_name` | topic | +| --------------- | ---------------------- | +| `push` | `gitlab.push` | +| `merge_request` | `gitlab.merge_request` | + +Please find all possible webhook event types at the +[official documentation](https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html). + +## Installation + +Install the [`events-backend` plugin](../events-backend/README.md). + +Install this module: + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-events-backend-module-gitlab +``` + +Add the event router to the `EventsBackend`: + +```diff ++const gitlabEventRouter = new GitlabEventRouter(); + + EventsBackend ++ .addPublishers(gitlabEventRouter) ++ .addSubscribers(gitlabEventRouter); +// [...] +``` diff --git a/plugins/events-backend-module-gitlab/api-report.md b/plugins/events-backend-module-gitlab/api-report.md new file mode 100644 index 0000000000..8b5183a8d0 --- /dev/null +++ b/plugins/events-backend-module-gitlab/api-report.md @@ -0,0 +1,21 @@ +## API Report File for "@backstage/plugin-events-backend-module-gitlab" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { EventParams } from '@backstage/plugin-events-node'; +import { SubTopicEventRouter } from '@backstage/plugin-events-node'; + +// @public +export class GitlabEventRouter extends SubTopicEventRouter { + constructor(); + // (undocumented) + protected determineSubTopic(params: EventParams): string | undefined; +} + +// @alpha +export const gitlabEventRouterEventsModule: ( + options?: undefined, +) => BackendFeature; +``` diff --git a/plugins/events-backend-module-gitlab/package.json b/plugins/events-backend-module-gitlab/package.json new file mode 100644 index 0000000000..72f5a97a5d --- /dev/null +++ b/plugins/events-backend-module-gitlab/package.json @@ -0,0 +1,40 @@ +{ + "name": "@backstage/plugin-events-backend-module-gitlab", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "alphaTypes": "dist/index.alpha.d.ts", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build --experimental-type-build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-plugin-api": "workspace:^", + "@backstage/plugin-events-node": "workspace:^", + "winston": "^3.2.1" + }, + "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "@backstage/plugin-events-backend-test-utils": "workspace:^", + "supertest": "^6.1.3" + }, + "files": [ + "alpha", + "dist" + ] +} diff --git a/plugins/events-backend-module-gitlab/src/index.ts b/plugins/events-backend-module-gitlab/src/index.ts new file mode 100644 index 0000000000..ea96244df4 --- /dev/null +++ b/plugins/events-backend-module-gitlab/src/index.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2020 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. + */ + +/** + * The module "gitlab" for the Backstage backend plugin "events-backend" + * adding an event router for GitLab. + * + * @packageDocumentation + */ + +export { GitlabEventRouter } from './router/GitlabEventRouter'; +export { gitlabEventRouterEventsModule } from './service/GitlabEventRouterEventsModule'; diff --git a/plugins/events-backend-module-gitlab/src/router/GitlabEventRouter.test.ts b/plugins/events-backend-module-gitlab/src/router/GitlabEventRouter.test.ts new file mode 100644 index 0000000000..6ced12d3cb --- /dev/null +++ b/plugins/events-backend-module-gitlab/src/router/GitlabEventRouter.test.ts @@ -0,0 +1,50 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils'; +import { GitlabEventRouter } from './GitlabEventRouter'; + +describe('GitlabEventRouter', () => { + const eventRouter = new GitlabEventRouter(); + const topic = 'gitlab'; + const eventPayload = { event_name: 'test_type', test: 'payload' }; + const metadata = {}; + + it('no $.event_name', () => { + const eventBroker = new TestEventBroker(); + eventRouter.setEventBroker(eventBroker); + + eventRouter.onEvent({ + topic, + eventPayload: { invalid: 'payload' }, + metadata, + }); + + expect(eventBroker.published).toEqual([]); + }); + + it('with $.event_name', () => { + const eventBroker = new TestEventBroker(); + eventRouter.setEventBroker(eventBroker); + + eventRouter.onEvent({ topic, eventPayload, metadata }); + + expect(eventBroker.published.length).toBe(1); + expect(eventBroker.published[0].topic).toEqual('gitlab.test_type'); + expect(eventBroker.published[0].eventPayload).toEqual(eventPayload); + expect(eventBroker.published[0].metadata).toEqual(metadata); + }); +}); diff --git a/plugins/events-backend-module-gitlab/src/router/GitlabEventRouter.ts b/plugins/events-backend-module-gitlab/src/router/GitlabEventRouter.ts new file mode 100644 index 0000000000..16324340ee --- /dev/null +++ b/plugins/events-backend-module-gitlab/src/router/GitlabEventRouter.ts @@ -0,0 +1,42 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + EventParams, + SubTopicEventRouter, +} from '@backstage/plugin-events-node'; + +/** + * Subscribes to the generic `gitlab` topic + * and publishes the events under the more concrete sub-topic + * depending on the `$.event_name` field provided. + * + * @public + */ +export class GitlabEventRouter extends SubTopicEventRouter { + constructor() { + super('gitlab'); + } + + protected determineSubTopic(params: EventParams): string | undefined { + if ('event_name' in (params.eventPayload as object)) { + const payload = params.eventPayload as { event_name: string }; + return payload.event_name; + } + + return undefined; + } +} diff --git a/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.test.ts b/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.test.ts new file mode 100644 index 0000000000..f0ffca3397 --- /dev/null +++ b/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.test.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { startTestBackend } from '@backstage/backend-test-utils'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { gitlabEventRouterEventsModule } from './GitlabEventRouterEventsModule'; +import { GitlabEventRouter } from '../router/GitlabEventRouter'; + +describe('gitlabEventRouterEventsModule', () => { + it('should be correctly wired and set up', async () => { + let addedPublisher: GitlabEventRouter | undefined; + let addedSubscriber: GitlabEventRouter | undefined; + const extensionPoint = { + addPublishers: (publisher: any) => { + addedPublisher = publisher; + }, + addSubscribers: (subscriber: any) => { + addedSubscriber = subscriber; + }, + }; + + await startTestBackend({ + extensionPoints: [[eventsExtensionPoint, extensionPoint]], + services: [], + features: [gitlabEventRouterEventsModule()], + }); + + expect(addedPublisher).not.toBeUndefined(); + expect(addedPublisher).toBeInstanceOf(GitlabEventRouter); + expect(addedSubscriber).not.toBeUndefined(); + expect(addedSubscriber).toBeInstanceOf(GitlabEventRouter); + }); +}); diff --git a/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.ts b/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.ts new file mode 100644 index 0000000000..9ab2e1263e --- /dev/null +++ b/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { GitlabEventRouter } from '../router/GitlabEventRouter'; + +/** + * Module for the events-backend plugin, adding an event router for GitLab. + * + * Registers the {@link GitlabEventRouter}. + * + * @alpha + */ +export const gitlabEventRouterEventsModule = createBackendModule({ + pluginId: 'events', + moduleId: 'gitlabEventRouter', + register(env) { + env.registerInit({ + deps: { + events: eventsExtensionPoint, + }, + async init({ events }) { + const eventRouter = new GitlabEventRouter(); + + events.addPublishers(eventRouter); + events.addSubscribers(eventRouter); + }, + }); + }, +}); diff --git a/plugins/events-backend-module-gitlab/src/setupTests.ts b/plugins/events-backend-module-gitlab/src/setupTests.ts new file mode 100644 index 0000000000..d3232290a7 --- /dev/null +++ b/plugins/events-backend-module-gitlab/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 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/yarn.lock b/yarn.lock index c0810933bf..25d9da5229 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6369,6 +6369,20 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-events-backend-module-gitlab@workspace:plugins/events-backend-module-gitlab": + version: 0.0.0-use.local + resolution: "@backstage/plugin-events-backend-module-gitlab@workspace:plugins/events-backend-module-gitlab" + dependencies: + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/plugin-events-backend-test-utils": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" + supertest: ^6.1.3 + winston: ^3.2.1 + languageName: unknown + linkType: soft + "@backstage/plugin-events-backend-test-utils@workspace:^, @backstage/plugin-events-backend-test-utils@workspace:plugins/events-backend-test-utils": version: 0.0.0-use.local resolution: "@backstage/plugin-events-backend-test-utils@workspace:plugins/events-backend-test-utils" From 12cd94b7e902fda59405002de062476fdbbbe5b4 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Mon, 24 Oct 2022 13:00:19 +0200 Subject: [PATCH 314/434] feat(events/azure): add `AzureDevOpsEventRouter` Add an event router for Azure DevOps which handles events from the topic `azureDevOps` and re-publishes events under their more specific topic based on the `$.eventType` payload field like e.g., `azureDevOps.git.push`. Signed-off-by: Patrick Jungermann --- .changeset/moody-countries-live.md | 14 ++++++ .github/CODEOWNERS | 1 + .../events-backend-module-azure/.eslintrc.js | 1 + plugins/events-backend-module-azure/README.md | 43 ++++++++++++++++ .../events-backend-module-azure/api-report.md | 21 ++++++++ .../events-backend-module-azure/package.json | 40 +++++++++++++++ .../events-backend-module-azure/src/index.ts | 25 ++++++++++ .../src/router/AzureDevOpsEventRouter.test.ts | 50 +++++++++++++++++++ .../src/router/AzureDevOpsEventRouter.ts | 42 ++++++++++++++++ ...AzureDevOpsEventRouterEventsModule.test.ts | 46 +++++++++++++++++ .../AzureDevOpsEventRouterEventsModule.ts | 44 ++++++++++++++++ .../src/setupTests.ts | 17 +++++++ yarn.lock | 14 ++++++ 13 files changed, 358 insertions(+) create mode 100644 .changeset/moody-countries-live.md create mode 100644 plugins/events-backend-module-azure/.eslintrc.js create mode 100644 plugins/events-backend-module-azure/README.md create mode 100644 plugins/events-backend-module-azure/api-report.md create mode 100644 plugins/events-backend-module-azure/package.json create mode 100644 plugins/events-backend-module-azure/src/index.ts create mode 100644 plugins/events-backend-module-azure/src/router/AzureDevOpsEventRouter.test.ts create mode 100644 plugins/events-backend-module-azure/src/router/AzureDevOpsEventRouter.ts create mode 100644 plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.test.ts create mode 100644 plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.ts create mode 100644 plugins/events-backend-module-azure/src/setupTests.ts diff --git a/.changeset/moody-countries-live.md b/.changeset/moody-countries-live.md new file mode 100644 index 0000000000..d6cc53871b --- /dev/null +++ b/.changeset/moody-countries-live.md @@ -0,0 +1,14 @@ +--- +'@backstage/plugin-events-backend-module-azure': minor +--- + +Adds a new module `azure` to plugin-events-backend. + +The module adds a new event router `AzureDevOpsEventRouter`. + +The event router will re-publish events received at topic `azureDevOps` +under a more specific topic depending on their `$.eventType` value +(e.g., `azureDevOps.git.push`). + +Please find more information at +https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-azure/README.md. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 747b7816b3..85e9726578 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -38,6 +38,7 @@ yarn.lock @backstage/reviewers @backst /plugins/cost-insights-* @backstage/reviewers @backstage/silver-lining /plugins/events-backend @backstage/reviewers @pjungermann /plugins/events-backend-module-aws-sqs @backstage/reviewers @pjungermann +/plugins/events-backend-module-azure @backstage/reviewers @pjungermann /plugins/events-backend-module-bitbucket-cloud @backstage/reviewers @pjungermann /plugins/events-backend-module-github @backstage/reviewers @pjungermann /plugins/events-backend-module-gitlab @backstage/reviewers @pjungermann diff --git a/plugins/events-backend-module-azure/.eslintrc.js b/plugins/events-backend-module-azure/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/events-backend-module-azure/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/events-backend-module-azure/README.md b/plugins/events-backend-module-azure/README.md new file mode 100644 index 0000000000..d16315b6e7 --- /dev/null +++ b/plugins/events-backend-module-azure/README.md @@ -0,0 +1,43 @@ +# events-backend-module-azure + +Welcome to the `events-backend-module-azure` backend plugin! + +This plugin is a module for the `events-backend` backend plugin +and extends it with an `AzureDevOpsEventRouter`. + +The event router will subscribe to the topic `azureDevOps` +and route the events to more concrete topics based on the value +of the provided `$.eventType` payload field. + +Examples: + +| `$.eventType` | topic | +| ------------------------- | ------------------------------------- | +| `git.push` | `azureDevOps.git.push` | +| `git.pullrequest.created` | `azureDevOps.git.pullrequest.created` | + +Please find all possible webhook event types at the +[official documentation of events](https://learn.microsoft.com/en-us/azure/devops/service-hooks/events?source=recommendations&view=azure-devops) +and [webhooks](https://learn.microsoft.com/en-us/azure/devops/service-hooks/services/webhooks?view=azure-devops). + +## Installation + +Install the [`events-backend` plugin](../events-backend/README.md). + +Install this module: + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-events-backend-module-azure +``` + +Add the event router to the `EventsBackend`: + +```diff ++const githubEventRouter = new AzureDevOpsEventRouter(); + + EventsBackend ++ .addPublishers(githubEventRouter) ++ .addSubscribers(githubEventRouter); +// [...] +``` diff --git a/plugins/events-backend-module-azure/api-report.md b/plugins/events-backend-module-azure/api-report.md new file mode 100644 index 0000000000..510ec91c47 --- /dev/null +++ b/plugins/events-backend-module-azure/api-report.md @@ -0,0 +1,21 @@ +## API Report File for "@backstage/plugin-events-backend-module-azure" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { EventParams } from '@backstage/plugin-events-node'; +import { SubTopicEventRouter } from '@backstage/plugin-events-node'; + +// @public +export class AzureDevOpsEventRouter extends SubTopicEventRouter { + constructor(); + // (undocumented) + protected determineSubTopic(params: EventParams): string | undefined; +} + +// @alpha +export const azureDevOpsEventRouterEventsModule: ( + options?: undefined, +) => BackendFeature; +``` diff --git a/plugins/events-backend-module-azure/package.json b/plugins/events-backend-module-azure/package.json new file mode 100644 index 0000000000..ffea618dd0 --- /dev/null +++ b/plugins/events-backend-module-azure/package.json @@ -0,0 +1,40 @@ +{ + "name": "@backstage/plugin-events-backend-module-azure", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "alphaTypes": "dist/index.alpha.d.ts", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build --experimental-type-build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-plugin-api": "workspace:^", + "@backstage/plugin-events-node": "workspace:^", + "winston": "^3.2.1" + }, + "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "@backstage/plugin-events-backend-test-utils": "workspace:^", + "supertest": "^6.1.3" + }, + "files": [ + "alpha", + "dist" + ] +} diff --git a/plugins/events-backend-module-azure/src/index.ts b/plugins/events-backend-module-azure/src/index.ts new file mode 100644 index 0000000000..9a83f751f6 --- /dev/null +++ b/plugins/events-backend-module-azure/src/index.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2020 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. + */ + +/** + * The module "azure" for the Backstage backend plugin "events-backend" + * adding an event router for Azure DevOps. + * + * @packageDocumentation + */ + +export { AzureDevOpsEventRouter } from './router/AzureDevOpsEventRouter'; +export { azureDevOpsEventRouterEventsModule } from './service/AzureDevOpsEventRouterEventsModule'; diff --git a/plugins/events-backend-module-azure/src/router/AzureDevOpsEventRouter.test.ts b/plugins/events-backend-module-azure/src/router/AzureDevOpsEventRouter.test.ts new file mode 100644 index 0000000000..56e761a8fc --- /dev/null +++ b/plugins/events-backend-module-azure/src/router/AzureDevOpsEventRouter.test.ts @@ -0,0 +1,50 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils'; +import { AzureDevOpsEventRouter } from './AzureDevOpsEventRouter'; + +describe('AzureDevOpsEventRouter', () => { + const eventRouter = new AzureDevOpsEventRouter(); + const topic = 'azureDevOps'; + const eventPayload = { eventType: 'test.type', test: 'payload' }; + const metadata = {}; + + it('no $.eventType', () => { + const eventBroker = new TestEventBroker(); + eventRouter.setEventBroker(eventBroker); + + eventRouter.onEvent({ + topic, + eventPayload: { invalid: 'payload' }, + metadata, + }); + + expect(eventBroker.published).toEqual([]); + }); + + it('with $.eventType', () => { + const eventBroker = new TestEventBroker(); + eventRouter.setEventBroker(eventBroker); + + eventRouter.onEvent({ topic, eventPayload, metadata }); + + expect(eventBroker.published.length).toBe(1); + expect(eventBroker.published[0].topic).toEqual('azureDevOps.test.type'); + expect(eventBroker.published[0].eventPayload).toEqual(eventPayload); + expect(eventBroker.published[0].metadata).toEqual(metadata); + }); +}); diff --git a/plugins/events-backend-module-azure/src/router/AzureDevOpsEventRouter.ts b/plugins/events-backend-module-azure/src/router/AzureDevOpsEventRouter.ts new file mode 100644 index 0000000000..11dd7546dd --- /dev/null +++ b/plugins/events-backend-module-azure/src/router/AzureDevOpsEventRouter.ts @@ -0,0 +1,42 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + EventParams, + SubTopicEventRouter, +} from '@backstage/plugin-events-node'; + +/** + * Subscribes to the generic `azureDevOps` topic + * and publishes the events under the more concrete sub-topic + * depending on the `$.eventType` provided. + * + * @public + */ +export class AzureDevOpsEventRouter extends SubTopicEventRouter { + constructor() { + super('azureDevOps'); + } + + protected determineSubTopic(params: EventParams): string | undefined { + if ('eventType' in (params.eventPayload as object)) { + const payload = params.eventPayload as { eventType: string }; + return payload.eventType; + } + + return undefined; + } +} diff --git a/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.test.ts b/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.test.ts new file mode 100644 index 0000000000..86ab7ea17d --- /dev/null +++ b/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.test.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { startTestBackend } from '@backstage/backend-test-utils'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { azureDevOpsEventRouterEventsModule } from './AzureDevOpsEventRouterEventsModule'; +import { AzureDevOpsEventRouter } from '../router/AzureDevOpsEventRouter'; + +describe('azureDevOpsEventRouterEventsModule', () => { + it('should be correctly wired and set up', async () => { + let addedPublisher: AzureDevOpsEventRouter | undefined; + let addedSubscriber: AzureDevOpsEventRouter | undefined; + const extensionPoint = { + addPublishers: (publisher: any) => { + addedPublisher = publisher; + }, + addSubscribers: (subscriber: any) => { + addedSubscriber = subscriber; + }, + }; + + await startTestBackend({ + extensionPoints: [[eventsExtensionPoint, extensionPoint]], + services: [], + features: [azureDevOpsEventRouterEventsModule()], + }); + + expect(addedPublisher).not.toBeUndefined(); + expect(addedPublisher).toBeInstanceOf(AzureDevOpsEventRouter); + expect(addedSubscriber).not.toBeUndefined(); + expect(addedSubscriber).toBeInstanceOf(AzureDevOpsEventRouter); + }); +}); diff --git a/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.ts b/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.ts new file mode 100644 index 0000000000..1219452bd8 --- /dev/null +++ b/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { AzureDevOpsEventRouter } from '../router/AzureDevOpsEventRouter'; + +/** + * Module for the events-backend plugin, adding an event router for Azure DevOps. + * + * Registers the {@link AzureDevOpsEventRouter}. + * + * @alpha + */ +export const azureDevOpsEventRouterEventsModule = createBackendModule({ + pluginId: 'events', + moduleId: 'azureDevOpsEventRouter', + register(env) { + env.registerInit({ + deps: { + events: eventsExtensionPoint, + }, + async init({ events }) { + const eventRouter = new AzureDevOpsEventRouter(); + + events.addPublishers(eventRouter); + events.addSubscribers(eventRouter); + }, + }); + }, +}); diff --git a/plugins/events-backend-module-azure/src/setupTests.ts b/plugins/events-backend-module-azure/src/setupTests.ts new file mode 100644 index 0000000000..d3232290a7 --- /dev/null +++ b/plugins/events-backend-module-azure/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 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/yarn.lock b/yarn.lock index 25d9da5229..679664a60b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6341,6 +6341,20 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-events-backend-module-azure@workspace:plugins/events-backend-module-azure": + version: 0.0.0-use.local + resolution: "@backstage/plugin-events-backend-module-azure@workspace:plugins/events-backend-module-azure" + dependencies: + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/plugin-events-backend-test-utils": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" + supertest: ^6.1.3 + winston: ^3.2.1 + languageName: unknown + linkType: soft + "@backstage/plugin-events-backend-module-bitbucket-cloud@workspace:plugins/events-backend-module-bitbucket-cloud": version: 0.0.0-use.local resolution: "@backstage/plugin-events-backend-module-bitbucket-cloud@workspace:plugins/events-backend-module-bitbucket-cloud" From 0f01f91a031ccf74cbb3ac3c6654cb3dfa839511 Mon Sep 17 00:00:00 2001 From: stephenburrows22 <118028944+stephenburrows22@users.noreply.github.com> Date: Sat, 12 Nov 2022 00:17:12 +0000 Subject: [PATCH 315/434] Update ADOPTERS.md added details for MSCI Signed-off-by: stephenburrows22 <118028944+stephenburrows22@users.noreply.github.com> --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index cd2e0e761c..0b8b1a1ccf 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -219,3 +219,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Loft](https://loft.com.br) | [Squad DevTools](mailto:squad_devtools@loft.com.br) | We're using Backstage to give visibility and promote ownership of all our applications, resources and tools. Now moving to use it as a Developer Portal to create applications, AWS resources etc. | | [Raízen](https://www.raizen.com) | [Melquisedque Bernardes Pereira](https://github.com/rayleshh) and [Paulo Eduardo Peixoto](https://github.com/padupe) | Backstage helps us to organize and make available, in a simple and direct way, all the infrastructure for new projects. In addition, it has become a great support tool for our developers. | | [Trifork](https://trifork.com) | [Casper Thygesen](https://github.com/cthtrifork) | We're using Backstage as part of our dataplatform product. It integrates with the infrastructure components and is the developer portal for all the platform users. | +| [MSCI](http://msci.com) | [Stephen Burrows](mailto:stephen.burrows@msci.com) | Developer portal, service catalog, documentation and tooling From 25f6d7bddbded53fbeef4f3700d7b505ffca7bec Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Wed, 9 Nov 2022 12:16:09 +0100 Subject: [PATCH 316/434] feat(events/gerrit): add `GerritEventRouter` Add an event router for Gerrit which handles events from the topic `gerrit` and re-publishes events under their more specific topic based on the `$.type` payload field like e.g., `gerrit.change-merged`. Signed-off-by: Patrick Jungermann --- .changeset/light-eagles-poke.md | 14 ++++++ .github/CODEOWNERS | 1 + .../events-backend-module-gerrit/.eslintrc.js | 1 + .../events-backend-module-gerrit/README.md | 42 ++++++++++++++++ .../api-report.md | 21 ++++++++ .../events-backend-module-gerrit/package.json | 40 +++++++++++++++ .../events-backend-module-gerrit/src/index.ts | 25 ++++++++++ .../src/router/GerritEventRouter.test.ts | 50 +++++++++++++++++++ .../src/router/GerritEventRouter.ts | 42 ++++++++++++++++ .../GerritEventRouterEventsModule.test.ts | 46 +++++++++++++++++ .../service/GerritEventRouterEventsModule.ts | 44 ++++++++++++++++ .../src/setupTests.ts | 17 +++++++ yarn.lock | 14 ++++++ 13 files changed, 357 insertions(+) create mode 100644 .changeset/light-eagles-poke.md create mode 100644 plugins/events-backend-module-gerrit/.eslintrc.js create mode 100644 plugins/events-backend-module-gerrit/README.md create mode 100644 plugins/events-backend-module-gerrit/api-report.md create mode 100644 plugins/events-backend-module-gerrit/package.json create mode 100644 plugins/events-backend-module-gerrit/src/index.ts create mode 100644 plugins/events-backend-module-gerrit/src/router/GerritEventRouter.test.ts create mode 100644 plugins/events-backend-module-gerrit/src/router/GerritEventRouter.ts create mode 100644 plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.test.ts create mode 100644 plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.ts create mode 100644 plugins/events-backend-module-gerrit/src/setupTests.ts diff --git a/.changeset/light-eagles-poke.md b/.changeset/light-eagles-poke.md new file mode 100644 index 0000000000..8b1f5bb522 --- /dev/null +++ b/.changeset/light-eagles-poke.md @@ -0,0 +1,14 @@ +--- +'@backstage/plugin-events-backend-module-gerrit': minor +--- + +Adds a new module `gerrit` to plugin-events-backend. + +The module adds a new event router `GerritEventRouter`. + +The event router will re-publish events received at topic `gerrit` +under a more specific topic depending on their `$.type` value +(e.g., `gerrit.change-merged`). + +Please find more information at +https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-gerrit/README.md. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 85e9726578..3f17c9591f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -40,6 +40,7 @@ yarn.lock @backstage/reviewers @backst /plugins/events-backend-module-aws-sqs @backstage/reviewers @pjungermann /plugins/events-backend-module-azure @backstage/reviewers @pjungermann /plugins/events-backend-module-bitbucket-cloud @backstage/reviewers @pjungermann +/plugins/events-backend-module-gerrit @backstage/reviewers @pjungermann /plugins/events-backend-module-github @backstage/reviewers @pjungermann /plugins/events-backend-module-gitlab @backstage/reviewers @pjungermann /plugins/events-backend-test-utils @backstage/reviewers @pjungermann diff --git a/plugins/events-backend-module-gerrit/.eslintrc.js b/plugins/events-backend-module-gerrit/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/events-backend-module-gerrit/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/events-backend-module-gerrit/README.md b/plugins/events-backend-module-gerrit/README.md new file mode 100644 index 0000000000..933b7a172f --- /dev/null +++ b/plugins/events-backend-module-gerrit/README.md @@ -0,0 +1,42 @@ +# events-backend-module-gerrit + +Welcome to the `events-backend-module-gerrit` backend plugin! + +This plugin is a module for the `events-backend` backend plugin +and extends it with an `GerritEventRouter`. + +The event router will subscribe to the topic `gerrit` +and route the events to more concrete topics based on the value +of the provided `$.type` payload field. + +Examples: + +| `$.type` | topic | +| ---------------- | ----------------------- | +| `change-created` | `gerrit.change-created` | +| `change-merged` | `gerrit.change-merged` | + +Please find all possible webhook event types at the +[official documentation](https://gerrit-review.googlesource.com/Documentation/cmd-stream-events.html#events). + +## Installation + +Install the [`events-backend` plugin](../events-backend/README.md). + +Install this module: + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-events-backend-module-gerrit +``` + +Add the event router to the `EventsBackend`: + +```diff ++const gerritEventRouter = new GerritEventRouter(); + + EventsBackend ++ .addPublishers(gerritEventRouter) ++ .addSubscribers(gerritEventRouter); +// [...] +``` diff --git a/plugins/events-backend-module-gerrit/api-report.md b/plugins/events-backend-module-gerrit/api-report.md new file mode 100644 index 0000000000..268e5970fa --- /dev/null +++ b/plugins/events-backend-module-gerrit/api-report.md @@ -0,0 +1,21 @@ +## API Report File for "@backstage/plugin-events-backend-module-gerrit" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { EventParams } from '@backstage/plugin-events-node'; +import { SubTopicEventRouter } from '@backstage/plugin-events-node'; + +// @public +export class GerritEventRouter extends SubTopicEventRouter { + constructor(); + // (undocumented) + protected determineSubTopic(params: EventParams): string | undefined; +} + +// @alpha +export const gerritEventRouterEventsModule: ( + options?: undefined, +) => BackendFeature; +``` diff --git a/plugins/events-backend-module-gerrit/package.json b/plugins/events-backend-module-gerrit/package.json new file mode 100644 index 0000000000..f1808fc306 --- /dev/null +++ b/plugins/events-backend-module-gerrit/package.json @@ -0,0 +1,40 @@ +{ + "name": "@backstage/plugin-events-backend-module-gerrit", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "alphaTypes": "dist/index.alpha.d.ts", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build --experimental-type-build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-plugin-api": "workspace:^", + "@backstage/plugin-events-node": "workspace:^", + "winston": "^3.2.1" + }, + "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "@backstage/plugin-events-backend-test-utils": "workspace:^", + "supertest": "^6.1.3" + }, + "files": [ + "alpha", + "dist" + ] +} diff --git a/plugins/events-backend-module-gerrit/src/index.ts b/plugins/events-backend-module-gerrit/src/index.ts new file mode 100644 index 0000000000..1a9ebb03ee --- /dev/null +++ b/plugins/events-backend-module-gerrit/src/index.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2020 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. + */ + +/** + * The module `gerrit` for the Backstage backend plugin "events-backend" + * adding an event router for Gerrit. + * + * @packageDocumentation + */ + +export { GerritEventRouter } from './router/GerritEventRouter'; +export { gerritEventRouterEventsModule } from './service/GerritEventRouterEventsModule'; diff --git a/plugins/events-backend-module-gerrit/src/router/GerritEventRouter.test.ts b/plugins/events-backend-module-gerrit/src/router/GerritEventRouter.test.ts new file mode 100644 index 0000000000..7302a26012 --- /dev/null +++ b/plugins/events-backend-module-gerrit/src/router/GerritEventRouter.test.ts @@ -0,0 +1,50 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils'; +import { GerritEventRouter } from './GerritEventRouter'; + +describe('GerritEventRouter', () => { + const eventRouter = new GerritEventRouter(); + const topic = 'gerrit'; + const eventPayload = { type: 'test-type', test: 'payload' }; + const metadata = {}; + + it('no $.type', () => { + const eventBroker = new TestEventBroker(); + eventRouter.setEventBroker(eventBroker); + + eventRouter.onEvent({ + topic, + eventPayload: { invalid: 'payload' }, + metadata, + }); + + expect(eventBroker.published).toEqual([]); + }); + + it('with $.type', () => { + const eventBroker = new TestEventBroker(); + eventRouter.setEventBroker(eventBroker); + + eventRouter.onEvent({ topic, eventPayload, metadata }); + + expect(eventBroker.published.length).toBe(1); + expect(eventBroker.published[0].topic).toEqual('gerrit.test-type'); + expect(eventBroker.published[0].eventPayload).toEqual(eventPayload); + expect(eventBroker.published[0].metadata).toEqual(metadata); + }); +}); diff --git a/plugins/events-backend-module-gerrit/src/router/GerritEventRouter.ts b/plugins/events-backend-module-gerrit/src/router/GerritEventRouter.ts new file mode 100644 index 0000000000..3d97508b62 --- /dev/null +++ b/plugins/events-backend-module-gerrit/src/router/GerritEventRouter.ts @@ -0,0 +1,42 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + EventParams, + SubTopicEventRouter, +} from '@backstage/plugin-events-node'; + +/** + * Subscribes to the generic `gerrit` topic + * and publishes the events under the more concrete sub-topic + * depending on the `$.type` field provided. + * + * @public + */ +export class GerritEventRouter extends SubTopicEventRouter { + constructor() { + super('gerrit'); + } + + protected determineSubTopic(params: EventParams): string | undefined { + if ('type' in (params.eventPayload as object)) { + const payload = params.eventPayload as { type: string }; + return payload.type; + } + + return undefined; + } +} diff --git a/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.test.ts b/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.test.ts new file mode 100644 index 0000000000..b5fd6a80ca --- /dev/null +++ b/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.test.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { startTestBackend } from '@backstage/backend-test-utils'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { gerritEventRouterEventsModule } from './GerritEventRouterEventsModule'; +import { GerritEventRouter } from '../router/GerritEventRouter'; + +describe('gerritEventRouterEventsModule', () => { + it('should be correctly wired and set up', async () => { + let addedPublisher: GerritEventRouter | undefined; + let addedSubscriber: GerritEventRouter | undefined; + const extensionPoint = { + addPublishers: (publisher: any) => { + addedPublisher = publisher; + }, + addSubscribers: (subscriber: any) => { + addedSubscriber = subscriber; + }, + }; + + await startTestBackend({ + extensionPoints: [[eventsExtensionPoint, extensionPoint]], + services: [], + features: [gerritEventRouterEventsModule()], + }); + + expect(addedPublisher).not.toBeUndefined(); + expect(addedPublisher).toBeInstanceOf(GerritEventRouter); + expect(addedSubscriber).not.toBeUndefined(); + expect(addedSubscriber).toBeInstanceOf(GerritEventRouter); + }); +}); diff --git a/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.ts b/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.ts new file mode 100644 index 0000000000..734b574edd --- /dev/null +++ b/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { GerritEventRouter } from '../router/GerritEventRouter'; + +/** + * Module for the events-backend plugin, adding an event router for Gerrit. + * + * Registers the {@link GerritEventRouter}. + * + * @alpha + */ +export const gerritEventRouterEventsModule = createBackendModule({ + pluginId: 'events', + moduleId: 'gerritEventRouter', + register(env) { + env.registerInit({ + deps: { + events: eventsExtensionPoint, + }, + async init({ events }) { + const eventRouter = new GerritEventRouter(); + + events.addPublishers(eventRouter); + events.addSubscribers(eventRouter); + }, + }); + }, +}); diff --git a/plugins/events-backend-module-gerrit/src/setupTests.ts b/plugins/events-backend-module-gerrit/src/setupTests.ts new file mode 100644 index 0000000000..d3232290a7 --- /dev/null +++ b/plugins/events-backend-module-gerrit/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 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/yarn.lock b/yarn.lock index 679664a60b..9b0f6dec5f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6369,6 +6369,20 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-events-backend-module-gerrit@workspace:plugins/events-backend-module-gerrit": + version: 0.0.0-use.local + resolution: "@backstage/plugin-events-backend-module-gerrit@workspace:plugins/events-backend-module-gerrit" + dependencies: + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/plugin-events-backend-test-utils": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" + supertest: ^6.1.3 + winston: ^3.2.1 + languageName: unknown + linkType: soft + "@backstage/plugin-events-backend-module-github@workspace:plugins/events-backend-module-github": version: 0.0.0-use.local resolution: "@backstage/plugin-events-backend-module-github@workspace:plugins/events-backend-module-github" From 89d705e8060a6523734a33001af4c020c211e2d0 Mon Sep 17 00:00:00 2001 From: Adam Kunicki Date: Fri, 11 Nov 2022 20:48:15 -0800 Subject: [PATCH 317/434] Permit customizing the header name for the IAP jwt This creates a new configuration parameter `jwtHeader` for the gcp-iap auth provider. This allows setting a custom header to look in for the IAP issued JWT. Signed-off-by: Adam Kunicki --- .changeset/great-icons-greet.md | 5 ++ docs/auth/google/gcp-iap-auth.md | 1 + .../src/providers/gcp-iap/helpers.test.ts | 6 +- .../src/providers/gcp-iap/helpers.ts | 6 +- .../src/providers/gcp-iap/provider.test.ts | 72 ++++++++++--------- .../src/providers/gcp-iap/provider.ts | 9 ++- .../src/providers/gcp-iap/types.ts | 2 +- 7 files changed, 57 insertions(+), 44 deletions(-) create mode 100644 .changeset/great-icons-greet.md diff --git a/.changeset/great-icons-greet.md b/.changeset/great-icons-greet.md new file mode 100644 index 0000000000..f32f6f1808 --- /dev/null +++ b/.changeset/great-icons-greet.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Add support for custom JWT header name in GCP IAP auth. diff --git a/docs/auth/google/gcp-iap-auth.md b/docs/auth/google/gcp-iap-auth.md index 1ebfcaf15b..90d267b327 100644 --- a/docs/auth/google/gcp-iap-auth.md +++ b/docs/auth/google/gcp-iap-auth.md @@ -26,6 +26,7 @@ auth: providers: gcp-iap: audience: '/projects//global/backendServices/' + jwtHeader: x-custom-header # Optional: Only if you are using a custom header for the IAP JWT ``` You can find the project number and service ID in the Google Cloud Console. diff --git a/plugins/auth-backend/src/providers/gcp-iap/helpers.test.ts b/plugins/auth-backend/src/providers/gcp-iap/helpers.test.ts index c0e351c90b..0162366f61 100644 --- a/plugins/auth-backend/src/providers/gcp-iap/helpers.test.ts +++ b/plugins/auth-backend/src/providers/gcp-iap/helpers.test.ts @@ -95,19 +95,19 @@ describe('helpers', () => { parseRequestToken(7, undefined as any), ).rejects.toMatchObject({ name: 'AuthenticationError', - message: 'Missing Google IAP header: x-goog-iap-jwt-assertion', + message: 'Missing Google IAP header', }); await expect( parseRequestToken(undefined, undefined as any), ).rejects.toMatchObject({ name: 'AuthenticationError', - message: 'Missing Google IAP header: x-goog-iap-jwt-assertion', + message: 'Missing Google IAP header', }); await expect( parseRequestToken('', undefined as any), ).rejects.toMatchObject({ name: 'AuthenticationError', - message: 'Missing Google IAP header: x-goog-iap-jwt-assertion', + message: 'Missing Google IAP header', }); }); diff --git a/plugins/auth-backend/src/providers/gcp-iap/helpers.ts b/plugins/auth-backend/src/providers/gcp-iap/helpers.ts index c7e81adc73..26d9a8c904 100644 --- a/plugins/auth-backend/src/providers/gcp-iap/helpers.ts +++ b/plugins/auth-backend/src/providers/gcp-iap/helpers.ts @@ -17,7 +17,7 @@ import { AuthenticationError } from '@backstage/errors'; import { OAuth2Client, TokenPayload } from 'google-auth-library'; import { AuthHandler } from '../types'; -import { GcpIapResult, IAP_JWT_HEADER } from './types'; +import { GcpIapResult } from './types'; export function createTokenValidator( audience: string, @@ -52,9 +52,7 @@ export async function parseRequestToken( tokenValidator: (token: string) => Promise, ): Promise { if (typeof jwtToken !== 'string' || !jwtToken) { - throw new AuthenticationError( - `Missing Google IAP header: ${IAP_JWT_HEADER}`, - ); + throw new AuthenticationError('Missing Google IAP header'); } let payload: TokenPayload; diff --git a/plugins/auth-backend/src/providers/gcp-iap/provider.test.ts b/plugins/auth-backend/src/providers/gcp-iap/provider.test.ts index b1b2a3f66e..c01db3a853 100644 --- a/plugins/auth-backend/src/providers/gcp-iap/provider.test.ts +++ b/plugins/auth-backend/src/providers/gcp-iap/provider.test.ts @@ -18,6 +18,7 @@ import express from 'express'; import request from 'supertest'; import { AuthResolverContext } from '../types'; import { GcpIapProvider } from './provider'; +import { DEFAULT_IAP_JWT_HEADER } from './types'; beforeEach(() => { jest.clearAllMocks(); @@ -28,44 +29,47 @@ describe('GcpIapProvider', () => { const signInResolver = jest.fn(); const tokenValidator = jest.fn(); - it('runs the happy path', async () => { - const provider = new GcpIapProvider({ - authHandler, - signInResolver, - tokenValidator, - resolverContext: {} as AuthResolverContext, - }); + it.each([undefined, 'x-custom-header'])( + 'runs the happy path', + async jwtHeader => { + const provider = new GcpIapProvider({ + authHandler, + signInResolver, + tokenValidator, + resolverContext: {} as AuthResolverContext, + jwtHeader: jwtHeader, + }); - // { "sub": "user:default/me", "ent": ["group:default/home"] } - const backstageToken = - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyOmRlZmF1bHQvbWUiLCJlbnQiOlsiZ3JvdXA6ZGVmYXVsdC9ob21lIl19.CbmAKzFErGmtsnpRxyPc7dHv7WEjb5lY6206YCzR_Rc'; - const iapToken = { sub: 's', email: 'e@mail.com' }; + // { "sub": "user:default/me", "ent": ["group:default/home"] } + const backstageToken = + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyOmRlZmF1bHQvbWUiLCJlbnQiOlsiZ3JvdXA6ZGVmYXVsdC9ob21lIl19.CbmAKzFErGmtsnpRxyPc7dHv7WEjb5lY6206YCzR_Rc'; + const iapToken = { sub: 's', email: 'e@mail.com' }; - authHandler.mockResolvedValueOnce({ email: 'e@mail.com' }); - signInResolver.mockResolvedValueOnce({ token: backstageToken }); - tokenValidator.mockResolvedValueOnce(iapToken); + authHandler.mockResolvedValueOnce({ email: 'e@mail.com' }); + signInResolver.mockResolvedValueOnce({ token: backstageToken }); + tokenValidator.mockResolvedValueOnce(iapToken); - const app = express(); - app.use('/refresh', provider.refresh.bind(provider)); + const app = express(); + app.use('/refresh', provider.refresh.bind(provider)); - const response = await request(app) - .get('/refresh') - .set('x-goog-iap-jwt-assertion', 'token'); + const header = jwtHeader || DEFAULT_IAP_JWT_HEADER; + const response = await request(app).get('/refresh').set(header, 'token'); - expect(response.status).toBe(200); - expect(response.get('content-type')).toBe( - 'application/json; charset=utf-8', - ); - expect(response.body).toEqual({ - backstageIdentity: { - token: backstageToken, - identity: { - type: 'user', - userEntityRef: 'user:default/me', - ownershipEntityRefs: ['group:default/home'], + expect(response.status).toBe(200); + expect(response.get('content-type')).toBe( + 'application/json; charset=utf-8', + ); + expect(response.body).toEqual({ + backstageIdentity: { + token: backstageToken, + identity: { + type: 'user', + userEntityRef: 'user:default/me', + ownershipEntityRefs: ['group:default/home'], + }, }, - }, - providerInfo: { iapToken }, - }); - }); + providerInfo: { iapToken }, + }); + }, + ); }); diff --git a/plugins/auth-backend/src/providers/gcp-iap/provider.ts b/plugins/auth-backend/src/providers/gcp-iap/provider.ts index 500b062d5b..7e77853737 100644 --- a/plugins/auth-backend/src/providers/gcp-iap/provider.ts +++ b/plugins/auth-backend/src/providers/gcp-iap/provider.ts @@ -29,24 +29,27 @@ import { defaultAuthHandler, parseRequestToken, } from './helpers'; -import { GcpIapResponse, GcpIapResult, IAP_JWT_HEADER } from './types'; +import { GcpIapResponse, GcpIapResult, DEFAULT_IAP_JWT_HEADER } from './types'; export class GcpIapProvider implements AuthProviderRouteHandlers { private readonly authHandler: AuthHandler; private readonly signInResolver: SignInResolver; private readonly tokenValidator: (token: string) => Promise; private readonly resolverContext: AuthResolverContext; + private readonly jwtHeader: string; constructor(options: { authHandler: AuthHandler; signInResolver: SignInResolver; tokenValidator: (token: string) => Promise; resolverContext: AuthResolverContext; + jwtHeader?: string; }) { this.authHandler = options.authHandler; this.signInResolver = options.signInResolver; this.tokenValidator = options.tokenValidator; this.resolverContext = options.resolverContext; + this.jwtHeader = options?.jwtHeader || DEFAULT_IAP_JWT_HEADER; } async start() {} @@ -55,7 +58,7 @@ export class GcpIapProvider implements AuthProviderRouteHandlers { async refresh(req: express.Request, res: express.Response): Promise { const result = await parseRequestToken( - req.header(IAP_JWT_HEADER), + req.header(this.jwtHeader), this.tokenValidator, ); @@ -103,6 +106,7 @@ export const gcpIap = createAuthProviderIntegration({ }) { return ({ config, resolverContext }) => { const audience = config.getString('audience'); + const jwtHeader = config.getOptionalString('jwtHeader'); const authHandler = options.authHandler ?? defaultAuthHandler; const signInResolver = options.signIn.resolver; @@ -113,6 +117,7 @@ export const gcpIap = createAuthProviderIntegration({ signInResolver, tokenValidator, resolverContext, + jwtHeader, }); }; }, diff --git a/plugins/auth-backend/src/providers/gcp-iap/types.ts b/plugins/auth-backend/src/providers/gcp-iap/types.ts index 25828b7d51..6519de64ac 100644 --- a/plugins/auth-backend/src/providers/gcp-iap/types.ts +++ b/plugins/auth-backend/src/providers/gcp-iap/types.ts @@ -20,7 +20,7 @@ import { AuthResponse } from '../types'; /** * The header name used by the IAP. */ -export const IAP_JWT_HEADER = 'x-goog-iap-jwt-assertion'; +export const DEFAULT_IAP_JWT_HEADER = 'x-goog-iap-jwt-assertion'; /** * The data extracted from an IAP token. From be40512430f5292c0cce26c87336d1d1b750cc69 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 12 Nov 2022 17:23:20 +0100 Subject: [PATCH 318/434] Revert "chore: (eslint) restrict imports of @material-ui Link" This reverts commit 7539b3674830af1ca98ea3d74ca4be6b290c4473. Signed-off-by: Patrik Oldsberg --- .changeset/great-colts-invite.md | 16 ---------------- packages/cli/config/eslint-factory.js | 11 ----------- 2 files changed, 27 deletions(-) delete mode 100644 .changeset/great-colts-invite.md diff --git a/.changeset/great-colts-invite.md b/.changeset/great-colts-invite.md deleted file mode 100644 index 1ca71580dc..0000000000 --- a/.changeset/great-colts-invite.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -'@backstage/cli': minor ---- - -Added a new ESLint rule that restricts imports of Link from @material-ui - -The rule can be can be overridden in the following way: - -```diff -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { -+ restrictedImports: [ -+ { name: '@material-ui/core', importNames: [] }, -+ { name: '@material-ui/core/Link', importNames: [] }, -+ ], -}); -``` diff --git a/packages/cli/config/eslint-factory.js b/packages/cli/config/eslint-factory.js index 04e23b2077..e213f58e4e 100644 --- a/packages/cli/config/eslint-factory.js +++ b/packages/cli/config/eslint-factory.js @@ -239,17 +239,6 @@ function createConfigForRole(dir, role, extraConfig = {}) { name: '@material-ui/icons/', // because this is possible too ._. message: "Please import '@material-ui/icons/' instead.", }, - { - name: '@material-ui/core', - importNames: ['Link'], - message: - 'Prefer using `Link` from `@backstage/core-components` rather than material-UI', - }, - { - name: '@material-ui/core/Link', - message: - 'Prefer using `Link` from `@backstage/core-components` rather than material-UI', - }, ...require('module').builtinModules, ...(extraConfig.restrictedImports ?? []), ], From f14bd69e29872a820a6ed53ffa1950891b126d5e Mon Sep 17 00:00:00 2001 From: Leena <19555355+sploschee@users.noreply.github.com> Date: Sat, 12 Nov 2022 16:37:57 +0000 Subject: [PATCH 319/434] fix(docs): update listed contents of .dockerignore It appears that further items have been added to out-of-the-box .dockerignore file created when running `@backstage/create-app` Updated to reflect the current contents was: ``` .git node_modules packages/*/src packages/*/node_modules plugins ``` now: ``` .git .yarn/cache .yarn/install-state.gz node_modules packages/*/src packages/*/node_modules plugins *.local.yaml ``` Signed-off-by: Leena <19555355+sploschee@users.noreply.github.com> --- docs/deployment/docker.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index 04a509d316..0b28e4d506 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -108,10 +108,13 @@ root of the repo to speed up the build by reducing build context size: ```text .git +.yarn/cache +.yarn/install-state.gz node_modules packages/*/src packages/*/node_modules plugins +*.local.yaml ``` With the project built and the `.dockerignore` and `Dockerfile` in place, we are From 19048e60a4446c2c98bc1f21c979224cbc936fc5 Mon Sep 17 00:00:00 2001 From: Leena <19555355+sploschee@users.noreply.github.com> Date: Sat, 12 Nov 2022 17:26:07 +0000 Subject: [PATCH 320/434] remove yarn3 specific items in .gitignore as per comment Signed-off-by: Leena <19555355+sploschee@users.noreply.github.com> --- docs/deployment/docker.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index 0b28e4d506..68cdf74132 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -108,8 +108,6 @@ root of the repo to speed up the build by reducing build context size: ```text .git -.yarn/cache -.yarn/install-state.gz node_modules packages/*/src packages/*/node_modules From 946f7bfd6b71d7f4b959a280b88e8e9785ea6c5a Mon Sep 17 00:00:00 2001 From: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Date: Sat, 12 Nov 2022 14:45:01 -0600 Subject: [PATCH 321/434] Made list-deprecations visible and stable Signed-off-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> --- packages/cli/cli-report.md | 11 +++++++++++ packages/cli/src/commands/index.ts | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/cli/cli-report.md b/packages/cli/cli-report.md index 9afd12fb48..aef56380d2 100644 --- a/packages/cli/cli-report.md +++ b/packages/cli/cli-report.md @@ -390,6 +390,7 @@ Commands: build [options] lint [options] clean + list-deprecations [options] test [options] help [command] ``` @@ -426,6 +427,16 @@ Options: -h, --help ``` +### `backstage-cli repo list-deprecations` + +``` +Usage: backstage-cli repo list-deprecations [options] + +Options: + --json + -h, --help +``` + ### `backstage-cli repo test` ``` diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 266b4fd9f1..82cb60e62f 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -66,8 +66,8 @@ export function registerRepoCommand(program: Command) { .action(lazy(() => import('./repo/clean').then(m => m.command))); command - .command('list-deprecations', { hidden: true }) - .description('List deprecations. [EXPERIMENTAL]') + .command('list-deprecations') + .description('List deprecations') .option('--json', 'Output as JSON') .action( lazy(() => import('./repo/list-deprecations').then(m => m.command)), From e52d6ad8617935d880bc2c7a5adf5487146893c5 Mon Sep 17 00:00:00 2001 From: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Date: Sat, 12 Nov 2022 14:47:41 -0600 Subject: [PATCH 322/434] Added changeset Signed-off-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> --- .changeset/chilled-moles-itch.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/chilled-moles-itch.md diff --git a/.changeset/chilled-moles-itch.md b/.changeset/chilled-moles-itch.md new file mode 100644 index 0000000000..2421993779 --- /dev/null +++ b/.changeset/chilled-moles-itch.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Updated the `backstage-cli` so that the `list-deprecations` command is visible and also removed the "[EXPERIMENTAL]" tag. From 3626b7358e0027cb8ac227c6aea8ce1f27335133 Mon Sep 17 00:00:00 2001 From: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Date: Sun, 13 Nov 2022 13:30:17 -0600 Subject: [PATCH 323/434] Updated content based on feedback Signed-off-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> --- docs/features/software-catalog/external-integrations.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index f3387d31f0..66813cc4d2 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -159,10 +159,10 @@ Check out the numbered markings - let's go through them one by one. the outcome of that. This example issues a `fetch` to the right service and issues a full refresh of its entity bucket based on that. 5. The method translates the foreign data model to the native `Entity` form, as - expected by the catalog. Make sure that in this method you include the - `backstage.io/managed-by-location` and `backstage.io/managed-by-origin-location` - annotations on your `Entity`. If these are not present they will not show up - in the Catalog and you will see warnings in your logs. The + expected by the catalog. The `Entity` must include the + `backstage.io/managed-by-location` and + `backstage.io/managed-by-origin-location annotations`; otherwise, it will not + appear in the Catalog and will generate warning logs. The [Well-known Annotations](./well-known-annotations.md#backstageiomanaged-by-location) documentation has guidance on what values to use for these. 6. Finally, we issue a "mutation" to the catalog. This persists the entities in From b763cf3456cb8be998967f4ff5e4d3778761fe29 Mon Sep 17 00:00:00 2001 From: Leena <19555355+sploschee@users.noreply.github.com> Date: Mon, 14 Nov 2022 08:10:50 +0000 Subject: [PATCH 324/434] reverted removal of yarn3 specific items Signed-off-by: Leena <19555355+sploschee@users.noreply.github.com> --- docs/deployment/docker.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index 68cdf74132..0b28e4d506 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -108,6 +108,8 @@ root of the repo to speed up the build by reducing build context size: ```text .git +.yarn/cache +.yarn/install-state.gz node_modules packages/*/src packages/*/node_modules From 6829241d0677bd74b51f53e360d44ae9a52081a3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 08:58:54 +0000 Subject: [PATCH 325/434] Update dependency @swc/core to v1.3.16 Signed-off-by: Renovate Bot --- storybook/yarn.lock | 86 ++++++++++++++++++++++----------------------- yarn.lock | 86 ++++++++++++++++++++++----------------------- 2 files changed, 86 insertions(+), 86 deletions(-) diff --git a/storybook/yarn.lock b/storybook/yarn.lock index c864d817ab..f6b5be55d0 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -3107,90 +3107,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-darwin-arm64@npm:1.3.14" +"@swc/core-darwin-arm64@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-darwin-arm64@npm:1.3.16" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-darwin-x64@npm:1.3.14" +"@swc/core-darwin-x64@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-darwin-x64@npm:1.3.16" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.14" +"@swc/core-linux-arm-gnueabihf@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.16" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.14" +"@swc/core-linux-arm64-gnu@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.16" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.14" +"@swc/core-linux-arm64-musl@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.16" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.14" +"@swc/core-linux-x64-gnu@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.16" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-linux-x64-musl@npm:1.3.14" +"@swc/core-linux-x64-musl@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-linux-x64-musl@npm:1.3.16" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.14" +"@swc/core-win32-arm64-msvc@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.16" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.14" +"@swc/core-win32-ia32-msvc@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.16" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.14" +"@swc/core-win32-x64-msvc@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.16" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.9": - version: 1.3.14 - resolution: "@swc/core@npm:1.3.14" + version: 1.3.16 + resolution: "@swc/core@npm:1.3.16" dependencies: - "@swc/core-darwin-arm64": 1.3.14 - "@swc/core-darwin-x64": 1.3.14 - "@swc/core-linux-arm-gnueabihf": 1.3.14 - "@swc/core-linux-arm64-gnu": 1.3.14 - "@swc/core-linux-arm64-musl": 1.3.14 - "@swc/core-linux-x64-gnu": 1.3.14 - "@swc/core-linux-x64-musl": 1.3.14 - "@swc/core-win32-arm64-msvc": 1.3.14 - "@swc/core-win32-ia32-msvc": 1.3.14 - "@swc/core-win32-x64-msvc": 1.3.14 + "@swc/core-darwin-arm64": 1.3.16 + "@swc/core-darwin-x64": 1.3.16 + "@swc/core-linux-arm-gnueabihf": 1.3.16 + "@swc/core-linux-arm64-gnu": 1.3.16 + "@swc/core-linux-arm64-musl": 1.3.16 + "@swc/core-linux-x64-gnu": 1.3.16 + "@swc/core-linux-x64-musl": 1.3.16 + "@swc/core-win32-arm64-msvc": 1.3.16 + "@swc/core-win32-ia32-msvc": 1.3.16 + "@swc/core-win32-x64-msvc": 1.3.16 dependenciesMeta: "@swc/core-darwin-arm64": optional: true @@ -3214,7 +3214,7 @@ __metadata: optional: true bin: swcx: run_swcx.js - checksum: 79e9857ee3d5af22d9a6e644d7608594fa8ccd9102dbc088addc0f6ee9e1e8e3fc8835545730707395aa47197ab119fa323aedf4184cf51892379b307aedddc0 + checksum: 4361252c928c487a02f526aecd8f3072b923244234c2701916944cf13c252b6d5ce2466caf3e0797d3e92e71a89d4a044f8577e51e8f7fe3af0fe30d94e94b13 languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index d88fa508c4..9545663c4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12929,90 +12929,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-darwin-arm64@npm:1.3.14" +"@swc/core-darwin-arm64@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-darwin-arm64@npm:1.3.16" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-darwin-x64@npm:1.3.14" +"@swc/core-darwin-x64@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-darwin-x64@npm:1.3.16" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.14" +"@swc/core-linux-arm-gnueabihf@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.16" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.14" +"@swc/core-linux-arm64-gnu@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.16" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.14" +"@swc/core-linux-arm64-musl@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.16" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.14" +"@swc/core-linux-x64-gnu@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.16" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-linux-x64-musl@npm:1.3.14" +"@swc/core-linux-x64-musl@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-linux-x64-musl@npm:1.3.16" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.14" +"@swc/core-win32-arm64-msvc@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.16" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.14" +"@swc/core-win32-ia32-msvc@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.16" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.14": - version: 1.3.14 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.14" +"@swc/core-win32-x64-msvc@npm:1.3.16": + version: 1.3.16 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.16" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.9": - version: 1.3.14 - resolution: "@swc/core@npm:1.3.14" + version: 1.3.16 + resolution: "@swc/core@npm:1.3.16" dependencies: - "@swc/core-darwin-arm64": 1.3.14 - "@swc/core-darwin-x64": 1.3.14 - "@swc/core-linux-arm-gnueabihf": 1.3.14 - "@swc/core-linux-arm64-gnu": 1.3.14 - "@swc/core-linux-arm64-musl": 1.3.14 - "@swc/core-linux-x64-gnu": 1.3.14 - "@swc/core-linux-x64-musl": 1.3.14 - "@swc/core-win32-arm64-msvc": 1.3.14 - "@swc/core-win32-ia32-msvc": 1.3.14 - "@swc/core-win32-x64-msvc": 1.3.14 + "@swc/core-darwin-arm64": 1.3.16 + "@swc/core-darwin-x64": 1.3.16 + "@swc/core-linux-arm-gnueabihf": 1.3.16 + "@swc/core-linux-arm64-gnu": 1.3.16 + "@swc/core-linux-arm64-musl": 1.3.16 + "@swc/core-linux-x64-gnu": 1.3.16 + "@swc/core-linux-x64-musl": 1.3.16 + "@swc/core-win32-arm64-msvc": 1.3.16 + "@swc/core-win32-ia32-msvc": 1.3.16 + "@swc/core-win32-x64-msvc": 1.3.16 dependenciesMeta: "@swc/core-darwin-arm64": optional: true @@ -13036,7 +13036,7 @@ __metadata: optional: true bin: swcx: run_swcx.js - checksum: 79e9857ee3d5af22d9a6e644d7608594fa8ccd9102dbc088addc0f6ee9e1e8e3fc8835545730707395aa47197ab119fa323aedf4184cf51892379b307aedddc0 + checksum: 4361252c928c487a02f526aecd8f3072b923244234c2701916944cf13c252b6d5ce2466caf3e0797d3e92e71a89d4a044f8577e51e8f7fe3af0fe30d94e94b13 languageName: node linkType: hard From 120415442e5deb6d01f99f536a03a107e829d1b7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 08:59:55 +0000 Subject: [PATCH 326/434] Update dependency ajv to v8.11.2 Signed-off-by: Renovate Bot --- yarn.lock | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index d88fa508c4..f14ca3bd27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15992,7 +15992,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0, ajv@npm:^8.6.3, ajv@npm:^8.8.0": +"ajv@npm:^8.0.0, ajv@npm:^8.11.0, ajv@npm:^8.6.3, ajv@npm:^8.8.0": version: 8.11.0 resolution: "ajv@npm:8.11.0" dependencies: @@ -16004,6 +16004,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:^8.10.0": + version: 8.11.2 + resolution: "ajv@npm:8.11.2" + dependencies: + fast-deep-equal: ^3.1.1 + json-schema-traverse: ^1.0.0 + require-from-string: ^2.0.2 + uri-js: ^4.2.2 + checksum: 53435bf79ee7d1eabba8085962dba4c08d08593334b304db7772887f0b7beebc1b3d957432f7437ed4b60e53b5d966a57b439869890209c50fed610459999e3e + languageName: node + linkType: hard + "alphanum-sort@npm:^1.0.2": version: 1.0.2 resolution: "alphanum-sort@npm:1.0.2" From bab2ae85a5c28dd68cae01697feda3c040ba0eff Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 14 Nov 2022 10:40:50 +0100 Subject: [PATCH 327/434] write test for capturing rank prop Signed-off-by: Emma Indal --- ...StackOverflowSearchResultListItem.test.tsx | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.test.tsx b/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.test.tsx index 61e901591e..9e27149efb 100644 --- a/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.test.tsx +++ b/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.test.tsx @@ -15,9 +15,15 @@ */ import React from 'react'; -import { renderInTestApp } from '@backstage/test-utils'; +import { + MockAnalyticsApi, + renderInTestApp, + TestApiProvider, +} from '@backstage/test-utils'; +import userEvent from '@testing-library/user-event'; import { screen } from '@testing-library/react'; import { StackOverflowSearchResultListItem } from './StackOverflowSearchResultListItem'; +import { analyticsApiRef } from '@backstage/core-plugin-api'; describe('', () => { it('should render without exploding', async () => { @@ -40,4 +46,36 @@ describe('', () => { screen.getByText(/Customizing Spotify backstage UI/i).closest('a'), ).toHaveAttribute('href', 'https://stackoverflow.com/questions/7'); }); + + it('should capture analytics for rank', async () => { + const analyticsSpy = new MockAnalyticsApi(); + + await renderInTestApp( + + + , + , + ); + + await userEvent.click( + screen.getByText(/Customizing Spotify backstage UI/i), + ); + + expect(analyticsSpy.getEvents()[0]).toMatchObject({ + action: 'discover', + attributes: { to: 'https://stackoverflow.com/questions/7' }, + context: { extension: 'App', pluginId: 'root', routeRef: 'unknown' }, + subject: 'Customizing Spotify backstage UI', + value: 1, + }); + }); }); From 4043f4c6cf7965d52bd508fa072a9b43f7791fbe Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 14 Nov 2022 10:50:59 +0100 Subject: [PATCH 328/434] accept result rank prop Signed-off-by: Emma Indal --- .../StackOverflowSearchResultListItem.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.tsx b/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.tsx index c793939593..581fe34dfb 100644 --- a/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.tsx +++ b/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.tsx @@ -25,19 +25,29 @@ import { Box, Chip, } from '@material-ui/core'; +import { useAnalytics } from '@backstage/core-plugin-api'; type StackOverflowSearchResultListItemProps = { result: any; // TODO(emmaindal): type to StackOverflowDocument. icon?: React.ReactNode; + rank?: number; }; export const StackOverflowSearchResultListItem = ( props: StackOverflowSearchResultListItemProps, ) => { const { location, title, text, answers, tags } = props.result; + const analytics = useAnalytics(); + + const handleClick = () => { + analytics.captureEvent('discover', title, { + attributes: { to: location }, + value: props.rank, + }); + }; return ( - + {props.icon && {props.icon}} From 8c4fe3171e25a43d1a1682ba74bff05ac42a10a7 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 14 Nov 2022 10:52:01 +0100 Subject: [PATCH 329/434] update api report Signed-off-by: Emma Indal --- plugins/stack-overflow/api-report.md | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/stack-overflow/api-report.md b/plugins/stack-overflow/api-report.md index 81cfe1395b..9af9231094 100644 --- a/plugins/stack-overflow/api-report.md +++ b/plugins/stack-overflow/api-report.md @@ -44,5 +44,6 @@ export type StackOverflowQuestionsRequestParams = { export const StackOverflowSearchResultListItem: (props: { result: any; icon?: ReactNode; + rank?: number | undefined; }) => JSX.Element; ``` From e32d5643e33523db22126c5744f6fb0393fa958d Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 14 Nov 2022 10:55:49 +0100 Subject: [PATCH 330/434] add changeset Signed-off-by: Emma Indal --- .changeset/many-starfishes-exist.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/many-starfishes-exist.md diff --git a/.changeset/many-starfishes-exist.md b/.changeset/many-starfishes-exist.md new file mode 100644 index 0000000000..d6f891aa78 --- /dev/null +++ b/.changeset/many-starfishes-exist.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-stack-overflow': patch +--- + +`StackOverflowSearchResultListItem` now accept optional rank property to be able to capture rank analytics data. From d672fc26584d369c9d4be75ee69eee3e1362f392 Mon Sep 17 00:00:00 2001 From: Guilherme Oenning Date: Mon, 14 Nov 2022 10:22:55 +0000 Subject: [PATCH 331/434] add ESW to adopters Signed-off-by: Guilherme Oenning Signed-off-by: Guilherme Oenning --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index 0b8b1a1ccf..ec2c7637fe 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -220,3 +220,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Raízen](https://www.raizen.com) | [Melquisedque Bernardes Pereira](https://github.com/rayleshh) and [Paulo Eduardo Peixoto](https://github.com/padupe) | Backstage helps us to organize and make available, in a simple and direct way, all the infrastructure for new projects. In addition, it has become a great support tool for our developers. | | [Trifork](https://trifork.com) | [Casper Thygesen](https://github.com/cthtrifork) | We're using Backstage as part of our dataplatform product. It integrates with the infrastructure components and is the developer portal for all the platform users. | | [MSCI](http://msci.com) | [Stephen Burrows](mailto:stephen.burrows@msci.com) | Developer portal, service catalog, documentation and tooling +| [ESW](http://esw.com) | [Alisson Fabiano](https://github.com/afabianoo), [Bruno Quintella](https://github.com/quintelab) and [Guilherme Oenning](https://github.com/goenning) | Backstage is our one stop shop to find everything related to all our services, such as ownership, dependencies, production status, tech health and much more. From d69fff6a9ca6bd67f3157523c7e26b5e7a13842e Mon Sep 17 00:00:00 2001 From: Guilherme Oenning Date: Mon, 14 Nov 2022 10:24:14 +0000 Subject: [PATCH 332/434] should be https :) Signed-off-by: Guilherme Oenning --- ADOPTERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ADOPTERS.md b/ADOPTERS.md index ec2c7637fe..76ec9ea348 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -220,4 +220,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Raízen](https://www.raizen.com) | [Melquisedque Bernardes Pereira](https://github.com/rayleshh) and [Paulo Eduardo Peixoto](https://github.com/padupe) | Backstage helps us to organize and make available, in a simple and direct way, all the infrastructure for new projects. In addition, it has become a great support tool for our developers. | | [Trifork](https://trifork.com) | [Casper Thygesen](https://github.com/cthtrifork) | We're using Backstage as part of our dataplatform product. It integrates with the infrastructure components and is the developer portal for all the platform users. | | [MSCI](http://msci.com) | [Stephen Burrows](mailto:stephen.burrows@msci.com) | Developer portal, service catalog, documentation and tooling -| [ESW](http://esw.com) | [Alisson Fabiano](https://github.com/afabianoo), [Bruno Quintella](https://github.com/quintelab) and [Guilherme Oenning](https://github.com/goenning) | Backstage is our one stop shop to find everything related to all our services, such as ownership, dependencies, production status, tech health and much more. +| [ESW](https://esw.com) | [Alisson Fabiano](https://github.com/afabianoo), [Bruno Quintella](https://github.com/quintelab) and [Guilherme Oenning](https://github.com/goenning) | Backstage is our one stop shop to find everything related to all our services, such as ownership, dependencies, production status, tech health and much more. From 5b6008f79d7e73da14f500c8748a2ac1984f0345 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 11:47:51 +0000 Subject: [PATCH 333/434] Update dependency @graphql-codegen/cli to v2.13.12 Signed-off-by: Renovate Bot --- yarn.lock | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/yarn.lock b/yarn.lock index 12fc34d8ea..ab1d2d0c3b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9710,13 +9710,13 @@ __metadata: linkType: hard "@graphql-codegen/cli@npm:^2.3.1": - version: 2.13.11 - resolution: "@graphql-codegen/cli@npm:2.13.11" + version: 2.13.12 + resolution: "@graphql-codegen/cli@npm:2.13.12" dependencies: "@babel/generator": ^7.18.13 "@babel/template": ^7.18.10 "@babel/types": ^7.18.13 - "@graphql-codegen/core": 2.6.5 + "@graphql-codegen/core": 2.6.6 "@graphql-codegen/plugin-helpers": ^2.7.2 "@graphql-tools/apollo-engine-loader": ^7.3.6 "@graphql-tools/code-file-loader": ^7.3.1 @@ -9756,21 +9756,21 @@ __metadata: graphql-code-generator: cjs/bin.js graphql-codegen: cjs/bin.js graphql-codegen-esm: esm/bin.js - checksum: 8d5d6f848f245b2091b85785466805cced26d788a66c3e03fbcfd6dc8b5bac4215b6b687d746ad0ee05685c700eecc93b502fd73c3383e5ac4a19cc1b4198ac1 + checksum: 367d4687e1d4bf44f0a7f3cb4e71656774f006512883a51ceae905495b2e76819e6b49dfe63e3effe59abb990a4c17bb985878a4592bf2ff959dc822723c1370 languageName: node linkType: hard -"@graphql-codegen/core@npm:2.6.5": - version: 2.6.5 - resolution: "@graphql-codegen/core@npm:2.6.5" +"@graphql-codegen/core@npm:2.6.6": + version: 2.6.6 + resolution: "@graphql-codegen/core@npm:2.6.6" dependencies: "@graphql-codegen/plugin-helpers": ^2.7.2 "@graphql-tools/schema": ^9.0.0 - "@graphql-tools/utils": 9.0.0 + "@graphql-tools/utils": ^9.1.1 tslib: ~2.4.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 22a30285af6adf5acd8ed2f45363c77b718a1789f024094a4fcc62fc164440f0fed595b5eecfa216e3568a81ba07dd8f2e6111cb49f2ce46160b14167a330c41 + checksum: 4a506dfb7dad577510b0358444ad5c5080459c00e1740099212d28c08fc4f02824014602172b95a61c6092cc97b3838fafd02b3e2eadf99dd9b6fa390464935a languageName: node linkType: hard @@ -10455,17 +10455,6 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/utils@npm:9.0.0": - version: 9.0.0 - resolution: "@graphql-tools/utils@npm:9.0.0" - dependencies: - tslib: ^2.4.0 - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: 8da22b13e0cfceac20f2ee08c45f360d0bd1390fa0edd8496ea75a0ca7d10ab3bbafca6b4b0dbc3f233a05cd53096e3063b9208f727c72db00e461751164afbd - languageName: node - linkType: hard - "@graphql-tools/utils@npm:9.1.0": version: 9.1.0 resolution: "@graphql-tools/utils@npm:9.1.0" @@ -10477,6 +10466,17 @@ __metadata: languageName: node linkType: hard +"@graphql-tools/utils@npm:^9.1.1": + version: 9.1.1 + resolution: "@graphql-tools/utils@npm:9.1.1" + dependencies: + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 5a5120417c00b0f8a834b69dca9b7496022f8b1ed3719c2cf7de8253ff639ecc0f4a8e2bcaf0193ce44bd59431098180e94bdd96406e9f260e058b16c0e26975 + languageName: node + linkType: hard + "@graphql-tools/wrap@npm:8.5.0": version: 8.5.0 resolution: "@graphql-tools/wrap@npm:8.5.0" From cef70b6685a549f66b00619f1bf6281287206744 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 12:35:39 +0000 Subject: [PATCH 334/434] Update dependency @types/dockerode to v3.3.13 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e006f4d76a..b1443e701e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14677,12 +14677,12 @@ __metadata: linkType: hard "@types/dockerode@npm:^3.3.0": - version: 3.3.12 - resolution: "@types/dockerode@npm:3.3.12" + version: 3.3.13 + resolution: "@types/dockerode@npm:3.3.13" dependencies: "@types/docker-modem": "*" "@types/node": "*" - checksum: 65f16894dca4d359395ed9619ed10d5297917a63b9d86660578e38b97380f5f871188556ab1a5003852e9535a5001ecd7d6c03a1da4391e7c31b30762de55e69 + checksum: dbcf3e33f5d8b731a1540d8b72c91d12583eb87d47adf8defb71f8bc1b328a26a035c66068255929ef99a7906da53ac6e4be76099e8fa7e9720c134b1ab3e153 languageName: node linkType: hard From 67928d16f1071c0704146b0678e1f01cc5e71449 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 12:36:39 +0000 Subject: [PATCH 335/434] Update dependency core-js to v3.26.1 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e006f4d76a..4749487e8f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20045,9 +20045,9 @@ __metadata: linkType: hard "core-js@npm:^3.6.5": - version: 3.26.0 - resolution: "core-js@npm:3.26.0" - checksum: 0149eb9d3909fde9c17626af3a6e625c326e8598d0bb5e6c5b48a18e5fcd4eaf48d4964d873667d8148542ff590fb98eb3f93618da114ca54999d6bc0349734b + version: 3.26.1 + resolution: "core-js@npm:3.26.1" + checksum: 0a01149f51ff1e9f41d1ea49cc4c9222047949ea597189ede7c4cf8cde3b097766b9c7615acc77c86fe65b4002f20b638a133dfba7b41dba830d707aeeed45ad languageName: node linkType: hard From c73f1fa5cc5a204fbcf2f9c86071914c7a4c1a07 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 14 Nov 2022 14:23:45 +0100 Subject: [PATCH 336/434] exit prerelease Signed-off-by: Johan Haals --- .changeset/pre.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 75e70fc165..008636c972 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -1,5 +1,5 @@ { - "mode": "pre", + "mode": "exit", "tag": "next", "initialVersions": { "example-app": "0.2.76", From 4077ec711e9f945014b9a6880fa41f0b5c325125 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 14 Nov 2022 14:49:24 +0100 Subject: [PATCH 337/434] Update .changeset/good-doors-attend.md Signed-off-by: Patrik Oldsberg --- .changeset/good-doors-attend.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/good-doors-attend.md b/.changeset/good-doors-attend.md index 43294b252a..0f8a5344ee 100644 --- a/.changeset/good-doors-attend.md +++ b/.changeset/good-doors-attend.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder': patch --- -Fixed tiny grammar error in EntityNamePicker. The first letter of the description is now capatalised. +Fixed tiny grammar error in EntityNamePicker. The first letter of the description is now capitalized. From 83055aa7aa972e4e91a18a6ac5c9af424e0c054c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 14:01:31 +0000 Subject: [PATCH 338/434] Update dependency @codemirror/language to v6.3.1 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b1443e701e..d959daf2f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9241,8 +9241,8 @@ __metadata: linkType: hard "@codemirror/language@npm:^6.0.0": - version: 6.3.0 - resolution: "@codemirror/language@npm:6.3.0" + version: 6.3.1 + resolution: "@codemirror/language@npm:6.3.1" dependencies: "@codemirror/state": ^6.0.0 "@codemirror/view": ^6.0.0 @@ -9250,7 +9250,7 @@ __metadata: "@lezer/highlight": ^1.0.0 "@lezer/lr": ^1.0.0 style-mod: ^4.0.0 - checksum: 996d6aad1a4cfb455f3459951d5ecfb67ff5240cc29397b3b801e569fcda24f87364aa7e42b63e85ecf62af80eaecd01258303dbf5b5f0b1eba31daa9a5bd258 + checksum: 349b9806e1e2ce5d99ba1f5815cc4772e6032f68c95718594e8335196ef0686bc6378db7cdd5f0fda57ba068eebf0ee413bb336e32cc1ff958a743190a0266da languageName: node linkType: hard From c72c6172db7f051eb231f7dfb6bd6a3eba72f1cd Mon Sep 17 00:00:00 2001 From: Harry Powell Date: Mon, 14 Nov 2022 14:18:18 +0000 Subject: [PATCH 339/434] Correct kubernetes.ts file path in installation.md Correcting file path from `packages/backend/src/plugin/kubernetes.ts` to `packages/backend/src/plugins/kubernetes.ts` Signed-off-by: Harry Powell --- docs/features/kubernetes/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/kubernetes/installation.md b/docs/features/kubernetes/installation.md index 5b4e2fa716..616991123d 100644 --- a/docs/features/kubernetes/installation.md +++ b/docs/features/kubernetes/installation.md @@ -102,7 +102,7 @@ If either existing don't work for your use-case, it is possible to implement a custom [KubernetesClustersSupplier](https://backstage.io/docs/reference/plugin-kubernetes-backend.kubernetesclusterssupplier). -Change the following in `packages/backend/src/plugin/kubernetes.ts`: +Change the following in `packages/backend/src/plugins/kubernetes.ts`: ```diff -import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend'; From af85d98bad67e336328ae71d8f16d94dc0ea2c52 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 14 Nov 2022 15:28:08 +0100 Subject: [PATCH 340/434] fixed deprecation in some files backend-common Signed-off-by: Simon --- .../src/database/connectors/mysql.ts | 2 +- .../src/reading/AwsS3UrlReader.test.ts | 4 +-- .../src/reading/AzureUrlReader.test.ts | 4 +-- .../reading/BitbucketCloudUrlReader.test.ts | 2 +- .../src/reading/BitbucketUrlReader.test.ts | 28 +++++++++---------- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/packages/backend-common/src/database/connectors/mysql.ts b/packages/backend-common/src/database/connectors/mysql.ts index b75dc3d99c..4283ff42bd 100644 --- a/packages/backend-common/src/database/connectors/mysql.ts +++ b/packages/backend-common/src/database/connectors/mysql.ts @@ -115,7 +115,7 @@ export function parseMysqlConnectionString( password, host: hostname, port: Number(port || 3306), - database: decodeURIComponent(pathname.substr(1)), + database: decodeURIComponent(pathname.substring(1)), }; const ssl = searchParams.get('ssl'); diff --git a/packages/backend-common/src/reading/AwsS3UrlReader.test.ts b/packages/backend-common/src/reading/AwsS3UrlReader.test.ts index 454b8a2c5a..9f81322eec 100644 --- a/packages/backend-common/src/reading/AwsS3UrlReader.test.ts +++ b/packages/backend-common/src/reading/AwsS3UrlReader.test.ts @@ -247,7 +247,7 @@ describe('AwsS3UrlReader', () => { }); it('returns contents of an object in a bucket', async () => { - const response = await reader.read( + const response = await reader.readUrl( 'https://test-bucket.s3.us-east-2.amazonaws.com/awsS3-mock-object.yaml', ); expect(response.toString().trim()).toBe('site_name: Test'); @@ -255,7 +255,7 @@ describe('AwsS3UrlReader', () => { it('rejects unknown targets', async () => { await expect( - reader.read( + reader.readUrl( 'https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml', ), ).rejects.toThrow( diff --git a/packages/backend-common/src/reading/AzureUrlReader.test.ts b/packages/backend-common/src/reading/AzureUrlReader.test.ts index bc088d8bc9..0ad1346c3c 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.test.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.test.ts @@ -116,7 +116,7 @@ describe('AzureUrlReader', () => { treeResponseFactory, }); - const data = await reader.read(url); + const data = await reader.readUrl(url); const res = await JSON.parse(data.toString('utf-8')); expect(res).toEqual(response); }); @@ -145,7 +145,7 @@ describe('AzureUrlReader', () => { logger, treeResponseFactory, }); - await reader.read(url); + await reader.readUrl(url); }).rejects.toThrow(error); }); }); diff --git a/packages/backend-common/src/reading/BitbucketCloudUrlReader.test.ts b/packages/backend-common/src/reading/BitbucketCloudUrlReader.test.ts index 12ace2755b..ca6e15a005 100644 --- a/packages/backend-common/src/reading/BitbucketCloudUrlReader.test.ts +++ b/packages/backend-common/src/reading/BitbucketCloudUrlReader.test.ts @@ -161,7 +161,7 @@ describe('BitbucketCloudUrlReader', () => { describe('read', () => { it('rejects unknown targets', async () => { await expect( - reader.read('https://not.bitbucket.com/apa'), + reader.readUrl('https://not.bitbucket.com/apa'), ).rejects.toThrow( 'Incorrect URL: https://not.bitbucket.com/apa, Error: Invalid Bitbucket Cloud URL or file path', ); diff --git a/packages/backend-common/src/reading/BitbucketUrlReader.test.ts b/packages/backend-common/src/reading/BitbucketUrlReader.test.ts index 922480f8e7..c18e779592 100644 --- a/packages/backend-common/src/reading/BitbucketUrlReader.test.ts +++ b/packages/backend-common/src/reading/BitbucketUrlReader.test.ts @@ -16,8 +16,8 @@ import { ConfigReader } from '@backstage/config'; import { - BitbucketIntegration, - readBitbucketIntegrationConfig, + BitbucketCloudIntegration, + readBitbucketCloudIntegrationConfig } from '@backstage/integration'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; import fs from 'fs-extra'; @@ -27,14 +27,14 @@ import { setupServer } from 'msw/node'; import os from 'os'; import path from 'path'; import { NotModifiedError } from '@backstage/errors'; -import { BitbucketUrlReader } from './BitbucketUrlReader'; +import { BitbucketCloudUrlReader } from './BitbucketCloudUrlReader'; import { DefaultReadTreeResponseFactory } from './tree'; import { getVoidLogger } from '../logging'; import getRawBody from 'raw-body'; const logger = getVoidLogger(); -describe('BitbucketUrlReader.factory', () => { +describe('BitbucketCloudUrlReader.factory', () => { it('only apply integration configs not inherited from bitbucketCloud or bitbucketServer', () => { const config = new ConfigReader({ integrations: { @@ -57,7 +57,7 @@ describe('BitbucketUrlReader.factory', () => { config: config, }); - const tuples = BitbucketUrlReader.factory({ + const tuples = BitbucketCloudUrlReader.factory({ config, logger, treeResponseFactory, @@ -67,34 +67,32 @@ describe('BitbucketUrlReader.factory', () => { }); }); -describe('BitbucketUrlReader', () => { +describe('BitbucketCloudUrlReader', () => { const treeResponseFactory = DefaultReadTreeResponseFactory.create({ config: new ConfigReader({}), }); - const bitbucketProcessor = new BitbucketUrlReader( - new BitbucketIntegration( - readBitbucketIntegrationConfig( + const bitbucketProcessor = new BitbucketCloudUrlReader( + new BitbucketCloudIntegration( + readBitbucketCloudIntegrationConfig( new ConfigReader({ host: 'bitbucket.org', apiBaseUrl: 'https://api.bitbucket.org/2.0', }), ), ), - logger, { treeResponseFactory }, ); - const hostedBitbucketProcessor = new BitbucketUrlReader( - new BitbucketIntegration( - readBitbucketIntegrationConfig( + const hostedBitbucketProcessor = new BitbucketCloudUrlReader( + new BitbucketCloudIntegration( + readBitbucketCloudIntegrationConfig( new ConfigReader({ host: 'bitbucket.mycompany.net', apiBaseUrl: 'https://api.bitbucket.mycompany.net/rest/api/1.0', }), ), ), - logger, { treeResponseFactory }, ); @@ -209,7 +207,7 @@ describe('BitbucketUrlReader', () => { describe('read', () => { it('rejects unknown targets', async () => { await expect( - bitbucketProcessor.read('https://not.bitbucket.com/apa'), + bitbucketProcessor.readUrl('https://not.bitbucket.com/apa'), ).rejects.toThrow( 'Incorrect URL: https://not.bitbucket.com/apa, Error: Invalid Bitbucket URL or file path', ); From 4801c60746fab0825860886b8b6b4dbf8993d5c4 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 14 Nov 2022 15:38:18 +0100 Subject: [PATCH 341/434] done with deprecations in backend except BitBucketUrl Signed-off-by: Simon --- .../backend-common/src/reading/FetchUrlReader.test.ts | 6 +++--- .../backend-common/src/reading/GithubUrlReader.test.ts | 4 ++-- .../backend-common/src/reading/GitlabUrlReader.test.ts | 4 ++-- .../src/reading/UrlReaderPredicateMux.test.ts | 4 ++-- .../backend-common/src/reading/UrlReaderPredicateMux.ts | 2 +- packages/backend-common/src/reading/integration.test.ts | 8 ++++---- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/backend-common/src/reading/FetchUrlReader.test.ts b/packages/backend-common/src/reading/FetchUrlReader.test.ts index 75172e83b0..d3e7ff840b 100644 --- a/packages/backend-common/src/reading/FetchUrlReader.test.ts +++ b/packages/backend-common/src/reading/FetchUrlReader.test.ts @@ -171,7 +171,7 @@ describe('FetchUrlReader', () => { describe('read', () => { it('should return etag from the response', async () => { - const buffer = await fetchUrlReader.read( + const buffer = await fetchUrlReader.readUrl( 'https://backstage.io/some-resource', ); expect(buffer.toString()).toBe('content foo'); @@ -179,13 +179,13 @@ describe('FetchUrlReader', () => { it('should throw NotFound if server responds with 404', async () => { await expect( - fetchUrlReader.read('https://backstage.io/not-exists'), + fetchUrlReader.readUrl('https://backstage.io/not-exists'), ).rejects.toThrow(NotFoundError); }); it('should throw Error if server responds with 500', async () => { await expect( - fetchUrlReader.read('https://backstage.io/error'), + fetchUrlReader.readUrl('https://backstage.io/error'), ).rejects.toThrow(Error); }); }); diff --git a/packages/backend-common/src/reading/GithubUrlReader.test.ts b/packages/backend-common/src/reading/GithubUrlReader.test.ts index a5f9d26de5..2315d1f9e8 100644 --- a/packages/backend-common/src/reading/GithubUrlReader.test.ts +++ b/packages/backend-common/src/reading/GithubUrlReader.test.ts @@ -92,7 +92,7 @@ describe('GithubUrlReader', () => { describe('implementation', () => { it('rejects unknown targets', async () => { await expect( - githubProcessor.read('https://not.github.com/apa'), + githubProcessor.readUrl('https://not.github.com/apa'), ).rejects.toThrow( 'Incorrect URL: https://not.github.com/apa, Error: Invalid GitHub URL or file path', ); @@ -135,7 +135,7 @@ describe('GithubUrlReader', () => { ), ); - await gheProcessor.read( + await gheProcessor.readUrl( 'https://github.com/backstage/mock/tree/blob/main', ); }); diff --git a/packages/backend-common/src/reading/GitlabUrlReader.test.ts b/packages/backend-common/src/reading/GitlabUrlReader.test.ts index 29ef3f4ce8..2e229f003c 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.test.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.test.ts @@ -150,7 +150,7 @@ describe('GitlabUrlReader', () => { treeResponseFactory, }); - const data = await reader.read(url); + const data = await reader.readUrl(url); const res = await JSON.parse(data.toString('utf-8')); expect(res).toEqual(response); }); @@ -169,7 +169,7 @@ describe('GitlabUrlReader', () => { logger, treeResponseFactory, }); - await reader.read(url); + await reader.readUrl(url); }).rejects.toThrow(error); }); }); diff --git a/packages/backend-common/src/reading/UrlReaderPredicateMux.test.ts b/packages/backend-common/src/reading/UrlReaderPredicateMux.test.ts index 5a11e068df..e3d412b9ab 100644 --- a/packages/backend-common/src/reading/UrlReaderPredicateMux.test.ts +++ b/packages/backend-common/src/reading/UrlReaderPredicateMux.test.ts @@ -41,7 +41,7 @@ describe('UrlReaderPredicateMux', () => { reader: barReader, }); - await mux.read('http://foo/1'); + await mux.readUrl('http://foo/1'); expect(fooReader.read).toHaveBeenCalledWith('http://foo/1'); await mux.readUrl('http://foo/2'); expect(fooReader.readUrl).toHaveBeenCalledWith('http://foo/2', undefined); @@ -50,7 +50,7 @@ describe('UrlReaderPredicateMux', () => { await mux.search('http://foo/4'); expect(fooReader.search).toHaveBeenCalledWith('http://foo/4', undefined); - await mux.read('http://bar/1'); + await mux.readUrl('http://bar/1'); expect(barReader.read).toHaveBeenCalledWith('http://bar/1'); await mux.readUrl('http://bar/2'); expect(barReader.readUrl).toHaveBeenCalledWith('http://bar/2', undefined); diff --git a/packages/backend-common/src/reading/UrlReaderPredicateMux.ts b/packages/backend-common/src/reading/UrlReaderPredicateMux.ts index d5d30605b2..7330e053ff 100644 --- a/packages/backend-common/src/reading/UrlReaderPredicateMux.ts +++ b/packages/backend-common/src/reading/UrlReaderPredicateMux.ts @@ -50,7 +50,7 @@ export class UrlReaderPredicateMux implements UrlReader { for (const { predicate, reader } of this.readers) { if (predicate(parsed)) { - return reader.read(url); + return reader.readUrl(url); } } diff --git a/packages/backend-common/src/reading/integration.test.ts b/packages/backend-common/src/reading/integration.test.ts index 951df29605..0855c86f4f 100644 --- a/packages/backend-common/src/reading/integration.test.ts +++ b/packages/backend-common/src/reading/integration.test.ts @@ -89,7 +89,7 @@ describe.skip('UrlReaders', () => { it( 'should read data from azure', withRetries(3, async () => { - const data = await reader.read( + const data = await reader.readUrl( 'https://dev.azure.com/backstage-verification/test-templates/_git/test-templates?path=%2Ftemplate.yaml', ); expect(data.toString()).toContain('test-template-azure'); @@ -110,7 +110,7 @@ describe.skip('UrlReaders', () => { it( 'should read data from gitlab', withRetries(3, async () => { - const data = await reader.read( + const data = await reader.readUrl( 'https://gitlab.com/backstage-verification/test-templates/-/blob/master/template.yaml', ); expect(data.toString()).toContain('test-template-gitlab'); @@ -131,7 +131,7 @@ describe.skip('UrlReaders', () => { it( 'should read data from bitbucket', withRetries(3, async () => { - const data = await reader.read( + const data = await reader.readUrl( 'https://bitbucket.org/backstage-verification/test-template/src/master/template.yaml', ); expect(data.toString()).toContain('test-template-bitbucket'); @@ -152,7 +152,7 @@ describe.skip('UrlReaders', () => { it( 'should read data from github', withRetries(3, async () => { - const data = await reader.read( + const data = await reader.readUrl( 'https://github.com/backstage-verification/test-templates/blob/master/template.yaml', ); expect(data.toString()).toContain('test-template-github'); From 837e58841411f8fd3fe56e4c982e58912cc528f5 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 14 Nov 2022 16:24:48 +0100 Subject: [PATCH 342/434] Update .changeset/cyan-seahorses-itch.md Signed-off-by: Patrik Oldsberg --- .changeset/cyan-seahorses-itch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/cyan-seahorses-itch.md b/.changeset/cyan-seahorses-itch.md index c3ced5ceb7..32d25aa39d 100644 --- a/.changeset/cyan-seahorses-itch.md +++ b/.changeset/cyan-seahorses-itch.md @@ -1,5 +1,5 @@ --- -'@backstage/core-components': minor +'@backstage/core-components': patch --- Add optional step to SimpleStepper From 9bafcfc2095d3f23fdfc960c8a0dd10bdc51afe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 14 Nov 2022 16:50:17 +0100 Subject: [PATCH 343/434] update tests to be more robust against catalog-client changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../lib/catalog/CatalogIdentityClient.test.ts | 6 +- .../badges-backend/src/service/router.test.ts | 32 ++- .../CatalogGraphCard.test.tsx | 51 +++-- .../CatalogGraphPage.test.tsx | 137 ++++++------ .../EntityRelationsGraph.test.tsx | 200 ++++++++++-------- .../useEntityStore.test.ts | 30 ++- .../src/api/CatalogImportClient.test.ts | 12 +- .../StepPrepareCreatePullRequest.test.tsx | 2 +- .../DefaultExplorePage.test.tsx | 4 +- .../DomainExplorerContent.test.tsx | 4 +- .../GroupsExplorerContent.test.tsx | 4 +- .../components/FossaPage/FossaPage.test.tsx | 9 +- .../src/service/TodoReaderService.test.ts | 2 +- 13 files changed, 269 insertions(+), 224 deletions(-) diff --git a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts index e4d9304892..96cd8d32cb 100644 --- a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts +++ b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts @@ -24,7 +24,7 @@ import { import { CatalogIdentityClient } from './CatalogIdentityClient'; describe('CatalogIdentityClient', () => { - const catalogApi: jest.Mocked = { + const catalogApi = { getLocationById: jest.fn(), getEntityByRef: jest.fn(), getEntities: jest.fn(), @@ -48,7 +48,7 @@ describe('CatalogIdentityClient', () => { catalogApi.getEntities.mockResolvedValueOnce({ items: [{} as UserEntity] }); tokenManager.getToken.mockResolvedValue({ token: 'my-token' }); const client = new CatalogIdentityClient({ - catalogApi, + catalogApi: catalogApi as Partial as CatalogApi, tokenManager, }); @@ -106,7 +106,7 @@ describe('CatalogIdentityClient', () => { tokenManager.getToken.mockResolvedValue({ token: 'my-token' }); const client = new CatalogIdentityClient({ - catalogApi, + catalogApi: catalogApi as Partial as CatalogApi, tokenManager, }); diff --git a/plugins/badges-backend/src/service/router.test.ts b/plugins/badges-backend/src/service/router.test.ts index 9dc60ea1b5..109b64231d 100644 --- a/plugins/badges-backend/src/service/router.test.ts +++ b/plugins/badges-backend/src/service/router.test.ts @@ -29,7 +29,19 @@ import { BadgeBuilder } from '../lib'; describe('createRouter', () => { let app: express.Express; let badgeBuilder: jest.Mocked; - let catalog: jest.Mocked; + const catalog = { + addLocation: jest.fn(), + getEntities: jest.fn(), + getEntityByRef: jest.fn(), + getLocationByRef: jest.fn(), + getLocationById: jest.fn(), + removeLocationById: jest.fn(), + removeEntityByUid: jest.fn(), + refreshEntity: jest.fn(), + getEntityAncestors: jest.fn(), + getEntityFacets: jest.fn(), + validateEntity: jest.fn(), + }; let config: Config; let discovery: PluginEndpointDiscovery; @@ -57,20 +69,6 @@ describe('createRouter', () => { createBadgeJson: jest.fn(), createBadgeSvg: jest.fn(), }; - catalog = { - addLocation: jest.fn(), - getEntities: jest.fn(), - getEntityByRef: jest.fn(), - getLocationByRef: jest.fn(), - getLocationById: jest.fn(), - removeLocationById: jest.fn(), - removeEntityByUid: jest.fn(), - refreshEntity: jest.fn(), - getEntityAncestors: jest.fn(), - getEntityFacets: jest.fn(), - validateEntity: jest.fn(), - }; - config = new ConfigReader({ backend: { baseUrl: 'http://127.0.0.1', @@ -81,7 +79,7 @@ describe('createRouter', () => { const router = await createRouter({ badgeBuilder, - catalog, + catalog: catalog as Partial as CatalogApi, config, discovery, }); @@ -95,7 +93,7 @@ describe('createRouter', () => { it('works', async () => { const router = await createRouter({ badgeBuilder, - catalog, + catalog: catalog as Partial as CatalogApi, config, discovery, }); diff --git a/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.test.tsx b/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.test.tsx index 7cd6d29bbc..c5940be395 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.test.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.test.tsx @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { Entity } from '@backstage/catalog-model'; import { ApiProvider } from '@backstage/core-app-api'; import { analyticsApiRef } from '@backstage/core-plugin-api'; import { - CatalogApi, catalogApiRef, EntityProvider, entityRouteRef, @@ -36,10 +36,24 @@ import { CatalogGraphCard } from './CatalogGraphCard'; describe('', () => { let entity: Entity; let wrapper: JSX.Element; - let catalog: jest.Mocked; + const catalog = { + getEntities: jest.fn(), + getEntityByRef: jest.fn(), + removeEntityByUid: jest.fn(), + getLocationById: jest.fn(), + getLocationByRef: jest.fn(), + addLocation: jest.fn(), + removeLocationById: jest.fn(), + refreshEntity: jest.fn(), + getEntityAncestors: jest.fn(), + getEntityFacets: jest.fn(), + validateEntity: jest.fn(), + }; let apis: TestApiRegistry; beforeEach(() => { + jest.clearAllMocks(); + entity = { apiVersion: 'a', kind: 'b', @@ -48,19 +62,6 @@ describe('', () => { namespace: 'd', }, }; - catalog = { - getEntities: jest.fn(), - getEntityByRef: jest.fn(async _ => ({ ...entity, relations: [] })), - removeEntityByUid: jest.fn(), - getLocationById: jest.fn(), - getLocationByRef: jest.fn(), - addLocation: jest.fn(), - removeLocationById: jest.fn(), - refreshEntity: jest.fn(), - getEntityAncestors: jest.fn(), - getEntityFacets: jest.fn(), - validateEntity: jest.fn(), - }; apis = TestApiRegistry.from([catalogApiRef, catalog]); wrapper = ( @@ -73,6 +74,11 @@ describe('', () => { }); test('renders without exploding', async () => { + catalog.getEntityByRef.mockImplementation(async _ => ({ + ...entity, + relations: [], + })); + const { findByText, findAllByTestId } = await renderInTestApp(wrapper, { mountedRoutes: { '/entity/{kind}/{namespace}/{name}': entityRouteRef, @@ -86,6 +92,11 @@ describe('', () => { }); test('renders with custom title', async () => { + catalog.getEntityByRef.mockImplementation(async _ => ({ + ...entity, + relations: [], + })); + const { findByText } = await renderInTestApp( @@ -104,6 +115,11 @@ describe('', () => { }); test('renders link to standalone viewer', async () => { + catalog.getEntityByRef.mockImplementation(async _ => ({ + ...entity, + relations: [], + })); + const { findByText, getByText } = await renderInTestApp(wrapper, { mountedRoutes: { '/entity/{kind}/{namespace}/{name}': entityRouteRef, @@ -145,6 +161,11 @@ describe('', () => { }); test('captures analytics event on click', async () => { + catalog.getEntityByRef.mockImplementation(async _ => ({ + ...entity, + relations: [], + })); + const analyticsSpy = new MockAnalyticsApi(); const { findByText } = await renderInTestApp( diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.test.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.test.tsx index 9cca6ef9be..9a5d1f833e 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.test.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.test.tsx @@ -13,13 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { RELATION_HAS_PART, RELATION_PART_OF } from '@backstage/catalog-model'; import { analyticsApiRef } from '@backstage/core-plugin-api'; -import { - CatalogApi, - catalogApiRef, - entityRouteRef, -} from '@backstage/plugin-catalog-react'; +import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; import { MockAnalyticsApi, renderInTestApp, @@ -38,63 +35,59 @@ jest.mock('react-router', () => ({ describe('', () => { let wrapper: JSX.Element; - let catalog: jest.Mocked; + const entityC = { + apiVersion: 'a', + kind: 'b', + metadata: { + name: 'c', + namespace: 'd', + }, + relations: [ + { + type: RELATION_PART_OF, + targetRef: 'b:d/e', + target: { + kind: 'b', + namespace: 'd', + name: 'e', + }, + }, + ], + }; + const entityE = { + apiVersion: 'a', + kind: 'b', + metadata: { + name: 'e', + namespace: 'd', + }, + relations: [ + { + type: RELATION_HAS_PART, + targetRef: 'b:d/c', + target: { + kind: 'b', + namespace: 'd', + name: 'c', + }, + }, + ], + }; + const catalog = { + getEntities: jest.fn(), + getEntityByRef: jest.fn(), + removeEntityByUid: jest.fn(), + getLocationById: jest.fn(), + getLocationByRef: jest.fn(), + addLocation: jest.fn(), + removeLocationById: jest.fn(), + refreshEntity: jest.fn(), + getEntityAncestors: jest.fn(), + getEntityFacets: jest.fn(), + validateEntity: jest.fn(), + }; beforeEach(() => { - const entityC = { - apiVersion: 'a', - kind: 'b', - metadata: { - name: 'c', - namespace: 'd', - }, - relations: [ - { - type: RELATION_PART_OF, - targetRef: 'b:d/e', - target: { - kind: 'b', - namespace: 'd', - name: 'e', - }, - }, - ], - }; - const entityE = { - apiVersion: 'a', - kind: 'b', - metadata: { - name: 'e', - namespace: 'd', - }, - relations: [ - { - type: RELATION_HAS_PART, - targetRef: 'b:d/c', - target: { - kind: 'b', - namespace: 'd', - name: 'c', - }, - }, - ], - }; - catalog = { - getEntities: jest.fn(), - getEntityByRef: jest.fn(async (n: any) => - n === 'b:d/e' ? entityE : entityC, - ), - removeEntityByUid: jest.fn(), - getLocationById: jest.fn(), - getLocationByRef: jest.fn(), - addLocation: jest.fn(), - removeLocationById: jest.fn(), - refreshEntity: jest.fn(), - getEntityAncestors: jest.fn(), - getEntityFacets: jest.fn(), - validateEntity: jest.fn(), - }; - wrapper = ( ', () => { afterEach(() => jest.resetAllMocks()); test('should render without exploding', async () => { + catalog.getEntityByRef.mockImplementation(async (n: any) => + n === 'b:d/e' ? entityE : entityC, + ); + const { getByText, findByText, findAllByTestId } = await renderInTestApp( wrapper, { @@ -128,6 +125,10 @@ describe('', () => { }); test('should toggle filters', async () => { + catalog.getEntityByRef.mockImplementation(async (n: any) => + n === 'b:d/e' ? entityE : entityC, + ); + const { getByText, queryByText } = await renderInTestApp(wrapper, { mountedRoutes: { '/entity/{kind}/{namespace}/{name}': entityRouteRef, @@ -142,6 +143,10 @@ describe('', () => { }); test('should select other entity', async () => { + catalog.getEntityByRef.mockImplementation(async (n: any) => + n === 'b:d/e' ? entityE : entityC, + ); + const { getByText, findByText, findAllByTestId } = await renderInTestApp( wrapper, { @@ -159,6 +164,10 @@ describe('', () => { }); test('should navigate to entity', async () => { + catalog.getEntityByRef.mockImplementation(async (n: any) => + n === 'b:d/e' ? entityE : entityC, + ); + const { getByText, findAllByTestId } = await renderInTestApp(wrapper, { mountedRoutes: { '/entity/{kind}/{namespace}/{name}': entityRouteRef, @@ -174,6 +183,10 @@ describe('', () => { }); test('should capture analytics event when selecting other entity', async () => { + catalog.getEntityByRef.mockImplementation(async (n: any) => + n === 'b:d/e' ? entityE : entityC, + ); + const analyticsSpy = new MockAnalyticsApi(); const { getByText, findAllByTestId } = await renderInTestApp( @@ -200,6 +213,10 @@ describe('', () => { }); test('should capture analytics event when navigating to entity', async () => { + catalog.getEntityByRef.mockImplementation(async (n: any) => + n === 'b:d/e' ? entityE : entityC, + ); + const analyticsSpy = new MockAnalyticsApi(); const { getByText, findAllByTestId } = await renderInTestApp( diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.test.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.test.tsx index c79f975789..d7b9f9e3eb 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.test.tsx +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.test.tsx @@ -22,7 +22,7 @@ import { RELATION_PART_OF, } from '@backstage/catalog-model'; import { DependencyGraphTypes } from '@backstage/core-components'; -import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; import userEvent from '@testing-library/user-event'; import React, { FunctionComponent } from 'react'; @@ -30,98 +30,96 @@ import { EntityRelationsGraph } from './EntityRelationsGraph'; describe('', () => { let Wrapper: FunctionComponent; - let catalog: jest.Mocked; + const entities: { [ref: string]: Entity } = { + 'b:d/c': { + apiVersion: 'a', + kind: 'b', + metadata: { + name: 'c', + namespace: 'd', + }, + relations: [ + { + targetRef: 'k:d/a1', + type: RELATION_OWNER_OF, + }, + { + targetRef: 'b:d/c1', + type: RELATION_HAS_PART, + }, + ], + }, + 'k:d/a1': { + apiVersion: 'a', + kind: 'k', + metadata: { + name: 'a1', + namespace: 'd', + }, + relations: [ + { + targetRef: 'b:d/c', + type: RELATION_OWNED_BY, + }, + { + targetRef: 'b:d/c1', + type: RELATION_OWNED_BY, + }, + ], + }, + 'b:d/c1': { + apiVersion: 'a', + kind: 'b', + metadata: { + name: 'c1', + namespace: 'd', + }, + relations: [ + { + targetRef: 'b:d/c', + type: RELATION_PART_OF, + }, + { + targetRef: 'k:d/a1', + type: RELATION_OWNER_OF, + }, + { + targetRef: 'b:d/c2', + type: RELATION_HAS_PART, + }, + ], + }, + 'b:d/c2': { + apiVersion: 'a', + kind: 'b', + metadata: { + name: 'c2', + namespace: 'd', + }, + relations: [ + { + targetRef: 'b:d/c1', + type: RELATION_PART_OF, + }, + ], + }, + }; + const catalog = { + getEntities: jest.fn(), + getEntityByRef: jest.fn(), + removeEntityByUid: jest.fn(), + getLocationById: jest.fn(), + getLocationByRef: jest.fn(), + addLocation: jest.fn(), + removeLocationById: jest.fn(), + refreshEntity: jest.fn(), + getEntityAncestors: jest.fn(), + getEntityFacets: jest.fn(), + validateEntity: jest.fn(), + }; const CUSTOM_TEST_ID = 'custom-test-id'; beforeEach(() => { - const entities: { [ref: string]: Entity } = { - 'b:d/c': { - apiVersion: 'a', - kind: 'b', - metadata: { - name: 'c', - namespace: 'd', - }, - relations: [ - { - targetRef: 'k:d/a1', - type: RELATION_OWNER_OF, - }, - { - targetRef: 'b:d/c1', - type: RELATION_HAS_PART, - }, - ], - }, - 'k:d/a1': { - apiVersion: 'a', - kind: 'k', - metadata: { - name: 'a1', - namespace: 'd', - }, - relations: [ - { - targetRef: 'b:d/c', - type: RELATION_OWNED_BY, - }, - { - targetRef: 'b:d/c1', - type: RELATION_OWNED_BY, - }, - ], - }, - 'b:d/c1': { - apiVersion: 'a', - kind: 'b', - metadata: { - name: 'c1', - namespace: 'd', - }, - relations: [ - { - targetRef: 'b:d/c', - type: RELATION_PART_OF, - }, - { - targetRef: 'k:d/a1', - type: RELATION_OWNER_OF, - }, - { - targetRef: 'b:d/c2', - type: RELATION_HAS_PART, - }, - ], - }, - 'b:d/c2': { - apiVersion: 'a', - kind: 'b', - metadata: { - name: 'c2', - namespace: 'd', - }, - relations: [ - { - targetRef: 'b:d/c1', - type: RELATION_PART_OF, - }, - ], - }, - }; - catalog = { - getEntities: jest.fn(), - getEntityByRef: jest.fn(async n => entities[n as string]), - removeEntityByUid: jest.fn(), - getLocationById: jest.fn(), - getLocationByRef: jest.fn(), - addLocation: jest.fn(), - removeLocationById: jest.fn(), - refreshEntity: jest.fn(), - getEntityAncestors: jest.fn(), - getEntityFacets: jest.fn(), - validateEntity: jest.fn(), - }; - Wrapper = ({ children }) => ( {children} @@ -129,7 +127,7 @@ describe('', () => { ); }); - afterAll(() => { + afterEach(() => { jest.resetAllMocks(); }); @@ -213,6 +211,8 @@ describe('', () => { }); test('renders at max depth of one', async () => { + catalog.getEntityByRef.mockImplementation(async n => entities[n as string]); + const { findByText, findAllByTestId, findAllByText } = await renderInTestApp( @@ -235,7 +235,9 @@ describe('', () => { expect(catalog.getEntityByRef).toHaveBeenCalledTimes(3); }); - test('renders simplied graph at full depth', async () => { + test('renders simplified graph at full depth', async () => { + catalog.getEntityByRef.mockImplementation(async n => entities[n as string]); + const { findByText, findAllByText, findAllByTestId } = await renderInTestApp( @@ -261,6 +263,8 @@ describe('', () => { }); test('renders full graph at full depth', async () => { + catalog.getEntityByRef.mockImplementation(async n => entities[n as string]); + const { findAllByText, findByText, findAllByTestId } = await renderInTestApp( @@ -288,6 +292,8 @@ describe('', () => { }); test('renders full graph at full depth with merged relations', async () => { + catalog.getEntityByRef.mockImplementation(async n => entities[n as string]); + const { findAllByText, findByText, findAllByTestId } = await renderInTestApp( @@ -313,6 +319,8 @@ describe('', () => { }); test('renders a graph with multiple root nodes', async () => { + catalog.getEntityByRef.mockImplementation(async n => entities[n as string]); + const { findAllByText, findByText, findAllByTestId } = await renderInTestApp( @@ -339,6 +347,8 @@ describe('', () => { }); test('renders a graph with filtered kinds and relations', async () => { + catalog.getEntityByRef.mockImplementation(async n => entities[n as string]); + const { findAllByText, findByText, findAllByTestId } = await renderInTestApp( @@ -361,6 +371,8 @@ describe('', () => { }); test('handle clicks on a node', async () => { + catalog.getEntityByRef.mockImplementation(async n => entities[n as string]); + const onNodeClick = jest.fn(); const { findByText } = await renderInTestApp( @@ -376,6 +388,8 @@ describe('', () => { }); test('render custom node', async () => { + catalog.getEntityByRef.mockImplementation(async n => entities[n as string]); + const renderNode = (props: DependencyGraphTypes.RenderNodeProps) => ( {props.node.id} @@ -398,6 +412,8 @@ describe('', () => { }); test('render custom label', async () => { + catalog.getEntityByRef.mockImplementation(async n => entities[n as string]); + const renderLabel = (props: DependencyGraphTypes.RenderLabelProps) => ( {`Test-Label${props.edge.label}`} diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityStore.test.ts b/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityStore.test.ts index e76b1001c6..802f993802 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityStore.test.ts +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityStore.test.ts @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { Entity } from '@backstage/catalog-model'; import { useApi as useApiMocked } from '@backstage/core-plugin-api'; -import { CatalogApi } from '@backstage/plugin-catalog-react'; import { act, renderHook } from '@testing-library/react-hooks'; import { useEntityStore } from './useEntityStore'; @@ -24,23 +24,21 @@ jest.mock('@backstage/core-plugin-api'); const useApi = useApiMocked as jest.Mocked; describe('useEntityStore', () => { - let catalogApi: jest.Mocked; + const catalogApi = { + getEntities: jest.fn(), + getEntityByRef: jest.fn(), + removeEntityByUid: jest.fn(), + getLocationById: jest.fn(), + getLocationByRef: jest.fn(), + addLocation: jest.fn(), + removeLocationById: jest.fn(), + refreshEntity: jest.fn(), + getEntityAncestors: jest.fn(), + getEntityFacets: jest.fn(), + validateEntity: jest.fn(), + }; beforeEach(() => { - catalogApi = { - getEntities: jest.fn(), - getEntityByRef: jest.fn(), - removeEntityByUid: jest.fn(), - getLocationById: jest.fn(), - getLocationByRef: jest.fn(), - addLocation: jest.fn(), - removeLocationById: jest.fn(), - refreshEntity: jest.fn(), - getEntityAncestors: jest.fn(), - getEntityFacets: jest.fn(), - validateEntity: jest.fn(), - }; - useApi.mockReturnValue(catalogApi); }); diff --git a/plugins/catalog-import/src/api/CatalogImportClient.test.ts b/plugins/catalog-import/src/api/CatalogImportClient.test.ts index d507ac3bef..e77abc8a85 100644 --- a/plugins/catalog-import/src/api/CatalogImportClient.test.ts +++ b/plugins/catalog-import/src/api/CatalogImportClient.test.ts @@ -49,7 +49,7 @@ jest.mock('@octokit/rest', () => { import { ConfigReader, UrlPatternDiscovery } from '@backstage/core-app-api'; import { ScmIntegrations } from '@backstage/integration'; import { ScmAuthApi } from '@backstage/integration-react'; -import { catalogApiRef } from '@backstage/plugin-catalog-react'; +import { CatalogApi } from '@backstage/plugin-catalog-react'; import { setupRequestMockHandlers } from '@backstage/test-utils'; import { Octokit } from '@octokit/rest'; import { rest } from 'msw'; @@ -89,7 +89,7 @@ describe('CatalogImportClient', () => { }), ); - const catalogApi: jest.Mocked = { + const catalogApi = { getEntities: jest.fn(), addLocation: jest.fn(), removeLocationById: jest.fn(), @@ -111,7 +111,7 @@ describe('CatalogImportClient', () => { scmAuthApi, scmIntegrationsApi, identityApi, - catalogApi, + catalogApi: catalogApi as Partial as CatalogApi, configApi: new ConfigReader({ app: { baseUrl: 'https://demo.backstage.io/', @@ -458,7 +458,7 @@ describe('CatalogImportClient', () => { scmAuthApi, scmIntegrationsApi, identityApi, - catalogApi, + catalogApi: catalogApi as Partial as CatalogApi, configApi: new ConfigReader({ catalog: { import: { @@ -610,7 +610,7 @@ describe('CatalogImportClient', () => { scmAuthApi, scmIntegrationsApi, identityApi, - catalogApi, + catalogApi: catalogApi as Partial as CatalogApi, configApi: new ConfigReader({ catalog: { import: { @@ -680,7 +680,7 @@ describe('CatalogImportClient', () => { scmAuthApi, scmIntegrationsApi, identityApi, - catalogApi, + catalogApi: catalogApi as Partial as CatalogApi, configApi: new ConfigReader({ catalog: { import: { diff --git a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx index 5ad7e27c4b..ae6225f912 100644 --- a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx +++ b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx @@ -35,7 +35,7 @@ describe('', () => { preparePullRequest: jest.fn(), }; - const catalogApi: jest.Mocked = { + const catalogApi = { getEntities: jest.fn(), addLocation: jest.fn(), getEntityByRef: jest.fn(), diff --git a/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.test.tsx b/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.test.tsx index 399112fac6..62d197803f 100644 --- a/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.test.tsx +++ b/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.test.tsx @@ -21,8 +21,8 @@ import React from 'react'; import { DefaultExplorePage } from './DefaultExplorePage'; describe('', () => { - const catalogApi: jest.Mocked = { - addLocation: jest.fn(_a => new Promise(() => {})), + const catalogApi = { + addLocation: jest.fn(), getEntities: jest.fn(), getLocationByRef: jest.fn(), getLocationById: jest.fn(), diff --git a/plugins/explore/src/components/DomainExplorerContent/DomainExplorerContent.test.tsx b/plugins/explore/src/components/DomainExplorerContent/DomainExplorerContent.test.tsx index c84363f5c6..a62083f66f 100644 --- a/plugins/explore/src/components/DomainExplorerContent/DomainExplorerContent.test.tsx +++ b/plugins/explore/src/components/DomainExplorerContent/DomainExplorerContent.test.tsx @@ -22,8 +22,8 @@ import React from 'react'; import { DomainExplorerContent } from './DomainExplorerContent'; describe('', () => { - const catalogApi: jest.Mocked = { - addLocation: jest.fn(_a => new Promise(() => {})), + const catalogApi = { + addLocation: jest.fn(), getEntities: jest.fn(), getLocationByRef: jest.fn(), getLocationById: jest.fn(), diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx index a4769e8f4f..9b461fba7d 100644 --- a/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx @@ -22,8 +22,8 @@ import React from 'react'; import { GroupsExplorerContent } from '../GroupsExplorerContent'; describe('', () => { - const catalogApi: jest.Mocked = { - addLocation: jest.fn(_a => new Promise(() => {})), + const catalogApi = { + addLocation: jest.fn(), getEntities: jest.fn(), getLocationByRef: jest.fn(), getLocationById: jest.fn(), diff --git a/plugins/fossa/src/components/FossaPage/FossaPage.test.tsx b/plugins/fossa/src/components/FossaPage/FossaPage.test.tsx index 676a3cff3c..be07b4707f 100644 --- a/plugins/fossa/src/components/FossaPage/FossaPage.test.tsx +++ b/plugins/fossa/src/components/FossaPage/FossaPage.test.tsx @@ -15,21 +15,16 @@ */ import { Entity } from '@backstage/catalog-model'; -import { - CatalogApi, - catalogApiRef, - entityRouteRef, -} from '@backstage/plugin-catalog-react'; +import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; import React from 'react'; import { FossaApi, fossaApiRef } from '../../api'; import { FossaPage } from './FossaPage'; describe('', () => { - const catalogApi: jest.Mocked = { + const catalogApi = { addLocation: jest.fn(), getEntities: jest.fn(), - getEntityByRef: jest.fn(), getLocationByRef: jest.fn(), getLocationById: jest.fn(), removeEntityByUid: jest.fn(), diff --git a/plugins/todo-backend/src/service/TodoReaderService.test.ts b/plugins/todo-backend/src/service/TodoReaderService.test.ts index 8077e2ddb9..3f68636a05 100644 --- a/plugins/todo-backend/src/service/TodoReaderService.test.ts +++ b/plugins/todo-backend/src/service/TodoReaderService.test.ts @@ -58,7 +58,7 @@ function mockCatalogClient(entity?: Entity): jest.Mocked { if (entity) { mock.getEntityByRef.mockReturnValue(entity); } - return mock; + return mock as Partial> as jest.Mocked; } function mockTodoReader(items?: TodoItem[]): jest.Mocked { From da25293910f208d00296af7c7de497a8f8ff7278 Mon Sep 17 00:00:00 2001 From: Phil Kuang Date: Fri, 11 Nov 2022 14:11:42 -0500 Subject: [PATCH 344/434] refactor(scaffolder): wrap full field schema and prop type def in helper Signed-off-by: Phil Kuang --- .../writing-custom-field-extensions.md | 25 ++-- plugins/scaffolder/api-report.md | 116 ++++++++++-------- .../EntityNamePicker/EntityNamePicker.tsx | 7 +- .../fields/EntityNamePicker/schema.ts | 11 +- .../fields/EntityPicker/EntityPicker.tsx | 10 +- .../components/fields/EntityPicker/index.ts | 5 +- .../components/fields/EntityPicker/schema.ts | 17 ++- .../EntityTagsPicker/EntityTagsPicker.tsx | 13 +- .../fields/EntityTagsPicker/index.ts | 2 +- .../fields/EntityTagsPicker/schema.ts | 21 ++-- .../OwnedEntityPicker/OwnedEntityPicker.tsx | 14 +-- .../fields/OwnedEntityPicker/index.ts | 2 +- .../fields/OwnedEntityPicker/schema.ts | 17 +-- .../fields/OwnerPicker/OwnerPicker.tsx | 10 +- .../components/fields/OwnerPicker/index.ts | 5 +- .../components/fields/OwnerPicker/schema.ts | 16 +-- .../fields/RepoUrlPicker/RepoUrlPicker.tsx | 10 +- .../components/fields/RepoUrlPicker/index.ts | 2 +- .../components/fields/RepoUrlPicker/schema.ts | 18 ++- .../scaffolder/src/components/fields/index.ts | 2 +- .../scaffolder/src/components/fields/utils.ts | 45 +++++-- plugins/scaffolder/src/extensions/types.ts | 2 +- 22 files changed, 169 insertions(+), 201 deletions(-) diff --git a/docs/features/software-templates/writing-custom-field-extensions.md b/docs/features/software-templates/writing-custom-field-extensions.md index d0a36ecaf7..1d28bd5db9 100644 --- a/docs/features/software-templates/writing-custom-field-extensions.md +++ b/docs/features/software-templates/writing-custom-field-extensions.md @@ -212,7 +212,7 @@ export const MyCustomExtensionWithOptions = ({ rawErrors, required, formData, -}: FieldProps) => { +}: FieldExtensionComponentProps) => { return ( ) => { +}: MyCustomExtensionWithOptionsProps) => { return ( ( // @public export type CustomFieldExtensionSchema = { + returnValue: JSONSchema7; uiOptions?: JSONSchema7; - returnValue?: JSONSchema7; }; // @public @@ -90,19 +90,20 @@ export const EntityPickerFieldExtension: FieldExtensionComponent< } >; -// @public -export type EntityPickerUiOptions = typeof EntityPickerUiOptionsSchema.type; - // @public (undocumented) -export const EntityPickerUiOptionsSchema: { - schema: JSONSchema7; - type: { +export const EntityPickerFieldSchema: FieldSchema< + string, + { defaultKind?: string | undefined; defaultNamespace?: string | false | undefined; allowedKinds?: string[] | undefined; allowArbitraryValues?: boolean | undefined; - }; -}; + } +>; + +// @public +export type EntityPickerUiOptions = + typeof EntityPickerFieldSchema.uiOptionsType; // @public export const EntityTagsPickerFieldExtension: FieldExtensionComponent< @@ -114,19 +115,19 @@ export const EntityTagsPickerFieldExtension: FieldExtensionComponent< } >; -// @public -export type EntityTagsPickerUiOptions = - typeof EntityTagsPickerUiOptionsSchema.type; - // @public (undocumented) -export const EntityTagsPickerUiOptionsSchema: { - schema: JSONSchema7; - type: { +export const EntityTagsPickerFieldSchema: FieldSchema< + string[], + { showCounts?: boolean | undefined; kinds?: string[] | undefined; helperText?: string | undefined; - }; -}; + } +>; + +// @public +export type EntityTagsPickerUiOptions = + typeof EntityTagsPickerFieldSchema.uiOptionsType; // @public export type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null; @@ -155,6 +156,16 @@ export type FieldExtensionOptions< schema?: CustomFieldExtensionSchema; }; +// @public +export interface FieldSchema { + // (undocumented) + readonly schema: CustomFieldExtensionSchema; + // (undocumented) + readonly type: FieldExtensionComponentProps; + // (undocumented) + readonly uiOptionsType: TUiOptions; +} + // @public export type LayoutComponent<_TInputProps> = () => null; @@ -193,12 +204,18 @@ export type LogEvent = { }; // @public -export function makeJsonSchemaFromZod( - schema: T, -): { - schema: JSONSchema7; - type: T extends z.ZodType ? I : never; -}; +export function makeFieldSchemaFromZod< + TReturnSchema extends z.ZodType, + TUiOptionsSchema extends z.ZodType = z.ZodType, +>( + returnSchema: TReturnSchema, + uiOptionsSchema?: TUiOptionsSchema, +): FieldSchema< + TReturnSchema extends z.ZodType ? IReturn : never, + TUiOptionsSchema extends z.ZodType + ? IUiOptions + : never +>; // @alpha export type NextCustomFieldValidator = ( @@ -268,20 +285,20 @@ export const OwnedEntityPickerFieldExtension: FieldExtensionComponent< } >; -// @public -export type OwnedEntityPickerUiOptions = - typeof OwnedEntityPickerUiOptionsSchema.type; - // @public (undocumented) -export const OwnedEntityPickerUiOptionsSchema: { - schema: JSONSchema7; - type: { +export const OwnedEntityPickerFieldSchema: FieldSchema< + string, + { defaultKind?: string | undefined; defaultNamespace?: string | false | undefined; allowedKinds?: string[] | undefined; allowArbitraryValues?: boolean | undefined; - }; -}; + } +>; + +// @public +export type OwnedEntityPickerUiOptions = + typeof OwnedEntityPickerFieldSchema.uiOptionsType; // @public export const OwnerPickerFieldExtension: FieldExtensionComponent< @@ -293,18 +310,18 @@ export const OwnerPickerFieldExtension: FieldExtensionComponent< } >; -// @public -export type OwnerPickerUiOptions = typeof OwnerPickerUiOptionsSchema.type; - // @public (undocumented) -export const OwnerPickerUiOptionsSchema: { - schema: JSONSchema7; - type: { +export const OwnerPickerFieldSchema: FieldSchema< + string, + { defaultNamespace?: string | false | undefined; allowedKinds?: string[] | undefined; allowArbitraryValues?: boolean | undefined; - }; -}; + } +>; + +// @public +export type OwnerPickerUiOptions = typeof OwnerPickerFieldSchema.uiOptionsType; // @public export const repoPickerValidation: ( @@ -340,13 +357,10 @@ export const RepoUrlPickerFieldExtension: FieldExtensionComponent< } >; -// @public -export type RepoUrlPickerUiOptions = typeof RepoUrlPickerUiOptionsSchema.type; - // @public (undocumented) -export const RepoUrlPickerUiOptionsSchema: { - schema: JSONSchema7; - type: { +export const RepoUrlPickerFieldSchema: FieldSchema< + string, + { allowedOwners?: string[] | undefined; allowedOrganizations?: string[] | undefined; allowedRepos?: string[] | undefined; @@ -365,8 +379,12 @@ export const RepoUrlPickerUiOptionsSchema: { secretsKey: string; } | undefined; - }; -}; + } +>; + +// @public +export type RepoUrlPickerUiOptions = + typeof RepoUrlPickerFieldSchema.uiOptionsType; // @public (undocumented) export const rootRouteRef: RouteRef; diff --git a/plugins/scaffolder/src/components/fields/EntityNamePicker/EntityNamePicker.tsx b/plugins/scaffolder/src/components/fields/EntityNamePicker/EntityNamePicker.tsx index eba05cfb92..555b726917 100644 --- a/plugins/scaffolder/src/components/fields/EntityNamePicker/EntityNamePicker.tsx +++ b/plugins/scaffolder/src/components/fields/EntityNamePicker/EntityNamePicker.tsx @@ -14,8 +14,7 @@ * limitations under the License. */ import React from 'react'; -import { FieldExtensionComponentProps } from '../../../extensions'; -import { EntityNamePickerReturnValue } from './schema'; +import { EntityNamePickerProps } from './schema'; import { TextField } from '@material-ui/core'; export { EntityNamePickerSchema } from './schema'; @@ -23,9 +22,7 @@ export { EntityNamePickerSchema } from './schema'; /** * EntityName Picker */ -export const EntityNamePicker = ( - props: FieldExtensionComponentProps, -) => { +export const EntityNamePicker = (props: EntityNamePickerProps) => { const { onChange, required, diff --git a/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts b/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts index 3139839bf4..27e33befb5 100644 --- a/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/EntityNamePicker/schema.ts @@ -14,13 +14,10 @@ * limitations under the License. */ import { z } from 'zod'; -import { makeJsonSchemaFromZod } from '../utils'; +import { makeFieldSchemaFromZod } from '../utils'; -const EntityNamePickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); +const EntityNamePickerFieldSchema = makeFieldSchemaFromZod(z.string()); -export type EntityNamePickerReturnValue = - typeof EntityNamePickerReturnValueSchema.type; +export const EntityNamePickerSchema = EntityNamePickerFieldSchema.schema; -export const EntityNamePickerSchema = { - returnValue: EntityNamePickerReturnValueSchema.schema, -}; +export type EntityNamePickerProps = typeof EntityNamePickerFieldSchema.type; diff --git a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx index 8fcc412d0a..bc78e00576 100644 --- a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx @@ -23,8 +23,7 @@ import FormControl from '@material-ui/core/FormControl'; import Autocomplete from '@material-ui/lab/Autocomplete'; import React, { useCallback, useEffect } from 'react'; import useAsync from 'react-use/lib/useAsync'; -import { FieldExtensionComponentProps } from '../../../extensions'; -import { EntityPickerReturnValue, EntityPickerUiOptions } from './schema'; +import { EntityPickerProps } from './schema'; export { EntityPickerSchema } from './schema'; @@ -34,12 +33,7 @@ export { EntityPickerSchema } from './schema'; * * @public */ -export const EntityPicker = ( - props: FieldExtensionComponentProps< - EntityPickerReturnValue, - EntityPickerUiOptions - >, -) => { +export const EntityPicker = (props: EntityPickerProps) => { const { onChange, schema: { title = 'Entity', description = 'An entity from the catalog' }, diff --git a/plugins/scaffolder/src/components/fields/EntityPicker/index.ts b/plugins/scaffolder/src/components/fields/EntityPicker/index.ts index d1044e4e67..b8df596c98 100644 --- a/plugins/scaffolder/src/components/fields/EntityPicker/index.ts +++ b/plugins/scaffolder/src/components/fields/EntityPicker/index.ts @@ -13,7 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { - type EntityPickerUiOptions, - EntityPickerUiOptionsSchema, -} from './schema'; +export { EntityPickerFieldSchema, type EntityPickerUiOptions } from './schema'; diff --git a/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts b/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts index 3d14a2bf3e..9236457fc0 100644 --- a/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/EntityPicker/schema.ts @@ -14,12 +14,13 @@ * limitations under the License. */ import { z } from 'zod'; -import { makeJsonSchemaFromZod } from '../utils'; +import { makeFieldSchemaFromZod } from '../utils'; /** * @public */ -export const EntityPickerUiOptionsSchema = makeJsonSchemaFromZod( +export const EntityPickerFieldSchema = makeFieldSchemaFromZod( + z.string(), z.object({ allowedKinds: z .array(z.string()) @@ -44,19 +45,15 @@ export const EntityPickerUiOptionsSchema = makeJsonSchemaFromZod( }), ); -const EntityPickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); - /** * The input props that can be specified under `ui:options` for the * `EntityPicker` field extension. * * @public */ -export type EntityPickerUiOptions = typeof EntityPickerUiOptionsSchema.type; +export type EntityPickerUiOptions = + typeof EntityPickerFieldSchema.uiOptionsType; -export type EntityPickerReturnValue = typeof EntityPickerReturnValueSchema.type; +export type EntityPickerProps = typeof EntityPickerFieldSchema.type; -export const EntityPickerSchema = { - uiOptions: EntityPickerUiOptionsSchema.schema, - returnValue: EntityPickerReturnValueSchema.schema, -}; +export const EntityPickerSchema = EntityPickerFieldSchema.schema; diff --git a/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx b/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx index 6d5404cee1..549ccdb8aa 100644 --- a/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx +++ b/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx @@ -22,11 +22,7 @@ import { useApi } from '@backstage/core-plugin-api'; import { catalogApiRef } from '@backstage/plugin-catalog-react'; import { FormControl, TextField } from '@material-ui/core'; import { Autocomplete } from '@material-ui/lab'; -import { FieldExtensionComponentProps } from '../../../extensions'; -import { - EntityTagsPickerReturnValue, - EntityTagsPickerUiOptions, -} from './schema'; +import { EntityTagsPickerProps } from './schema'; export { EntityTagsPickerSchema } from './schema'; @@ -36,12 +32,7 @@ export { EntityTagsPickerSchema } from './schema'; * * @public */ -export const EntityTagsPicker = ( - props: FieldExtensionComponentProps< - EntityTagsPickerReturnValue, - EntityTagsPickerUiOptions - >, -) => { +export const EntityTagsPicker = (props: EntityTagsPickerProps) => { const { formData, onChange, uiSchema } = props; const catalogApi = useApi(catalogApiRef); const [tagOptions, setTagOptions] = useState([]); diff --git a/plugins/scaffolder/src/components/fields/EntityTagsPicker/index.ts b/plugins/scaffolder/src/components/fields/EntityTagsPicker/index.ts index 850fc17c8e..52bad9a80d 100644 --- a/plugins/scaffolder/src/components/fields/EntityTagsPicker/index.ts +++ b/plugins/scaffolder/src/components/fields/EntityTagsPicker/index.ts @@ -14,6 +14,6 @@ * limitations under the License. */ export { + EntityTagsPickerFieldSchema, type EntityTagsPickerUiOptions, - EntityTagsPickerUiOptionsSchema, } from './schema'; diff --git a/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts b/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts index d3a5391385..6677d16e98 100644 --- a/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/EntityTagsPicker/schema.ts @@ -14,12 +14,13 @@ * limitations under the License. */ import { z } from 'zod'; -import { makeJsonSchemaFromZod } from '../utils'; +import { makeFieldSchemaFromZod } from '../utils'; /** * @public */ -export const EntityTagsPickerUiOptionsSchema = makeJsonSchemaFromZod( +export const EntityTagsPickerFieldSchema = makeFieldSchemaFromZod( + z.array(z.string()), z.object({ kinds: z .array(z.string()) @@ -33,9 +34,9 @@ export const EntityTagsPickerUiOptionsSchema = makeJsonSchemaFromZod( }), ); -const EntityTagsPickerReturnValueSchema = makeJsonSchemaFromZod( - z.array(z.string()), -); +export const EntityTagsPickerSchema = EntityTagsPickerFieldSchema.schema; + +export type EntityTagsPickerProps = typeof EntityTagsPickerFieldSchema.type; /** * The input props that can be specified under `ui:options` for the @@ -44,12 +45,4 @@ const EntityTagsPickerReturnValueSchema = makeJsonSchemaFromZod( * @public */ export type EntityTagsPickerUiOptions = - typeof EntityTagsPickerUiOptionsSchema.type; - -export type EntityTagsPickerReturnValue = - typeof EntityTagsPickerReturnValueSchema.type; - -export const EntityTagsPickerSchema = { - uiOptions: EntityTagsPickerUiOptionsSchema.schema, - returnValue: EntityTagsPickerReturnValueSchema.schema, -}; + typeof EntityTagsPickerFieldSchema.uiOptionsType; diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx index 47bcb6c9b8..01a174a6a3 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx @@ -26,25 +26,17 @@ import Autocomplete from '@material-ui/lab/Autocomplete'; import React, { useMemo } from 'react'; import useAsync from 'react-use/lib/useAsync'; -import { FieldExtensionComponentProps } from '../../../extensions'; -import { - OwnedEntityPickerReturnValue, - OwnedEntityPickerUiOptions, -} from './schema'; +import { OwnedEntityPickerProps } from './schema'; export { OwnedEntityPickerSchema } from './schema'; + /** * The underlying component that is rendered in the form for the `OwnedEntityPicker` * field extension. * * @public */ -export const OwnedEntityPicker = ( - props: FieldExtensionComponentProps< - OwnedEntityPickerReturnValue, - OwnedEntityPickerUiOptions - >, -) => { +export const OwnedEntityPicker = (props: OwnedEntityPickerProps) => { const { onChange, schema: { title = 'Entity', description = 'An entity from the catalog' }, diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/index.ts b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/index.ts index 0101eb8845..985dae1d3c 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/index.ts +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/index.ts @@ -14,6 +14,6 @@ * limitations under the License. */ export { + OwnedEntityPickerFieldSchema, type OwnedEntityPickerUiOptions, - OwnedEntityPickerUiOptionsSchema, } from './schema'; diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts index c967448729..4190b89f95 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/schema.ts @@ -14,12 +14,13 @@ * limitations under the License. */ import { z } from 'zod'; -import { makeJsonSchemaFromZod } from '../utils'; +import { makeFieldSchemaFromZod } from '../utils'; /** * @public */ -export const OwnedEntityPickerUiOptionsSchema = makeJsonSchemaFromZod( +export const OwnedEntityPickerFieldSchema = makeFieldSchemaFromZod( + z.string(), z.object({ allowedKinds: z .array(z.string()) @@ -44,8 +45,6 @@ export const OwnedEntityPickerUiOptionsSchema = makeJsonSchemaFromZod( }), ); -const OwnedEntityPickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); - /** * The input props that can be specified under `ui:options` for the * `OwnedEntityPicker` field extension. @@ -53,12 +52,8 @@ const OwnedEntityPickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); * @public */ export type OwnedEntityPickerUiOptions = - typeof OwnedEntityPickerUiOptionsSchema.type; + typeof OwnedEntityPickerFieldSchema.uiOptionsType; -export type OwnedEntityPickerReturnValue = - typeof OwnedEntityPickerReturnValueSchema.type; +export type OwnedEntityPickerProps = typeof OwnedEntityPickerFieldSchema.type; -export const OwnedEntityPickerSchema = { - uiOptions: OwnedEntityPickerUiOptionsSchema.schema, - returnValue: OwnedEntityPickerReturnValueSchema.schema, -}; +export const OwnedEntityPickerSchema = OwnedEntityPickerFieldSchema.schema; diff --git a/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.tsx b/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.tsx index 10333684d0..1c4c356906 100644 --- a/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.tsx +++ b/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.tsx @@ -15,8 +15,7 @@ */ import React from 'react'; import { EntityPicker } from '../EntityPicker/EntityPicker'; -import { FieldExtensionComponentProps } from '../../../extensions'; -import { OwnerPickerReturnValue, OwnerPickerUiOptions } from './schema'; +import { OwnerPickerProps } from './schema'; export { OwnerPickerSchema } from './schema'; @@ -26,12 +25,7 @@ export { OwnerPickerSchema } from './schema'; * * @public */ -export const OwnerPicker = ( - props: FieldExtensionComponentProps< - OwnerPickerReturnValue, - OwnerPickerUiOptions - >, -) => { +export const OwnerPicker = (props: OwnerPickerProps) => { const { schema: { title = 'Owner', description = 'The owner of the component' }, uiSchema, diff --git a/plugins/scaffolder/src/components/fields/OwnerPicker/index.ts b/plugins/scaffolder/src/components/fields/OwnerPicker/index.ts index 5d436358b3..9d94650e04 100644 --- a/plugins/scaffolder/src/components/fields/OwnerPicker/index.ts +++ b/plugins/scaffolder/src/components/fields/OwnerPicker/index.ts @@ -13,7 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { - type OwnerPickerUiOptions, - OwnerPickerUiOptionsSchema, -} from './schema'; +export { OwnerPickerFieldSchema, type OwnerPickerUiOptions } from './schema'; diff --git a/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts b/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts index accc8f80fc..56edef1343 100644 --- a/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/OwnerPicker/schema.ts @@ -14,12 +14,13 @@ * limitations under the License. */ import { z } from 'zod'; -import { makeJsonSchemaFromZod } from '../utils'; +import { makeFieldSchemaFromZod } from '../utils'; /** * @public */ -export const OwnerPickerUiOptionsSchema = makeJsonSchemaFromZod( +export const OwnerPickerFieldSchema = makeFieldSchemaFromZod( + z.string(), z.object({ allowedKinds: z .array(z.string()) @@ -41,19 +42,14 @@ export const OwnerPickerUiOptionsSchema = makeJsonSchemaFromZod( }), ); -const OwnerPickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); - /** * The input props that can be specified under `ui:options` for the * `OwnerPicker` field extension. * * @public */ -export type OwnerPickerUiOptions = typeof OwnerPickerUiOptionsSchema.type; +export type OwnerPickerUiOptions = typeof OwnerPickerFieldSchema.uiOptionsType; -export type OwnerPickerReturnValue = typeof OwnerPickerReturnValueSchema.type; +export type OwnerPickerProps = typeof OwnerPickerFieldSchema.type; -export const OwnerPickerSchema = { - uiOptions: OwnerPickerUiOptionsSchema.schema, - returnValue: OwnerPickerReturnValueSchema.schema, -}; +export const OwnerPickerSchema = OwnerPickerFieldSchema.schema; diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx index 8aca07e995..827eff6ea2 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx @@ -24,11 +24,10 @@ import { GitlabRepoPicker } from './GitlabRepoPicker'; import { AzureRepoPicker } from './AzureRepoPicker'; import { BitbucketRepoPicker } from './BitbucketRepoPicker'; import { GerritRepoPicker } from './GerritRepoPicker'; -import { FieldExtensionComponentProps } from '../../../extensions'; import { RepoUrlPickerHost } from './RepoUrlPickerHost'; import { RepoUrlPickerRepoName } from './RepoUrlPickerRepoName'; import { parseRepoPickerUrl, serializeRepoPickerUrl } from './utils'; -import { RepoUrlPickerReturnValue, RepoUrlPickerUiOptions } from './schema'; +import { RepoUrlPickerProps } from './schema'; import { RepoUrlPickerState } from './types'; import useDebounce from 'react-use/lib/useDebounce'; import { useTemplateSecrets } from '../../secrets'; @@ -41,12 +40,7 @@ export { RepoUrlPickerSchema } from './schema'; * * @public */ -export const RepoUrlPicker = ( - props: FieldExtensionComponentProps< - RepoUrlPickerReturnValue, - RepoUrlPickerUiOptions - >, -) => { +export const RepoUrlPicker = (props: RepoUrlPickerProps) => { const { uiSchema, onChange, rawErrors, formData } = props; const [state, setState] = useState( parseRepoPickerUrl(formData), diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.ts b/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.ts index 34124d0ccd..33e5ef1715 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.ts +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.ts @@ -14,7 +14,7 @@ * limitations under the License. */ export { + RepoUrlPickerFieldSchema, type RepoUrlPickerUiOptions, - RepoUrlPickerUiOptionsSchema, } from './schema'; export { repoPickerValidation } from './validation'; diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts b/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts index bf8fa3cf5c..8f8674a0a7 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/schema.ts @@ -14,12 +14,13 @@ * limitations under the License. */ import { z } from 'zod'; -import { makeJsonSchemaFromZod } from '../utils'; +import { makeFieldSchemaFromZod } from '../utils'; /** * @public */ -export const RepoUrlPickerUiOptionsSchema = makeJsonSchemaFromZod( +export const RepoUrlPickerFieldSchema = makeFieldSchemaFromZod( + z.string(), z.object({ allowedHosts: z .array(z.string()) @@ -77,23 +78,18 @@ export const RepoUrlPickerUiOptionsSchema = makeJsonSchemaFromZod( }), ); -const RepoUrlPickerReturnValueSchema = makeJsonSchemaFromZod(z.string()); - /** * The input props that can be specified under `ui:options` for the * `RepoUrlPicker` field extension. * * @public */ -export type RepoUrlPickerUiOptions = typeof RepoUrlPickerUiOptionsSchema.type; +export type RepoUrlPickerUiOptions = + typeof RepoUrlPickerFieldSchema.uiOptionsType; -export type RepoUrlPickerReturnValue = - typeof RepoUrlPickerReturnValueSchema.type; +export type RepoUrlPickerProps = typeof RepoUrlPickerFieldSchema.type; // NOTE: There is a bug with this failing validation in the custom field explorer due // to https://github.com/rjsf-team/react-jsonschema-form/issues/675 even if // requestUserCredentials is not defined -export const RepoUrlPickerSchema = { - uiOptions: RepoUrlPickerUiOptionsSchema.schema, - returnValue: RepoUrlPickerReturnValueSchema.schema, -}; +export const RepoUrlPickerSchema = RepoUrlPickerFieldSchema.schema; diff --git a/plugins/scaffolder/src/components/fields/index.ts b/plugins/scaffolder/src/components/fields/index.ts index e78b92da00..8d86f601ce 100644 --- a/plugins/scaffolder/src/components/fields/index.ts +++ b/plugins/scaffolder/src/components/fields/index.ts @@ -18,4 +18,4 @@ export * from './OwnerPicker'; export * from './RepoUrlPicker'; export * from './OwnedEntityPicker'; export * from './EntityTagsPicker'; -export { makeJsonSchemaFromZod } from './utils'; +export { type FieldSchema, makeFieldSchemaFromZod } from './utils'; diff --git a/plugins/scaffolder/src/components/fields/utils.ts b/plugins/scaffolder/src/components/fields/utils.ts index 2f56e31db5..2d3e2aab1e 100644 --- a/plugins/scaffolder/src/components/fields/utils.ts +++ b/plugins/scaffolder/src/components/fields/utils.ts @@ -16,20 +16,47 @@ import { JSONSchema7 } from 'json-schema'; import { z } from 'zod'; import zodToJsonSchema from 'zod-to-json-schema'; +import { + CustomFieldExtensionSchema, + FieldExtensionComponentProps, +} from '../../extensions'; /** * @public - * Utility function to convert zod schemas to JSON schemas with - * type inference extraction that abstracts away zod typings + * FieldSchema encapsulates a JSONSchema7 along with the + * matching FieldExtensionComponentProps type for a field extension. */ -export function makeJsonSchemaFromZod( - schema: T, -): { - schema: JSONSchema7; - type: T extends z.ZodType ? I : never; -} { +export interface FieldSchema { + readonly schema: CustomFieldExtensionSchema; + readonly type: FieldExtensionComponentProps; + readonly uiOptionsType: TUiOptions; +} + +/** + * @public + * Utility function to convert zod return and UI options schemas to a + * CustomFieldExtensionSchema with FieldExtensionComponentProps type inference + */ +export function makeFieldSchemaFromZod< + TReturnSchema extends z.ZodType, + TUiOptionsSchema extends z.ZodType = z.ZodType, +>( + returnSchema: TReturnSchema, + uiOptionsSchema?: TUiOptionsSchema, +): FieldSchema< + TReturnSchema extends z.ZodType ? IReturn : never, + TUiOptionsSchema extends z.ZodType + ? IUiOptions + : never +> { return { - schema: zodToJsonSchema(schema) as JSONSchema7, + schema: { + returnValue: zodToJsonSchema(returnSchema) as JSONSchema7, + uiOptions: uiOptionsSchema + ? (zodToJsonSchema(uiOptionsSchema) as JSONSchema7) + : undefined, + }, type: null as any, + uiOptionsType: null as any, }; } diff --git a/plugins/scaffolder/src/extensions/types.ts b/plugins/scaffolder/src/extensions/types.ts index b15de56fc1..3834b39c0a 100644 --- a/plugins/scaffolder/src/extensions/types.ts +++ b/plugins/scaffolder/src/extensions/types.ts @@ -41,8 +41,8 @@ export type CustomFieldValidator = ( * @public */ export type CustomFieldExtensionSchema = { + returnValue: JSONSchema7; uiOptions?: JSONSchema7; - returnValue?: JSONSchema7; }; /** From e9ad86dd8222c341c7868f5327954fcec7f87d51 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 14 Nov 2022 17:54:55 +0100 Subject: [PATCH 345/434] fixed tests that failed from converting to readUrl Signed-off-by: Simon --- packages/backend-common/src/reading/AwsS3UrlReader.test.ts | 4 +++- packages/backend-common/src/reading/AzureUrlReader.test.ts | 7 +++++-- packages/backend-common/src/reading/AzureUrlReader.ts | 2 +- packages/backend-common/src/reading/FetchUrlReader.test.ts | 5 ++++- .../backend-common/src/reading/GitlabUrlReader.test.ts | 2 +- .../src/reading/UrlReaderPredicateMux.test.ts | 4 ++-- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/backend-common/src/reading/AwsS3UrlReader.test.ts b/packages/backend-common/src/reading/AwsS3UrlReader.test.ts index 9f81322eec..dfa1629412 100644 --- a/packages/backend-common/src/reading/AwsS3UrlReader.test.ts +++ b/packages/backend-common/src/reading/AwsS3UrlReader.test.ts @@ -250,7 +250,9 @@ describe('AwsS3UrlReader', () => { const response = await reader.readUrl( 'https://test-bucket.s3.us-east-2.amazonaws.com/awsS3-mock-object.yaml', ); - expect(response.toString().trim()).toBe('site_name: Test'); + const fromStream = await getRawBody(response.stream!()); + + expect(fromStream.toString().trim()).toBe('site_name: Test'); }); it('rejects unknown targets', async () => { diff --git a/packages/backend-common/src/reading/AzureUrlReader.test.ts b/packages/backend-common/src/reading/AzureUrlReader.test.ts index 0ad1346c3c..b50aa30804 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.test.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.test.ts @@ -30,6 +30,8 @@ import { NotModifiedError } from '@backstage/errors'; import { getVoidLogger } from '../logging'; import { AzureUrlReader } from './AzureUrlReader'; import { DefaultReadTreeResponseFactory } from './tree'; +import getRawBody from 'raw-body'; + const logger = getVoidLogger(); @@ -117,7 +119,8 @@ describe('AzureUrlReader', () => { }); const data = await reader.readUrl(url); - const res = await JSON.parse(data.toString('utf-8')); + const fromStream = await getRawBody(data.stream!()); + const res = await JSON.parse(fromStream.toString()); expect(res).toEqual(response); }); @@ -336,4 +339,4 @@ describe('AzureUrlReader', () => { ).rejects.toThrow(NotModifiedError); }); }); -}); +}); \ No newline at end of file diff --git a/packages/backend-common/src/reading/AzureUrlReader.ts b/packages/backend-common/src/reading/AzureUrlReader.ts index 140496c181..9514b410fd 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.ts @@ -200,4 +200,4 @@ export class AzureUrlReader implements UrlReader { const { host, token } = this.integration.config; return `azure{host=${host},authed=${Boolean(token)}}`; } -} +} \ No newline at end of file diff --git a/packages/backend-common/src/reading/FetchUrlReader.test.ts b/packages/backend-common/src/reading/FetchUrlReader.test.ts index d3e7ff840b..18828f2dd0 100644 --- a/packages/backend-common/src/reading/FetchUrlReader.test.ts +++ b/packages/backend-common/src/reading/FetchUrlReader.test.ts @@ -22,6 +22,8 @@ import { setupServer } from 'msw/node'; import { getVoidLogger } from '../logging'; import { FetchUrlReader } from './FetchUrlReader'; import { DefaultReadTreeResponseFactory } from './tree'; +import getRawBody from 'raw-body'; + const fetchUrlReader = new FetchUrlReader(); @@ -174,7 +176,8 @@ describe('FetchUrlReader', () => { const buffer = await fetchUrlReader.readUrl( 'https://backstage.io/some-resource', ); - expect(buffer.toString()).toBe('content foo'); + const fromStream = await getRawBody(buffer.stream!()); + expect(fromStream.toString()).toBe('content foo'); }); it('should throw NotFound if server responds with 404', async () => { diff --git a/packages/backend-common/src/reading/GitlabUrlReader.test.ts b/packages/backend-common/src/reading/GitlabUrlReader.test.ts index 2e229f003c..1a31d3051e 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.test.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.test.ts @@ -151,7 +151,7 @@ describe('GitlabUrlReader', () => { }); const data = await reader.readUrl(url); - const res = await JSON.parse(data.toString('utf-8')); + const res = await JSON.parse(data.toString()); expect(res).toEqual(response); }); diff --git a/packages/backend-common/src/reading/UrlReaderPredicateMux.test.ts b/packages/backend-common/src/reading/UrlReaderPredicateMux.test.ts index e3d412b9ab..38473557e0 100644 --- a/packages/backend-common/src/reading/UrlReaderPredicateMux.test.ts +++ b/packages/backend-common/src/reading/UrlReaderPredicateMux.test.ts @@ -42,7 +42,7 @@ describe('UrlReaderPredicateMux', () => { }); await mux.readUrl('http://foo/1'); - expect(fooReader.read).toHaveBeenCalledWith('http://foo/1'); + expect(fooReader.readUrl).toHaveBeenCalledWith('http://foo/1', undefined); await mux.readUrl('http://foo/2'); expect(fooReader.readUrl).toHaveBeenCalledWith('http://foo/2', undefined); await mux.readTree('http://foo/3'); @@ -51,7 +51,7 @@ describe('UrlReaderPredicateMux', () => { expect(fooReader.search).toHaveBeenCalledWith('http://foo/4', undefined); await mux.readUrl('http://bar/1'); - expect(barReader.read).toHaveBeenCalledWith('http://bar/1'); + expect(barReader.readUrl).toHaveBeenCalledWith('http://bar/1', undefined); await mux.readUrl('http://bar/2'); expect(barReader.readUrl).toHaveBeenCalledWith('http://bar/2', undefined); await mux.readTree('http://bar/3'); From 1fcd60eb4dfd06cdb8565c6843a215606afc3a83 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 14 Nov 2022 19:11:19 +0100 Subject: [PATCH 346/434] fixed last failing test in backend-common Signed-off-by: Simon --- packages/backend-common/src/reading/GitlabUrlReader.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/backend-common/src/reading/GitlabUrlReader.test.ts b/packages/backend-common/src/reading/GitlabUrlReader.test.ts index 1a31d3051e..727fb5d3c0 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.test.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.test.ts @@ -26,6 +26,7 @@ import { getVoidLogger } from '../logging'; import { GitlabUrlReader } from './GitlabUrlReader'; import { DefaultReadTreeResponseFactory } from './tree'; import { NotModifiedError, NotFoundError } from '@backstage/errors'; +import getRawBody from 'raw-body'; import { GitLabIntegration, readGitLabIntegrationConfig, @@ -151,7 +152,8 @@ describe('GitlabUrlReader', () => { }); const data = await reader.readUrl(url); - const res = await JSON.parse(data.toString()); + const fromStream = await getRawBody(data.stream!()); + const res = await JSON.parse(fromStream.toString()); expect(res).toEqual(response); }); From 7b0279ee0248b7bf89fae9c278a6111ddff46cbd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 19:11:30 +0000 Subject: [PATCH 347/434] Update dependency react-hot-loader to v4.13.1 Signed-off-by: Renovate Bot --- storybook/yarn.lock | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/storybook/yarn.lock b/storybook/yarn.lock index a8c455b7a0..b0789605a4 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -7874,7 +7874,7 @@ __metadata: languageName: node linkType: hard -"loader-utils@npm:^1.1.0, loader-utils@npm:^1.2.3": +"loader-utils@npm:^1.2.3": version: 1.4.1 resolution: "loader-utils@npm:1.4.1" dependencies: @@ -7896,6 +7896,17 @@ __metadata: languageName: node linkType: hard +"loader-utils@npm:^2.0.3": + version: 2.0.4 + resolution: "loader-utils@npm:2.0.4" + dependencies: + big.js: ^5.2.2 + emojis-list: ^3.0.0 + json5: ^2.1.2 + checksum: a5281f5fff1eaa310ad5e1164095689443630f3411e927f95031ab4fb83b4a98f388185bb1fe949e8ab8d4247004336a625e9255c22122b815bb9a4c5d8fc3b7 + languageName: node + linkType: hard + "locate-path@npm:^3.0.0": version: 3.0.0 resolution: "locate-path@npm:3.0.0" @@ -9756,25 +9767,25 @@ __metadata: linkType: hard "react-hot-loader@npm:^4.13.0": - version: 4.13.0 - resolution: "react-hot-loader@npm:4.13.0" + version: 4.13.1 + resolution: "react-hot-loader@npm:4.13.1" dependencies: fast-levenshtein: ^2.0.6 global: ^4.3.0 hoist-non-react-statics: ^3.3.0 - loader-utils: ^1.1.0 + loader-utils: ^2.0.3 prop-types: ^15.6.1 react-lifecycles-compat: ^3.0.4 shallowequal: ^1.1.0 source-map: ^0.7.3 peerDependencies: - "@types/react": "^15.0.0 || ^16.0.0 || ^17.0.0 " - react: "^15.0.0 || ^16.0.0 || ^17.0.0 " - react-dom: "^15.0.0 || ^16.0.0 || ^17.0.0 " + "@types/react": ^15.0.0 || ^16.0.0 || ^17.0.0 + react: ^15.0.0 || ^16.0.0 || ^17.0.0 + react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: effdbf4644ce912ae20ad94be62083970c74b26a59fe24ed0024cf73190a5b3edf59650cb693bdd7b70791df8ab8530de273d73b895c4831a91da8a76683e3a3 + checksum: f90890d5160dcb2bfae4022cba065d8e5c26b86f34c4604cbbdd39f5e4dfd82c05c317bb05ef3d4da2aa0be7e8e205c905daea1af40d3a7ef0d07c3d289da11c languageName: node linkType: hard From 40920c5b367689a26c20e6c1f2b2b74666f07bc7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 19:37:36 +0000 Subject: [PATCH 348/434] Update dependency eslint-plugin-deprecation to v1.3.3 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0841181a34..420a8e87c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22730,8 +22730,8 @@ __metadata: linkType: hard "eslint-plugin-deprecation@npm:^1.3.2": - version: 1.3.2 - resolution: "eslint-plugin-deprecation@npm:1.3.2" + version: 1.3.3 + resolution: "eslint-plugin-deprecation@npm:1.3.3" dependencies: "@typescript-eslint/experimental-utils": ^5.0.0 tslib: ^2.3.1 @@ -22739,7 +22739,7 @@ __metadata: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 typescript: ^3.7.5 || ^4.0.0 - checksum: 763776eec6af02ad442bf9ed7e73da198da6969b51418b43f79b3f0a27395e85e9988a3b182e61fab7812a35e17539ba72464d1123a87cc25b195288cbd0c31d + checksum: 5e14d7bc8245a14784623632d43a6210880a4aad4c029fd44686a5516c248287f32406ff230f6e9d238784854b24cd09da953ec8f73d9d19a7c4b3905884e432 languageName: node linkType: hard From 562f8bc6bbeb4ea6e3c889f2258c013651f34ee0 Mon Sep 17 00:00:00 2001 From: Jan Van Bruggen Date: Mon, 14 Nov 2022 23:12:09 -0700 Subject: [PATCH 349/434] Add missing angle brackets I'm new to Backstage, but this sentence doesn't seem to be calling attention to the package's owner/namespace/prefix. Therefore, it seems to intend `scope` as a variable, not an owner/namespace/prefix. Signed-off-by: Jan Van Bruggen --- docs/overview/architecture-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/overview/architecture-overview.md b/docs/overview/architecture-overview.md index 45f3190a5d..384ab6cf32 100644 --- a/docs/overview/architecture-overview.md +++ b/docs/overview/architecture-overview.md @@ -205,7 +205,7 @@ A typical plugin consists of up to five packages, two frontend ones, two backend, and one isomorphic package. All packages within the plugin must share a common prefix, typically of the form `@/plugin-`, but alternatives like `backstage-plugin-` or -`@scope/backstage-plugin-` are also valid. Along with this prefix, +`@/backstage-plugin-` are also valid. Along with this prefix, each of the packages have their own unique suffix that denotes their role. In addition to these five plugin packages it's also possible for a plugin to have additional frontend and backend modules that can be installed to enable optional From fa633304c3bfa48c5ea90153ac6e284d2243c043 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 15 Nov 2022 08:50:29 +0100 Subject: [PATCH 350/434] merge from master and fixed some more deprecations Signed-off-by: Simon --- .../src/validation/CommonValidatorFunctions.test.ts | 2 +- packages/config/src/index.ts | 2 +- .../src/components/SupportButton/SupportButton.tsx | 2 +- yarn.lock | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/catalog-model/src/validation/CommonValidatorFunctions.test.ts b/packages/catalog-model/src/validation/CommonValidatorFunctions.test.ts index 9a9ec8bcda..a887a9aa2e 100644 --- a/packages/catalog-model/src/validation/CommonValidatorFunctions.test.ts +++ b/packages/catalog-model/src/validation/CommonValidatorFunctions.test.ts @@ -224,7 +224,7 @@ describe('CommonValidatorFunctions', () => { ['abc xyz', true], ['abc xyz abc.', true], ])(`isValidString %p ? %p`, (value, result) => { - expect(CommonValidatorFunctions.isValidString(value)).toBe(result); + expect(CommonValidatorFunctions.isNonEmptyString(value)).toBe(result); }); it.each([ diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index c8800d0ad2..a795a02b86 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -25,6 +25,6 @@ export type { JsonObject, JsonPrimitive, JsonValue, -} from './deprecatedTypes'; +} from '@backstage/types'; export { ConfigReader } from './reader'; export type { AppConfig, Config } from './types'; diff --git a/packages/core-components/src/components/SupportButton/SupportButton.tsx b/packages/core-components/src/components/SupportButton/SupportButton.tsx index 01de79bdee..4e0bb866f5 100644 --- a/packages/core-components/src/components/SupportButton/SupportButton.tsx +++ b/packages/core-components/src/components/SupportButton/SupportButton.tsx @@ -68,7 +68,7 @@ const SupportListItem = ({ item }: { item: SupportItem }) => { ( + secondary={item.links?.reduce( (prev, link, idx) => [ ...prev, idx > 0 &&
, diff --git a/yarn.lock b/yarn.lock index 0841181a34..c77ebcf329 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38915,7 +38915,7 @@ __metadata: "typescript@patch:typescript@~4.6.0#~builtin, typescript@patch:typescript@~4.6.3#~builtin": version: 4.6.4 - resolution: "typescript@patch:typescript@npm%3A4.6.4#~builtin::version=4.6.4&hash=a1c5e5" + resolution: "typescript@patch:typescript@npm%3A4.6.4#~builtin::version=4.6.4&hash=f456af" bin: tsc: bin/tsc tsserver: bin/tsserver @@ -38925,7 +38925,7 @@ __metadata: "typescript@patch:typescript@~4.7.0#~builtin": version: 4.7.4 - resolution: "typescript@patch:typescript@npm%3A4.7.4#~builtin::version=4.7.4&hash=a1c5e5" + resolution: "typescript@patch:typescript@npm%3A4.7.4#~builtin::version=4.7.4&hash=f456af" bin: tsc: bin/tsc tsserver: bin/tsserver From d1b0d6675480ee65f123c346e179b94a974ee8ce Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 15 Nov 2022 09:13:20 +0100 Subject: [PATCH 351/434] removed blank row Signed-off-by: Simon --- packages/backend-common/src/reading/AzureUrlReader.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/backend-common/src/reading/AzureUrlReader.test.ts b/packages/backend-common/src/reading/AzureUrlReader.test.ts index b50aa30804..035f9bcb05 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.test.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.test.ts @@ -32,7 +32,6 @@ import { AzureUrlReader } from './AzureUrlReader'; import { DefaultReadTreeResponseFactory } from './tree'; import getRawBody from 'raw-body'; - const logger = getVoidLogger(); const treeResponseFactory = DefaultReadTreeResponseFactory.create({ From 931eb6d3bcd15a4b5964976d90a402b97b349182 Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Tue, 15 Nov 2022 09:26:00 +0100 Subject: [PATCH 352/434] fix readme Signed-off-by: Nikita Karpukhin --- plugins/user-settings/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/user-settings/README.md b/plugins/user-settings/README.md index 1549b8de65..07e1d6dcbb 100644 --- a/plugins/user-settings/README.md +++ b/plugins/user-settings/README.md @@ -104,7 +104,7 @@ import { } from '@backstage/plugin-user-settings'; import { AdvancedSettings } from './advancedSettings'; -export const settingsPage = () => ( +export const settingsPage = ( From 3b022fedb65d6b995ad44480a404f763fcc245b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 10 Nov 2022 11:56:29 +0100 Subject: [PATCH 353/434] richer errors in the msgraph import steps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw Signed-off-by: Simon --- .changeset/clean-socks-call.md | 5 +++++ .../src/microsoftGraph/read.ts | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/clean-socks-call.md diff --git a/.changeset/clean-socks-call.md b/.changeset/clean-socks-call.md new file mode 100644 index 0000000000..9b802618f6 --- /dev/null +++ b/.changeset/clean-socks-call.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-msgraph': patch +--- + +Added cause information to logged warnings diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts index 8e1d9a3776..0ed411bfea 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts @@ -122,7 +122,7 @@ export async function readMicrosoftGraphUsers( 120, ); } catch (e) { - options.logger.warn(`Unable to load photo for ${user.id}`); + options.logger.warn(`Unable to load photo for ${user.id}, ${e}`); } const entity = await transformer(user, userPhoto); @@ -206,7 +206,7 @@ export async function readMicrosoftGraphUsersInGroups( expand: options.userExpand, }); } catch (e) { - options.logger.warn(`Unable to load user for ${userId}`); + options.logger.warn(`Unable to load user for ${userId}, ${e}`); } if (user) { try { @@ -217,7 +217,7 @@ export async function readMicrosoftGraphUsersInGroups( 120, ); } catch (e) { - options.logger.warn(`Unable to load userphoto for ${userId}`); + options.logger.warn(`Unable to load userphoto for ${userId}, ${e}`); } const entity = await transformer(user, userPhoto); From 128b3e98fb8d8eb3fbd18ba84794882afdfedd2b Mon Sep 17 00:00:00 2001 From: Casper Thygesen <73483987+cthtrifork@users.noreply.github.com> Date: Tue, 8 Nov 2022 19:48:03 +0100 Subject: [PATCH 354/434] Add default errorHandler() to vault-backend Right now any uncaught error causes backstarte to crash We should use `packages/backend-common/src/middleware/errorHandler.ts` middleware like the other backend plugins Signed-off-by: Casper Thygesen <73483987+cthtrifork@users.noreply.github.com> Signed-off-by: cthtrifork Signed-off-by: Simon --- plugins/vault-backend/src/service/VaultBuilder.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/vault-backend/src/service/VaultBuilder.ts b/plugins/vault-backend/src/service/VaultBuilder.ts index 67260f45ca..b82a5802bb 100644 --- a/plugins/vault-backend/src/service/VaultBuilder.ts +++ b/plugins/vault-backend/src/service/VaultBuilder.ts @@ -20,6 +20,7 @@ import { Logger } from 'winston'; import express, { Router } from 'express'; import { VaultClient } from './vaultApi'; import { TaskRunner, PluginTaskScheduler } from '@backstage/backend-tasks'; +import { errorHandler } from '@backstage/backend-common'; /** * Environment values needed by the VaultBuilder @@ -145,6 +146,7 @@ export class VaultBuilder { res.json({ items: secrets }); }); + router.use(errorHandler()); return router; } } From e2e5242c328bf835f24290101b8a28cb753e6359 Mon Sep 17 00:00:00 2001 From: Casper Thygesen <73483987+cthtrifork@users.noreply.github.com> Date: Tue, 8 Nov 2022 19:51:34 +0100 Subject: [PATCH 355/434] added changeset Signed-off-by: cthtrifork Signed-off-by: Simon --- .changeset/rude-mayflies-heal.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/rude-mayflies-heal.md diff --git a/.changeset/rude-mayflies-heal.md b/.changeset/rude-mayflies-heal.md new file mode 100644 index 0000000000..738ade0f3c --- /dev/null +++ b/.changeset/rude-mayflies-heal.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-vault-backend': patch +--- + +Added errorHandler() middleware to vault-backend to prevent errors to cause a crash From 9a4613e53486579a52e8f8eec375d9a8e8d6d948 Mon Sep 17 00:00:00 2001 From: Casper Thygesen <73483987+cthtrifork@users.noreply.github.com> Date: Wed, 9 Nov 2022 06:43:09 +0100 Subject: [PATCH 356/434] Improved patch notes Co-authored-by: Philipp Hugenroth Signed-off-by: Casper Thygesen <73483987+cthtrifork@users.noreply.github.com> Signed-off-by: Simon --- .changeset/rude-mayflies-heal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/rude-mayflies-heal.md b/.changeset/rude-mayflies-heal.md index 738ade0f3c..01cbf01e28 100644 --- a/.changeset/rude-mayflies-heal.md +++ b/.changeset/rude-mayflies-heal.md @@ -2,4 +2,4 @@ '@backstage/plugin-vault-backend': patch --- -Added errorHandler() middleware to vault-backend to prevent errors to cause a crash +Added `errorHandler()` middleware to `router` to prevent crashes caused by fatal errors in plugin backend From 30744a518667fcb269631923fcb7e416036db025 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Nov 2022 13:58:37 +0000 Subject: [PATCH 357/434] build(deps): bump loader-utils from 1.4.0 to 1.4.1 in /storybook Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.0 to 1.4.1. - [Release notes](https://github.com/webpack/loader-utils/releases) - [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.1/CHANGELOG.md) - [Commits](https://github.com/webpack/loader-utils/compare/v1.4.0...v1.4.1) --- updated-dependencies: - dependency-name: loader-utils dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: Simon --- storybook/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/storybook/yarn.lock b/storybook/yarn.lock index f6b5be55d0..a8c455b7a0 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -7875,13 +7875,13 @@ __metadata: linkType: hard "loader-utils@npm:^1.1.0, loader-utils@npm:^1.2.3": - version: 1.4.0 - resolution: "loader-utils@npm:1.4.0" + version: 1.4.1 + resolution: "loader-utils@npm:1.4.1" dependencies: big.js: ^5.2.2 emojis-list: ^3.0.0 json5: ^1.0.1 - checksum: d150b15e7a42ac47d935c8b484b79e44ff6ab4c75df7cc4cb9093350cf014ec0b17bdb60c5d6f91a37b8b218bd63b973e263c65944f58ca2573e402b9a27e717 + checksum: ea0b648cba0194e04a90aab6270619f0e35be009e33a443d9e642e93056cd49e6ca4c9678bd1c777a2392551bc5f4d0f24a87f5040608da1274aa84c6eebb502 languageName: node linkType: hard From 0d33bdc4ac21a798ea2d761ebcf3dd8ffc59ec30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arn=C3=BE=C3=B3r=20J=C3=B3nsson?= Date: Wed, 9 Nov 2022 18:42:19 +0100 Subject: [PATCH 358/434] Add optional step to SimpleStepper Signed-off-by: Arnthor Jonsson Signed-off-by: Simon --- .changeset/cyan-seahorses-itch.md | 5 ++++ .../SimpleStepper/SimpleStepper.stories.tsx | 20 +++++++++++++ .../SimpleStepper/SimpleStepper.test.tsx | 28 +++++++++++++++++++ .../SimpleStepper/SimpleStepperFooter.tsx | 27 ++++++++++++++++++ .../src/components/SimpleStepper/types.ts | 5 ++++ 5 files changed, 85 insertions(+) create mode 100644 .changeset/cyan-seahorses-itch.md diff --git a/.changeset/cyan-seahorses-itch.md b/.changeset/cyan-seahorses-itch.md new file mode 100644 index 0000000000..c3ced5ceb7 --- /dev/null +++ b/.changeset/cyan-seahorses-itch.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': minor +--- + +Add optional step to SimpleStepper diff --git a/packages/core-components/src/components/SimpleStepper/SimpleStepper.stories.tsx b/packages/core-components/src/components/SimpleStepper/SimpleStepper.stories.tsx index 2f3f26f23e..aedd5e6b80 100644 --- a/packages/core-components/src/components/SimpleStepper/SimpleStepper.stories.tsx +++ b/packages/core-components/src/components/SimpleStepper/SimpleStepper.stories.tsx @@ -91,3 +91,23 @@ export const CompletionStep = (args: StepperProps) => { }; CompletionStep.args = defaultArgs; + +export const OptionalStep = (args: StepperProps) => { + return ( + + +