From 21f409d7768714ce4e09e218b1a393482f68d8b3 Mon Sep 17 00:00:00 2001 From: Rbillon59 Date: Mon, 18 Sep 2023 14:37:51 +0200 Subject: [PATCH 01/37] feat: Export ScorecardInfo and ScorecardsList Components to be able to use manually queried CheckResults directly. Signed-off-by: Rbillon59 --- .changeset/twenty-bags-sin.md | 5 +++++ plugins/tech-insights/api-report.md | 12 ++++++++++++ plugins/tech-insights/src/index.ts | 2 ++ plugins/tech-insights/src/plugin.ts | 24 ++++++++++++++++++++++++ 4 files changed, 43 insertions(+) create mode 100644 .changeset/twenty-bags-sin.md diff --git a/.changeset/twenty-bags-sin.md b/.changeset/twenty-bags-sin.md new file mode 100644 index 0000000000..5eb455f20e --- /dev/null +++ b/.changeset/twenty-bags-sin.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-tech-insights': patch +--- + +Export ScorecardInfo and ScorecardsList Components to be able to use manually queried CheckResults directly. diff --git a/plugins/tech-insights/api-report.md b/plugins/tech-insights/api-report.md index 14fe512ba0..b641ae728e 100644 --- a/plugins/tech-insights/api-report.md +++ b/plugins/tech-insights/api-report.md @@ -68,6 +68,18 @@ export interface InsightFacts { // @public export const jsonRulesEngineCheckResultRenderer: CheckResultRenderer; +// @public (undocumented) +export const ScorecardInfo: (props: { + checkResults: CheckResult[]; + title: string; + description?: string | undefined; +}) => JSX_2.Element; + +// @public (undocumented) +export const ScorecardsList: (props: { + checkResults: CheckResult[]; +}) => JSX_2.Element; + // @public export interface TechInsightsApi { // (undocumented) diff --git a/plugins/tech-insights/src/index.ts b/plugins/tech-insights/src/index.ts index 9e075df038..e7659e39d4 100644 --- a/plugins/tech-insights/src/index.ts +++ b/plugins/tech-insights/src/index.ts @@ -17,6 +17,8 @@ export { techInsightsPlugin, EntityTechInsightsScorecardContent, EntityTechInsightsScorecardCard, + ScorecardInfo, + ScorecardsList, } from './plugin'; export { techInsightsApiRef, TechInsightsClient } from './api'; diff --git a/plugins/tech-insights/src/plugin.ts b/plugins/tech-insights/src/plugin.ts index 961519cd97..412d2a0a1d 100644 --- a/plugins/tech-insights/src/plugin.ts +++ b/plugins/tech-insights/src/plugin.ts @@ -42,6 +42,30 @@ export const techInsightsPlugin = createPlugin({ }, }); +/** + * @public + */ +export const ScorecardInfo = techInsightsPlugin.provide( + createRoutableExtension({ + name: 'ScorecardInfo', + component: () => + import('./components/ScorecardsInfo').then(m => m.ScorecardInfo), + mountPoint: rootRouteRef, + }), +); + +/** + * @public + */ +export const ScorecardsList = techInsightsPlugin.provide( + createRoutableExtension({ + name: 'ScorecardsList', + component: () => + import('./components/ScorecardsList').then(m => m.ScorecardsList), + mountPoint: rootRouteRef, + }), +); + /** * @public */ From 10a0d818da44e8cdbb24da12a49301569b2b0432 Mon Sep 17 00:00:00 2001 From: Romain Billon Date: Tue, 26 Sep 2023 09:08:02 +0200 Subject: [PATCH 02/37] Update .changeset/twenty-bags-sin.md Co-authored-by: Vincenzo Scamporlino Signed-off-by: Romain Billon --- .changeset/twenty-bags-sin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/twenty-bags-sin.md b/.changeset/twenty-bags-sin.md index 5eb455f20e..797fd5bfef 100644 --- a/.changeset/twenty-bags-sin.md +++ b/.changeset/twenty-bags-sin.md @@ -2,4 +2,4 @@ '@backstage/plugin-tech-insights': patch --- -Export ScorecardInfo and ScorecardsList Components to be able to use manually queried CheckResults directly. +Export `ScorecardInfo` and `ScorecardsList` components to be able to use manually queried check results directly. From 56ab78349efc8525e662c440828729a19db665fa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 10:11:32 +0000 Subject: [PATCH 03/37] chore(deps): update dependency @storybook/testing-library to v0.2.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- storybook/yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/storybook/yarn.lock b/storybook/yarn.lock index e0f77cd510..ad29114af0 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -2790,13 +2790,13 @@ __metadata: linkType: hard "@storybook/testing-library@npm:^0.2.0": - version: 0.2.1 - resolution: "@storybook/testing-library@npm:0.2.1" + version: 0.2.2 + resolution: "@storybook/testing-library@npm:0.2.2" dependencies: "@testing-library/dom": ^9.0.0 - "@testing-library/user-event": ~14.4.0 + "@testing-library/user-event": ^14.4.0 ts-dedent: ^2.2.0 - checksum: 2688361b634921219e4dc8e4acbc6622cfba6c224bd9bf17bf9bfb3655c906129cc82edd69354b9b1889b6f43c9c5e74bd51adb4407b68033d78279b93aee457 + checksum: 8ccdc1fbbb3472264c56b0aaf2f1c5d273f1ae9b230a53adf9cf82bf82c1a555550894f0e8869c206fa07b1fe8423da4d56590377756c58de3ec560b35a96c46 languageName: node linkType: hard @@ -2986,12 +2986,12 @@ __metadata: languageName: node linkType: hard -"@testing-library/user-event@npm:~14.4.0": - version: 14.4.3 - resolution: "@testing-library/user-event@npm:14.4.3" +"@testing-library/user-event@npm:^14.4.0": + version: 14.5.1 + resolution: "@testing-library/user-event@npm:14.5.1" peerDependencies: "@testing-library/dom": ">=7.21.4" - checksum: 852c48ea6db1c9471b18276617c84fec4320771e466cd58339a732ca3fd73ad35e5a43ae14f51af51a8d0a150dcf60fcaab049ef367871207bea8f92c4b8195e + checksum: 3e6bc9fd53dfe2f3648190193ed2fd4bca2a1bfb47f68810df3b33f05412526e5fd5c4ef9dc5375635e0f4cdf1859916867b597eed22bda1321e04242ea6c519 languageName: node linkType: hard From b977d6d5a807322bc89afaa96a30474a8373a450 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 19:43:11 +0000 Subject: [PATCH 04/37] fix(deps): update dependency @codemirror/view to v6.21.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9a356d0351..2cc7e06051 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10487,13 +10487,13 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0": - version: 6.21.0 - resolution: "@codemirror/view@npm:6.21.0" + version: 6.21.2 + resolution: "@codemirror/view@npm:6.21.2" dependencies: "@codemirror/state": ^6.1.4 style-mod: ^4.1.0 w3c-keyname: ^2.2.4 - checksum: da49d5541b137a812e1837709130b9a4502fac71b87c45d45384116a7a2b1dab556c283abb673946ba9d044a640ab9058727b85de9b7b576c44848dfbf0ed7bb + checksum: d972a32f26882a1811ffab833f8705339cd4c1bfe56765ed6ecbc1d84466b71a728adb8f4b4fc566ca3bccee5aacd2585e79cb96a851dcd48777e2320dab1892 languageName: node linkType: hard From 65498193e84c5073f23a96d9113d23789dd8d2b2 Mon Sep 17 00:00:00 2001 From: AmbrishRamachandiran Date: Tue, 3 Oct 2023 13:14:38 +0530 Subject: [PATCH 05/37] Updated playlist Screens Signed-off-by: AmbrishRamachandiran --- .changeset/wild-queens-grab.md | 5 +++++ plugins/playlist/README.md | 8 ++++++++ plugins/playlist/docs/playlist-delete.png | Bin 0 -> 96342 bytes .../playlist/docs/playlist-duplicate-error.png | Bin 0 -> 123047 bytes 4 files changed, 13 insertions(+) create mode 100644 .changeset/wild-queens-grab.md create mode 100644 plugins/playlist/docs/playlist-delete.png create mode 100644 plugins/playlist/docs/playlist-duplicate-error.png diff --git a/.changeset/wild-queens-grab.md b/.changeset/wild-queens-grab.md new file mode 100644 index 0000000000..d9aedf3fc5 --- /dev/null +++ b/.changeset/wild-queens-grab.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-playlist': patch +--- + +Updated Playlist Screens diff --git a/plugins/playlist/README.md b/plugins/playlist/README.md index 25caa02742..1e81d07e56 100644 --- a/plugins/playlist/README.md +++ b/plugins/playlist/README.md @@ -154,6 +154,10 @@ playlist: ![Create New Playlist example](./docs/playlist-create-new.png) +### Duplicate Playlist Error + +![Duplicate Playlist Error example](./docs/playlist-duplicate-error.png) + ### Edit Existing Playlist ![Edit Existing Playlist example](./docs/playlist-edit-existing.png) @@ -166,6 +170,10 @@ playlist: ![Add to Playlist from Entity example](./docs/playlist-add-from-entity.png) +### Delete Playlist + +![Delete Playlist example](./docs/playlist-delete.png) + ## Links - [playlist-backend](../playlist-backend) provides the backend API for this frontend. diff --git a/plugins/playlist/docs/playlist-delete.png b/plugins/playlist/docs/playlist-delete.png new file mode 100644 index 0000000000000000000000000000000000000000..7e9ec7d9968c455d9f01183b39a8983d0fe8e14f GIT binary patch literal 96342 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 literal 0 HcmV?d00001 diff --git a/plugins/playlist/docs/playlist-duplicate-error.png b/plugins/playlist/docs/playlist-duplicate-error.png new file mode 100644 index 0000000000000000000000000000000000000000..8d2bec2588f06cca57e6bc98b7985f057d4a4dbb GIT binary patch literal 123047 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࠯& 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 literal 0 HcmV?d00001 From d7eba6cab4e9533a5e8929a25fb918220345a5f8 Mon Sep 17 00:00:00 2001 From: Yevhenii Huselietov Date: Sun, 1 Oct 2023 17:07:03 +0300 Subject: [PATCH 06/37] Export DashboardSnapshotList for NewRelic Signed-off-by: Yevhenii Huselietov --- .changeset/rotten-rings-confess.md | 9 ++++++ plugins/newrelic-dashboard/api-report.md | 10 +++++++ plugins/newrelic-dashboard/src/index.ts | 2 ++ plugins/newrelic-dashboard/src/plugin.ts | 38 +++++++++++++++++++++--- 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 .changeset/rotten-rings-confess.md diff --git a/.changeset/rotten-rings-confess.md b/.changeset/rotten-rings-confess.md new file mode 100644 index 0000000000..8948a90347 --- /dev/null +++ b/.changeset/rotten-rings-confess.md @@ -0,0 +1,9 @@ +--- +'@backstage/plugin-newrelic-dashboard': minor +--- + +Changes in `newrelic-dashboard` plugin: + +- Make DashboardSnapshotList component public +- Settle discrepancies in the exported API +- Deprecate DashboardSnapshotComponent diff --git a/plugins/newrelic-dashboard/api-report.md b/plugins/newrelic-dashboard/api-report.md index ce7b8d5b7e..283523d781 100644 --- a/plugins/newrelic-dashboard/api-report.md +++ b/plugins/newrelic-dashboard/api-report.md @@ -11,12 +11,22 @@ import { JSX as JSX_2 } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; // @public +export const DashboardSnapshot: (props: { + guid: string; + name: string; + permalink: string; +}) => JSX_2.Element; + +// @public @deprecated export const DashboardSnapshotComponent: (props: { guid: string; name: string; permalink: string; }) => JSX_2.Element; +// @public +export const DashboardSnapshotList: (props: { guid: string }) => JSX_2.Element; + // @public (undocumented) export const EntityNewRelicDashboardCard: () => JSX_2.Element; diff --git a/plugins/newrelic-dashboard/src/index.ts b/plugins/newrelic-dashboard/src/index.ts index ba87b8a514..bbdfb70190 100644 --- a/plugins/newrelic-dashboard/src/index.ts +++ b/plugins/newrelic-dashboard/src/index.ts @@ -18,6 +18,8 @@ export { newRelicDashboardPlugin, EntityNewRelicDashboardCard, EntityNewRelicDashboardContent, + DashboardSnapshot, + DashboardSnapshotList, DashboardSnapshotComponent, } from './plugin'; export { isNewRelicDashboardAvailable } from './Router'; diff --git a/plugins/newrelic-dashboard/src/plugin.ts b/plugins/newrelic-dashboard/src/plugin.ts index 51be731ca7..360f1cb911 100644 --- a/plugins/newrelic-dashboard/src/plugin.ts +++ b/plugins/newrelic-dashboard/src/plugin.ts @@ -52,7 +52,7 @@ export const newRelicDashboardPlugin = createPlugin({ /** @public */ export const EntityNewRelicDashboardContent = newRelicDashboardPlugin.provide( createComponentExtension({ - name: 'EntityNewRelicDashboardPage', + name: 'EntityNewRelicDashboardContent', component: { lazy: () => import('./Router').then(m => m.Router), }, @@ -62,7 +62,7 @@ export const EntityNewRelicDashboardContent = newRelicDashboardPlugin.provide( /** @public */ export const EntityNewRelicDashboardCard = newRelicDashboardPlugin.provide( createComponentExtension({ - name: 'EntityNewRelicDashboardListComponent', + name: 'EntityNewRelicDashboardCard', component: { lazy: () => import('./components/NewRelicDashboard/DashboardEntityList').then( @@ -80,9 +80,9 @@ export const EntityNewRelicDashboardCard = newRelicDashboardPlugin.provide( * * @public */ -export const DashboardSnapshotComponent = newRelicDashboardPlugin.provide( +export const DashboardSnapshot = newRelicDashboardPlugin.provide( createComponentExtension({ - name: 'DashboardSnapshotComponent', + name: 'DashboardSnapshot', component: { lazy: () => import( @@ -91,3 +91,33 @@ export const DashboardSnapshotComponent = newRelicDashboardPlugin.provide( }, }), ); + +/** + * Render dashboard snapshots from Newrelic in backstage. Use dashboards which have the tag `isDashboardPage: true` + * + * @deprecated + * Use DashboardSnapshot export name instead + * + * @public + */ +export const DashboardSnapshotComponent = DashboardSnapshot; + +/** + * Render a dashboard snapshots list from Newrelic in backstage. Use dashboards which have the tag `isDashboardPage: true` + * + * @remarks + * This can be helpful for rendering dashboards outside of Entity Catalog. + * + * @public + */ +export const DashboardSnapshotList = newRelicDashboardPlugin.provide( + createComponentExtension({ + name: 'DashboardSnapshotList', + component: { + lazy: () => + import( + './components/NewRelicDashboard/DashboardSnapshotList/DashboardSnapshotList' + ).then(m => m.DashboardSnapshotList), + }, + }), +); From aba6edda91c91d87bf28761de529f9cd1130201f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 3 Oct 2023 14:51:39 +0200 Subject: [PATCH 07/37] try to address flaky SearchModal test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- plugins/search/src/components/SearchModal/SearchModal.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/search/src/components/SearchModal/SearchModal.test.tsx b/plugins/search/src/components/SearchModal/SearchModal.test.tsx index 10be8ba6f8..274f9e21a1 100644 --- a/plugins/search/src/components/SearchModal/SearchModal.test.tsx +++ b/plugins/search/src/components/SearchModal/SearchModal.test.tsx @@ -205,6 +205,7 @@ describe('SearchModal', () => { const input = screen.getByLabelText('Search'); await userEvent.clear(input); + await 'a tick'; await userEvent.type(input, 'new term{enter}'); expect(navigate).toHaveBeenCalledWith('/search?query=new term'); From d47050df850662e55f546c39ff274914e0eca7a9 Mon Sep 17 00:00:00 2001 From: AmbrishRamachandiran Date: Tue, 3 Oct 2023 19:00:52 +0530 Subject: [PATCH 08/37] Updated changeset Signed-off-by: AmbrishRamachandiran --- .changeset/wild-queens-grab.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/wild-queens-grab.md b/.changeset/wild-queens-grab.md index d9aedf3fc5..287dc0482e 100644 --- a/.changeset/wild-queens-grab.md +++ b/.changeset/wild-queens-grab.md @@ -2,4 +2,4 @@ '@backstage/plugin-playlist': patch --- -Updated Playlist Screens +Updated Playlist read me with additional screenshots From 174673e2eaf976982a87d6573650be650edcd8ef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 14:11:57 +0000 Subject: [PATCH 09/37] fix(deps): update dependency libsodium-wrappers to v0.7.13 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index fa31e2f6fc..504be4a8d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -31166,18 +31166,18 @@ __metadata: linkType: hard "libsodium-wrappers@npm:^0.7.11": - version: 0.7.11 - resolution: "libsodium-wrappers@npm:0.7.11" + version: 0.7.13 + resolution: "libsodium-wrappers@npm:0.7.13" dependencies: - libsodium: ^0.7.11 - checksum: 6a6ef47b2213e3fb4687196c28fee4c9885f70d89547d845e62d96014d3d5ad9f59cb05fadc601debc0031a3cfd0b9b416d7efbeb5bf66db6aa0ed69f55a6293 + libsodium: ^0.7.13 + checksum: d184395f7c33023414b191ef9ea2171eb1a5cb061503e886ea877590cb7adc3a4feaf794b9b08731a20515518fa23dbf1c1bfcd376e5ab01728e95cf1cb7525a languageName: node linkType: hard -"libsodium@npm:^0.7.11": - version: 0.7.11 - resolution: "libsodium@npm:0.7.11" - checksum: 0a3493ac1829d1e346178b6984c4eb449dc77157c906876441386c0c653142e3fa56f623ce980bb50e580196578689298c9cd406ce6d514904090e370c6bc0f7 +"libsodium@npm:^0.7.13": + version: 0.7.13 + resolution: "libsodium@npm:0.7.13" + checksum: 75a5f70e84c197d54d9b67dcbd852abbd41cca8facd510767c7c8400a52a23da293e83eebf1693831b2c0c0498f266bd9350a8c27ec66f46a055890dff758d38 languageName: node linkType: hard From 3f2e59867154c7cd69b1d27de984f06171b15f37 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 29 Sep 2023 16:17:59 +0200 Subject: [PATCH 10/37] frontend-app-api: partial support for old routing system Co-authored-by: Camila Belo Co-authored-by: Philipp Hugenroth Signed-off-by: Patrik Oldsberg --- .../extractRouteInfoFromInstanceTree.test.ts | 467 ++++++++++++++++++ .../extractRouteInfoFromInstanceTree.ts | 67 +++ .../frontend-app-api/src/wiring/createApp.tsx | 53 +- 3 files changed, 547 insertions(+), 40 deletions(-) create mode 100644 packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts create mode 100644 packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts new file mode 100644 index 0000000000..24cf450fcd --- /dev/null +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts @@ -0,0 +1,467 @@ +/* + * 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 React from 'react'; +import { RouteRef, createRouteRef } from '@backstage/core-plugin-api'; +import { extractRouteInfoFromInstanceTree } from './extractRouteInfoFromInstanceTree'; +import { + coreExtensionData, + createExtensionInput, + createPageExtension, + createPlugin, +} from '@backstage/frontend-plugin-api'; +import { createInstances } from '../wiring/createApp'; +import { MockConfigApi } from '@backstage/test-utils'; + +const ref1 = createRouteRef({ id: 'page1' }); +const ref2 = createRouteRef({ id: 'page2' }); +const ref3 = createRouteRef({ id: 'page3' }); +const ref4 = createRouteRef({ id: 'page4' }); +const ref5 = createRouteRef({ id: 'page5' }); +const refOrder = [ref1, ref2, ref3, ref4, ref5]; + +function sortedEntries(map: Map): [RouteRef, T][] { + return Array.from(map).sort( + ([a], [b]) => refOrder.indexOf(a) - refOrder.indexOf(b), + ); +} + +// async function routeObj( +// path: string, +// refs: RouteRef[], +// children: any[] = [], +// type: 'mounted' | 'gathered' = 'mounted', +// backstagePlugin?: BackstagePlugin, +// ) { +// return { +// path: path, +// caseSensitive: false, +// element: type, +// routeRefs: new Set(refs), +// children: [ +// { +// path: '*', +// caseSensitive: false, +// element: 'match-all', +// routeRefs: new Set(), +// plugins: new Set(), +// }, +// ...children, +// ], +// plugins: backstagePlugin ? new Set([backstagePlugin]) : new Set(), +// }; +// } + +const emptyLoader = () => Promise.resolve(React.createElement('div')); + +describe('discovery', () => { + it('should collect routes', () => { + const extensions = [ + createPageExtension({ + id: 'nothing', + defaultPath: 'nothing', + loader: emptyLoader, + }), + createPageExtension({ + id: 'page1', + defaultPath: 'foo', + routeRef: ref1, + inputs: { + routes: createExtensionInput({ + element: coreExtensionData.reactElement, + }), + }, + loader: emptyLoader, + }), + createPageExtension({ + id: 'page2', + at: 'page1/routes', + defaultPath: 'bar/:id', + routeRef: ref2, + inputs: { + routes: createExtensionInput({ + element: coreExtensionData.reactElement, + }), + }, + loader: emptyLoader, + }), + createPageExtension({ + id: 'page3', + at: 'page2/routes', + defaultPath: 'baz', + routeRef: ref3, + loader: emptyLoader, + }), + createPageExtension({ + id: 'page4', + defaultPath: 'divsoup', + routeRef: ref4, + loader: emptyLoader, + }), + createPageExtension({ + id: 'page5', + at: 'page1/routes', + defaultPath: 'blop', + routeRef: ref5, + loader: emptyLoader, + }), + ]; + + const { rootInstances } = createInstances({ + config: new MockConfigApi({}), + plugins: [ + createPlugin({ + id: 'test', + extensions, + }), + ], + }); + + const info = extractRouteInfoFromInstanceTree(rootInstances); + + expect(sortedEntries(info.routePaths)).toEqual([ + [ref1, 'foo'], + [ref2, 'bar/:id'], + [ref3, 'baz'], + [ref4, 'divsoup'], + [ref5, 'blop'], + ]); + expect(sortedEntries(info.routeParents)).toEqual([ + [ref1, undefined], + [ref2, ref1], + [ref3, ref2], + [ref4, undefined], + [ref5, ref1], + ]); + // expect(routing.objects).toEqual([ + // routeObj( + // 'foo', + // [ref1], + // [ + // routeObj( + // 'bar/:id', + // [ref2], + // [routeObj('baz', [ref3], undefined, undefined, plugin)], + // undefined, + // plugin, + // ), + // routeObj('blop', [ref5], undefined, undefined, plugin), + // ], + // undefined, + // plugin, + // ), + // routeObj('divsoup', [ref4], undefined, undefined, plugin), + // ]); + }); + + // it('should handle all react router Route patterns', () => { + // const root = ( + // + // + // }> + // + // } /> + // + // + // }> + // } /> + // } /> + // + // + // + // ); + + // const { routing } = traverseElementTree({ + // root, + // discoverers: [childDiscoverer, routeElementDiscoverer], + // collectors: { + // routing: routingV2Collector, + // }, + // }); + // expect(sortedEntries(routing.paths)).toEqual([ + // [ref1, 'foo'], + // [ref2, 'bar/:id'], + // [ref3, 'baz'], + // [ref4, 'divsoup'], + // [ref5, 'blop'], + // ]); + // expect(sortedEntries(routing.parents)).toEqual([ + // [ref1, undefined], + // [ref2, ref1], + // [ref3, undefined], + // [ref4, ref3], + // [ref5, ref3], + // ]); + // }); + + // it('should handle absolute route paths', () => { + // const root = ( + // + // + // }> + // + // } /> + // + // + // }> + // } /> + // } /> + // + // + // + // ); + + // const { routing } = traverseElementTree({ + // root, + // discoverers: [childDiscoverer, routeElementDiscoverer], + // collectors: { + // routing: routingV2Collector, + // }, + // }); + // expect(sortedEntries(routing.paths)).toEqual([ + // [ref1, 'foo'], + // [ref2, 'bar/:id'], + // [ref3, 'baz'], + // [ref4, 'divsoup'], + // [ref5, 'blop'], + // ]); + // expect(sortedEntries(routing.parents)).toEqual([ + // [ref1, undefined], + // [ref2, ref1], + // [ref3, undefined], + // [ref4, ref3], + // [ref5, ref3], + // ]); + // }); + + // it('should use the route aggregator key to bind child routes to the same path', () => { + // const root = ( + // + // + // + // + //
+ // + //
+ // HELLO + //
+ // }> + // + // + // + // + // + // + //
+ //
+ // ); + + // const { routing } = traverseElementTree({ + // root, + // discoverers: [childDiscoverer, routeElementDiscoverer], + // collectors: { + // routing: routingV2Collector, + // }, + // }); + // expect(sortedEntries(routing.paths)).toEqual([ + // [ref1, 'foo'], + // [ref2, 'foo'], + // [ref3, 'bar'], + // [ref4, ''], + // [ref5, ''], + // ]); + // expect(sortedEntries(routing.parents)).toEqual([ + // [ref1, undefined], + // [ref2, undefined], + // [ref3, undefined], + // [ref4, ref3], + // [ref5, ref3], + // ]); + // expect(routing.objects).toEqual([ + // routeObj('foo', [ref1, ref2], [], 'gathered', plugin), + // routeObj( + // 'bar', + // [ref3], + // [routeObj('', [ref4, ref5], [], 'gathered', plugin)], + // undefined, + // plugin, + // ), + // ]); + // }); + + // it('should use the route aggregator but stop when encountering explicit path', () => { + // const root = ( + // + // + // }> + // + // + // + // }> + // } /> + // + // + // + // + // + // + // + // + // ); + + // const { routing } = traverseElementTree({ + // root, + // discoverers: [childDiscoverer, routeElementDiscoverer], + // collectors: { + // routing: routingV2Collector, + // }, + // }); + // expect(sortedEntries(routing.paths)).toEqual([ + // [ref1, 'foo'], + // [ref2, 'bar'], + // [ref3, 'baz'], + // [ref4, 'blop'], + // [ref5, 'bar'], + // ]); + // expect(sortedEntries(routing.parents)).toEqual([ + // [ref1, undefined], + // [ref2, ref1], + // [ref3, ref2], + // [ref4, ref3], + // [ref5, ref1], + // ]); + // expect(routing.objects).toEqual([ + // routeObj( + // 'foo', + // [ref1], + // [ + // routeObj( + // 'bar', + // [ref2, ref5], + // [ + // routeObj( + // 'baz', + // [ref3], + // [routeObj('blop', [ref4], undefined, undefined, plugin)], + // undefined, + // plugin, + // ), + // ], + // 'gathered', + // plugin, + // ), + // ], + // undefined, + // plugin, + // ), + // ]); + // }); + + // it('should throw when you provide path property on an extension', () => { + // expect(() => { + // traverseElementTree({ + // root: , + // discoverers: [childDiscoverer, routeElementDiscoverer], + // collectors: { + // routing: routingV2Collector, + // }, + // }); + // }).toThrow( + // 'Path property may not be set directly on a routable extension "Extension(Extension1)"', + // ); + // }); + + // it('should throw when element prop is not a string', () => { + // const Div = 'div' as unknown as ComponentType<{ path: boolean }>; + // expect(() => { + // traverseElementTree({ + // root:
, + // discoverers: [childDiscoverer, routeElementDiscoverer], + // collectors: { + // routing: routingV2Collector, + // }, + // }); + // }).toThrow('Element path must be a string at "div"'); + // }); + + // it('should throw when the mount point gatherers have an element prop', () => { + // const AnyAggregationComponent = AggregationComponent as any; + // expect(() => { + // traverseElementTree({ + // root: } />, + // discoverers: [childDiscoverer, routeElementDiscoverer], + // collectors: { + // routing: routingV2Collector, + // }, + // }); + // }).toThrow( + // 'Mount point gatherers may not have an element prop "AggregationComponent"', + // ); + // }); + + // it('should ignore path props within route elements', () => { + // const { routing } = traverseElementTree({ + // root: } />, + // discoverers: [childDiscoverer, routeElementDiscoverer], + // collectors: { + // routing: routingV2Collector, + // }, + // }); + // expect(sortedEntries(routing.paths)).toEqual([[ref1, 'foo']]); + // expect(sortedEntries(routing.parents)).toEqual([[ref1, undefined]]); + // expect(routing.objects).toEqual([ + // routeObj('foo', [ref1], [], undefined, plugin), + // ]); + // }); + + // it('should throw when a routable extension does not have a path set', () => { + // expect(() => { + // traverseElementTree({ + // root: , + // discoverers: [childDiscoverer, routeElementDiscoverer], + // collectors: { + // routing: routingV2Collector, + // }, + // }); + // }).toThrow( + // 'Routable extension "Extension(Extension3)" with mount point "routeRef{type=absolute,id=ref3}" must be assigned a path', + // ); + // }); + + // it('should throw when Route elements contain multiple routable extensions', () => { + // expect(() => { + // traverseElementTree({ + // root: ( + // + // + // + // + // } + // /> + // ), + // discoverers: [childDiscoverer, routeElementDiscoverer], + // collectors: { + // routing: routingV2Collector, + // }, + // }); + // }).toThrow( + // 'Route element with path "foo" may not contain multiple routable extensions', + // ); + // }); +}); diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts new file mode 100644 index 0000000000..290f5707e9 --- /dev/null +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts @@ -0,0 +1,67 @@ +/* + * Copyright 2023 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 { RouteRef } from '@backstage/core-plugin-api'; +import { coreExtensionData } from '@backstage/frontend-plugin-api'; +import { ExtensionInstance } from '../wiring/createExtensionInstance'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { BackstageRouteObject } from '../../../core-app-api/src/routing/types'; + +// Joins a list of paths together, avoiding trailing and duplicate slashes +export function joinPaths(...paths: string[]): string { + const normalized = paths.join('/').replace(/\/\/+/g, '/'); + if (normalized !== '/' && normalized.endsWith('/')) { + return normalized.slice(0, -1); + } + return normalized; +} + +export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { + routePaths: Map; + routeParents: Map; + routeObjects: BackstageRouteObject[]; +} { + const routePaths = new Map(); + const routeParents = new Map(); + + function visit(current: ExtensionInstance, parent?: RouteRef) { + const routePath = current.getData(coreExtensionData.routePath) ?? ''; + const routeRef = current.getData(coreExtensionData.routeRef); + + if (routeRef) { + const routeRefId = (routeRef as any).id; // TODO: properly + if (routeRefId !== current.id) { + throw new Error( + `Route ref '${routeRefId}' must have the same ID as extension '${current.id}'`, + ); + } + routePaths.set(routeRef, routePath); + routeParents.set(routeRef, parent); + } + + for (const children of current.attachments.values()) { + for (const child of children) { + visit(child, routeRef ?? parent); + } + } + } + + for (const root of roots) { + visit(root); + } + + return { routePaths, routeParents, routeObjects: [] }; +} diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index deb19d919d..4afd1d1a2f 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -74,6 +74,8 @@ import { defaultConfigLoaderSync } from '../../../core-app-api/src/app/defaultCo // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { overrideBaseUrlConfigs } from '../../../core-app-api/src/app/overrideBaseUrlConfigs'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { RoutingProvider as LegacyRoutingProvider } from '../../../core-app-api/src/routing/RoutingProvider'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports import { apis as defaultApis, components as defaultComponents, @@ -82,6 +84,7 @@ import { import { BrowserRouter, Route } from 'react-router-dom'; import { SidebarItem } from '@backstage/core-components'; import { DarkTheme, LightTheme } from '../extensions/themes'; +import { extractRouteInfoFromInstanceTree } from '../routing/extractRouteInfoFromInstanceTree'; /** @public */ export interface ExtensionTreeNode { @@ -281,7 +284,7 @@ export function createApp(options: { config, }); - const routePaths = extractRouteInfoFromInstanceTree(rootInstances); + const routeInfo = extractRouteInfoFromInstanceTree(rootInstances); const coreInstance = rootInstances.find(({ id }) => id === 'core'); if (!coreInstance) { @@ -304,10 +307,15 @@ export function createApp(options: { - - {/* TODO: set base path using the logic from AppRouter */} - {rootElements} - + + + {/* TODO: set base path using the logic from AppRouter */} + {rootElements} + + @@ -458,38 +466,3 @@ function createApiHolder( return new ApiResolver(factoryRegistry); } - -/** @internal */ -export function extractRouteInfoFromInstanceTree( - roots: ExtensionInstance[], -): Map { - const results = new Map(); - - function visit(current: ExtensionInstance, basePath: string) { - const routePath = current.getData(coreExtensionData.routePath) ?? ''; - const routeRef = current.getData(coreExtensionData.routeRef); - - // TODO: join paths in a more robust way - const fullPath = basePath + routePath; - if (routeRef) { - const routeRefId = (routeRef as any).id; // TODO: properly - if (routeRefId !== current.id) { - throw new Error( - `Route ref '${routeRefId}' must have the same ID as extension '${current.id}'`, - ); - } - results.set(routeRef, fullPath); - } - - for (const children of current.attachments.values()) { - for (const child of children) { - visit(child, fullPath); - } - } - } - - for (const root of roots) { - visit(root, ''); - } - return results; -} From 6fd3af691259dc4fbcdd4b8e53325640a88a028d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 29 Sep 2023 16:53:47 +0200 Subject: [PATCH 11/37] frontend-app-api: add support for collecting route objects Co-authored-by: Camila Belo Co-authored-by: Philipp Hugenroth Signed-off-by: Patrik Oldsberg --- .../extractRouteInfoFromInstanceTree.test.ts | 108 +++++++++--------- .../extractRouteInfoFromInstanceTree.ts | 47 +++++++- .../frontend-app-api/src/wiring/createApp.tsx | 2 +- .../src/wiring/createExtensionInstance.ts | 4 +- 4 files changed, 102 insertions(+), 59 deletions(-) diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts index 24cf450fcd..b556662236 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts @@ -15,7 +15,11 @@ */ import React from 'react'; -import { RouteRef, createRouteRef } from '@backstage/core-plugin-api'; +import { + BackstagePlugin, + RouteRef, + createRouteRef, +} from '@backstage/core-plugin-api'; import { extractRouteInfoFromInstanceTree } from './extractRouteInfoFromInstanceTree'; import { coreExtensionData, @@ -23,7 +27,7 @@ import { createPageExtension, createPlugin, } from '@backstage/frontend-plugin-api'; -import { createInstances } from '../wiring/createApp'; +import { createInstances, toLegacyPlugin } from '../wiring/createApp'; import { MockConfigApi } from '@backstage/test-utils'; const ref1 = createRouteRef({ id: 'page1' }); @@ -39,31 +43,31 @@ function sortedEntries(map: Map): [RouteRef, T][] { ); } -// async function routeObj( -// path: string, -// refs: RouteRef[], -// children: any[] = [], -// type: 'mounted' | 'gathered' = 'mounted', -// backstagePlugin?: BackstagePlugin, -// ) { -// return { -// path: path, -// caseSensitive: false, -// element: type, -// routeRefs: new Set(refs), -// children: [ -// { -// path: '*', -// caseSensitive: false, -// element: 'match-all', -// routeRefs: new Set(), -// plugins: new Set(), -// }, -// ...children, -// ], -// plugins: backstagePlugin ? new Set([backstagePlugin]) : new Set(), -// }; -// } +function routeObj( + path: string, + refs: RouteRef[], + children: any[] = [], + type: 'mounted' | 'gathered' = 'mounted', + backstagePlugin?: BackstagePlugin, +) { + return { + path: path, + caseSensitive: false, + element: type, + routeRefs: new Set(refs), + children: [ + { + path: '*', + caseSensitive: false, + element: 'match-all', + routeRefs: new Set(), + plugins: new Set(), + }, + ...children, + ], + plugins: backstagePlugin ? new Set([backstagePlugin]) : new Set(), + }; +} const emptyLoader = () => Promise.resolve(React.createElement('div')); @@ -120,14 +124,13 @@ describe('discovery', () => { }), ]; + const plugin = createPlugin({ + id: 'test', + extensions, + }); const { rootInstances } = createInstances({ config: new MockConfigApi({}), - plugins: [ - createPlugin({ - id: 'test', - extensions, - }), - ], + plugins: [plugin], }); const info = extractRouteInfoFromInstanceTree(rootInstances); @@ -146,25 +149,26 @@ describe('discovery', () => { [ref4, undefined], [ref5, ref1], ]); - // expect(routing.objects).toEqual([ - // routeObj( - // 'foo', - // [ref1], - // [ - // routeObj( - // 'bar/:id', - // [ref2], - // [routeObj('baz', [ref3], undefined, undefined, plugin)], - // undefined, - // plugin, - // ), - // routeObj('blop', [ref5], undefined, undefined, plugin), - // ], - // undefined, - // plugin, - // ), - // routeObj('divsoup', [ref4], undefined, undefined, plugin), - // ]); + expect(info.routeObjects).toEqual([ + routeObj('nothing', []), + routeObj( + 'foo', + [ref1], + [ + routeObj( + 'bar/:id', + [ref2], + [routeObj('baz', [ref3], undefined, undefined, expect.any(Object))], + undefined, + expect.any(Object), + ), + routeObj('blop', [ref5], undefined, undefined, expect.any(Object)), + ], + undefined, + expect.any(Object), + ), + routeObj('divsoup', [ref4], undefined, undefined, expect.any(Object)), + ]); }); // it('should handle all react router Route patterns', () => { diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts index 290f5707e9..8d3947b970 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts @@ -19,6 +19,19 @@ import { coreExtensionData } from '@backstage/frontend-plugin-api'; import { ExtensionInstance } from '../wiring/createExtensionInstance'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { BackstageRouteObject } from '../../../core-app-api/src/routing/types'; +import { toLegacyPlugin } from '../wiring/createApp'; + +// We always add a child that matches all subroutes but without any route refs. This makes +// sure that we're always able to match each route no matter how deep the navigation goes. +// The route resolver then takes care of selecting the most specific match in order to find +// mount points that are as deep in the routing tree as possible. +export const MATCH_ALL_ROUTE: BackstageRouteObject = { + caseSensitive: false, + path: '*', + element: 'match-all', // These elements aren't used, so we add in a bit of debug information + routeRefs: new Set(), + plugins: new Set(), +}; // Joins a list of paths together, avoiding trailing and duplicate slashes export function joinPaths(...paths: string[]): string { @@ -36,10 +49,30 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { } { const routePaths = new Map(); const routeParents = new Map(); + const routeObjects = new Array(); - function visit(current: ExtensionInstance, parent?: RouteRef) { - const routePath = current.getData(coreExtensionData.routePath) ?? ''; + function visit( + current: ExtensionInstance, + parentRef?: RouteRef, + parentObj?: BackstageRouteObject, + ) { + const routePath = current.getData(coreExtensionData.routePath) ?? ''; // TODO: need to gather routes instead const routeRef = current.getData(coreExtensionData.routeRef); + const parentChildren = parentObj?.children ?? routeObjects; + let currentObj = parentObj; + + if (routePath) { + currentObj = { + path: routePath, + element: 'mounted', + routeRefs: new Set(), + caseSensitive: false, + children: [MATCH_ALL_ROUTE], + plugins: new Set(), + }; + + parentChildren.push(currentObj); + } if (routeRef) { const routeRefId = (routeRef as any).id; // TODO: properly @@ -49,12 +82,16 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { ); } routePaths.set(routeRef, routePath); - routeParents.set(routeRef, parent); + routeParents.set(routeRef, parentRef); + currentObj?.routeRefs.add(routeRef); + if (current.source) { + currentObj?.plugins.add(toLegacyPlugin(current.source)); + } } for (const children of current.attachments.values()) { for (const child of children) { - visit(child, routeRef ?? parent); + visit(child, routeRef ?? parentRef, currentObj); } } } @@ -63,5 +100,5 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { visit(root); } - return { routePaths, routeParents, routeObjects: [] }; + return { routePaths, routeParents, routeObjects }; } diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index 4afd1d1a2f..4f32bc2219 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -336,7 +336,7 @@ export function createApp(options: { }; } -function toLegacyPlugin(plugin: BackstagePlugin): LegacyBackstagePlugin { +export function toLegacyPlugin(plugin: BackstagePlugin): LegacyBackstagePlugin { const errorMsg = 'Not implemented in legacy plugin compatibility layer'; const notImplemented = () => { throw new Error(errorMsg); diff --git a/packages/frontend-app-api/src/wiring/createExtensionInstance.ts b/packages/frontend-app-api/src/wiring/createExtensionInstance.ts index afa3cbfefc..18551eb8da 100644 --- a/packages/frontend-app-api/src/wiring/createExtensionInstance.ts +++ b/packages/frontend-app-api/src/wiring/createExtensionInstance.ts @@ -36,6 +36,8 @@ export interface ExtensionInstance { * Maps input names to the actual instances given to them. */ readonly attachments: Map; + + readonly source?: BackstagePlugin; } function resolveInputData( @@ -141,7 +143,7 @@ export function createExtensionInstance(options: { getData(ref: ExtensionDataRef): T | undefined { return extensionData.get(ref.id) as T | undefined; }, - + source, attachments, }; } From 07c11f7598e31520f1d1cae9a5b57b1e05394434 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 1 Oct 2023 15:49:39 +0200 Subject: [PATCH 12/37] frontend-app-api: slim down route infro extraction test setup Signed-off-by: Patrik Oldsberg --- .../extractRouteInfoFromInstanceTree.test.ts | 66 ++++++++++--------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts index b556662236..1b7f12391c 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts @@ -27,7 +27,7 @@ import { createPageExtension, createPlugin, } from '@backstage/frontend-plugin-api'; -import { createInstances, toLegacyPlugin } from '../wiring/createApp'; +import { createInstances } from '../wiring/createApp'; import { MockConfigApi } from '@backstage/test-utils'; const ref1 = createRouteRef({ id: 'page1' }); @@ -37,6 +37,28 @@ const ref4 = createRouteRef({ id: 'page4' }); const ref5 = createRouteRef({ id: 'page5' }); const refOrder = [ref1, ref2, ref3, ref4, ref5]; +const emptyLoader = () => Promise.resolve(React.createElement('div')); + +function createTestExtension(options: { + id: string; + at?: string; + path: string; + routeRef?: RouteRef; +}) { + return createPageExtension({ + id: options.id, + at: options.at, + defaultPath: options.path, + routeRef: options.routeRef, + inputs: { + routes: createExtensionInput({ + element: coreExtensionData.reactElement, + }), + }, + loader: emptyLoader, + }); +} + function sortedEntries(map: Map): [RouteRef, T][] { return Array.from(map).sort( ([a], [b]) => refOrder.indexOf(a) - refOrder.indexOf(b), @@ -69,58 +91,40 @@ function routeObj( }; } -const emptyLoader = () => Promise.resolve(React.createElement('div')); - describe('discovery', () => { it('should collect routes', () => { const extensions = [ - createPageExtension({ + createTestExtension({ id: 'nothing', - defaultPath: 'nothing', - loader: emptyLoader, + path: 'nothing', }), - createPageExtension({ + createTestExtension({ id: 'page1', - defaultPath: 'foo', + path: 'foo', routeRef: ref1, - inputs: { - routes: createExtensionInput({ - element: coreExtensionData.reactElement, - }), - }, - loader: emptyLoader, }), - createPageExtension({ + createTestExtension({ id: 'page2', at: 'page1/routes', - defaultPath: 'bar/:id', + path: 'bar/:id', routeRef: ref2, - inputs: { - routes: createExtensionInput({ - element: coreExtensionData.reactElement, - }), - }, - loader: emptyLoader, }), - createPageExtension({ + createTestExtension({ id: 'page3', at: 'page2/routes', - defaultPath: 'baz', + path: 'baz', routeRef: ref3, - loader: emptyLoader, }), - createPageExtension({ + createTestExtension({ id: 'page4', - defaultPath: 'divsoup', + path: 'divsoup', routeRef: ref4, - loader: emptyLoader, }), - createPageExtension({ + createTestExtension({ id: 'page5', at: 'page1/routes', - defaultPath: 'blop', + path: 'blop', routeRef: ref5, - loader: emptyLoader, }), ]; From 261e6b31613c043731ab0ae8ad15d23cd9f1a6e8 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 1 Oct 2023 15:53:53 +0200 Subject: [PATCH 13/37] frontend-app-api: abstraction for route info extractino tests + another test Signed-off-by: Patrik Oldsberg --- .../extractRouteInfoFromInstanceTree.test.ts | 113 ++++++++++-------- 1 file changed, 62 insertions(+), 51 deletions(-) diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts index 1b7f12391c..fbc3c95fa8 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts @@ -22,6 +22,7 @@ import { } from '@backstage/core-plugin-api'; import { extractRouteInfoFromInstanceTree } from './extractRouteInfoFromInstanceTree'; import { + Extension, coreExtensionData, createExtensionInput, createPageExtension, @@ -59,6 +60,19 @@ function createTestExtension(options: { }); } +function routeInfoFromExtensions(extensions: Extension[]) { + const plugin = createPlugin({ + id: 'test', + extensions, + }); + const { rootInstances } = createInstances({ + config: new MockConfigApi({}), + plugins: [plugin], + }); + + return extractRouteInfoFromInstanceTree(rootInstances); +} + function sortedEntries(map: Map): [RouteRef, T][] { return Array.from(map).sort( ([a], [b]) => refOrder.indexOf(a) - refOrder.indexOf(b), @@ -93,7 +107,7 @@ function routeObj( describe('discovery', () => { it('should collect routes', () => { - const extensions = [ + const info = routeInfoFromExtensions([ createTestExtension({ id: 'nothing', path: 'nothing', @@ -126,18 +140,7 @@ describe('discovery', () => { path: 'blop', routeRef: ref5, }), - ]; - - const plugin = createPlugin({ - id: 'test', - extensions, - }); - const { rootInstances } = createInstances({ - config: new MockConfigApi({}), - plugins: [plugin], - }); - - const info = extractRouteInfoFromInstanceTree(rootInstances); + ]); expect(sortedEntries(info.routePaths)).toEqual([ [ref1, 'foo'], @@ -175,45 +178,53 @@ describe('discovery', () => { ]); }); - // it('should handle all react router Route patterns', () => { - // const root = ( - // - // - // }> - // - // } /> - // - // - // }> - // } /> - // } /> - // - // - // - // ); + it('should handle all react router Route patterns', () => { + const info = routeInfoFromExtensions([ + createTestExtension({ + id: 'page1', + path: 'foo', + routeRef: ref1, + }), + createTestExtension({ + id: 'page2', + at: 'page1/routes', + path: 'bar/:id', + routeRef: ref2, + }), + createTestExtension({ + id: 'page3', + path: 'baz', + routeRef: ref3, + }), + createTestExtension({ + id: 'page4', + at: 'page3/routes', + path: 'divsoup', + routeRef: ref4, + }), + createTestExtension({ + id: 'page5', + at: 'page3/routes', + path: 'blop', + routeRef: ref5, + }), + ]); - // const { routing } = traverseElementTree({ - // root, - // discoverers: [childDiscoverer, routeElementDiscoverer], - // collectors: { - // routing: routingV2Collector, - // }, - // }); - // expect(sortedEntries(routing.paths)).toEqual([ - // [ref1, 'foo'], - // [ref2, 'bar/:id'], - // [ref3, 'baz'], - // [ref4, 'divsoup'], - // [ref5, 'blop'], - // ]); - // expect(sortedEntries(routing.parents)).toEqual([ - // [ref1, undefined], - // [ref2, ref1], - // [ref3, undefined], - // [ref4, ref3], - // [ref5, ref3], - // ]); - // }); + expect(sortedEntries(info.routePaths)).toEqual([ + [ref1, 'foo'], + [ref2, 'bar/:id'], + [ref3, 'baz'], + [ref4, 'divsoup'], + [ref5, 'blop'], + ]); + expect(sortedEntries(info.routeParents)).toEqual([ + [ref1, undefined], + [ref2, ref1], + [ref3, undefined], + [ref4, ref3], + [ref5, ref3], + ]); + }); // it('should handle absolute route paths', () => { // const root = ( From 4cfc21d6eb28a25242ac6b5be41e533ebd4d7bbe Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 3 Oct 2023 15:46:44 +0200 Subject: [PATCH 14/37] frontend-app-api: improve legacy plugin conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Vincenzo Scamporlino Co-authored-by: Camila Belo Signed-off-by: Patrik Oldsberg --- packages/frontend-app-api/package.json | 1 + .../frontend-app-api/src/wiring/createApp.tsx | 26 +++++++++++++++---- yarn.lock | 1 + 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/packages/frontend-app-api/package.json b/packages/frontend-app-api/package.json index 5fb84070d4..477cf8f736 100644 --- a/packages/frontend-app-api/package.json +++ b/packages/frontend-app-api/package.json @@ -42,6 +42,7 @@ "@backstage/plugin-graphiql": "workspace:^", "@backstage/theme": "workspace:^", "@backstage/types": "workspace:^", + "@backstage/version-bridge": "workspace:^", "@material-ui/core": "^4.12.4", "@material-ui/icons": "^4.11.3", "@types/react": "^16.13.1 || ^17.0.0", diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index 4f32bc2219..540b47849f 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -85,6 +85,7 @@ import { BrowserRouter, Route } from 'react-router-dom'; import { SidebarItem } from '@backstage/core-components'; import { DarkTheme, LightTheme } from '../extensions/themes'; import { extractRouteInfoFromInstanceTree } from '../routing/extractRouteInfoFromInstanceTree'; +import { getOrCreateGlobalSingleton } from '@backstage/version-bridge'; /** @public */ export interface ExtensionTreeNode { @@ -336,25 +337,40 @@ export function createApp(options: { }; } +// Make sure that we only convert each new plugin instance to its legacy equivalent once +const legacyPluginStore = getOrCreateGlobalSingleton( + 'legacy-plugin-compatibility-store', + () => new WeakMap(), +); + export function toLegacyPlugin(plugin: BackstagePlugin): LegacyBackstagePlugin { + let legacy = legacyPluginStore.get(plugin); + if (legacy) { + return legacy; + } + const errorMsg = 'Not implemented in legacy plugin compatibility layer'; const notImplemented = () => { throw new Error(errorMsg); }; - return { + + legacy = { getId(): string { return plugin.id; }, - get routes(): never { - throw new Error(errorMsg); + get routes() { + return {}; }, - get externalRoutes(): never { - throw new Error(errorMsg); + get externalRoutes() { + return {}; }, getApis: notImplemented, getFeatureFlags: notImplemented, provide: notImplemented, }; + + legacyPluginStore.set(plugin, legacy); + return legacy; } function createLegacyAppContext(plugins: BackstagePlugin[]): AppContext { diff --git a/yarn.lock b/yarn.lock index 8f0279aff3..37455d3e56 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4311,6 +4311,7 @@ __metadata: "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" "@backstage/types": "workspace:^" + "@backstage/version-bridge": "workspace:^" "@material-ui/core": ^4.12.4 "@material-ui/icons": ^4.11.3 "@testing-library/jest-dom": ^5.10.1 From 7aad08e56403c6b956d6c90d6f4f498b89a294a1 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 3 Oct 2023 15:47:38 +0200 Subject: [PATCH 15/37] frontend-app-api: further routing info extraction improvements + test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Camila Belo Co-authored-by: Vincenzo Scamporlino Signed-off-by: Patrik Oldsberg --- .../extractRouteInfoFromInstanceTree.test.ts | 217 ++++++++++-------- .../extractRouteInfoFromInstanceTree.ts | 32 ++- 2 files changed, 152 insertions(+), 97 deletions(-) diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts index fbc3c95fa8..b4e2675d51 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts @@ -24,8 +24,8 @@ import { extractRouteInfoFromInstanceTree } from './extractRouteInfoFromInstance import { Extension, coreExtensionData, + createExtension, createExtensionInput, - createPageExtension, createPlugin, } from '@backstage/frontend-plugin-api'; import { createInstances } from '../wiring/createApp'; @@ -38,25 +38,32 @@ const ref4 = createRouteRef({ id: 'page4' }); const ref5 = createRouteRef({ id: 'page5' }); const refOrder = [ref1, ref2, ref3, ref4, ref5]; -const emptyLoader = () => Promise.resolve(React.createElement('div')); - function createTestExtension(options: { id: string; at?: string; - path: string; + path?: string; routeRef?: RouteRef; }) { - return createPageExtension({ + return createExtension({ id: options.id, - at: options.at, - defaultPath: options.path, - routeRef: options.routeRef, + at: options.at ?? 'core.routes/children', + output: { + element: coreExtensionData.reactElement, + path: coreExtensionData.routePath.optional(), + routeRef: coreExtensionData.routeRef.optional(), + }, inputs: { - routes: createExtensionInput({ + children: createExtensionInput({ element: coreExtensionData.reactElement, }), }, - loader: emptyLoader, + factory({ bind }) { + bind({ + path: options.path, + routeRef: options.routeRef, + element: React.createElement('div'), + }); + }, }); } @@ -119,13 +126,13 @@ describe('discovery', () => { }), createTestExtension({ id: 'page2', - at: 'page1/routes', + at: 'page1/children', path: 'bar/:id', routeRef: ref2, }), createTestExtension({ id: 'page3', - at: 'page2/routes', + at: 'page2/children', path: 'baz', routeRef: ref3, }), @@ -136,7 +143,7 @@ describe('discovery', () => { }), createTestExtension({ id: 'page5', - at: 'page1/routes', + at: 'page1/children', path: 'blop', routeRef: ref5, }), @@ -187,7 +194,7 @@ describe('discovery', () => { }), createTestExtension({ id: 'page2', - at: 'page1/routes', + at: 'page1/children', path: 'bar/:id', routeRef: ref2, }), @@ -198,13 +205,13 @@ describe('discovery', () => { }), createTestExtension({ id: 'page4', - at: 'page3/routes', + at: 'page3/children', path: 'divsoup', routeRef: ref4, }), createTestExtension({ id: 'page5', - at: 'page3/routes', + at: 'page3/children', path: 'blop', routeRef: ref5, }), @@ -227,37 +234,45 @@ describe('discovery', () => { }); // it('should handle absolute route paths', () => { - // const root = ( - // - // - // }> - // - // } /> - // - // - // }> - // } /> - // } /> - // - // - // - // ); + // const info = routeInfoFromExtensions([ + // createTestExtension({ + // id: 'page1', + // path: '/foo', + // routeRef: ref1, + // }), + // createTestExtension({ + // id: 'page2', + // at: 'page1/children', + // path: '/bar/:id', + // routeRef: ref2, + // }), + // createTestExtension({ + // id: 'page3', + // path: '/baz', + // routeRef: ref3, + // }), + // createTestExtension({ + // id: 'page4', + // at: 'page3/children', + // path: '/divsoup', + // routeRef: ref4, + // }), + // createTestExtension({ + // id: 'page5', + // at: 'page3/children', + // path: '/blop', + // routeRef: ref5, + // }), + // ]); - // const { routing } = traverseElementTree({ - // root, - // discoverers: [childDiscoverer, routeElementDiscoverer], - // collectors: { - // routing: routingV2Collector, - // }, - // }); - // expect(sortedEntries(routing.paths)).toEqual([ + // expect(sortedEntries(info.routePaths)).toEqual([ // [ref1, 'foo'], // [ref2, 'bar/:id'], // [ref3, 'baz'], // [ref4, 'divsoup'], // [ref5, 'blop'], // ]); - // expect(sortedEntries(routing.parents)).toEqual([ + // expect(sortedEntries(info.routeParents)).toEqual([ // [ref1, undefined], // [ref2, ref1], // [ref3, undefined], @@ -266,60 +281,76 @@ describe('discovery', () => { // ]); // }); - // it('should use the route aggregator key to bind child routes to the same path', () => { - // const root = ( - // - // - // - // - //
- // - //
- // HELLO - //
- // }> - // - // - // - // - // - // - //
- //
- // ); + it('should use the route aggregator key to bind child routes to the same path', () => { + const info = routeInfoFromExtensions([ + createTestExtension({ + id: 'foo', + path: 'foo', + }), + createTestExtension({ + id: 'page1', + at: 'foo/children', + routeRef: ref1, + }), + createTestExtension({ + id: 'fooChild', + at: 'foo/children', + }), + createTestExtension({ + id: 'page2', + at: 'fooChild/children', + routeRef: ref2, + }), + createTestExtension({ + id: 'fooEmpty', + }), + createTestExtension({ + id: 'page3', + path: 'bar', + routeRef: ref3, + }), + createTestExtension({ + id: 'page3Child', + at: 'page3/children', + path: '', + }), + createTestExtension({ + id: 'page4', + at: 'page3Child/children', + routeRef: ref4, + }), + createTestExtension({ + id: 'page5', + at: 'page4/children', + routeRef: ref5, + }), + ]); - // const { routing } = traverseElementTree({ - // root, - // discoverers: [childDiscoverer, routeElementDiscoverer], - // collectors: { - // routing: routingV2Collector, - // }, - // }); - // expect(sortedEntries(routing.paths)).toEqual([ - // [ref1, 'foo'], - // [ref2, 'foo'], - // [ref3, 'bar'], - // [ref4, ''], - // [ref5, ''], - // ]); - // expect(sortedEntries(routing.parents)).toEqual([ - // [ref1, undefined], - // [ref2, undefined], - // [ref3, undefined], - // [ref4, ref3], - // [ref5, ref3], - // ]); - // expect(routing.objects).toEqual([ - // routeObj('foo', [ref1, ref2], [], 'gathered', plugin), - // routeObj( - // 'bar', - // [ref3], - // [routeObj('', [ref4, ref5], [], 'gathered', plugin)], - // undefined, - // plugin, - // ), - // ]); - // }); + expect(sortedEntries(info.routePaths)).toEqual([ + [ref1, 'foo'], + [ref2, 'foo'], + [ref3, 'bar'], + [ref4, ''], + [ref5, ''], + ]); + expect(sortedEntries(info.routeParents)).toEqual([ + [ref1, undefined], + [ref2, undefined], + [ref3, undefined], + [ref4, ref3], + [ref5, ref4], + ]); + expect(info.routeObjects).toEqual([ + routeObj('foo', [ref1, ref2], [], 'mounted', expect.any(Object)), + routeObj( + 'bar', + [ref3], + [routeObj('', [ref4, ref5], [], 'mounted', expect.any(Object))], + 'mounted', + expect.any(Object), + ), + ]); + }); // it('should use the route aggregator but stop when encountering explicit path', () => { // const root = ( diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts index 8d3947b970..2d6af97198 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts @@ -53,15 +53,19 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { function visit( current: ExtensionInstance, + collectedPath?: string, + foundRefForCollectedPath: boolean = false, parentRef?: RouteRef, parentObj?: BackstageRouteObject, ) { - const routePath = current.getData(coreExtensionData.routePath) ?? ''; // TODO: need to gather routes instead + const routePath = current.getData(coreExtensionData.routePath); const routeRef = current.getData(coreExtensionData.routeRef); const parentChildren = parentObj?.children ?? routeObjects; let currentObj = parentObj; + let newCollectedPath = collectedPath; + let newFoundRefForCollectedPath = foundRefForCollectedPath; - if (routePath) { + if (routePath !== undefined) { currentObj = { path: routePath, element: 'mounted', @@ -72,6 +76,15 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { }; parentChildren.push(currentObj); + + if (newFoundRefForCollectedPath) { + newCollectedPath = routePath; + newFoundRefForCollectedPath = false; + } else { + newCollectedPath = collectedPath + ? joinPaths(collectedPath, routePath) + : routePath; + } } if (routeRef) { @@ -81,7 +94,12 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { `Route ref '${routeRefId}' must have the same ID as extension '${current.id}'`, ); } - routePaths.set(routeRef, routePath); + + if (newCollectedPath !== undefined) { + routePaths.set(routeRef, newCollectedPath); + newFoundRefForCollectedPath = true; + } + routeParents.set(routeRef, parentRef); currentObj?.routeRefs.add(routeRef); if (current.source) { @@ -91,7 +109,13 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { for (const children of current.attachments.values()) { for (const child of children) { - visit(child, routeRef ?? parentRef, currentObj); + visit( + child, + newCollectedPath, + newFoundRefForCollectedPath, + routeRef ?? parentRef, + currentObj, + ); } } } From e92ad1c067372e0737a8960a2a53ecb23288e09a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 3 Oct 2023 17:39:45 +0200 Subject: [PATCH 16/37] frontend-app-api: finish route info collection implementation and tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Vincenzo Scamporlino Co-authored-by: Camila Belo Signed-off-by: Patrik Oldsberg --- .../extractRouteInfoFromInstanceTree.test.ts | 423 +++++++++--------- .../extractRouteInfoFromInstanceTree.ts | 19 +- 2 files changed, 233 insertions(+), 209 deletions(-) diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts index b4e2675d51..c64dc7a3b9 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.test.ts @@ -233,53 +233,53 @@ describe('discovery', () => { ]); }); - // it('should handle absolute route paths', () => { - // const info = routeInfoFromExtensions([ - // createTestExtension({ - // id: 'page1', - // path: '/foo', - // routeRef: ref1, - // }), - // createTestExtension({ - // id: 'page2', - // at: 'page1/children', - // path: '/bar/:id', - // routeRef: ref2, - // }), - // createTestExtension({ - // id: 'page3', - // path: '/baz', - // routeRef: ref3, - // }), - // createTestExtension({ - // id: 'page4', - // at: 'page3/children', - // path: '/divsoup', - // routeRef: ref4, - // }), - // createTestExtension({ - // id: 'page5', - // at: 'page3/children', - // path: '/blop', - // routeRef: ref5, - // }), - // ]); + it('should strip leading slashes in route paths', () => { + const info = routeInfoFromExtensions([ + createTestExtension({ + id: 'page1', + path: '/foo', + routeRef: ref1, + }), + createTestExtension({ + id: 'page2', + at: 'page1/children', + path: '/bar/:id', + routeRef: ref2, + }), + createTestExtension({ + id: 'page3', + path: '/baz', + routeRef: ref3, + }), + createTestExtension({ + id: 'page4', + at: 'page3/children', + path: '/divsoup', + routeRef: ref4, + }), + createTestExtension({ + id: 'page5', + at: 'page3/children', + path: '/blop', + routeRef: ref5, + }), + ]); - // expect(sortedEntries(info.routePaths)).toEqual([ - // [ref1, 'foo'], - // [ref2, 'bar/:id'], - // [ref3, 'baz'], - // [ref4, 'divsoup'], - // [ref5, 'blop'], - // ]); - // expect(sortedEntries(info.routeParents)).toEqual([ - // [ref1, undefined], - // [ref2, ref1], - // [ref3, undefined], - // [ref4, ref3], - // [ref5, ref3], - // ]); - // }); + expect(sortedEntries(info.routePaths)).toEqual([ + [ref1, 'foo'], + [ref2, 'bar/:id'], + [ref3, 'baz'], + [ref4, 'divsoup'], + [ref5, 'blop'], + ]); + expect(sortedEntries(info.routeParents)).toEqual([ + [ref1, undefined], + [ref2, ref1], + [ref3, undefined], + [ref4, ref3], + [ref5, ref3], + ]); + }); it('should use the route aggregator key to bind child routes to the same path', () => { const info = routeInfoFromExtensions([ @@ -338,7 +338,7 @@ describe('discovery', () => { [ref2, undefined], [ref3, undefined], [ref4, ref3], - [ref5, ref4], + [ref5, ref3], ]); expect(info.routeObjects).toEqual([ routeObj('foo', [ref1, ref2], [], 'mounted', expect.any(Object)), @@ -352,166 +352,177 @@ describe('discovery', () => { ]); }); - // it('should use the route aggregator but stop when encountering explicit path', () => { - // const root = ( - // - // - // }> - // - // - // - // }> - // } /> - // - // - // - // - // - // - // - // - // ); + it('should use the route aggregator but stop when encountering explicit path', () => { + const info = routeInfoFromExtensions([ + createTestExtension({ + id: 'page1', + path: 'foo', + routeRef: ref1, + }), + createTestExtension({ + id: 'page1Child', + at: 'page1/children', + path: 'bar', + }), + createTestExtension({ + id: 'page2', + at: 'page1Child/children', + routeRef: ref2, + }), + createTestExtension({ + id: 'page3', + at: 'page2/children', + path: 'baz', + routeRef: ref3, + }), + createTestExtension({ + id: 'page4', + at: 'page3/children', + path: '/blop', + routeRef: ref4, + }), + createTestExtension({ + id: 'page5', + at: 'page2/children', + routeRef: ref5, + }), + ]); - // const { routing } = traverseElementTree({ - // root, - // discoverers: [childDiscoverer, routeElementDiscoverer], - // collectors: { - // routing: routingV2Collector, - // }, - // }); - // expect(sortedEntries(routing.paths)).toEqual([ - // [ref1, 'foo'], - // [ref2, 'bar'], - // [ref3, 'baz'], - // [ref4, 'blop'], - // [ref5, 'bar'], - // ]); - // expect(sortedEntries(routing.parents)).toEqual([ - // [ref1, undefined], - // [ref2, ref1], - // [ref3, ref2], - // [ref4, ref3], - // [ref5, ref1], - // ]); - // expect(routing.objects).toEqual([ - // routeObj( - // 'foo', - // [ref1], - // [ - // routeObj( - // 'bar', - // [ref2, ref5], - // [ - // routeObj( - // 'baz', - // [ref3], - // [routeObj('blop', [ref4], undefined, undefined, plugin)], - // undefined, - // plugin, - // ), - // ], - // 'gathered', - // plugin, - // ), - // ], - // undefined, - // plugin, - // ), - // ]); - // }); + expect(sortedEntries(info.routePaths)).toEqual([ + [ref1, 'foo'], + [ref2, 'bar'], + [ref3, 'baz'], + [ref4, 'blop'], + [ref5, 'bar'], + ]); + expect(sortedEntries(info.routeParents)).toEqual([ + [ref1, undefined], + [ref2, ref1], + [ref3, ref2], + [ref4, ref3], + [ref5, ref1], + ]); + expect(info.routeObjects).toEqual([ + routeObj( + 'foo', + [ref1], + [ + routeObj( + 'bar', + [ref2, ref5], + [ + routeObj( + 'baz', + [ref3], + [ + routeObj( + 'blop', + [ref4], + undefined, + undefined, + expect.any(Object), + ), + ], + undefined, + expect.any(Object), + ), + ], + 'mounted', + expect.any(Object), + ), + ], + undefined, + expect.any(Object), + ), + ]); + }); - // it('should throw when you provide path property on an extension', () => { - // expect(() => { - // traverseElementTree({ - // root: , - // discoverers: [childDiscoverer, routeElementDiscoverer], - // collectors: { - // routing: routingV2Collector, - // }, - // }); - // }).toThrow( - // 'Path property may not be set directly on a routable extension "Extension(Extension1)"', - // ); - // }); + it('should account for loose route paths', () => { + const info = routeInfoFromExtensions([ + createTestExtension({ + id: 'r', + path: 'r', + }), + createTestExtension({ + id: 'page1', + at: 'r/children', + path: 'x', + routeRef: ref1, + }), + createTestExtension({ + id: 'y', + path: 'y', + at: 'r/children', + }), + createTestExtension({ + id: 'page2', + at: 'y/children', + path: '1', + routeRef: ref2, + }), + createTestExtension({ + id: 'page3', + at: 'page2/children', + path: 'a', + routeRef: ref3, + }), + createTestExtension({ + id: 'page4', + at: 'page2/children', + path: 'b', + routeRef: ref4, + }), + ]); - // it('should throw when element prop is not a string', () => { - // const Div = 'div' as unknown as ComponentType<{ path: boolean }>; - // expect(() => { - // traverseElementTree({ - // root:
, - // discoverers: [childDiscoverer, routeElementDiscoverer], - // collectors: { - // routing: routingV2Collector, - // }, - // }); - // }).toThrow('Element path must be a string at "div"'); - // }); - - // it('should throw when the mount point gatherers have an element prop', () => { - // const AnyAggregationComponent = AggregationComponent as any; - // expect(() => { - // traverseElementTree({ - // root: } />, - // discoverers: [childDiscoverer, routeElementDiscoverer], - // collectors: { - // routing: routingV2Collector, - // }, - // }); - // }).toThrow( - // 'Mount point gatherers may not have an element prop "AggregationComponent"', - // ); - // }); - - // it('should ignore path props within route elements', () => { - // const { routing } = traverseElementTree({ - // root: } />, - // discoverers: [childDiscoverer, routeElementDiscoverer], - // collectors: { - // routing: routingV2Collector, - // }, - // }); - // expect(sortedEntries(routing.paths)).toEqual([[ref1, 'foo']]); - // expect(sortedEntries(routing.parents)).toEqual([[ref1, undefined]]); - // expect(routing.objects).toEqual([ - // routeObj('foo', [ref1], [], undefined, plugin), - // ]); - // }); - - // it('should throw when a routable extension does not have a path set', () => { - // expect(() => { - // traverseElementTree({ - // root: , - // discoverers: [childDiscoverer, routeElementDiscoverer], - // collectors: { - // routing: routingV2Collector, - // }, - // }); - // }).toThrow( - // 'Routable extension "Extension(Extension3)" with mount point "routeRef{type=absolute,id=ref3}" must be assigned a path', - // ); - // }); - - // it('should throw when Route elements contain multiple routable extensions', () => { - // expect(() => { - // traverseElementTree({ - // root: ( - // - // - // - // - // } - // /> - // ), - // discoverers: [childDiscoverer, routeElementDiscoverer], - // collectors: { - // routing: routingV2Collector, - // }, - // }); - // }).toThrow( - // 'Route element with path "foo" may not contain multiple routable extensions', - // ); - // }); + expect(sortedEntries(info.routePaths)).toEqual([ + [ref1, 'r/x'], + [ref2, 'r/y/1'], + [ref3, 'a'], + [ref4, 'b'], + ]); + expect(sortedEntries(info.routeParents)).toEqual([ + [ref1, undefined], + [ref2, undefined], + [ref3, ref2], + [ref4, ref2], + ]); + expect(info.routeObjects).toEqual([ + routeObj( + 'r', + [], + [ + routeObj('x', [ref1], [], 'mounted', expect.any(Object)), + routeObj( + 'y', + [], + [ + routeObj( + '1', + [ref2], + [ + routeObj( + 'a', + [ref3], + undefined, + 'mounted', + expect.any(Object), + ), + routeObj( + 'b', + [ref4], + undefined, + 'mounted', + expect.any(Object), + ), + ], + 'mounted', + expect.any(Object), + ), + ], + 'mounted', + ), + ], + ), + ]); + }); }); diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts index 2d6af97198..a7df7978cc 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts @@ -56,14 +56,19 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { collectedPath?: string, foundRefForCollectedPath: boolean = false, parentRef?: RouteRef, + candidateParentRef?: RouteRef, parentObj?: BackstageRouteObject, ) { - const routePath = current.getData(coreExtensionData.routePath); + const routePath = current + .getData(coreExtensionData.routePath) + ?.replace(/^\//, ''); const routeRef = current.getData(coreExtensionData.routeRef); const parentChildren = parentObj?.children ?? routeObjects; let currentObj = parentObj; let newCollectedPath = collectedPath; let newFoundRefForCollectedPath = foundRefForCollectedPath; + let newParentRef = parentRef; + let newCandidateParentRef = candidateParentRef; if (routePath !== undefined) { currentObj = { @@ -85,6 +90,9 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { ? joinPaths(collectedPath, routePath) : routePath; } + + newParentRef = candidateParentRef; + newCandidateParentRef = undefined; } if (routeRef) { @@ -95,12 +103,16 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { ); } + if (!newCandidateParentRef) { + newCandidateParentRef = routeRef; + } + if (newCollectedPath !== undefined) { routePaths.set(routeRef, newCollectedPath); newFoundRefForCollectedPath = true; } - routeParents.set(routeRef, parentRef); + routeParents.set(routeRef, newParentRef); currentObj?.routeRefs.add(routeRef); if (current.source) { currentObj?.plugins.add(toLegacyPlugin(current.source)); @@ -113,7 +125,8 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { child, newCollectedPath, newFoundRefForCollectedPath, - routeRef ?? parentRef, + newParentRef, + newCandidateParentRef, currentObj, ); } From 5948344f0fd7461555c7e2c8fb6ac1a0ce75ffa0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 15:45:45 +0000 Subject: [PATCH 17/37] fix(deps): update dependency axios to v1.5.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 77598be80f..fddc6a5540 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20253,13 +20253,13 @@ __metadata: linkType: hard "axios@npm:^1.4.0": - version: 1.5.0 - resolution: "axios@npm:1.5.0" + version: 1.5.1 + resolution: "axios@npm:1.5.1" dependencies: follow-redirects: ^1.15.0 form-data: ^4.0.0 proxy-from-env: ^1.1.0 - checksum: e7405a5dbbea97760d0e6cd58fecba311b0401ddb4a8efbc4108f5537da9b3f278bde566deb777935a960beec4fa18e7b8353881f2f465e4f2c0e949fead35be + checksum: 4444f06601f4ede154183767863d2b8e472b4a6bfc5253597ed6d21899887e1fd0ee2b3de792ac4f8459fe2e359d2aa07c216e45fd8b9e4e0688a6ebf48a5a8d languageName: node linkType: hard From 783a6b70e671207c2d6e1bf137209bdd443f6cf6 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 3 Oct 2023 17:58:07 +0200 Subject: [PATCH 18/37] frontend-app-api: explain the route info extraction a bit Signed-off-by: Patrik Oldsberg --- .../extractRouteInfoFromInstanceTree.ts | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts index a7df7978cc..30305b0d2c 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromInstanceTree.ts @@ -47,8 +47,13 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { routeParents: Map; routeObjects: BackstageRouteObject[]; } { + // This tracks the route path for each route ref, the value is the route path relative to the parent ref const routePaths = new Map(); + // This tracks the parents of each route ref. To find the full path of any route ref you traverse + // upwards in this tree and substitute each route ref for its route path along then way. const routeParents = new Map(); + // This route object tree is passed to react-router in order to be able to look up the current route + // ref or extension/source based on our current location. const routeObjects = new Array(); function visit( @@ -65,11 +70,14 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { const routeRef = current.getData(coreExtensionData.routeRef); const parentChildren = parentObj?.children ?? routeObjects; let currentObj = parentObj; + let newCollectedPath = collectedPath; let newFoundRefForCollectedPath = foundRefForCollectedPath; + let newParentRef = parentRef; let newCandidateParentRef = candidateParentRef; + // Whenever a route path is encountered, a new node is created in the routing tree. if (routePath !== undefined) { currentObj = { path: routePath, @@ -79,9 +87,16 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { children: [MATCH_ALL_ROUTE], plugins: new Set(), }; - parentChildren.push(currentObj); + // Each route path that we discover creates a new node in the routing tree, at that point + // we also switch out our candidate parent ref to be the active one. + newParentRef = candidateParentRef; + newCandidateParentRef = undefined; + + // We need to collect and concatenate route paths until the path has been assigned a route ref: + // Once we find a route ref the collection starts over from an empty path, that way each route + // path assignment only contains the diff from the parent ref. if (newFoundRefForCollectedPath) { newCollectedPath = routePath; newFoundRefForCollectedPath = false; @@ -90,11 +105,9 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { ? joinPaths(collectedPath, routePath) : routePath; } - - newParentRef = candidateParentRef; - newCandidateParentRef = undefined; } + // Whenever a route ref is encountered, we need to give it a route path and position in the ref tree. if (routeRef) { const routeRefId = (routeRef as any).id; // TODO: properly if (routeRefId !== current.id) { @@ -103,10 +116,15 @@ export function extractRouteInfoFromInstanceTree(roots: ExtensionInstance[]): { ); } + // The first route ref we find after encountering a route path is selected to be used as the + // parent ref further down the tree. We don't start using this candidate ref until we encounter + // another route path though, at which point we repeat the process and select another candidate. if (!newCandidateParentRef) { newCandidateParentRef = routeRef; } + // Check if we've encountered any route paths since the closest route ref, in that case we assign + // that path to this and following route refs until we encounter another route path. if (newCollectedPath !== undefined) { routePaths.set(routeRef, newCollectedPath); newFoundRefForCollectedPath = true; From 1718ec75b78988c067f4c991d6b47752e0356b75 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 3 Oct 2023 17:58:46 +0200 Subject: [PATCH 19/37] changesets: add changeset for routing system support in frontend-app-api Signed-off-by: Patrik Oldsberg --- .changeset/unlucky-experts-breathe.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/unlucky-experts-breathe.md diff --git a/.changeset/unlucky-experts-breathe.md b/.changeset/unlucky-experts-breathe.md new file mode 100644 index 0000000000..018b1826d2 --- /dev/null +++ b/.changeset/unlucky-experts-breathe.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-app-api': patch +--- + +Added support for the existing routing system. From 1578c156740cf2248d6e9bd86c9f3e3ef9327d8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 23:31:34 +0000 Subject: [PATCH 20/37] chore(deps): bump postcss from 8.4.23 to 8.4.31 in /microsite Bumps [postcss](https://github.com/postcss/postcss) from 8.4.23 to 8.4.31. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.4.23...8.4.31) --- updated-dependencies: - dependency-name: postcss dependency-type: indirect ... Signed-off-by: dependabot[bot] --- microsite/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 27b077b8da..6b97dbd352 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -9421,13 +9421,13 @@ __metadata: linkType: hard "postcss@npm:^8.4.17, postcss@npm:^8.4.19, postcss@npm:^8.4.21": - version: 8.4.23 - resolution: "postcss@npm:8.4.23" + version: 8.4.31 + resolution: "postcss@npm:8.4.31" dependencies: nanoid: ^3.3.6 picocolors: ^1.0.0 source-map-js: ^1.0.2 - checksum: 8bb9d1b2ea6e694f8987d4f18c94617971b2b8d141602725fedcc2222fdc413b776a6e1b969a25d627d7b2681ca5aabb56f59e727ef94072e1b6ac8412105a2f + checksum: 1d8611341b073143ad90486fcdfeab49edd243377b1f51834dc4f6d028e82ce5190e4f11bb2633276864503654fb7cab28e67abdc0fbf9d1f88cad4a0ff0beea languageName: node linkType: hard From 4d660049f57e255788187c13e094e01d4fdc36b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 23:36:16 +0000 Subject: [PATCH 21/37] chore(deps): bump postcss from 8.4.29 to 8.4.31 Bumps [postcss](https://github.com/postcss/postcss) from 8.4.29 to 8.4.31. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.4.29...8.4.31) --- updated-dependencies: - dependency-name: postcss dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 77598be80f..34355626df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35781,13 +35781,13 @@ __metadata: linkType: hard "postcss@npm:^8.1.0, postcss@npm:^8.4.21": - version: 8.4.29 - resolution: "postcss@npm:8.4.29" + version: 8.4.31 + resolution: "postcss@npm:8.4.31" dependencies: nanoid: ^3.3.6 picocolors: ^1.0.0 source-map-js: ^1.0.2 - checksum: dd6daa25e781db9ae5b651d9b7bfde0ec6e60e86a37da69a18eb4773d5ddd51e28fc4ff054fbdc04636a31462e6bf09a1e50986f69ac52b10d46b7457cd36d12 + checksum: 1d8611341b073143ad90486fcdfeab49edd243377b1f51834dc4f6d028e82ce5190e4f11bb2633276864503654fb7cab28e67abdc0fbf9d1f88cad4a0ff0beea languageName: node linkType: hard From 6c0e35d536d98661c45a9a6a5f59bd7b0453e4df Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 23:43:09 +0000 Subject: [PATCH 22/37] fix(deps): update dependency postcss to v8.4.31 [security] Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 77598be80f..34355626df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35781,13 +35781,13 @@ __metadata: linkType: hard "postcss@npm:^8.1.0, postcss@npm:^8.4.21": - version: 8.4.29 - resolution: "postcss@npm:8.4.29" + version: 8.4.31 + resolution: "postcss@npm:8.4.31" dependencies: nanoid: ^3.3.6 picocolors: ^1.0.0 source-map-js: ^1.0.2 - checksum: dd6daa25e781db9ae5b651d9b7bfde0ec6e60e86a37da69a18eb4773d5ddd51e28fc4ff054fbdc04636a31462e6bf09a1e50986f69ac52b10d46b7457cd36d12 + checksum: 1d8611341b073143ad90486fcdfeab49edd243377b1f51834dc4f6d028e82ce5190e4f11bb2633276864503654fb7cab28e67abdc0fbf9d1f88cad4a0ff0beea languageName: node linkType: hard From 5ad53447565fd74c31a3e5643ee2613f4e144a9f Mon Sep 17 00:00:00 2001 From: Thomas Cooper <57812123+coopernetes@users.noreply.github.com> Date: Mon, 2 Oct 2023 15:38:30 -0400 Subject: [PATCH 23/37] feat: support strings for fontSize in Typography Signed-off-by: Thomas Cooper <57812123+coopernetes@users.noreply.github.com> --- .changeset/smooth-rings-mate.md | 5 +++ packages/theme/api-report.md | 55 ++++++++++++++++++++++++++++---- packages/theme/src/base/types.ts | 18 +++++++---- 3 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 .changeset/smooth-rings-mate.md diff --git a/.changeset/smooth-rings-mate.md b/.changeset/smooth-rings-mate.md new file mode 100644 index 0000000000..4b9a53f71b --- /dev/null +++ b/.changeset/smooth-rings-mate.md @@ -0,0 +1,5 @@ +--- +'@backstage/theme': patch +--- + +Fixed a bug to support string fontSize values (`"2.5rem"`) instead of forcing numeric-only values & requiring casts. In addition, added an optional fontFamily prop for h1-h6 BackstageTypography variants to allow further customization. diff --git a/packages/theme/api-report.md b/packages/theme/api-report.md index d6380ee6e8..bf226d4d9e 100644 --- a/packages/theme/api-report.md +++ b/packages/theme/api-report.md @@ -117,32 +117,38 @@ export type BackstageTypography = { htmlFontSize: number; fontFamily: string; h1: { - fontSize: number; + fontFamily?: string; + fontSize: number | string; fontWeight: number; marginBottom: number; }; h2: { - fontSize: number; + fontFamily?: string; + fontSize: number | string; fontWeight: number; marginBottom: number; }; h3: { - fontSize: number; + fontFamily?: string; + fontSize: number | string; fontWeight: number; marginBottom: number; }; h4: { - fontSize: number; + fontFamily?: string; + fontSize: number | string; fontWeight: number; marginBottom: number; }; h5: { - fontSize: number; + fontFamily?: string; + fontSize: number | string; fontWeight: number; marginBottom: number; }; h6: { - fontSize: number; + fontFamily?: string; + fontSize: number | string; fontWeight: number; marginBottom: number; }; @@ -172,7 +178,42 @@ export function createBaseThemeOptions( options: BaseThemeOptionsInput, ): { palette: PaletteOptions; - typography: BackstageTypography; + typography: + | BackstageTypography + | { + htmlFontSize: number; + fontFamily: string; + h1: { + fontSize: number; + fontWeight: number; + marginBottom: number; + }; + h2: { + fontSize: number; + fontWeight: number; + marginBottom: number; + }; + h3: { + fontSize: number; + fontWeight: number; + marginBottom: number; + }; + h4: { + fontWeight: number; + fontSize: number; + marginBottom: number; + }; + h5: { + fontWeight: number; + fontSize: number; + marginBottom: number; + }; + h6: { + fontWeight: number; + fontSize: number; + marginBottom: number; + }; + }; page: PageTheme; getPageTheme: ({ themeId }: PageThemeSelector) => PageTheme; }; diff --git a/packages/theme/src/base/types.ts b/packages/theme/src/base/types.ts index 3e34a0abb7..d62d944741 100644 --- a/packages/theme/src/base/types.ts +++ b/packages/theme/src/base/types.ts @@ -124,32 +124,38 @@ export type BackstageTypography = { htmlFontSize: number; fontFamily: string; h1: { - fontSize: number; + fontFamily?: string; + fontSize: number | string; fontWeight: number; marginBottom: number; }; h2: { - fontSize: number; + fontFamily?: string; + fontSize: number | string; fontWeight: number; marginBottom: number; }; h3: { - fontSize: number; + fontFamily?: string; + fontSize: number | string; fontWeight: number; marginBottom: number; }; h4: { - fontSize: number; + fontFamily?: string; + fontSize: number | string; fontWeight: number; marginBottom: number; }; h5: { - fontSize: number; + fontFamily?: string; + fontSize: number | string; fontWeight: number; marginBottom: number; }; h6: { - fontSize: number; + fontFamily?: string; + fontSize: number | string; fontWeight: number; marginBottom: number; }; From 0d91666ae6dc83a5df79b333d28767a821023824 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Oct 2023 08:57:12 +0000 Subject: [PATCH 24/37] chore(deps): update dependency @types/supertest to v2.0.14 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 77598be80f..82905af16b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18567,11 +18567,11 @@ __metadata: linkType: hard "@types/supertest@npm:^2.0.12, @types/supertest@npm:^2.0.8": - version: 2.0.13 - resolution: "@types/supertest@npm:2.0.13" + version: 2.0.14 + resolution: "@types/supertest@npm:2.0.14" dependencies: "@types/superagent": "*" - checksum: fe66be8e16626f254dc9d9691706942689f47a84edf7d3baaeadd6d4d576dbf915ee70cebdd7034015e83fa91fcd2dcff1cd0252514e4c510619817a183b5b4f + checksum: 9f6850a22b8f0fd4c26a6dfd9b64771a66476b1a4f841a3b84a9da843ce69463efbf37594fe107297dd14a225d199b802464d48d70e9413238c637903d392137 languageName: node linkType: hard From 239ab25ebcf84eb4bdc1a5451369f4e3c5bc40e7 Mon Sep 17 00:00:00 2001 From: Thomas Cooper <57812123+coopernetes@users.noreply.github.com> Date: Tue, 3 Oct 2023 19:33:28 -0400 Subject: [PATCH 25/37] address review comments Signed-off-by: Thomas Cooper <57812123+coopernetes@users.noreply.github.com> --- .changeset/smooth-rings-mate.md | 2 +- packages/theme/api-report.md | 37 +------------------ .../theme/src/base/createBaseThemeOptions.ts | 2 +- 3 files changed, 3 insertions(+), 38 deletions(-) diff --git a/.changeset/smooth-rings-mate.md b/.changeset/smooth-rings-mate.md index 4b9a53f71b..f46ef2cb5c 100644 --- a/.changeset/smooth-rings-mate.md +++ b/.changeset/smooth-rings-mate.md @@ -2,4 +2,4 @@ '@backstage/theme': patch --- -Fixed a bug to support string fontSize values (`"2.5rem"`) instead of forcing numeric-only values & requiring casts. In addition, added an optional fontFamily prop for h1-h6 BackstageTypography variants to allow further customization. +Added support for string `fontSize` values (e.g. `"2.5rem"`) in themes in addition to numbers. Also added an optional `fontFamily` prop for header typography variants to allow further customization. diff --git a/packages/theme/api-report.md b/packages/theme/api-report.md index bf226d4d9e..4ab05e8770 100644 --- a/packages/theme/api-report.md +++ b/packages/theme/api-report.md @@ -178,42 +178,7 @@ export function createBaseThemeOptions( options: BaseThemeOptionsInput, ): { palette: PaletteOptions; - typography: - | BackstageTypography - | { - htmlFontSize: number; - fontFamily: string; - h1: { - fontSize: number; - fontWeight: number; - marginBottom: number; - }; - h2: { - fontSize: number; - fontWeight: number; - marginBottom: number; - }; - h3: { - fontSize: number; - fontWeight: number; - marginBottom: number; - }; - h4: { - fontWeight: number; - fontSize: number; - marginBottom: number; - }; - h5: { - fontWeight: number; - fontSize: number; - marginBottom: number; - }; - h6: { - fontWeight: number; - fontSize: number; - marginBottom: number; - }; - }; + typography: BackstageTypography; page: PageTheme; getPageTheme: ({ themeId }: PageThemeSelector) => PageTheme; }; diff --git a/packages/theme/src/base/createBaseThemeOptions.ts b/packages/theme/src/base/createBaseThemeOptions.ts index bca56114d7..f0c8ab5fe9 100644 --- a/packages/theme/src/base/createBaseThemeOptions.ts +++ b/packages/theme/src/base/createBaseThemeOptions.ts @@ -57,7 +57,7 @@ export function createBaseThemeOptions( throw new Error(`${defaultPageTheme} is not defined in pageTheme.`); } - const defaultTypography = { + const defaultTypography: BackstageTypography = { htmlFontSize, fontFamily, h1: { From 5addd014a6327f10826a824ccdec004e61d49d2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 5 Oct 2023 09:32:20 +0200 Subject: [PATCH 26/37] just some small fixes to the testing docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- docs/plugins/testing.md | 82 +++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 44 deletions(-) diff --git a/docs/plugins/testing.md b/docs/plugins/testing.md index 2fa086c444..3a7da2d410 100644 --- a/docs/plugins/testing.md +++ b/docs/plugins/testing.md @@ -18,11 +18,11 @@ Running all tests: yarn test -Running an individual test (e.g. `MyComponent.test.js`): +Running an individual test (e.g. `MyComponent.test.tsx`): yarn test MyComponent -To run both `MyComponent.test.js` and `MyControl.test.js` suite of tests: +To run both `MyComponent.test.tsx` and `MyControl.test.tsx` suite of tests: yarn test MyCo @@ -32,9 +32,9 @@ working on. ## Naming Test Files -Tests should be named `[filename].test.js`. +Tests should be named `[filename].test.ts`, or `[filename].test.tsx` if it contains JSX (as is the case for a lot of React tests, e.g. components). -For example, the tests for **`Link.js`** exist in the file **`Link.test.js`**. +For example, the tests for **`Link.tsx`** exist in the file **`Link.test.tsx`**. ## Third-Party Dependencies @@ -183,9 +183,9 @@ data then it actually does it. this way both tests fail if the data loading part breaks and the next developer immediately know the problem is that the data loading is broken, not that the loading indicator is broken. -# Examples +## Examples -## Utility Functions +### Utility Functions A utility function is a function with no side effects. It takes in arguments and returns a result or displays an error or console message, like so: @@ -241,12 +241,12 @@ it('Works with midCharIx', () => { }); ``` -## Non-React Classes +### Non-React Classes Testing a JavaScript object which is _not_ a React component follows a lot of the same principles as testing objects in other languages. -### API Testing Principles +#### API Testing Principles Testing an API involves verifying four things: @@ -255,7 +255,7 @@ Testing an API involves verifying four things: 3. Server response is translated into an expected JavaScript object. 4. Server errors are handled gracefully. -### Mocking API Calls +#### Mocking API Calls [Mocking in Jest](https://facebook.github.io/jest/docs/en/mock-functions.html) involves wrapping existing functions (like an API call function) with an @@ -263,52 +263,46 @@ alternative. For example: -**`./MyApi.js`** +**`./MyApi.ts`** ```ts -export { - fetchSomethingFromServer: () => { - // Live production call to a URI. Must be avoided during testing! - return fetch('blah'); - } -}; -``` - -**`./__mocks__/MyApi.js`** - -```ts -export { - fetchSomethingFromServer: () => { - // Simulate a production call, but avoid jest and just use a promise - return Promise.resolve('some result object simulating server data here'); - } +export async function fetchSomethingFromServer() { + // Live production call to a URI. Must be avoided during testing! + return fetch('blah'); } ``` -**`./MyApi.test.js`** +**`./__mocks__/MyApi.ts`** ```ts -/* eslint-disable import/first */ +export async function fetchSomethingFromServer() { + // Simulate a production call response + return 'some result object simulating server data here'; +} +``` -jest.mock('./MyApi'); // Instruct Jest to swap all future imports of './MyApi.js' to './__mocks__/MyApi.js' +**`./MyApi.test.ts`** -import MyApi from './MyApi'; // Will actually return the contents of the file in the __mocks__ folder now +```ts +// This import will actually return the contents of the file in the +// __mocks__ folder now, due to the jest.mock line below +import { fetchSomethingFromServer } from './MyApi'; -it('loads data', done => { - MyApi.fetchSomethingFromServer().then(result => { - expect(result).toBe('some result object simulating server data here'); - done(); - }); +// This instructs Jest to swap all imports of './MyApi.ts' to +// './__mocks__/MyApi.ts' - this gets automatically hoisted to the top +// of the file +jest.mock('./MyApi'); + +it('loads data', async () => { + await expect(fetchSomethingFromServer()).resolves.toBe( + 'some result object simulating server data here', + ); }); ``` -Note: make sure you disable the eslint `'import/first'` rule at the top of the -file since technically you are not allowed by the default settings to have an -import after the `jest.mock` call. +### React Components -## React Components - -### Working with the React Lifecycle +#### Working with the React Lifecycle The [React lifecycle](https://reactjs.org/docs/state-and-lifecycle.html) is asynchronous. @@ -317,7 +311,7 @@ When you call `setState` or update the `props` of a component, there are several asynchronous stages that must occur before a rerender. Note the following example: -```jsx +```tsx class MyComponent extends Component { load() { this.setState({loading: true}); @@ -350,7 +344,7 @@ For more information: - [React lifecycle](https://reactjs.org/docs/state-and-lifecycle.html) -### Accessing `store`, `theme`, routing, browser history, etc. +#### Accessing `store`, `theme`, routing, browser history, etc The Backstage application has several core providers at its root. To run your test wrapped in a "sample" Backstage application, you can use our utility @@ -369,6 +363,6 @@ functions: Note: wrapping in the test application **requires** you to do a `find()` or `dive()` since the wrapped component is now the application. -# Debugging Jest Tests +## Debugging Jest Tests You can find it [here](https://backstage.io/docs/local-dev/cli-build-system#debugging-jest-tests) From 9fb58a08f0c05240bcad20ecd7eb179962e24b6b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 09:19:39 +0000 Subject: [PATCH 27/37] chore(deps): update dependency @types/jquery to v3.5.21 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7d3fad372a..cb1ad35eb1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17703,11 +17703,11 @@ __metadata: linkType: hard "@types/jquery@npm:^3.3.34": - version: 3.5.20 - resolution: "@types/jquery@npm:3.5.20" + version: 3.5.21 + resolution: "@types/jquery@npm:3.5.21" dependencies: "@types/sizzle": "*" - checksum: 9bd69faea3d60f52d3029a87b890003042a9dcf4f538c23ac2c11b3bd0e0ccd86b281d5ba3028d1b02df67c69266b8dc0ef0a35696ae174515ecf34523a0287b + checksum: 48cce8892f0292ac68853677d408195436a460ed45445a2da13deddcf21b407b3f896bbf5714f320c8f44666fdff5ceba5c59e873a316486098040404dcf56f4 languageName: node linkType: hard From d6a89ded6f7ef99bff6848928961c82c8c4072b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 09:22:54 +0000 Subject: [PATCH 28/37] fix(deps): update dependency @swc/core to v1.3.92 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- microsite/yarn.lock | 86 ++++++++++++++++++++++----------------------- storybook/yarn.lock | 86 ++++++++++++++++++++++----------------------- yarn.lock | 86 ++++++++++++++++++++++----------------------- 3 files changed, 129 insertions(+), 129 deletions(-) diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 27b077b8da..3cfe6d0b74 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -2604,90 +2604,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-darwin-arm64@npm:1.3.90" +"@swc/core-darwin-arm64@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-darwin-arm64@npm:1.3.92" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-darwin-x64@npm:1.3.90" +"@swc/core-darwin-x64@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-darwin-x64@npm:1.3.92" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.90" +"@swc/core-linux-arm-gnueabihf@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.92" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.90" +"@swc/core-linux-arm64-gnu@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.92" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.90" +"@swc/core-linux-arm64-musl@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.92" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.90" +"@swc/core-linux-x64-gnu@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.92" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-x64-musl@npm:1.3.90" +"@swc/core-linux-x64-musl@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-x64-musl@npm:1.3.92" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.90" +"@swc/core-win32-arm64-msvc@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.92" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.90" +"@swc/core-win32-ia32-msvc@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.92" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.90" +"@swc/core-win32-x64-msvc@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.92" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.3.90 - resolution: "@swc/core@npm:1.3.90" + version: 1.3.92 + resolution: "@swc/core@npm:1.3.92" dependencies: - "@swc/core-darwin-arm64": 1.3.90 - "@swc/core-darwin-x64": 1.3.90 - "@swc/core-linux-arm-gnueabihf": 1.3.90 - "@swc/core-linux-arm64-gnu": 1.3.90 - "@swc/core-linux-arm64-musl": 1.3.90 - "@swc/core-linux-x64-gnu": 1.3.90 - "@swc/core-linux-x64-musl": 1.3.90 - "@swc/core-win32-arm64-msvc": 1.3.90 - "@swc/core-win32-ia32-msvc": 1.3.90 - "@swc/core-win32-x64-msvc": 1.3.90 + "@swc/core-darwin-arm64": 1.3.92 + "@swc/core-darwin-x64": 1.3.92 + "@swc/core-linux-arm-gnueabihf": 1.3.92 + "@swc/core-linux-arm64-gnu": 1.3.92 + "@swc/core-linux-arm64-musl": 1.3.92 + "@swc/core-linux-x64-gnu": 1.3.92 + "@swc/core-linux-x64-musl": 1.3.92 + "@swc/core-win32-arm64-msvc": 1.3.92 + "@swc/core-win32-ia32-msvc": 1.3.92 + "@swc/core-win32-x64-msvc": 1.3.92 "@swc/counter": ^0.1.1 "@swc/types": ^0.1.5 peerDependencies: @@ -2716,7 +2716,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: f8ced5187068dc73445c135065c6492f0ac559d0f7720c2482aa9663c87bd015f3d2abef6ee7b2f817280a5e8dd0946c59cce7e1499180644fbc948a9e3823ab + checksum: 88c0c62ff790e896180862c341be8bae98baf0a5c5e87f2f04f49e14b8c4fba460d6b352618b4dda066c8ae6bf152cd843eab25837f38128175208b8c0635721 languageName: node linkType: hard diff --git a/storybook/yarn.lock b/storybook/yarn.lock index e0f77cd510..c2c7582983 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -2840,90 +2840,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-darwin-arm64@npm:1.3.90" +"@swc/core-darwin-arm64@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-darwin-arm64@npm:1.3.92" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-darwin-x64@npm:1.3.90" +"@swc/core-darwin-x64@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-darwin-x64@npm:1.3.92" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.90" +"@swc/core-linux-arm-gnueabihf@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.92" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.90" +"@swc/core-linux-arm64-gnu@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.92" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.90" +"@swc/core-linux-arm64-musl@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.92" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.90" +"@swc/core-linux-x64-gnu@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.92" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-x64-musl@npm:1.3.90" +"@swc/core-linux-x64-musl@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-x64-musl@npm:1.3.92" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.90" +"@swc/core-win32-arm64-msvc@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.92" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.90" +"@swc/core-win32-ia32-msvc@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.92" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.90" +"@swc/core-win32-x64-msvc@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.92" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.3.90 - resolution: "@swc/core@npm:1.3.90" + version: 1.3.92 + resolution: "@swc/core@npm:1.3.92" dependencies: - "@swc/core-darwin-arm64": 1.3.90 - "@swc/core-darwin-x64": 1.3.90 - "@swc/core-linux-arm-gnueabihf": 1.3.90 - "@swc/core-linux-arm64-gnu": 1.3.90 - "@swc/core-linux-arm64-musl": 1.3.90 - "@swc/core-linux-x64-gnu": 1.3.90 - "@swc/core-linux-x64-musl": 1.3.90 - "@swc/core-win32-arm64-msvc": 1.3.90 - "@swc/core-win32-ia32-msvc": 1.3.90 - "@swc/core-win32-x64-msvc": 1.3.90 + "@swc/core-darwin-arm64": 1.3.92 + "@swc/core-darwin-x64": 1.3.92 + "@swc/core-linux-arm-gnueabihf": 1.3.92 + "@swc/core-linux-arm64-gnu": 1.3.92 + "@swc/core-linux-arm64-musl": 1.3.92 + "@swc/core-linux-x64-gnu": 1.3.92 + "@swc/core-linux-x64-musl": 1.3.92 + "@swc/core-win32-arm64-msvc": 1.3.92 + "@swc/core-win32-ia32-msvc": 1.3.92 + "@swc/core-win32-x64-msvc": 1.3.92 "@swc/counter": ^0.1.1 "@swc/types": ^0.1.5 peerDependencies: @@ -2952,7 +2952,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: f8ced5187068dc73445c135065c6492f0ac559d0f7720c2482aa9663c87bd015f3d2abef6ee7b2f817280a5e8dd0946c59cce7e1499180644fbc948a9e3823ab + checksum: 88c0c62ff790e896180862c341be8bae98baf0a5c5e87f2f04f49e14b8c4fba460d6b352618b4dda066c8ae6bf152cd843eab25837f38128175208b8c0635721 languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index 7d3fad372a..dc466a80c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16542,90 +16542,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-darwin-arm64@npm:1.3.90" +"@swc/core-darwin-arm64@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-darwin-arm64@npm:1.3.92" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-darwin-x64@npm:1.3.90" +"@swc/core-darwin-x64@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-darwin-x64@npm:1.3.92" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.90" +"@swc/core-linux-arm-gnueabihf@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.92" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.90" +"@swc/core-linux-arm64-gnu@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.92" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.90" +"@swc/core-linux-arm64-musl@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.92" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.90" +"@swc/core-linux-x64-gnu@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.92" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-linux-x64-musl@npm:1.3.90" +"@swc/core-linux-x64-musl@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-linux-x64-musl@npm:1.3.92" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.90" +"@swc/core-win32-arm64-msvc@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.92" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.90" +"@swc/core-win32-ia32-msvc@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.92" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.90": - version: 1.3.90 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.90" +"@swc/core-win32-x64-msvc@npm:1.3.92": + version: 1.3.92 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.92" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.3.90 - resolution: "@swc/core@npm:1.3.90" + version: 1.3.92 + resolution: "@swc/core@npm:1.3.92" dependencies: - "@swc/core-darwin-arm64": 1.3.90 - "@swc/core-darwin-x64": 1.3.90 - "@swc/core-linux-arm-gnueabihf": 1.3.90 - "@swc/core-linux-arm64-gnu": 1.3.90 - "@swc/core-linux-arm64-musl": 1.3.90 - "@swc/core-linux-x64-gnu": 1.3.90 - "@swc/core-linux-x64-musl": 1.3.90 - "@swc/core-win32-arm64-msvc": 1.3.90 - "@swc/core-win32-ia32-msvc": 1.3.90 - "@swc/core-win32-x64-msvc": 1.3.90 + "@swc/core-darwin-arm64": 1.3.92 + "@swc/core-darwin-x64": 1.3.92 + "@swc/core-linux-arm-gnueabihf": 1.3.92 + "@swc/core-linux-arm64-gnu": 1.3.92 + "@swc/core-linux-arm64-musl": 1.3.92 + "@swc/core-linux-x64-gnu": 1.3.92 + "@swc/core-linux-x64-musl": 1.3.92 + "@swc/core-win32-arm64-msvc": 1.3.92 + "@swc/core-win32-ia32-msvc": 1.3.92 + "@swc/core-win32-x64-msvc": 1.3.92 "@swc/counter": ^0.1.1 "@swc/types": ^0.1.5 peerDependencies: @@ -16654,7 +16654,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: f8ced5187068dc73445c135065c6492f0ac559d0f7720c2482aa9663c87bd015f3d2abef6ee7b2f817280a5e8dd0946c59cce7e1499180644fbc948a9e3823ab + checksum: 88c0c62ff790e896180862c341be8bae98baf0a5c5e87f2f04f49e14b8c4fba460d6b352618b4dda066c8ae6bf152cd843eab25837f38128175208b8c0635721 languageName: node linkType: hard From 07d0e9e317026ac5900bfc59439dc74e95cbc152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 5 Oct 2023 11:35:29 +0200 Subject: [PATCH 29/37] order module export keys in the test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- plugins/git-release-manager/src/plugin.test.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/git-release-manager/src/plugin.test.ts b/plugins/git-release-manager/src/plugin.test.ts index b293ea05eb..055482dd7b 100644 --- a/plugins/git-release-manager/src/plugin.test.ts +++ b/plugins/git-release-manager/src/plugin.test.ts @@ -18,15 +18,15 @@ import * as plugin from './plugin'; describe('git-release-manager', () => { it('should export plugin & friends', () => { - expect(Object.keys(plugin)).toMatchInlineSnapshot(` + expect(Object.keys(plugin).sort()).toMatchInlineSnapshot(` [ - "gitReleaseManagerApiRef", - "constants", - "helpers", - "components", - "testHelpers", - "gitReleaseManagerPlugin", "GitReleaseManagerPage", + "components", + "constants", + "gitReleaseManagerApiRef", + "gitReleaseManagerPlugin", + "helpers", + "testHelpers", ] `); }); From 9c6c61b3d1f581fb4a8af5f2ea362de68abc9628 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 09:43:39 +0000 Subject: [PATCH 30/37] chore(deps): update dependency @types/node to v16.18.57 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/yarn.lock b/yarn.lock index 41f1d87881..e374954bd4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18012,9 +18012,9 @@ __metadata: linkType: hard "@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0, @types/node@npm:^20.1.1": - version: 20.6.5 - resolution: "@types/node@npm:20.6.5" - checksum: b849e849cf7631458a65c5019c81962028e306d8c4455a48422277b240f5a7eb8a1f1dafa60306bd4c773b77263bb8b05c074b1026e868bd137bb2022cf63ea2 + version: 20.8.2 + resolution: "@types/node@npm:20.8.2" + checksum: 3da73e25d821bfcdb7de98589027e08bb4848e55408671c4a83ec0341e124b5313a0b20e1e4b4eff1168ea17a86f622ad73fcb04b761abd77496b9a27cbd5de5 languageName: node linkType: hard @@ -18033,16 +18033,16 @@ __metadata: linkType: hard "@types/node@npm:^16.11.26, @types/node@npm:^16.9.2": - version: 16.18.54 - resolution: "@types/node@npm:16.18.54" - checksum: 208e8fc64f605e9cd55ab5e620a0fd019d8fe5629e3e3c5de869a149b731ab0fac5720c516dccc0ecc834ac27df754723dfe6554551663f016ba5096ea8851df + version: 16.18.57 + resolution: "@types/node@npm:16.18.57" + checksum: db21a14416de3abce8dfc30d9e9513c505060ef4d197fdc1b1b7374feca3417a7757172d041989fd49910245e9f2d7869201accac3cceee7c75bfdf8759ead6d languageName: node linkType: hard "@types/node@npm:^18.11.17, @types/node@npm:^18.17.8": - version: 18.17.18 - resolution: "@types/node@npm:18.17.18" - checksum: 59cbd906363d37017fe9ba0c08c1446e440d4d977459609c5f90b8fb7eb41f273ce8af30c5a5b5d599d7de934c1b3702bc9fc27caf8d2270e5cdb659c5232991 + version: 18.18.3 + resolution: "@types/node@npm:18.18.3" + checksum: ed97a832179e0cfbb93738021fe16d0bc5c0f34bea35269c23c9dd5f0ecc8be93dbe5efd51630189a099b31786a47c1bde115508831a7245613a55c3ad1a7d6b languageName: node linkType: hard From bb469f8df57e4e85a987152553607a4bb81b4e75 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 10:08:11 +0000 Subject: [PATCH 31/37] fix(deps): update dependency @apollo/server to v4.9.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index d528b8e994..509f77447f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -200,8 +200,8 @@ __metadata: linkType: hard "@apollo/server@npm:^4.0.0": - version: 4.9.3 - resolution: "@apollo/server@npm:4.9.3" + version: 4.9.4 + resolution: "@apollo/server@npm:4.9.4" dependencies: "@apollo/cache-control-types": ^1.0.3 "@apollo/server-gateway-interface": ^1.1.1 @@ -231,7 +231,7 @@ __metadata: whatwg-mimetype: ^3.0.0 peerDependencies: graphql: ^16.6.0 - checksum: 28537d7646669a5dc1302cfd75d8a9bf473459ee585c6b778d174628a2cfb3f89a5ac742eca7de2a779b6c9e3f30da509a8787a71227520d009ac190aa7a9207 + checksum: bf7105ffceaed6e3c54f1506513944bb324ae32e92b1aabb3ec7de1b9fee1373bdec6e1a3f5efb7c7f8090671f1ba2d37c01f5b1456c93127ffede1a0b554bac languageName: node linkType: hard From 3d311d35cc0680c2fe38d16cde3533f204ffc80e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 10:08:50 +0000 Subject: [PATCH 32/37] fix(deps): update dependency @mui/material to v5.14.12 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 112 +++++++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/yarn.lock b/yarn.lock index d528b8e994..7e59f2691f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3305,12 +3305,12 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.22.15, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": - version: 7.22.15 - resolution: "@babel/runtime@npm:7.22.15" +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.1, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": + version: 7.23.1 + resolution: "@babel/runtime@npm:7.23.1" dependencies: regenerator-runtime: ^0.14.0 - checksum: 793296df1e41599a935a3d77ec01eb6088410d3fd4dbe4e92f06c6b7bb2f8355024e6d78621a3a35f44e0e23b0b59107f23d585384df4f3123256a1e1492040e + checksum: 0cd0d43e6e7dc7f9152fda8c8312b08321cda2f56ef53d6c22ebdd773abdc6f5d0a69008de90aa41908d00e2c1facb24715ff121274e689305c858355ff02c70 languageName: node linkType: hard @@ -13414,14 +13414,14 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.17": - version: 5.0.0-beta.17 - resolution: "@mui/base@npm:5.0.0-beta.17" +"@mui/base@npm:5.0.0-beta.18": + version: 5.0.0-beta.18 + resolution: "@mui/base@npm:5.0.0-beta.18" dependencies: - "@babel/runtime": ^7.22.15 + "@babel/runtime": ^7.23.1 "@floating-ui/react-dom": ^2.0.2 - "@mui/types": ^7.2.4 - "@mui/utils": ^5.14.11 + "@mui/types": ^7.2.5 + "@mui/utils": ^5.14.12 "@popperjs/core": ^2.11.8 clsx: ^2.0.0 prop-types: ^15.8.1 @@ -13432,27 +13432,27 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 96ffb85864fc796783514e089c0011ebcc5174705082dc98197ab035dfb287427069c0338e662a4680951849dfbe7a5231f4f6f2aee710af05c07e8578f93310 + checksum: 7d4ca1e9d537b7b5850567f1adecd1caa47b8613b43a587cf2f399cfda0a8c17dfda06b030c0bea554b76abe7ac25bb9b1af3c996574def5f860cda0c6ea4a3c languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.14.11": - version: 5.14.11 - resolution: "@mui/core-downloads-tracker@npm:5.14.11" - checksum: f3e7594c93d4cf5e3649336eef2b57842c171f3deb6890c03be7eccb88d3ac276aac1ab3ad409d124d16468314018778e2dbb92a62ac34c7f44b2813c47f29fb +"@mui/core-downloads-tracker@npm:^5.14.12": + version: 5.14.12 + resolution: "@mui/core-downloads-tracker@npm:5.14.12" + checksum: 1c1576ceecf7cade9e0d7a531632f5f9db24853d9ebbd47bb9ed943a3af7de734ad4f3374bab79880e9591db3ea55ea84cc10df72177f9ca5e32cc7662e04405 languageName: node linkType: hard "@mui/material@npm:^5.12.2": - version: 5.14.11 - resolution: "@mui/material@npm:5.14.11" + version: 5.14.12 + resolution: "@mui/material@npm:5.14.12" dependencies: - "@babel/runtime": ^7.22.15 - "@mui/base": 5.0.0-beta.17 - "@mui/core-downloads-tracker": ^5.14.11 - "@mui/system": ^5.14.11 - "@mui/types": ^7.2.4 - "@mui/utils": ^5.14.11 + "@babel/runtime": ^7.23.1 + "@mui/base": 5.0.0-beta.18 + "@mui/core-downloads-tracker": ^5.14.12 + "@mui/system": ^5.14.12 + "@mui/types": ^7.2.5 + "@mui/utils": ^5.14.12 "@types/react-transition-group": ^4.4.6 clsx: ^2.0.0 csstype: ^3.1.2 @@ -13472,16 +13472,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: 350d642773d4b19d5b9deac956203dafe89cd005ba8cd6017d1ab0e97ba45ca230050249f34a17f0f00efe466162d47487f160159bebe3e52af1b34dd28579d0 + checksum: a0d3b52ce3cc282da04036db0805f95f27b35a9c899f132f962fe96f05d3eb112e99ccbf6bd9d05cae617b24beda95470aedaff129d6e39d1b52e1ddf80a9e12 languageName: node linkType: hard -"@mui/private-theming@npm:^5.14.11": - version: 5.14.11 - resolution: "@mui/private-theming@npm:5.14.11" +"@mui/private-theming@npm:^5.14.12": + version: 5.14.12 + resolution: "@mui/private-theming@npm:5.14.12" dependencies: - "@babel/runtime": ^7.22.15 - "@mui/utils": ^5.14.11 + "@babel/runtime": ^7.23.1 + "@mui/utils": ^5.14.12 prop-types: ^15.8.1 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -13489,15 +13489,15 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: a5d461ae9679b1f3b79f529c51c055e03d84421812bb12110d735fbc5528ae188900488b32aa1b860cb978ac6dd0cb9f54a10e2ff214e853e969ef5c1ed87e84 + checksum: f8127347dc29126fece3b530cb156f6ababf747b64bb1c712874375e6efae6c738c014304d9553001d67a59b24ca6a665f2d03bb5ae137f03bdba90815f0ecc1 languageName: node linkType: hard -"@mui/styled-engine@npm:^5.14.11": - version: 5.14.11 - resolution: "@mui/styled-engine@npm:5.14.11" +"@mui/styled-engine@npm:^5.14.12": + version: 5.14.12 + resolution: "@mui/styled-engine@npm:5.14.12" dependencies: - "@babel/runtime": ^7.22.15 + "@babel/runtime": ^7.23.1 "@emotion/cache": ^11.11.0 csstype: ^3.1.2 prop-types: ^15.8.1 @@ -13510,19 +13510,19 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: 0a593f967ab56c32c611eae4a83bc23c4ab3a8931e76a6e553ed18230c2f4e9e912d519fe2f0a24970ff154c198634903f134eb54f00ceebde138a73b953622f + checksum: c689ccad59e7fd54cd8367838612daa4f132c64d8c6b99ccb7c8f9697b5c940a6bf7edcccd686ce437b565dbcf3bfc12bb0dea47cbd5fbd750ea1553017f9c0d languageName: node linkType: hard -"@mui/system@npm:^5.14.11": - version: 5.14.11 - resolution: "@mui/system@npm:5.14.11" +"@mui/system@npm:^5.14.12": + version: 5.14.12 + resolution: "@mui/system@npm:5.14.12" dependencies: - "@babel/runtime": ^7.22.15 - "@mui/private-theming": ^5.14.11 - "@mui/styled-engine": ^5.14.11 - "@mui/types": ^7.2.4 - "@mui/utils": ^5.14.11 + "@babel/runtime": ^7.23.1 + "@mui/private-theming": ^5.14.12 + "@mui/styled-engine": ^5.14.12 + "@mui/types": ^7.2.5 + "@mui/utils": ^5.14.12 clsx: ^2.0.0 csstype: ^3.1.2 prop-types: ^15.8.1 @@ -13538,28 +13538,28 @@ __metadata: optional: true "@types/react": optional: true - checksum: c3d0e1a09a9638663a6467452a7725593e9de6f9620e199add1080db42a7affaca39f52a1b6a52fb75d708f3e30336946babb2a8d1d43fab81c6a1fe3e420b21 + checksum: 70c3920eadc593395a2d258ddea0f3b28689c7f02fdaf97fc205e16efaeebe462b2ab01c69a20a3bcb011e0d07ea47fa66a433e70d0a1ce15d7b694fb3c52135 languageName: node linkType: hard -"@mui/types@npm:^7.2.4": - version: 7.2.4 - resolution: "@mui/types@npm:7.2.4" +"@mui/types@npm:^7.2.5": + version: 7.2.5 + resolution: "@mui/types@npm:7.2.5" peerDependencies: - "@types/react": "*" + "@types/react": ^17.0.0 || ^18.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 16bea0547492193a22fd1794382f314698a114f6c673825314c66b56766c3a9d305992cc495684722b7be16a1ecf7e6e48a79caa64f90c439b530e8c02611a61 + checksum: 2807e9a8eb251294eee6384a4d68b2159f7660466625f1781e9efea282aa7c6ff35b42bc7039c2d43e7a5ac80291dcb85c4110022b0b6de4e12b6406b62f3dc1 languageName: node linkType: hard -"@mui/utils@npm:^5.14.11": - version: 5.14.11 - resolution: "@mui/utils@npm:5.14.11" +"@mui/utils@npm:^5.14.12": + version: 5.14.12 + resolution: "@mui/utils@npm:5.14.12" dependencies: - "@babel/runtime": ^7.22.15 - "@types/prop-types": ^15.7.5 + "@babel/runtime": ^7.23.1 + "@types/prop-types": ^15.7.7 prop-types: ^15.8.1 react-is: ^18.2.0 peerDependencies: @@ -13568,7 +13568,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 84e640dea3589ea7edb7d8f33748d83d561d4ef413c4d3e2216ddf9c0842d8b04d162e3fa5ea59f03846934f17fb446ed8464e318dd4e2e299e3b44b06637d76 + checksum: 41470b6292b7a46c71fb0a0acc6a5f05a5e080648106b8805555de920e8f748669c7e8d39cbbcf0f52be9053927bb8439a748e24bd02bc1a220c9bded4435f42 languageName: node linkType: hard @@ -18203,7 +18203,7 @@ __metadata: languageName: node linkType: hard -"@types/prop-types@npm:*, @types/prop-types@npm:^15.0.0, @types/prop-types@npm:^15.7.3, @types/prop-types@npm:^15.7.5": +"@types/prop-types@npm:*, @types/prop-types@npm:^15.0.0, @types/prop-types@npm:^15.7.3, @types/prop-types@npm:^15.7.7": version: 15.7.8 resolution: "@types/prop-types@npm:15.7.8" checksum: 61dfad79da8b1081c450bab83b77935df487ae1cdd4660ec7df6be8e74725c15fa45cf486ce057addc956ca4ae78300b97091e2a25061133d1b9a1440bc896ae From bbe178272fd634a44ec75197b5c17ecc722e2a5c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 11:31:05 +0000 Subject: [PATCH 33/37] fix(deps): update dependency @roadiehq/backstage-plugin-github-pull-requests to v2.5.17 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 40 ++++------------------------------------ 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/yarn.lock b/yarn.lock index acc15f7f72..bf8f219fdd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7352,38 +7352,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-home@npm:^0.5.8": - version: 0.5.8 - resolution: "@backstage/plugin-home@npm:0.5.8" - dependencies: - "@backstage/catalog-model": ^1.4.2 - "@backstage/config": ^1.1.0 - "@backstage/core-components": ^0.13.5 - "@backstage/core-plugin-api": ^1.6.0 - "@backstage/plugin-catalog-react": ^1.8.4 - "@backstage/plugin-home-react": ^0.1.3 - "@backstage/theme": ^0.4.2 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@rjsf/core-v5": "npm:@rjsf/core@5.13.0" - "@rjsf/material-ui-v5": "npm:@rjsf/material-ui@5.13.0" - "@rjsf/utils": 5.13.0 - "@rjsf/validator-ajv8": 5.13.0 - "@types/react": ^16.13.1 || ^17.0.0 - lodash: ^4.17.21 - react-grid-layout: ^1.3.4 - react-resizable: ^3.0.4 - react-use: ^17.2.4 - zod: ^3.21.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 - react-dom: ^16.13.1 || ^17.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 4f895b3a7e7f61149ba7b8fd6ec998d1f83b6e5262073893c5863fe79c46e5e2f52b43346f310733e04815aaebd82b8a13d34616e8d0848f60f87b1fb3193d60 - languageName: node - linkType: hard - "@backstage/plugin-home@workspace:^, @backstage/plugin-home@workspace:plugins/home": version: 0.0.0-use.local resolution: "@backstage/plugin-home@workspace:plugins/home" @@ -14831,14 +14799,14 @@ __metadata: linkType: hard "@roadiehq/backstage-plugin-github-pull-requests@npm:^2.2.7": - version: 2.5.16 - resolution: "@roadiehq/backstage-plugin-github-pull-requests@npm:2.5.16" + version: 2.5.17 + resolution: "@roadiehq/backstage-plugin-github-pull-requests@npm:2.5.17" dependencies: "@backstage/catalog-model": ^1.4.2 "@backstage/core-components": ^0.13.5 "@backstage/core-plugin-api": ^1.6.0 "@backstage/plugin-catalog-react": ^1.8.4 - "@backstage/plugin-home": ^0.5.8 + "@backstage/plugin-home-react": ^0.1.3 "@material-ui/core": ^4.11.0 "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.60 @@ -14855,7 +14823,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: cb35e64d4df6f81829cd238e3b06b84453ad9231a30a0a4698ebb9d408445af0bfeb59d27bcc5d818013735f2f4d44a89ff9824258ff1565274c524c3ae905cc + checksum: 4a2203aad37ae8b268f3ff11967545bbcfc18741f3e3ea0e7106dcbb3f8af47a7701ebdcdf17e80023590394fb2f923e0f3691b7d0334586892f99335756a47d languageName: node linkType: hard From 360fa0d75d53fc7ea5651350b12913b45f069d65 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 11:31:37 +0000 Subject: [PATCH 34/37] fix(deps): update dependency @uiw/react-codemirror to v4.21.19 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index acc15f7f72..9ad13badfb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19036,9 +19036,9 @@ __metadata: languageName: node linkType: hard -"@uiw/codemirror-extensions-basic-setup@npm:4.21.18": - version: 4.21.18 - resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.21.18" +"@uiw/codemirror-extensions-basic-setup@npm:4.21.19": + version: 4.21.19 + resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.21.19" dependencies: "@codemirror/autocomplete": ^6.0.0 "@codemirror/commands": ^6.0.0 @@ -19055,19 +19055,19 @@ __metadata: "@codemirror/search": ">=6.0.0" "@codemirror/state": ">=6.0.0" "@codemirror/view": ">=6.0.0" - checksum: c643eebc45e2067080c46e28fdb4ac40043e5890f4862bd45fe5bf816894b6c118ea901ca9ba1dce8862877622ebd793db6ec220491506355ed562a0dc0c4507 + checksum: 85a1f8b3e071b4587f13609d8449406baa8dead51aa588b914ffa95aac1bdfe1e1aa78689d7927fb90a554b747409cc59cada18fcbe2c204f5936e5441fbade1 languageName: node linkType: hard "@uiw/react-codemirror@npm:^4.9.3": - version: 4.21.18 - resolution: "@uiw/react-codemirror@npm:4.21.18" + version: 4.21.19 + resolution: "@uiw/react-codemirror@npm:4.21.19" 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.21.18 + "@uiw/codemirror-extensions-basic-setup": 4.21.19 codemirror: ^6.0.0 peerDependencies: "@babel/runtime": ">=7.11.0" @@ -19077,7 +19077,7 @@ __metadata: codemirror: ">=6.0.0" react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: ef3897e9901b98fd981d4b9db2ae8702aa7ffda4cf5cab3286963580606a6dde38e77a4314c12574b6f5f251d62b62e59f0a1a445009b5927b8500f4b5fd795c + checksum: bcd016ac806ff34ab3ab16e17090c80c0ed7f835835575c7a15b21238cae9169662444323cbbc8ef2a62c5e8fd7d8b668fd3562cf79b509ededaf7cd4970adf0 languageName: node linkType: hard From fa5d2aebefbd68f16de775904add46c1c355a205 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 12:09:11 +0000 Subject: [PATCH 35/37] fix(deps): update dependency zod to v3.22.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7b52a29afc..aea6ea8e57 100644 --- a/yarn.lock +++ b/yarn.lock @@ -43219,9 +43219,9 @@ __metadata: linkType: hard "zod@npm:^3.21.4": - version: 3.22.3 - resolution: "zod@npm:3.22.3" - checksum: 65b05139be337078a70700b05942ab7f2ef5f11abe194df14ef257fac4e5c383476a4dc290731842996bd57fc8d5bf38e5a4c907fe8cdf8b15477f8da5bfcc00 + version: 3.22.4 + resolution: "zod@npm:3.22.4" + checksum: 80bfd7f8039b24fddeb0718a2ec7c02aa9856e4838d6aa4864335a047b6b37a3273b191ef335bf0b2002e5c514ef261ffcda5a589fb084a48c336ffc4cdbab7f languageName: node linkType: hard From 59cc6cf25147b69e524fe4b4605dafd787973302 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 13:41:49 +0000 Subject: [PATCH 36/37] fix(deps): update dependency @rollup/plugin-yaml to v4.1.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index aea6ea8e57..101c0a96fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14903,18 +14903,18 @@ __metadata: linkType: hard "@rollup/plugin-yaml@npm:^4.0.0": - version: 4.1.1 - resolution: "@rollup/plugin-yaml@npm:4.1.1" + version: 4.1.2 + resolution: "@rollup/plugin-yaml@npm:4.1.2" dependencies: "@rollup/pluginutils": ^5.0.1 js-yaml: ^4.1.0 tosource: ^2.0.0-alpha.3 peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true - checksum: 99c8f9d4a354056bec8a9398786777203d87db32db0cad681f65ee896cbbbb8a61ace0b1c3d801622782ccf28e56eac6cdde950541fb1f7b3e651ad9c705d5c3 + checksum: a044bb4568a10712465553ea5f31c13a2b7bc371a7f8382014e6b8048c0a264f5645f83f4d70ce9ab46b75117b94cdc032b597e9315fd2adcd8f30637f44bbea languageName: node linkType: hard From 925cd271ce1b5e4d00289b32fb1c455d1138f2de Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 13:42:29 +0000 Subject: [PATCH 37/37] chore(deps): update dependency better-sqlite3 to v8.7.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index aea6ea8e57..b48b1fb07e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20635,13 +20635,13 @@ __metadata: linkType: hard "better-sqlite3@npm:^8.0.0": - version: 8.6.0 - resolution: "better-sqlite3@npm:8.6.0" + version: 8.7.0 + resolution: "better-sqlite3@npm:8.7.0" dependencies: bindings: ^1.5.0 node-gyp: latest prebuild-install: ^7.1.1 - checksum: 9ebdfd675352347cda1ba30d620a3c512d9db827a1eba66460fd48203a7ad8138b0195893bbf47d40f704bcdd598710041271d4ed69779979b6f784c0d3579a1 + checksum: f1fa38a9a0e4fcd59ececb67c60371b9638d29c19ce9af034421e8a56c9a77e799bb1411b1c3cb08bb9678e15dfb8985553a9ef4098cf5558e7207a3e019f211 languageName: node linkType: hard