From 5a477ce8344c98cf6fe4c51a4d35be6a0e5a3168 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Tue, 5 Mar 2024 14:05:49 -0500 Subject: [PATCH 001/107] feat(apollo-explorer): allow callbacks using apiholder Signed-off-by: Karl Haworth --- plugins/apollo-explorer/package.json | 2 ++ .../ApolloExplorerPage/ApolloExplorerPage.tsx | 23 +++++++++++++++++-- yarn.lock | 4 +++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json index cd7b3e6b51..563b16f951 100644 --- a/plugins/apollo-explorer/package.json +++ b/plugins/apollo-explorer/package.json @@ -36,7 +36,9 @@ "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", "@material-ui/core": "^4.12.2", + "@material-ui/lab": "^4.0.0-alpha.61", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-use": "^17.5.0", "use-deep-compare-effect": "^1.8.1" }, "devDependencies": { diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx index f90af9bc17..f6bda693b5 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx @@ -18,6 +18,10 @@ import React from 'react'; import { Content, Header, Page } from '@backstage/core-components'; import { ApolloExplorerBrowser } from '../ApolloExplorerBrowser'; import { JSONObject } from '@apollo/explorer/src/helpers/types'; +import { ApiHolder, useApiHolder } from '@backstage/core-plugin-api'; +import { useAsync } from 'react-use'; +import { CircularProgress } from '@material-ui/core'; +import { Alert } from '@material-ui/lab'; type EndpointProps = { title: string; @@ -35,19 +39,34 @@ type EndpointProps = { }; }; +type EndpointPropsCallback = (options: { + apiHolder: ApiHolder; +}) => Promise; + type Props = { title?: string | undefined; subtitle?: string | undefined; - endpoints: EndpointProps[]; + endpoints: EndpointProps[] | EndpointPropsCallback; }; export const ApolloExplorerPage = (props: Props) => { const { title, subtitle, endpoints } = props; + const apiHolder = useApiHolder(); + + const { value, loading, error } = useAsync(async () => { + if (typeof endpoints === 'function') { + return await endpoints({ apiHolder }); + } + return endpoints; + }, []); + return (
- + {loading && } + {error && {error?.message}} + {value && } ); diff --git a/yarn.lock b/yarn.lock index eb05400306..edfc9eadb9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4676,10 +4676,12 @@ __metadata: "@backstage/core-plugin-api": "workspace:^" "@backstage/dev-utils": "workspace:^" "@material-ui/core": ^4.12.2 + "@material-ui/lab": ^4.0.0-alpha.61 "@testing-library/dom": ^9.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + react-use: ^17.5.0 use-deep-compare-effect: ^1.8.1 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 @@ -40267,7 +40269,7 @@ __metadata: languageName: node linkType: hard -"react-use@npm:^17.2.4, react-use@npm:^17.3.1, react-use@npm:^17.3.2, react-use@npm:^17.4.0": +"react-use@npm:^17.2.4, react-use@npm:^17.3.1, react-use@npm:^17.3.2, react-use@npm:^17.4.0, react-use@npm:^17.5.0": version: 17.5.0 resolution: "react-use@npm:17.5.0" dependencies: From c664b15b37f937d7e93105b72d7b29484d2b61a2 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Tue, 5 Mar 2024 14:11:42 -0500 Subject: [PATCH 002/107] add changeset Signed-off-by: Karl Haworth --- .changeset/warm-pugs-pretend.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/warm-pugs-pretend.md diff --git a/.changeset/warm-pugs-pretend.md b/.changeset/warm-pugs-pretend.md new file mode 100644 index 0000000000..f7adea6cc0 --- /dev/null +++ b/.changeset/warm-pugs-pretend.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-apollo-explorer': minor +--- + +feat(apollo-explorer): allow callbacks using apiholder From 626cf35c1806a504a2f0b1d26977e7bab56a9926 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Tue, 5 Mar 2024 14:19:38 -0500 Subject: [PATCH 003/107] update readme for functionality improvements Signed-off-by: Karl Haworth --- plugins/apollo-explorer/README.md | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/plugins/apollo-explorer/README.md b/plugins/apollo-explorer/README.md index 23ea71e934..71cb76c592 100644 --- a/plugins/apollo-explorer/README.md +++ b/plugins/apollo-explorer/README.md @@ -69,3 +69,41 @@ That's it! You should now see an `Apollo Explorer` item in your sidebar, and if Once you authenticate, your graph is ready to use ๐Ÿš€ ![Logged In](./docs/img/logged-in.png) + +### Authentication Tokens for Apollo Studio + +If you need to utilize an ApiRef to supply a token to Apollo, you may do so using an ApiHolder. + +In `packages/app/src/App.tsx` perform the following modifications from above. The import `ssoAuthApiRef` is used as an example + +```typescript +import { ApolloExplorerPage, EndpointProps } from '@backstage/plugin-apollo-explorer'; +import { ssoAuthApiRef } from '@backstage/devkit'; +import { ApiHolder } from '@backstage/core-plugin-api'; + + +async function apolloPluginEndpointsCallback(options: { apiHolder: ApiHolder }): Promise { + const sso = options.apiHolder.get(ssoAuthApiRef) + return [{ + title: 'Github', + graphRef: 'my-github-graph-ref@current', + initialState: { + headers: { + authorization: `Bearer ${await sso.getToken()}`, + }, + }, + }] +} + +const routes = ( + + {/* other routes... */} + + } + /> +``` From b90857e2ffc59fe823592d489fffad21c65db65e Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Tue, 5 Mar 2024 14:19:55 -0500 Subject: [PATCH 004/107] add exports to reduce duplication Signed-off-by: Karl Haworth --- .../apollo-explorer/src/components/ApolloExplorerPage/index.ts | 1 + plugins/apollo-explorer/src/index.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts b/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts index 8f62872fe6..0ecfb16ee5 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts @@ -14,3 +14,4 @@ * limitations under the License. */ export { ApolloExplorerPage } from './ApolloExplorerPage'; +export type { EndpointProps } from './components/ApolloExplorerPage'; diff --git a/plugins/apollo-explorer/src/index.ts b/plugins/apollo-explorer/src/index.ts index 565557e79f..6d0be1311f 100644 --- a/plugins/apollo-explorer/src/index.ts +++ b/plugins/apollo-explorer/src/index.ts @@ -20,3 +20,4 @@ * @packageDocumentation */ export { apolloExplorerPlugin, ApolloExplorerPage } from './plugin'; +export type { EndpointProps } from './ApolloExplorerPage'; From 7a408f720b5e4e29131b04eaa41f0d1dfe3a7a06 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Tue, 5 Mar 2024 14:24:09 -0500 Subject: [PATCH 005/107] update exports Signed-off-by: Karl Haworth --- .../src/components/ApolloExplorerPage/ApolloExplorerPage.tsx | 2 +- .../apollo-explorer/src/components/ApolloExplorerPage/index.ts | 2 +- plugins/apollo-explorer/src/index.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx index f6bda693b5..bb94c69063 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx @@ -23,7 +23,7 @@ import { useAsync } from 'react-use'; import { CircularProgress } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; -type EndpointProps = { +export type EndpointProps = { title: string; graphRef: string; persistExplorerState?: boolean; diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts b/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts index 0ecfb16ee5..1eef091978 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ export { ApolloExplorerPage } from './ApolloExplorerPage'; -export type { EndpointProps } from './components/ApolloExplorerPage'; +export type { EndpointProps } from './ApolloExplorerPage'; diff --git a/plugins/apollo-explorer/src/index.ts b/plugins/apollo-explorer/src/index.ts index 6d0be1311f..5911e246f0 100644 --- a/plugins/apollo-explorer/src/index.ts +++ b/plugins/apollo-explorer/src/index.ts @@ -20,4 +20,4 @@ * @packageDocumentation */ export { apolloExplorerPlugin, ApolloExplorerPage } from './plugin'; -export type { EndpointProps } from './ApolloExplorerPage'; +export type { EndpointProps } from './components/ApolloExplorerPage'; From 5fb1aa7fb1f5a439092673135389738336dfad4a Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Tue, 5 Mar 2024 15:19:50 -0500 Subject: [PATCH 006/107] update import for `useAsync` Signed-off-by: Karl Haworth --- .../src/components/ApolloExplorerPage/ApolloExplorerPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx index bb94c69063..a3ca428803 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx @@ -19,7 +19,7 @@ import { Content, Header, Page } from '@backstage/core-components'; import { ApolloExplorerBrowser } from '../ApolloExplorerBrowser'; import { JSONObject } from '@apollo/explorer/src/helpers/types'; import { ApiHolder, useApiHolder } from '@backstage/core-plugin-api'; -import { useAsync } from 'react-use'; +import useAsync from 'react-use/lib/useAsync'; import { CircularProgress } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; From 347b45a63c5c15999422a51f5cf88032496731aa Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Tue, 5 Mar 2024 15:31:15 -0500 Subject: [PATCH 007/107] update api report Signed-off-by: Karl Haworth --- plugins/apollo-explorer/api-report.md | 40 +++++++++++++++------------ 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/plugins/apollo-explorer/api-report.md b/plugins/apollo-explorer/api-report.md index 7d06876e89..978d90d062 100644 --- a/plugins/apollo-explorer/api-report.md +++ b/plugins/apollo-explorer/api-report.md @@ -5,6 +5,7 @@ ```ts /// +import { ApiHolder } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; import { JSONObject } from '@apollo/explorer/src/helpers/types'; import { JSX as JSX_2 } from 'react'; @@ -14,23 +15,9 @@ import { RouteRef } from '@backstage/core-plugin-api'; export const ApolloExplorerPage: (props: { title?: string | undefined; subtitle?: string | undefined; - endpoints: { - title: string; - graphRef: string; - persistExplorerState?: boolean | undefined; - initialState?: - | { - document?: string | undefined; - variables?: JSONObject | undefined; - headers?: Record | undefined; - displayOptions: { - docsPanelState?: 'closed' | 'open' | undefined; - showHeadersAndEnvVars?: boolean | undefined; - theme?: 'dark' | 'light' | undefined; - }; - } - | undefined; - }[]; + endpoints: + | EndpointProps[] + | ((options: { apiHolder: ApiHolder }) => Promise); }) => JSX_2.Element; // @public @@ -40,4 +27,23 @@ export const apolloExplorerPlugin: BackstagePlugin< }, {} >; + +// Warning: (ae-missing-release-tag) "EndpointProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type EndpointProps = { + title: string; + graphRef: string; + persistExplorerState?: boolean; + initialState?: { + document?: string; + variables?: JSONObject; + headers?: Record; + displayOptions: { + docsPanelState?: 'open' | 'closed'; + showHeadersAndEnvVars?: boolean; + theme?: 'dark' | 'light'; + }; + }; +}; ``` From 3d0d57228966a99c9806361d0b6b5126c74963cd Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Tue, 5 Mar 2024 15:45:28 -0500 Subject: [PATCH 008/107] add required release tag for exporting of type Signed-off-by: Karl Haworth --- plugins/apollo-explorer/api-report.md | 4 +--- .../src/components/ApolloExplorerPage/ApolloExplorerPage.tsx | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/apollo-explorer/api-report.md b/plugins/apollo-explorer/api-report.md index 978d90d062..b5bed224bc 100644 --- a/plugins/apollo-explorer/api-report.md +++ b/plugins/apollo-explorer/api-report.md @@ -28,9 +28,7 @@ export const apolloExplorerPlugin: BackstagePlugin< {} >; -// Warning: (ae-missing-release-tag) "EndpointProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type EndpointProps = { title: string; graphRef: string; diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx index a3ca428803..c0e4180909 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx @@ -23,6 +23,11 @@ import useAsync from 'react-use/lib/useAsync'; import { CircularProgress } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; +/** + * Exports types to be used with {@link @backstage/apollo-explorer#ApolloExplorerPage}. + * + * @public + */ export type EndpointProps = { title: string; graphRef: string; From 5410d196c82d5f3e34761b9e37a41535c30475fc Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Tue, 5 Mar 2024 15:46:08 -0500 Subject: [PATCH 009/107] fix typo Signed-off-by: Karl Haworth --- .../src/components/ApolloExplorerPage/ApolloExplorerPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx index c0e4180909..0a0ea0ccdc 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx @@ -24,7 +24,7 @@ import { CircularProgress } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; /** - * Exports types to be used with {@link @backstage/apollo-explorer#ApolloExplorerPage}. + * Export types to be used with {@link @backstage/apollo-explorer#ApolloExplorerPage}. * * @public */ From 86a6223c028b0e830d5834feb8bb98948a1db5f9 Mon Sep 17 00:00:00 2001 From: Anna Carolina <8171749+accezar@users.noreply.github.com> Date: Mon, 11 Mar 2024 13:24:20 -0300 Subject: [PATCH 010/107] docs(microsite): adding library check plugin to marketplace Signed-off-by: Anna Carolina <8171749+accezar@users.noreply.github.com> --- microsite/data/plugins/library-check.yaml | 10 ++++++++++ microsite/static/img/library-check-logo.png | Bin 0 -> 15306 bytes 2 files changed, 10 insertions(+) create mode 100644 microsite/data/plugins/library-check.yaml create mode 100644 microsite/static/img/library-check-logo.png diff --git a/microsite/data/plugins/library-check.yaml b/microsite/data/plugins/library-check.yaml new file mode 100644 index 0000000000..edd647cec1 --- /dev/null +++ b/microsite/data/plugins/library-check.yaml @@ -0,0 +1,10 @@ +--- +title: Library Check +author: anakrz +authorUrl: https://github.com/anakzr +category: Services +description: Check the status of project package or library based on main registries. +documentation: https://github.com/anakzr/backstage-plugin-library-check +iconUrl: /img/library-check-logo.png +npmPackageName: '@anakz/backstage-plugin-library-check' +addedDate: '2024-03-11' \ No newline at end of file diff --git a/microsite/static/img/library-check-logo.png b/microsite/static/img/library-check-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..299b1a01e842fd5e06c5e47454f5fc8e3b0ce237 GIT binary patch literal 15306 zcmd^m^;ebA*XIR6LRv&cLb|);(%sUX64K43QyQhaq(Qp7K|(q&NF&k`lG1bdzVED= z`4eX52NnzNx%)ZK?)dC*rT0>p=!EDH2n16`T3iJJLFjq>L46ATSG094xyD&zwJ?9M2ICR9{NQZ(L^Iw$f%7t5VFyKggu=_i0HPoeB*rSA$VW> zTQJK@wkv*o`;-K+Kt<;99#p2p;FmuYJ{bgZOc;R!fw*Hzph6&RA>>F9h=CX`A_P*I zgNgw0pHm8gK)S4HMIn$iuK(+gr-i{F5W$6vSFgzv8=HPei}Z^s2P;w1XLM3FB*2&< zf_SuvvhddsjD?mIDh{WDK6`U*wVUmCJn4z=27~Ge%KcVTdC&$g3#)UznzbXHYqe!G z1EyInwxUQ!(LWDOI@&;1gmDoqxl;@>8@N-E)oJKL;^LNtd_#y>c;-^M2gS(d`_7ox>=vZ=ncQc z^)J@qhSg_X6F`*E4;w=-#tp51$nx*$!WxMkaVf7$fT9;%cZA~bC7nwCZkyjV_R(f!*^ki-i)dl7*nEb+#;mxd^>F4OO< zqS}^qv;Q($`aS1i25eSZWbm^yg~@|aCW>%YHY$Qz6{S-@yffpZ$PhKb$qCEOs6m>o zVZ!;S<)30v)fi$n3(&HI`Rb4LW;(F`N+A~pcg97r!pYd|g{gMo{EUo)J7>|J3v+FA zgf%EWneZEKYRRAsEBS}b^a*-wxV9Qq+;f3s)8xg~wws`W52ckgV^6x&X+`}t%Je%N zEa{gs>N)C0KEsm6*kjQxZjsZ6l+Zm*x=-dwwYCw~2=U3fo+L?hod0la%`GkxP5WL} zYoVf)RPAjOJJ4wT_ZDYO5YX~te3o^;*j*8ae8vOLeW}r`co^J>|64q4Eb6f$qA_)e%293-THRKG`w6aQ>U4 zxz1E0m4~L=kIDGS?6i;SEZHx|_{`7QPyKxC#7EHJ9uO^{Pb^H)8TIEewk!KZo?NL_ zV?D@sQ}Q}r884S=>FsVf;o1-vV7_fN>`r4eLVR2Dt$*fh%7$Sg=Y12yTMBt4?QW8N zwqN_8&-^RE9bYz3Nup#}Nb{xqruh3~bJunv>ZHXopD4{NxrM>bo^_uQ(&A5!6v)GO zvS}@ZlyKg*I}#nhnr8g-ZMNokbK$?&UKJiZp0mv0c6G=Ss86jGMskb2%2izx-VI4e z5Ux-rD@tZ^RQi=oo^HIT)_qwGB#cQb%K9#RcvatHgwv}#cI8~d9qZd`a^A_~VFFCC zeQ#HZKA*7dP$MO!AR{G%Xz#xZv4<}NPL~{!zhQPDlW$h(h0geXTwcj|j_Z~NBY`Lg z<9=FMXrdC~_j7G>(KYrK)>%H+Uq!*krfpP3P3!xY25+zf-`mkEnqhKmWy^kgMiPN@ zHkFC@CDPk`e;kX~{wtal_s7g|dm>8FJ-6jL`no>z^OMAMjoPs%+06K4I|b^KpL=>q zT3?MrQI;-dc!#f*RXUF^HOg*cU<45L98{5`Hr&6z5`_@yKe6E@=ps6aM|?o8Kxynd z>iO7}t*I20%|jqAFL%#;yp>Hpg7TX&CvLD+IzJ=kAn8`*c3TW6-wrB1nZwG^eDF98 zL#HIZKSyA6L zSKN{2zM#V{kNeI`#N`(W&;*@8a-{d3G`F*>zL!is?5(9E**rfspB;%(Y))%egbK?3 zGv)*m#umjzH2YdlzQU3(;(~?@;Wj4PB#rZ~6gV54l@A z`9=seV4UhAo(ZCp^{F8Lt`hqnQ|b5=7|Ghx=f(c~vXKcao9=$K?7lbna1Vb&aF~O% z%-g<)&f_BKh@{ljJQKO;N9%<2Pny---)sR#xtGVcI4(#Ms5*^~X5UX=nx^hwUX~ws zIScQgHab!4WtwZ;)YTkKJ5w0HuNr$20xU_Vp3$k_e8BdZA#}F%M-Yr)LZ~~n|Kx9< zLF@C421S!hWQ>;)IGlC^3$wrel>E6{{kQrmeV@74TX?4~o5-Z^JL1t3$G@bC#^4|} zIB2En?Y{Ftd++{9H2hu77-C3Y`-t@Gv=8d<=D!~mxKU_qxYAi*fP==W-Yz@ATW2hn zSWTO=MiG^C6C~q!6r0D4i?<@w0W2foS{^|AC;Vtdcj^jo?GLYd>vyi?1XxLNT+9c} zrVH1(4AQ;JmMMx@qI#Tcv$^rfzL{AYf3a5&{C&V8pz`ts-%v0f1MjS3Fkb z*=qz7AGoW-z>LXz&6@>e4DDkBdE$M>Y{2q~ z52Tgh&do~ko@b%iC;loZy!-DU55M&2^26scrUOTBS9)&6c4+a*T%<)udg!FYQx~x? z%NjpsB4-QqGN*9y8?3@~ZT`R|fLdJUpynu`DSw80@29mK#~Ie*0`)A}iziD`pg+H% zWp|xMglqe^f`^ujT5E=lYZe*K&vo*n4(A34o&vw+%{a^rb6aZc2DEr`P}c?d;AIW` z`d+)g+P2PcbfGyk?LH?jhW$6vQ9@s@-UpY`W}Q z@7)_lEfD|GXvTGBzQkOy7!b7E@d0u0frq>M^~HH~rW92O!dtu50*Db27C3KfJf{C$ z$4GqEpfnc7#Lh}K4 z9URI9024#H>h+`rPUWqoWLl*{%IA;C07-2?vWAWO*HwH(U3uq4g=-ndz=I}4q1Fax z;<;uyWuUHiV@T!g+YF%C82C8>?liwSxr{(P^r9WDNVkS3 z^Ka=Xty8QCCoP1+l}nT`Ium{yIRWEK3*S!x(OHgnXshjimyHxcJANeRol+ROu6h zC=UncZnARByL6!0*15Nc#B#qL5ic8w7fCaSsL|xW%F$IFet)-eWy0RB6QuRxssD|Q zb+9R%GCNtdh2*^c#M4=0-l@!R=mV`N)*?736c9oNf={C|3+=g38s4cz)F_&L@DS?d*`oqj~@xo>+Qq7#{$KlAa?xhf1m!_ z-O*p7v2iPu#>nki2sqb9+U}xU$nSTJdxZWlQlUkF>0kMH$6p@XXB|lh8y}fI_wT4Y zRSLoommFKV4!ntMtbo~f*H}P=#l^*#Q@JB;|NNCSJ-Zett3AeyPzuG%-KxCmKe+Bu zBQ1`_c!3Hj-$}JDOG!9tbu+t#(}7dS5lT`95osA7ONLXJ`=1bnz1r*v=}zp zhx=0p8*s%(#k#B#;kG&gCl`Vw@r{fR-X9h%qcWCp5*uV{0!4yYgxd#5^K#A!!m40v z6RC2!j;(5d&6#yD^|GUamYG15Ps2~Dm}wz95$46QPNFS~1teP?wOit4??$1~f?~L? zqTXk1$6|#)*QIWFbU=0ux#c_ot}Tpu6?2_|=hszEnot|7wvol4f-&j_y_2~;BrB`kd5-@9g^Jm*>O}FhOhW3KE2VZUSMh%1 zAd`+tQiL{Mzu5qVB!1;69OF zD7j5<&+(k!&1hr3W;wDQX{l9$n4f3fuoj%HE>}`x_0U>24b$E;xinm$eZ>spDy_LX z3XzzSgZ#Ssl4;xw*Pg^EGk91j2pjkHUwFsey+mHEfSDGlq=cAF;LhhY))Q8kF|ou3 zdioHbi}jhjLK@c8&WiZ9QraeO01QJZ;Jd8I;?0%<>a#3gApZ(c+y-M+z4@Id`X@9? z4pL|(LyIGcD<`j{DyT02$0anxlv^nz!^523$hpLXLhIrDeWOj=%oIwM+r$fn55E8##TeWRq$x_AKq@RY@#YRaEYa-E(AOZ~cyL0h%^3 zTAT@Z7c%Eij?g}B_9uD!REOxFeH(llG=y9B#hL!(-d*)2XIXx4w9H4Lp@MrRvzY`Q z56NM6*cGhe9ty;*Q;WJzGjFq=udILA6Xy`ARq9GDZAMU_W&z~41Im@U?b_xOJb|{J zQ`i1KpYo~y64|z9SM$7!#KJ0LL$Y^yEyuFqkz??4u93*C>pp;-G8Y@KS5%e=|DWDB zi@FU6q0w?63?uW06|KtdIp)bndK;AkdX+4uoooI=wH@5>#82?=j2S~vl$UFvLbwGp z+lS@-9iQk^r(xv4Xn|Rnr{Sw4${k3WpkP<)8pfx+PmWvs&M3GuMljp$s(|e}d2O#0V zMc8+x<+^yCL#^l5uiluuA|8FN($P7mgySEiAixDIQuOT&1W{Uk>gB*4sYcZa-{+DV zw|0sE{?$Yw95n5%l3T^fT%Be=khvQMMMg;4!(X5Ey-kPctVCvw!yn4tRl*&2&#w|D zmA$Xw7;?iP{NJpaYP;?p#<022iKMM1>az2FIRF*?abv5RSb>IM_Sgm>G3rGI_xb1`_u#Xk|iUu$jn;P%{k>Ud7- zl5A)VtbKW-K;@D{T|2$qOx5>doj9j~?5t*y7QDciFeotYw@B)$2Z#s{Sp8x6WAF4c z3u8}Bx$u=E%S0%)*^xN-`!_tu9G*tt9PXJc6Q8z|#H@ZxEykvy)ZG1e$`qLaeDzgZ z5L3GUbEP1V0o4l7OcaTH)*e{P_!5GM`Slrv)X}Duv0}Kd{a@EU@--}cvI(Q~uV

CJYj3wJN*VMQ+{xBw86imN{}36PxQ0xG60>p*?K8=ORb*7mp2@sm$BXk1 zLR?=i6<-(g)l`WQO;)a#q+}%zR`IwzqQH9`eEWm2*kQFwa|PW!)l;f<0W zHmT$IPF&SAsiNfkU6lpuyGnlZqsi1Z? z?w{0@!NPTKVDBX;W>DDpGQEKyRrT}91+7Z3%GJ0K=0oaQySOL?UR+Fm1c8-CgOY2n z!gbk>CcN6;9MpQ}z}e{hxg!Vnua4@G8I2$)$6t3Jkh08}Hj2!eQ_3jsh$2VI9xYh;gS zjo6$ZzQVXCGre$};6+o}W)0T}oM(|-zVF3yBTF6pFV>2{DZPr(kHiQN7l_25s+$HU z!g9|6ykY$(*W z9iW^CxdmUdK;F_uJVxnQ442Msd&mNl2vS;6auxK$2O8n_w%BW(E6dxq26DN`tmhCY ziUjHeIzw!;Mxo-&a5|^&d&mya;{&bCFkNb!MK`u>`wyQ(G6K)PKuB^c)!pbV=v!}A z_2r4ecP>s`Kw?T+)6z=nOt6TD8>>b}kt6Kj=6FEeoB&d^a3o1J>O`Y(E(jLro7MHm zn!bN{W*|%bfS(pVkrG7Nrfce^5!USHQmpj0>1Nw)>)B9(6X2$Fj+zR%=g1d%m#aC5 zKNjfa@&~n7&x#3MRE7V=zQ4+RAV5blrDCTc2kIQoAO^we<`9Jti=iPpJo|rQER&&3 zQE5($;EoE$OBo+*O}n9p$2j24-ia~dS4TnkgZ`tk^rmGL5Nt4|@aND;pcS1E0Fx$% z5G8+7nQX5nGHeKR`kO^zy21;!8Sl@))P9@oiPoPy1sP(@C;S9u!$Bzde~8vmS5_ye z?4RyqpRA!O zqMAy5Zw0v&!A0!y!I!0KkM9T&WVseQ;Pn?f@KjcmWAR*YWJT6;kIQNf)!9y!R9wEh z{8Y#eHGl<=sTHXLGJs!Ya9#wGM=ss8#nyxfc3!m(4S1wMRkI~DJttvE0taWP&0z#!J!cPOu5%9ao3fj=WVULHTHby%1*d1>C{_Dj`|KC!X` z=hb`f$utBxdrkO*7eXxPmhZermIen#A`KjTK2^-UoM`AFeaz=tlmd5&vcUidf`dEx z&H1SKjDG?=FJ$37_c0m3z3{0|DYF$|!kj2YM1J)Oq)tI@YH~rH&5vO%zexzT?L_>i}y2}?P zOfzV1(6tM8idDLCIA*`p3snV?@;7C}tlc}VNT(e|@Ju?Lws_xG7=dQ!1Q;Gb6uIcr zET;-AuFv7ASnYxnJ)ezRIwj-vLo9iraARi3>A9a+%sfqd1; zy3`Mqa|rS=j5zU0RBaUHGyZgHV*0^UcDBY7s^<6=MzjX{st{~jmfKYB&7-3U>numl z1VJ=U#f@n)7c)>4656eX78bQB4wP0Hl_1}KjsY{ziSjQYq6^9{F|uh4i#`Xmq4%Ep zpWMQbBiV=V&nY{ly-S*R&s-Lv=Gj3H$UXl9GJm+~CyUm#{GTU}IaU>C{S3iM_iQ z%oYR@IQ}&3gy?k4+rzGxctkeS@q(B-@&+H7ThRKussr9wMC_x&+59OUN#Z7-O0>4} zG^M_q;IDj8sw#+%QmH1xd!;OYIfv2mCuigFkVEz#q&wezo7T#7P&e3DB;1Y&Sj3$w z0U}QxKd;K$Np`gl4_OGAU_VNBc^*cQ^sh}CRJ&ROkbZFB>7npXG^n0q_41q#LEFE> zttRhv@`gOa>v9#ZPH|QYAdM%N`n!K!dFJ(jjdB^=Zv&qh! zZV{bKT<%7G7jnpHA~xjVL}3@VB$2D`DsBCuy*M38SB!eHoxw`jpiyz>Oy4dKxZ)x5E5xJvs`v9xO0A>ceMl%F-E zIC*}Jm>6AdQ*3)aPSc8UWJ*85^C+=|MJ;(eZTe4AZo zH}gmoWNpv*=u}fj`wQu(Mli687@<+ygwj4xEq zMxWPSPzaqeXNIGAJ_RrDUopGcaOJ3|YTlkH+zDQRm{GA%u3p=Ucy)LvImx|qe#;t> zv84oNH=+1=Bee;&m8}7kpGZ5j;U9y|d_@hDiE@7Lsnti3TFrgtMjo-ggwqr%AAk0} zmwgNh6Kay@C;i-p(?2B&OLeU1DvJ|>C@E2@xnOLLe`ctfbYYu-&Gw<&t7xnJlY2CvGY59QgIcwl44Z<&Z6-#?@U|SW9Z_^jLPm z*_Y`&D`Gzu| zCLVkqdqsCZ3;hOX#uIORi8{Z?mqy);p}zkQJ~K$j>B_tYW{ds-xadf>zHQ2pa);X*&Orh?>V?S7}KDgtp2{B$jATc z_lnu?v|$^qMEBh)2sDb&vm($@nSp){+X;7mc9fof|9(LdWDwXxHneIt8HSfpk76kH z@wTSdvHB*elQ-#%=mxw}Nqh6h?9L1Yo5kBEX(RE1Df;@cJLNU+6Lx21FP7f6ewDPW zj?}5WQwy_;iuVdhoqUQD)LP{mi{$EcM(VFgx`){Lg99KTrR|w7*x#V_f&0o?}wzRi0+eBs#H-Cz6dOIzS0XM zYC?=MsX7!uiH|B>62tar7NCo=D-VO#UZU86)*hs3-(gciC$Uv(|A+z~HEd@!(AvdP zw_DNWIO)O;CGZ{;OC_FJ_?hJ-%VXXTMR$PMMS{`?MD3}X5ye4q zi?Z2Kdu?7#=S+|!S0)A{2@9=*n&f^{N1xf2`JM3Go|CrJg;UHVhP8EA98V#3k>>p|VAfk>p$1gQY2lF)M!? zi)gX1-6-@4B$-M^#lqnF<3fg?|K9J&vW;&xQj;Q{3}%@t$;}NZbbSX$ziigrg|zw; zzQ5vrIuTWO&7YQjPxgXGa{{qa1{51+#KmId>_P>f>r-7SwxIj88DDf8x~zJB>*NiZx3fW~o$QMY0g{ix`jSqRcpl`T+z ztcZPlPu;$tt9Kti`-mx(L|kW-8OXI_h>M5o!J}=CH;ZYS`9ye?Qby&mc)O8}o_<%< z4O*(wC!8?&&zod9sxz@Gnd`#ev`>4#<>+RrlYmCPKRG42kaKh}^9w4!WGJnc6vBku zV-GdxH~m4|)f>>!FF<=AJ^5-N0I-lMwo5wiNS!%xVzOj7fl;O)uraQ>v@PvB6XFSv z>tfgAL;}7e)N<&lqP#{w;4BKkeB=QlQ=3JM0_42zSi?Hj7W5^XBl}zmsWaoKie1W? zlL5D8M0I?tOI|9CI{U4gldMM^R}@w9W!}u!BQ;7Pa9W71bhJK@*zAf$8NYFQz8Ie# z{zN-sWN>vU@V~ll(uE1C@uIToOfWU7(gH$lfy~meY^Vo?e#xluzeZMhmJGM|dD~h= zpmnz{^l8**8>*f}mAtrdLF>A99TG1#soL7|btCCSb(LYE}0nNov%e`r0iey zwKORfRgd++XnU|0@L%$JcJ55wQ``}bJkIegc0>-|!(#eE{JCfI462@g6oe9>>r8wUBGX(x;N%7awT8ON?rthMFB_blz~M0T>J9_UxZTZGR3-zj2_?PQMHKxkD7! zbt-B${9@a>^6NjkZ2s)Q*Eg>b{V$fA-<)4tHV$_u2^e_uG16x`QnrVX&&1eTn|zm< zrAv;w)cdyJAwrvJ1^_p9pxfsUL6`XUxNd zq*rue9JaNc5qI!t7=fTL?w*q9%q^GDf;scM#o8ZQ0Z`y(&&KeFX$Wrq7~nR(kjvXe zjfe>t98As1tYY+D*XopHoO=oZy{>%#2+Ez=C_Q)NQ}Ty~keizN$j{HH{fzvkA2{41 z7y0)A;$I1DI?a2b!y!z2aJsfP$Os7d8MWiVUffqNLf2H7|27$(EaH`8N(w z7%17OywvfZ;{jV@P(&9`GbF=S{>pMZ zTi0OJ`1S#T6^VjHhx2{RIjI1TF|u9YBR*&2Yj~??Uf(iD?iLBf4WB24DzIR?YsSH9>k+@&))a!Ly{o)2a-s8YK>qlK;rfNPx%cZ!+qe6S6CVF^EZ;T^_;KwV#NAhZ5j59kvFnz# z1u(sfGPCn^v-a&=ButbFRLqIAlwc05aQ3-d-l~-la5XWuw-QV2%D)=P$v-}K4d-Ef zM6@wEnsr4kv|$RlF?qB1y#&0N*);f=@6EkT*WRgqG_fm}tN}pdX`$qt4giw#Sy84U zlXpuMH*Wa_I13%B{VvUW($bqKWrHZTYJeAs_V+1<#NhLNfW=1~vZ z5Zl+zV>PZ?&X?-L#)4h8N+e)xA`bvL1q0uCKlowUbe)R%qwqV9mASgt+K-&1C;(X@ zEQ{ctOhnbA{W>f8Lh5%(O9CtRdY1GJVdaz#pN__~^`6*t+GOdB3bzS!hy#q!7V%$l zU#mI8;qt9I(azl}Z2SBW#x}>1t6#!$56LT7x~XH(XH_8E(rNtF{u8Ba3Z8{(DgGLf zCG59&dyRr={Ln3YA$9Q}rJj*G6h>_XDp|L_{*kP^JXn8-v&d*a@DdioF~fxld4w%Y z5#cL!!7zfyvC)#buCZR%=5^gs=bEq5G9eawzuoMe)Pu8|oB5lNubP<90fP_i{H^5+5uZ z4FQmP$r=D*pNV6akxyk2?dzS8jL$8(=FRx(mGf)olB ze)Tn92cO%q$Nh@lU~;7L#aD0cy=xdZdINn*mRKKfpgqkh(mAg+62*`MIJTvzya%Az zuR#63Gg3HT<>*JN>UIbG!q-Q67Ri#Gk8+k0RvdfLFkS}=0CcQSHmXRGYneV%2icG1 z(^Bh|+LxZ3CRGGWo5?IHZ7KVYaJ>cq*MoF|<%DqJQj-JKlG;w_Oo96hS0@1l0C^Kv zrb`YLv1hXQ5Ouba?lX3Q#+s3ps^0IN-Uw?iER2fo0~L}qhXtJzt^=Hb$lH;+i5`^Mr)kC-zF@zlotG%^i zhjT{JTKj>gKYn`~gYbTVu+wYs%dNpW1#>FTPx!B4wX8@XYjuHgMt3?{oF;V5pe_#v z6M~UV!K*Xpq+69j0 z9Uq%VN(_WSJ~(zwX%`K60U-u<-hQg_J>l8Sb<$9WDsfc4*NcX~R*JurT(;ZG+$NF(ME43zcSDzVan{ShsOycO-*RoJcH%~R1Kd}1_pe2fKqlVamE+C7I%op@`KVy84O?ko zDB$JC(7wW>sJn(m-Jc@+VwGt!+S}_TB9?_U5-$TA>NP*TX{3yRC87y0I)F7Cd;(tQ zeaHPzb5q_0g()$Loc~IS&(LJ%M$xJl2_AQ0z&71lebIC38U1q`Ru-4_?E@9C*+8Aq z$l#^6CIt49f*$vhj1T~=Mlv?W-{RBfs}FnX8`Ram#%I?DPq)rPdwd%}Zto8^^16h2 zC|2$r&ByQYA&xI|(&2-`9Qsrtd%u7Rr#H^%&l43>@-EZ93KA zJgJR*p-9kl*Ua{T#x)#e=Pl?rM!*NePD+{ zwINUb^#Z(`paBb8?@?Evl3%A3hFpq!wjUZsU%$ODXyM!oJkr{NOlWFZ<7Yo#p(nlV zSsZB1zaofmxqoAp4ASQk)pm11vt>RUD%5O2J+RC-czZnOEAK@A+L>9}s_fu0&2@=x zUwPjkha*`$!Rn?Rg7J9yK!6%dcZy@@&iGpl8*-cd6XXqW(2|BVCBE`|js257e|y2k z9^CTe7UB&!GV#gQ+W617OvOW-iS~1EQ{lkimhD{?tNb%&Zo5MY$A4bVJumaPQgI=6 zU>nn7GOE7xd*j~F3PVg{dy0wjhOP|-7gKHG8}$X+Z`$4umtUpd0|fcoM)cU8qNV)F z_U^W_qN;tVqrNij0a`%_3)sSYH6QZ|cY-n5l}jbATA215H#>njvld?HwhsgYd<=Fy mS$z=yf7t~6- Date: Mon, 11 Mar 2024 13:56:07 -0300 Subject: [PATCH 011/107] docs(microsite): fixed dot and re-run prettier Signed-off-by: Anna Carolina <8171749+accezar@users.noreply.github.com> --- microsite/data/plugins/library-check.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/microsite/data/plugins/library-check.yaml b/microsite/data/plugins/library-check.yaml index edd647cec1..fdd2db1cd4 100644 --- a/microsite/data/plugins/library-check.yaml +++ b/microsite/data/plugins/library-check.yaml @@ -1,9 +1,9 @@ --- title: Library Check -author: anakrz +author: anakzr authorUrl: https://github.com/anakzr category: Services -description: Check the status of project package or library based on main registries. +description: Check the status of project package or library based on main registries documentation: https://github.com/anakzr/backstage-plugin-library-check iconUrl: /img/library-check-logo.png npmPackageName: '@anakz/backstage-plugin-library-check' From b0fcb2d8a3e3267ab395ed4f9fec84a3b40dbb22 Mon Sep 17 00:00:00 2001 From: Anna Carolina <8171749+accezar@users.noreply.github.com> Date: Mon, 11 Mar 2024 14:17:32 -0300 Subject: [PATCH 012/107] docs(microsite): fixed missed endline on plugin .yaml file declaration Signed-off-by: Anna Carolina <8171749+accezar@users.noreply.github.com> --- microsite/data/plugins/library-check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/data/plugins/library-check.yaml b/microsite/data/plugins/library-check.yaml index fdd2db1cd4..68489d676f 100644 --- a/microsite/data/plugins/library-check.yaml +++ b/microsite/data/plugins/library-check.yaml @@ -7,4 +7,4 @@ description: Check the status of project package or library based on main regist documentation: https://github.com/anakzr/backstage-plugin-library-check iconUrl: /img/library-check-logo.png npmPackageName: '@anakz/backstage-plugin-library-check' -addedDate: '2024-03-11' \ No newline at end of file +addedDate: '2024-03-11' From 1f622289218f917dde15dce7a23848102d3e2d59 Mon Sep 17 00:00:00 2001 From: Karl Haworth <58607256+karlhaworth@users.noreply.github.com> Date: Wed, 13 Mar 2024 06:35:38 -0400 Subject: [PATCH 013/107] Update plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx Co-authored-by: Vincenzo Scamporlino Signed-off-by: Karl Haworth <58607256+karlhaworth@users.noreply.github.com> --- .../src/components/ApolloExplorerPage/ApolloExplorerPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx index 0a0ea0ccdc..a3eb44362a 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx @@ -63,7 +63,7 @@ export const ApolloExplorerPage = (props: Props) => { return await endpoints({ apiHolder }); } return endpoints; - }, []); + }, [endpoints]); return ( From 24d302fce045e45a7cc20c43f146efe6e315371b Mon Sep 17 00:00:00 2001 From: Zach Hammer Date: Wed, 20 Mar 2024 12:55:33 -0400 Subject: [PATCH 014/107] Only hide EntityAutocompletePicker if there are no options Signed-off-by: Zach Hammer --- .../EntityAutocompletePicker.test.tsx | 50 +++++++++++++++++++ .../EntityAutocompletePicker.tsx | 4 +- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.test.tsx b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.test.tsx index 94af52f374..0516267041 100644 --- a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.test.tsx +++ b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.test.tsx @@ -88,6 +88,56 @@ describe('', () => { }); }); + it('hides filter if there are no available options', async () => { + const mockCatalogApiNoOptions: Partial> = { + getEntityFacets: jest.fn().mockResolvedValue({ + facets: { + 'spec.options': [], + }, + }), + }; + render( + + + + label="Options" + path="spec.options" + name="options" + Filter={EntityOptionFilter} + /> + + , + ); + await waitFor(() => { + expect(screen.queryByText('Options')).not.toBeInTheDocument(); + }); + }); + + it('renders filter if there is one available option', async () => { + const mockCatalogApiOneOption: Partial> = { + getEntityFacets: jest.fn().mockResolvedValue({ + facets: { + 'spec.options': [{ value: 'option1', count: 1 }], + }, + }), + }; + render( + + + + label="Options" + path="spec.options" + name="options" + Filter={EntityOptionFilter} + /> + + , + ); + await waitFor(() => { + expect(screen.queryByText('Options')).toBeInTheDocument(); + }); + }); + it('renders unique options in alphabetical order', async () => { render( diff --git a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx index 5e5bedaceb..a9b96f7e70 100644 --- a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx +++ b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx @@ -144,8 +144,8 @@ export function EntityAutocompletePicker< return null; } - // Hide if there are 1 or fewer options; nothing to pick from - if (availableOptions.length <= 1) return null; + // Hide if there are no options; nothing to pick from + if (availableOptions.length === 0) return null; return ( From ddf05c64932119575b434d523e0ac0364baa8dd6 Mon Sep 17 00:00:00 2001 From: Karl Haworth <58607256+karlhaworth@users.noreply.github.com> Date: Mon, 1 Apr 2024 07:20:27 -0400 Subject: [PATCH 015/107] add type Co-authored-by: Patrik Oldsberg Signed-off-by: Karl Haworth <58607256+karlhaworth@users.noreply.github.com> --- plugins/apollo-explorer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/apollo-explorer/README.md b/plugins/apollo-explorer/README.md index 71cb76c592..78c8920814 100644 --- a/plugins/apollo-explorer/README.md +++ b/plugins/apollo-explorer/README.md @@ -83,7 +83,7 @@ import { ApiHolder } from '@backstage/core-plugin-api'; async function apolloPluginEndpointsCallback(options: { apiHolder: ApiHolder }): Promise { - const sso = options.apiHolder.get(ssoAuthApiRef) + const sso = options.apiHolder.get(ssoAuthApiRef) return [{ title: 'Github', graphRef: 'my-github-graph-ref@current', From b863830aaa060c913b6424c1ff572a1b5dd0394b Mon Sep 17 00:00:00 2001 From: Zach Hammer Date: Wed, 20 Mar 2024 13:00:10 -0400 Subject: [PATCH 016/107] Add changeset Signed-off-by: Zach Hammer --- .changeset/moody-rice-jump.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/moody-rice-jump.md diff --git a/.changeset/moody-rice-jump.md b/.changeset/moody-rice-jump.md new file mode 100644 index 0000000000..00e71aa2af --- /dev/null +++ b/.changeset/moody-rice-jump.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Change behavior in EntityAutoCompletePicker to only hide filter if there are no available options. Previously the filter was hidden if there were <= 1 available options. From dd6b3f01c8ea4a7e849e433642dd520fa406d2cf Mon Sep 17 00:00:00 2001 From: Zach Hammer Date: Mon, 1 Apr 2024 17:01:08 -0400 Subject: [PATCH 017/107] remove redundant line Signed-off-by: Zach Hammer --- .../EntityAutocompletePicker/EntityAutocompletePicker.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx index a9b96f7e70..590a896a06 100644 --- a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx +++ b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx @@ -144,9 +144,6 @@ export function EntityAutocompletePicker< return null; } - // Hide if there are no options; nothing to pick from - if (availableOptions.length === 0) return null; - return ( From fecdba04d0f6b451bccdc217fc9e4896fd9378a8 Mon Sep 17 00:00:00 2001 From: Zach Hammer Date: Mon, 1 Apr 2024 17:09:50 -0400 Subject: [PATCH 018/107] refactor mock catalog api gen into function Signed-off-by: Zach Hammer --- .../EntityAutocompletePicker.test.tsx | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.test.tsx b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.test.tsx index 0516267041..26dee40ec3 100644 --- a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.test.tsx +++ b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.test.tsx @@ -30,7 +30,7 @@ interface EntityFilters extends DefaultEntityFilters { options?: EntityOptionFilter; } -const options = ['option1', 'option2', 'option3', 'option4']; +const defaultOptions = ['option1', 'option2', 'option3', 'option4']; class EntityOptionFilter implements EntityFilter { constructor(readonly values: string[]) {} @@ -46,20 +46,25 @@ class EntityOptionFilter implements EntityFilter { } } -describe('', () => { - const mockCatalogApi: Partial> = { +const makeMockCatalogApi = ( + opts: string[] = defaultOptions, +): Partial> => { + return { getEntityFacets: jest.fn().mockResolvedValue({ facets: { - 'spec.options': options.map((value, idx) => ({ value, count: idx })), + 'spec.options': opts.map((value, idx) => ({ value, count: idx })), }, }), }; +}; +describe('', () => { beforeEach(() => { jest.clearAllMocks(); }); it('renders all options', async () => { + const mockCatalogApi = makeMockCatalogApi(); render( @@ -83,21 +88,15 @@ describe('', () => { }); fireEvent.click(screen.getByTestId('options-picker-expand')); - options.forEach(option => { + defaultOptions.forEach(option => { expect(screen.getByText(option)).toBeInTheDocument(); }); }); it('hides filter if there are no available options', async () => { - const mockCatalogApiNoOptions: Partial> = { - getEntityFacets: jest.fn().mockResolvedValue({ - facets: { - 'spec.options': [], - }, - }), - }; + const mockCatalogApi = makeMockCatalogApi([]); render( - + label="Options" @@ -114,15 +113,9 @@ describe('', () => { }); it('renders filter if there is one available option', async () => { - const mockCatalogApiOneOption: Partial> = { - getEntityFacets: jest.fn().mockResolvedValue({ - facets: { - 'spec.options': [{ value: 'option1', count: 1 }], - }, - }), - }; + const mockCatalogApi = makeMockCatalogApi(['option1']); render( - + label="Options" @@ -139,6 +132,7 @@ describe('', () => { }); it('renders unique options in alphabetical order', async () => { + const mockCatalogApi = makeMockCatalogApi(); render( @@ -166,6 +160,7 @@ describe('', () => { }); it('renders options with counts', async () => { + const mockCatalogApi = makeMockCatalogApi(); render( @@ -194,6 +189,7 @@ describe('', () => { }); it('respects the query parameter filter value', async () => { + const mockCatalogApi = makeMockCatalogApi(); const updateFilters = jest.fn(); const queryParameters = { options: ['option3'] }; render( @@ -222,6 +218,7 @@ describe('', () => { }); it('adds options to filters', async () => { + const mockCatalogApi = makeMockCatalogApi(); const updateFilters = jest.fn(); render( @@ -251,6 +248,7 @@ describe('', () => { }); it('removes options from filters', async () => { + const mockCatalogApi = makeMockCatalogApi(); const updateFilters = jest.fn(); render( @@ -284,6 +282,7 @@ describe('', () => { }); it('responds to external queryParameters changes', async () => { + const mockCatalogApi = makeMockCatalogApi(); const updateFilters = jest.fn(); const rendered = render( @@ -330,6 +329,7 @@ describe('', () => { }); it('filters available values by kind as default', async () => { + const mockCatalogApi = makeMockCatalogApi(); render( ', () => { }); it('can be supplied with filters for available values', async () => { + const mockCatalogApi = makeMockCatalogApi(); render( Date: Thu, 14 Mar 2024 12:51:12 +0100 Subject: [PATCH 019/107] chore: use colors from theme for notification's severity Signed-off-by: Marek Libra --- .../src/service/router.ts | 4 +-- .../src/api/NotificationsClient.ts | 2 +- .../NotificationsTable/SeverityIcon.tsx | 26 ++++++++++++++++--- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/plugins/notifications-backend/src/service/router.ts b/plugins/notifications-backend/src/service/router.ts index f9e87335ed..a1b7bb3eaf 100644 --- a/plugins/notifications-backend/src/service/router.ts +++ b/plugins/notifications-backend/src/service/router.ts @@ -213,9 +213,9 @@ export async function createRouter( } opts.createdAfter = new Date(sinceEpoch); } - if (req.query.minimal_severity) { + if (req.query.minimumSeverity) { opts.minimumSeverity = normalizeSeverity( - req.query.minimal_severity.toString(), + req.query.minimumSeverity.toString(), ); } diff --git a/plugins/notifications/src/api/NotificationsClient.ts b/plugins/notifications/src/api/NotificationsClient.ts index c4fffded9e..10ad58bd92 100644 --- a/plugins/notifications/src/api/NotificationsClient.ts +++ b/plugins/notifications/src/api/NotificationsClient.ts @@ -68,7 +68,7 @@ export class NotificationsClient implements NotificationsApi { queryString.append('createdAfter', options.createdAfter.toISOString()); } if (options?.minimumSeverity !== undefined) { - queryString.append('minimal_severity', options.minimumSeverity); + queryString.append('minimumSeverity', options.minimumSeverity); } const urlSegment = `?${queryString}`; diff --git a/plugins/notifications/src/components/NotificationsTable/SeverityIcon.tsx b/plugins/notifications/src/components/NotificationsTable/SeverityIcon.tsx index 37680db3c2..062c2ae5b7 100644 --- a/plugins/notifications/src/components/NotificationsTable/SeverityIcon.tsx +++ b/plugins/notifications/src/components/NotificationsTable/SeverityIcon.tsx @@ -19,21 +19,39 @@ import NormalIcon from '@material-ui/icons/CheckOutlined'; import CriticalIcon from '@material-ui/icons/ErrorOutline'; import HighIcon from '@material-ui/icons/WarningOutlined'; import LowIcon from '@material-ui/icons/InfoOutlined'; +import { makeStyles } from '@material-ui/core/styles'; + +const useStyles = makeStyles(theme => ({ + critical: { + color: theme.palette.status.error, + }, + high: { + color: theme.palette.status.warning, + }, + normal: { + color: theme.palette.status.ok, + }, + low: { + color: theme.palette.status.running, + }, +})); export const SeverityIcon = ({ severity, }: { severity?: NotificationSeverity; }) => { + const classes = useStyles(); + switch (severity) { case 'critical': - return ; + return ; case 'high': - return ; + return ; case 'low': - return ; + return ; case 'normal': default: - return ; + return ; } }; From 939b4ecead509718473c057f28dd6b2ffbfeaf03 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 1 Apr 2024 12:19:30 +0200 Subject: [PATCH 020/107] .changesets: added changesets for notifications changes Signed-off-by: Patrik Oldsberg --- .changeset/clean-drinks-poke.md | 6 ++++++ .changeset/wet-plants-help.md | 5 +++++ 2 files changed, 11 insertions(+) create mode 100644 .changeset/clean-drinks-poke.md create mode 100644 .changeset/wet-plants-help.md diff --git a/.changeset/clean-drinks-poke.md b/.changeset/clean-drinks-poke.md new file mode 100644 index 0000000000..9c57c3ac56 --- /dev/null +++ b/.changeset/clean-drinks-poke.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-notifications-backend': minor +'@backstage/plugin-notifications': minor +--- + +Notifications-backend URL query parameter changed from `minimal_severity` to `minimumSeverity`. diff --git a/.changeset/wet-plants-help.md b/.changeset/wet-plants-help.md new file mode 100644 index 0000000000..c497c68421 --- /dev/null +++ b/.changeset/wet-plants-help.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications': patch +--- + +The severity icons now get their colors from the theme. From 7528e1f487552f213f391cede9329c431bf8f740 Mon Sep 17 00:00:00 2001 From: Joe Van Alstyne Date: Wed, 3 Apr 2024 16:32:34 +0900 Subject: [PATCH 021/107] enable custom config of `name` and `title` Signed-off-by: Joe Van Alstyne --- .../src/InternalOpenApiDocumentationProvider.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts b/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts index dd94000ad7..ff6e3d522c 100644 --- a/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts +++ b/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts @@ -229,13 +229,19 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider { const pluginsToMerge = this.config.getStringArray( 'catalog.providers.backstageOpenapi.plugins', ); + const name = this.config.getOptionalString( + 'catalog.providers.backstageOpenapi.name', + ); + const title = this.config.getOptionalString( + 'catalog.providers.backstageOpenapi.title', + ); logger.info(`Loading specs from from ${pluginsToMerge}.`); const documentationEntity: ApiEntity = { apiVersion: 'backstage.io/v1beta1', kind: 'API', metadata: { - name: 'INTERNAL_instance_openapi_doc', - title: 'Your Backstage Instance documentation', + name: name ?? 'INTERNAL_instance_openapi_doc', + title: title ?? 'Your Backstage Instance documentation', annotations: { [ANNOTATION_LOCATION]: 'internal-package:@backstage/plugin-catalog-backend-module-backstage-openapi', From 5a079cd70d6bfdb70d40687089498cfdb95214dc Mon Sep 17 00:00:00 2001 From: Joe Van Alstyne Date: Wed, 3 Apr 2024 16:33:16 +0900 Subject: [PATCH 022/107] add new config options to README.md Signed-off-by: Joe Van Alstyne --- .../catalog-backend-module-backstage-openapi/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/catalog-backend-module-backstage-openapi/README.md b/plugins/catalog-backend-module-backstage-openapi/README.md index a7f4727669..cd1c5f06c6 100644 --- a/plugins/catalog-backend-module-backstage-openapi/README.md +++ b/plugins/catalog-backend-module-backstage-openapi/README.md @@ -2,7 +2,7 @@ ## Summary -This module installs an entity provider that exports a single entity, your Backstage instance documentation, which merges as many backend plugins as you have defined in the config value `catalog.providers.openapi.plugins`. +This module installs an entity provider that exports a single entity, your Backstage instance documentation, which merges as many backend plugins as you have defined in the config value `catalog.providers.backstageOpenapi.plugins`. ## Notes @@ -10,7 +10,7 @@ This module installs an entity provider that exports a single entity, your Backs ## Installation -To your new backend file, add +To your new backend file, add: ```ts title="packages/backend/src/index.ts" backend.add( @@ -18,12 +18,14 @@ backend.add( ); ``` -Add a list of plugins to your config like, +Add a list of plugins (and optionally, a custom name/title) to your config like: ```yaml title="app-config.yaml" catalog: providers: - openapi: + backstageOpenapi: + name: 'internal_backstage_api' # Optional + title: 'Backstage API' # Optional plugins: - catalog - todo From 2e2167a8c589e1014cbd1f17096c7d80224e5d56 Mon Sep 17 00:00:00 2001 From: Joe Van Alstyne Date: Wed, 3 Apr 2024 16:43:44 +0900 Subject: [PATCH 023/107] changesets: minor bump Signed-off-by: Joe Van Alstyne --- .changeset/shaggy-books-mate.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/shaggy-books-mate.md diff --git a/.changeset/shaggy-books-mate.md b/.changeset/shaggy-books-mate.md new file mode 100644 index 0000000000..db1ca0bb09 --- /dev/null +++ b/.changeset/shaggy-books-mate.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-backstage-openapi': minor +--- + +The name and title of the returned openapi doc entity are now configurable From 89d9e2ee6c741e6a116dfaa4c9a37af25fc39d8d Mon Sep 17 00:00:00 2001 From: Joe Van Alstyne Date: Thu, 4 Apr 2024 16:23:48 +0900 Subject: [PATCH 024/107] feat: expand config options Signed-off-by: Joe Van Alstyne --- .../InternalOpenApiDocumentationProvider.ts | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts b/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts index ff6e3d522c..d55cb05a6d 100644 --- a/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts +++ b/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts @@ -229,19 +229,22 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider { const pluginsToMerge = this.config.getStringArray( 'catalog.providers.backstageOpenapi.plugins', ); - const name = this.config.getOptionalString( - 'catalog.providers.backstageOpenapi.name', - ); - const title = this.config.getOptionalString( - 'catalog.providers.backstageOpenapi.title', - ); - logger.info(`Loading specs from from ${pluginsToMerge}.`); + + const getOverride = (key: string, fallbackValue: string = '') => { + return ( + this.config.getOptionalString( + `catalog.providers.backstageOpenapi.entityOverrides.${key}`, + ) ?? fallbackValue + ); + }; + + logger.info(`Loading specs from ${pluginsToMerge}.`); const documentationEntity: ApiEntity = { apiVersion: 'backstage.io/v1beta1', kind: 'API', metadata: { - name: name ?? 'INTERNAL_instance_openapi_doc', - title: title ?? 'Your Backstage Instance documentation', + name: getOverride('metadata.name', 'backstage_openapi_doc'), + title: getOverride('metadata.title', 'Backstage API Documentation'), annotations: { [ANNOTATION_LOCATION]: 'internal-package:@backstage/plugin-catalog-backend-module-backstage-openapi', @@ -250,9 +253,9 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider { }, }, spec: { - type: 'openapi', - lifecycle: 'production', - owner: 'backstage', + type: getOverride('spec.type', 'openapi'), + lifecycle: getOverride('spec.lifecycle', 'production'), + owner: getOverride('spec.owner', 'backstage'), definition: JSON.stringify( await loadSpecs({ baseUrl: this.config.getString('backend.baseUrl'), From 2e22245e4528e5575544d6d73482f57a3c6f327c Mon Sep 17 00:00:00 2001 From: Joe Van Alstyne Date: Thu, 4 Apr 2024 16:24:37 +0900 Subject: [PATCH 025/107] chore: add config options to Config type Signed-off-by: Joe Van Alstyne --- .../config.d.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/plugins/catalog-backend-module-backstage-openapi/config.d.ts b/plugins/catalog-backend-module-backstage-openapi/config.d.ts index ce51640495..b7f197ca48 100644 --- a/plugins/catalog-backend-module-backstage-openapi/config.d.ts +++ b/plugins/catalog-backend-module-backstage-openapi/config.d.ts @@ -25,6 +25,20 @@ export interface Config { * A list of plugins, whose OpenAPI specs you want to collate in `InternalOpenApiDocumentationProvider`. */ plugins: string[]; + /** + * Options to ovveride the provided entity's default metadata and spec properties + */ + entityOverrides?: { + metadata?: { + name?: string; + title?: string; + }; + spec?: { + type?: string; + lifecycle?: string; + owner?: string; + }; + }; }; }; }; From 431dc50cd44f1f31764fb583513d624047338e24 Mon Sep 17 00:00:00 2001 From: Joe Van Alstyne Date: Thu, 4 Apr 2024 16:25:16 +0900 Subject: [PATCH 026/107] docs: add config options to example Signed-off-by: Joe Van Alstyne --- .../catalog-backend-module-backstage-openapi/README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/catalog-backend-module-backstage-openapi/README.md b/plugins/catalog-backend-module-backstage-openapi/README.md index cd1c5f06c6..8df5b5d6c9 100644 --- a/plugins/catalog-backend-module-backstage-openapi/README.md +++ b/plugins/catalog-backend-module-backstage-openapi/README.md @@ -18,18 +18,22 @@ backend.add( ); ``` -Add a list of plugins (and optionally, a custom name/title) to your config like: +Add a list of plugins and optional entity overrides to your config. For example: ```yaml title="app-config.yaml" catalog: providers: backstageOpenapi: - name: 'internal_backstage_api' # Optional - title: 'Backstage API' # Optional plugins: - catalog - todo - search + entityOverrides: # All optional + metadata: + name: 'my name' + title: 'my title' + spec: + owner: 'my team' ``` We will attempt to load each plugin's OpenAPI spec hosted at `${pluginRoute}/openapi.json`. These are automatically added if you are using `@backstage/backend-openapi-utils`'s `createValidatedOpenApiRouter`. From dee8dbf5060b3aaf8bf22ecd5e65ad932943cc8e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 08:02:09 +0000 Subject: [PATCH 027/107] fix(deps): update material-ui monorepo Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 170 +++++++++++++++++++++++++++--------------------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/yarn.lock b/yarn.lock index d96b24dbbe..85cbdfbdb3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3192,12 +3192,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.13.10, @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.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.8, @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.8 - resolution: "@babel/runtime@npm:7.23.8" +"@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.13.10, @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.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @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.24.4 + resolution: "@babel/runtime@npm:7.24.4" dependencies: regenerator-runtime: ^0.14.0 - checksum: 0bd5543c26811153822a9f382fd39886f66825ff2a397a19008011376533747cd05c33a91f6248c0b8b0edf0448d7c167ebfba34786088f1b7eb11c65be7dfc3 + checksum: 2f27d4c0ffac7ae7999ac0385e1106f2a06992a8bdcbf3da06adcac7413863cd08c198c2e4e970041bbea849e17f02e1df18875539b6afba76c781b6b59a07c3 languageName: node linkType: hard @@ -11333,38 +11333,38 @@ __metadata: languageName: node linkType: hard -"@floating-ui/core@npm:^1.5.3": - version: 1.5.3 - resolution: "@floating-ui/core@npm:1.5.3" +"@floating-ui/core@npm:^1.0.0": + version: 1.6.0 + resolution: "@floating-ui/core@npm:1.6.0" dependencies: - "@floating-ui/utils": ^0.2.0 - checksum: 72af8563e1742791acee82e86f82a0fbca7445809988d31eea3fd5771909463aa7655a6cb001cc244f8fe3a9de600420257e4dfb887ca33e2a31ac47b52e39a2 + "@floating-ui/utils": ^0.2.1 + checksum: 2e25c53b0c124c5c9577972f8ae21d081f2f7895e6695836a53074463e8c65b47722744d6d2b5a993164936da006a268bcfe87fe68fd24dc235b1cb86bed3127 languageName: node linkType: hard -"@floating-ui/dom@npm:^1.5.4": - version: 1.5.4 - resolution: "@floating-ui/dom@npm:1.5.4" +"@floating-ui/dom@npm:^1.6.1": + version: 1.6.3 + resolution: "@floating-ui/dom@npm:1.6.3" dependencies: - "@floating-ui/core": ^1.5.3 + "@floating-ui/core": ^1.0.0 "@floating-ui/utils": ^0.2.0 - checksum: 5e6f05532ff4e6daf9f2d91534184d8f942ddb8fd260c2543a49bdf0c0ff69fd0867937ce1d023126008724ac238f8fc89b5e48f82cdf9f8355a1d04edd085bd + checksum: 81cbb18ece3afc37992f436e469e7fabab2e433248e46fff4302d12493a175b0c64310f8a971e6e1eda7218df28ace6b70237b0f3c22fe12a21bba05b5579555 languageName: node linkType: hard -"@floating-ui/react-dom@npm:^2.0.0, @floating-ui/react-dom@npm:^2.0.5": - version: 2.0.6 - resolution: "@floating-ui/react-dom@npm:2.0.6" +"@floating-ui/react-dom@npm:^2.0.0, @floating-ui/react-dom@npm:^2.0.8": + version: 2.0.8 + resolution: "@floating-ui/react-dom@npm:2.0.8" dependencies: - "@floating-ui/dom": ^1.5.4 + "@floating-ui/dom": ^1.6.1 peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 3608537be6cae5f0442d3f826379b8e4a9ce5c4bdecf1d2b34e6709842d80444be1a00eca3641d680e2e6405d833092f58005d1b120a9d39ffd341c60b0c017c + checksum: 5da7f13a69281e38859a3203a608fe9de1d850b332b355c10c0c2427c7b7209a0374c10f6295b6577c1a70237af8b678340bd4cc0a4b1c66436a94755d81e526 languageName: node linkType: hard -"@floating-ui/utils@npm:^0.2.0": +"@floating-ui/utils@npm:^0.2.0, @floating-ui/utils@npm:^0.2.1": version: 0.2.1 resolution: "@floating-ui/utils@npm:0.2.1" checksum: 9ed4380653c7c217cd6f66ae51f20fdce433730dbc77f95b5abfb5a808f5fdb029c6ae249b4e0490a816f2453aa6e586d9a873cd157fdba4690f65628efc6e06 @@ -13147,14 +13147,14 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.32": - version: 5.0.0-beta.32 - resolution: "@mui/base@npm:5.0.0-beta.32" +"@mui/base@npm:5.0.0-beta.40": + version: 5.0.0-beta.40 + resolution: "@mui/base@npm:5.0.0-beta.40" dependencies: - "@babel/runtime": ^7.23.8 - "@floating-ui/react-dom": ^2.0.5 - "@mui/types": ^7.2.13 - "@mui/utils": ^5.15.5 + "@babel/runtime": ^7.23.9 + "@floating-ui/react-dom": ^2.0.8 + "@mui/types": ^7.2.14 + "@mui/utils": ^5.15.14 "@popperjs/core": ^2.11.8 clsx: ^2.1.0 prop-types: ^15.8.1 @@ -13165,30 +13165,30 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 5f27be8914c072ffcbe6720de9aa6129180e68927657e8bcbc03a6f322d1ee6c6740a199d72ed0b490a7b29b79cc0c59d1e05a427089b17f4cbc9cc756e67506 + checksum: 9c084ee67de372411a71af5eca9a5367db9f5bce57bb43973629c522760fe64fa2a43d2934dccd24d6dcbcd0ed399c5fc5c461226c86104f5767de1c9b8deba2 languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/core-downloads-tracker@npm:5.15.5" - checksum: 4c9b1281ebe8d17d402e22f7f50c347c0b3918b1ed17af721f4de5ce282d90bc6d90fe9730595998b2bbb2f7ebe57fc55d4c858f31754fccdb606af472a59dc8 +"@mui/core-downloads-tracker@npm:^5.15.15": + version: 5.15.15 + resolution: "@mui/core-downloads-tracker@npm:5.15.15" + checksum: 3e99a04e03f66d5fa5f0c23cdce0f9fa2331ba08c99a75dc2347ccaa1c6ed520153e04aaeb0d613c9dca099a3e6242558a6284c33d93f95cc65e3243b17860bc languageName: node linkType: hard "@mui/material@npm:^5.12.2": - version: 5.15.5 - resolution: "@mui/material@npm:5.15.5" + version: 5.15.15 + resolution: "@mui/material@npm:5.15.15" dependencies: - "@babel/runtime": ^7.23.8 - "@mui/base": 5.0.0-beta.32 - "@mui/core-downloads-tracker": ^5.15.5 - "@mui/system": ^5.15.5 - "@mui/types": ^7.2.13 - "@mui/utils": ^5.15.5 + "@babel/runtime": ^7.23.9 + "@mui/base": 5.0.0-beta.40 + "@mui/core-downloads-tracker": ^5.15.15 + "@mui/system": ^5.15.15 + "@mui/types": ^7.2.14 + "@mui/utils": ^5.15.14 "@types/react-transition-group": ^4.4.10 clsx: ^2.1.0 - csstype: ^3.1.2 + csstype: ^3.1.3 prop-types: ^15.8.1 react-is: ^18.2.0 react-transition-group: ^4.4.5 @@ -13205,16 +13205,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: dbfcb31810c674d9ab3b9145752433de3917d9c0d1b491bdff84c44b8f1124e8fe8ab04fa09b974b497983b7bd3011b86fb441ad365f979f971d3ddb46712060 + checksum: ee0dc22fc4d617f7cf69f2451b6d5139978e6c5319e3056e7719159aff786ee3b80abd07691e230371811d9b5b574aef4559d7855bfe2f8493d596d960a91ab7 languageName: node linkType: hard -"@mui/private-theming@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/private-theming@npm:5.15.5" +"@mui/private-theming@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/private-theming@npm:5.15.14" dependencies: - "@babel/runtime": ^7.23.8 - "@mui/utils": ^5.15.5 + "@babel/runtime": ^7.23.9 + "@mui/utils": ^5.15.14 prop-types: ^15.8.1 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -13222,17 +13222,17 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 3a5f7f190aa69a0ad69a34f77e54ee2fdcb088d21a61d4720b76d098d178e1c3f6a470fc5e7a30d351db10efbc062cb11af75b8789e2f38eaa2ca612bcb0f851 + checksum: 1b1ef54e8281c9b13fcc58f4c39682efc610946a68402283c19fcfbce8a7d7a231d61b536d6df9bf7a59a1426591bd403a453a59eb8efb9689437fb58554dc8c languageName: node linkType: hard -"@mui/styled-engine@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/styled-engine@npm:5.15.5" +"@mui/styled-engine@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/styled-engine@npm:5.15.14" dependencies: - "@babel/runtime": ^7.23.8 + "@babel/runtime": ^7.23.9 "@emotion/cache": ^11.11.0 - csstype: ^3.1.2 + csstype: ^3.1.3 prop-types: ^15.8.1 peerDependencies: "@emotion/react": ^11.4.1 @@ -13243,21 +13243,21 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: 42bb7f50ed33ec88f799bd90a00337689837ee0b2d603681fe69c9a14850e5ae1d037505365ce78cd564307cc2c0654c46cece8d9250adb21c77b1de316e3c45 + checksum: 23b45c859a4f0d2b10933d06a6082c0ff093f7b6d8d32a2bfe3a6e515fe46d7a38ca9e7150d45c025a2e98d963bae9a5991d131cf4748b62670075ef0fa321ed languageName: node linkType: hard "@mui/styles@npm:^5.14.18": - version: 5.15.5 - resolution: "@mui/styles@npm:5.15.5" + version: 5.15.15 + resolution: "@mui/styles@npm:5.15.15" dependencies: - "@babel/runtime": ^7.23.8 + "@babel/runtime": ^7.23.9 "@emotion/hash": ^0.9.1 - "@mui/private-theming": ^5.15.5 - "@mui/types": ^7.2.13 - "@mui/utils": ^5.15.5 + "@mui/private-theming": ^5.15.14 + "@mui/types": ^7.2.14 + "@mui/utils": ^5.15.14 clsx: ^2.1.0 - csstype: ^3.1.2 + csstype: ^3.1.3 hoist-non-react-statics: ^3.3.2 jss: ^10.10.0 jss-plugin-camel-case: ^10.10.0 @@ -13274,21 +13274,21 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: dc131c0e7763f7ac4fd96a1db3dd85abf59de5429a73f7cf9ed15d423fb9bb5883835c1951d36e8804da9ab2ed13d603ed349f12e7cd15885f8279d90d13511b + checksum: 5e436a8a22ae9a2e6fcb63ead3a6eff2092cc9731fce0b22d04ab9c67639a173a0e27fb617628e7720592862118a32248be458bedfabaf1de5448543a97b0307 languageName: node linkType: hard -"@mui/system@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/system@npm:5.15.5" +"@mui/system@npm:^5.15.15": + version: 5.15.15 + resolution: "@mui/system@npm:5.15.15" dependencies: - "@babel/runtime": ^7.23.8 - "@mui/private-theming": ^5.15.5 - "@mui/styled-engine": ^5.15.5 - "@mui/types": ^7.2.13 - "@mui/utils": ^5.15.5 + "@babel/runtime": ^7.23.9 + "@mui/private-theming": ^5.15.14 + "@mui/styled-engine": ^5.15.14 + "@mui/types": ^7.2.14 + "@mui/utils": ^5.15.14 clsx: ^2.1.0 - csstype: ^3.1.2 + csstype: ^3.1.3 prop-types: ^15.8.1 peerDependencies: "@emotion/react": ^11.5.0 @@ -13302,27 +13302,27 @@ __metadata: optional: true "@types/react": optional: true - checksum: 3f736f120d65fa14588cd7554a9ef63c9d4480716807d7ee5543b9f25d936b5ac0396a51a565c53b2905114fed5f94880c896f091e8d269260bfc53e8a8e2fb5 + checksum: 9ca96d5f66b2a9d6471909cc98c671eea5ec0a6d58a7ec071073b9e5200b95c3f017f0ca5cc946abc7f83074bd11830ca18f5e30bc98e25cd6ca217bd1b3a26f languageName: node linkType: hard -"@mui/types@npm:^7.2.13": - version: 7.2.13 - resolution: "@mui/types@npm:7.2.13" +"@mui/types@npm:^7.2.14": + version: 7.2.14 + resolution: "@mui/types@npm:7.2.14" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 58dfc96f9654288519ff01d6b54e6a242f05cadad51210deb85710a81be4fa1501a116c8968e2614b16c748fc1f407dc23beeeeae70fa37fceb6c6de876ff70d + checksum: 615c9f9110933157f5d3c4fee69d6e70b98fc0d9ebc3b63079b6a1e23e6b389748687a25ab4ac15b56166fc228885da87c3929503b41fa322cfdee0f6d411206 languageName: node linkType: hard -"@mui/utils@npm:^5.14.15, @mui/utils@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/utils@npm:5.15.5" +"@mui/utils@npm:^5.14.15, @mui/utils@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/utils@npm:5.15.14" dependencies: - "@babel/runtime": ^7.23.8 + "@babel/runtime": ^7.23.9 "@types/prop-types": ^15.7.11 prop-types: ^15.8.1 react-is: ^18.2.0 @@ -13332,7 +13332,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: fe71ce69e23cb4c00886138da1422e4baa66959cd10f97b2aa00f7324a038b13084ea4a0da123774c0018f48ddb6ce4f3cb20a915ec3c5c1ff5495bf337f665f + checksum: 36543ba7e3b65fb3219ed27e8f1455aff15b47a74c9b642c63e60774e22baa6492a196079e72bcfa5a570421dab32160398f892110bd444428bcf8b266b11893 languageName: node linkType: hard @@ -24780,10 +24780,10 @@ __metadata: languageName: node linkType: hard -"csstype@npm:^3.0.2, csstype@npm:^3.1.2": - version: 3.0.9 - resolution: "csstype@npm:3.0.9" - checksum: 199f9af7e673f9f188525c3102a329d637ff46c52f6385a4427ff5cb17adcb736189150170a7af7c5701d18d7704bdad130273f4aa7e44c6c4f9967e6115dc93 +"csstype@npm:^3.0.2, csstype@npm:^3.1.2, csstype@npm:^3.1.3": + version: 3.1.3 + resolution: "csstype@npm:3.1.3" + checksum: 8db785cc92d259102725b3c694ec0c823f5619a84741b5c7991b8ad135dfaa66093038a1cc63e03361a6cd28d122be48f2106ae72334e067dd619a51f49eddf7 languageName: node linkType: hard From 84c4560c4fa9862a9560bbc7c9431875086b8d84 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Thu, 4 Apr 2024 10:23:32 -0400 Subject: [PATCH 028/107] use authcallback method instead Signed-off-by: Karl Haworth --- .../ApolloExplorerBrowser.tsx | 45 ++++++++++++++++++- .../ApolloExplorerPage/ApolloExplorerPage.tsx | 27 +++++------ 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx index 57f9eb7f8a..9f09ba9967 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx @@ -19,6 +19,8 @@ import { Divider, makeStyles, Tab, Tabs } from '@material-ui/core'; import { JSONObject } from '@apollo/explorer/src/helpers/types'; import { ApolloExplorer } from '@apollo/explorer/react'; import { Content } from '@backstage/core-components'; +import { ApiHolder } from '@backstage/core-plugin-api'; +import { HandleRequest } from '@apollo/explorer/src/helpers/postMessageRelayHelpers'; const useStyles = makeStyles(theme => ({ tabs: { @@ -53,9 +55,42 @@ export type ApolloEndpointProps = { type Props = { endpoints: ApolloEndpointProps[]; + authCallback?: () => Promise; + apiHolder?: ApiHolder; }; -export const ApolloExplorerBrowser = ({ endpoints }: Props) => { +export const handleAuthRequest = ({ + legacyIncludeCookies, + authCallback, +}: { + legacyIncludeCookies?: boolean; + authCallback: any; +}): HandleRequest => { + let cookies = {}; + if (legacyIncludeCookies) { + cookies = { credentials: 'include' }; + } else if (legacyIncludeCookies !== undefined) { + cookies = { credentials: 'omit' }; + } else { + cookies = {}; + } + + const handleRequestWithCookiePref: HandleRequest = async ( + endpointUrl, + options, + ) => + fetch(endpointUrl, { + ...options, + headers: { + ...options.headers, + Authorization: `Bearer ${await authCallback({})}`, + }, + ...cookies, + }); + return handleRequestWithCookiePref; +}; + +export const ApolloExplorerBrowser = ({ endpoints, authCallback }: Props) => { const classes = useStyles(); const [tabIndex, setTabIndex] = useState(0); @@ -76,6 +111,14 @@ export const ApolloExplorerBrowser = ({ endpoints }: Props) => { diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx index 0a0ea0ccdc..250b304fac 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx @@ -19,9 +19,6 @@ import { Content, Header, Page } from '@backstage/core-components'; import { ApolloExplorerBrowser } from '../ApolloExplorerBrowser'; import { JSONObject } from '@apollo/explorer/src/helpers/types'; import { ApiHolder, useApiHolder } from '@backstage/core-plugin-api'; -import useAsync from 'react-use/lib/useAsync'; -import { CircularProgress } from '@material-ui/core'; -import { Alert } from '@material-ui/lab'; /** * Export types to be used with {@link @backstage/apollo-explorer#ApolloExplorerPage}. @@ -44,34 +41,30 @@ export type EndpointProps = { }; }; -type EndpointPropsCallback = (options: { +export type authCallback = (options: { apiHolder: ApiHolder; -}) => Promise; +}) => Promise; type Props = { title?: string | undefined; subtitle?: string | undefined; - endpoints: EndpointProps[] | EndpointPropsCallback; + endpoints: EndpointProps[]; + authCallback: authCallback; }; export const ApolloExplorerPage = (props: Props) => { - const { title, subtitle, endpoints } = props; - const apiHolder = useApiHolder(); + const { title, subtitle, endpoints, authCallback } = props; - const { value, loading, error } = useAsync(async () => { - if (typeof endpoints === 'function') { - return await endpoints({ apiHolder }); - } - return endpoints; - }, []); + const apiHolder = useApiHolder(); return (
- {loading && } - {error && {error?.message}} - {value && } + authCallback({ apiHolder })} + /> ); From a03eb38ae8ea2413a57c31d0affa164eaa94be28 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Thu, 4 Apr 2024 11:31:04 -0400 Subject: [PATCH 029/107] update readme for authCallback Signed-off-by: Karl Haworth --- plugins/apollo-explorer/README.md | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/plugins/apollo-explorer/README.md b/plugins/apollo-explorer/README.md index 78c8920814..258675f82d 100644 --- a/plugins/apollo-explorer/README.md +++ b/plugins/apollo-explorer/README.md @@ -74,25 +74,16 @@ Once you authenticate, your graph is ready to use ๐Ÿš€ If you need to utilize an ApiRef to supply a token to Apollo, you may do so using an ApiHolder. -In `packages/app/src/App.tsx` perform the following modifications from above. The import `ssoAuthApiRef` is used as an example +In `packages/app/src/App.tsx` perform the following modifications from above. The import `ssoAuthApiRef` is used as an example and does not exist. ```typescript import { ApolloExplorerPage, EndpointProps } from '@backstage/plugin-apollo-explorer'; import { ssoAuthApiRef } from '@backstage/devkit'; import { ApiHolder } from '@backstage/core-plugin-api'; - -async function apolloPluginEndpointsCallback(options: { apiHolder: ApiHolder }): Promise { - const sso = options.apiHolder.get(ssoAuthApiRef) - return [{ - title: 'Github', - graphRef: 'my-github-graph-ref@current', - initialState: { - headers: { - authorization: `Bearer ${await sso.getToken()}`, - }, - }, - }] +async function authCallback(options: { apiHolder: ApiHolder }): Promise { + const sso = options.apiHolder.get(ssoAuthApiRef) + return await sso.getToken() } const routes = ( @@ -102,8 +93,12 @@ const routes = ( path="/apollo-explorer" element={ } + authCallback={authCallback} /> ``` From 7a4074d3adc0b76567b36803b611ee57f676c877 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Thu, 4 Apr 2024 11:39:18 -0400 Subject: [PATCH 030/107] add exports Signed-off-by: Karl Haworth --- .../ApolloExplorerPage/ApolloExplorerPage.tsx | 13 ++++++++++--- .../src/components/ApolloExplorerPage/index.ts | 2 +- plugins/apollo-explorer/src/index.ts | 5 ++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx index 250b304fac..fbbced24d1 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx @@ -41,7 +41,12 @@ export type EndpointProps = { }; }; -export type authCallback = (options: { +/** + * Export types to be used with {@link @backstage/apollo-explorer#ApolloExplorerPage}. + * + * @public + */ +export type AuthCallback = (options: { apiHolder: ApiHolder; }) => Promise; @@ -49,7 +54,7 @@ type Props = { title?: string | undefined; subtitle?: string | undefined; endpoints: EndpointProps[]; - authCallback: authCallback; + authCallback?: AuthCallback; }; export const ApolloExplorerPage = (props: Props) => { @@ -63,7 +68,9 @@ export const ApolloExplorerPage = (props: Props) => { authCallback({ apiHolder })} + authCallback={ + authCallback ? () => authCallback({ apiHolder }) : undefined + } /> diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts b/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts index 1eef091978..3ca6d12fd0 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ export { ApolloExplorerPage } from './ApolloExplorerPage'; -export type { EndpointProps } from './ApolloExplorerPage'; +export type { EndpointProps, AuthCallback } from './ApolloExplorerPage'; diff --git a/plugins/apollo-explorer/src/index.ts b/plugins/apollo-explorer/src/index.ts index 5911e246f0..471ec9e710 100644 --- a/plugins/apollo-explorer/src/index.ts +++ b/plugins/apollo-explorer/src/index.ts @@ -20,4 +20,7 @@ * @packageDocumentation */ export { apolloExplorerPlugin, ApolloExplorerPage } from './plugin'; -export type { EndpointProps } from './components/ApolloExplorerPage'; +export type { + EndpointProps, + AuthCallback, +} from './components/ApolloExplorerPage'; From 5cafdc8206ff43c6a2bad53b596b7588ad6eadb2 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Thu, 4 Apr 2024 11:39:31 -0400 Subject: [PATCH 031/107] update api report Signed-off-by: Karl Haworth --- plugins/apollo-explorer/api-report.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/apollo-explorer/api-report.md b/plugins/apollo-explorer/api-report.md index b5bed224bc..df84f0e7d3 100644 --- a/plugins/apollo-explorer/api-report.md +++ b/plugins/apollo-explorer/api-report.md @@ -15,9 +15,8 @@ import { RouteRef } from '@backstage/core-plugin-api'; export const ApolloExplorerPage: (props: { title?: string | undefined; subtitle?: string | undefined; - endpoints: - | EndpointProps[] - | ((options: { apiHolder: ApiHolder }) => Promise); + endpoints: EndpointProps[]; + authCallback?: AuthCallback | undefined; }) => JSX_2.Element; // @public @@ -25,9 +24,15 @@ export const apolloExplorerPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; +// @public +export type AuthCallback = (options: { + apiHolder: ApiHolder; +}) => Promise; + // @public export type EndpointProps = { title: string; From 7da377383f7fe30ca5b89f782d348c1b9199d203 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Thu, 4 Apr 2024 12:10:48 -0400 Subject: [PATCH 032/107] update api-report Signed-off-by: Karl Haworth --- plugins/apollo-explorer/api-report.md | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/apollo-explorer/api-report.md b/plugins/apollo-explorer/api-report.md index df84f0e7d3..bbd220ab49 100644 --- a/plugins/apollo-explorer/api-report.md +++ b/plugins/apollo-explorer/api-report.md @@ -24,7 +24,6 @@ export const apolloExplorerPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; From e31bacc553e2ed49a0aadcd6eab512bf6f5f6be1 Mon Sep 17 00:00:00 2001 From: secustor Date: Thu, 4 Apr 2024 19:15:57 +0200 Subject: [PATCH 033/107] feat(packages/backend-common): allows providing authentification in parameters Signed-off-by: secustor --- .changeset/tame-pianos-hunt.md | 5 +++++ .../src/util/ContainerRunner.ts | 16 ++++++++++++++ .../src/util/DockerContainerRunner.test.ts | 22 +++++++++++++++++++ .../src/util/DockerContainerRunner.ts | 19 ++++++++++------ 4 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 .changeset/tame-pianos-hunt.md diff --git a/.changeset/tame-pianos-hunt.md b/.changeset/tame-pianos-hunt.md new file mode 100644 index 0000000000..b19f69a8b9 --- /dev/null +++ b/.changeset/tame-pianos-hunt.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': minor +--- + +Allow to provide authentification which in turn allows usage of private registries diff --git a/packages/backend-common/src/util/ContainerRunner.ts b/packages/backend-common/src/util/ContainerRunner.ts index 7dc12919b3..11d75bcd8d 100644 --- a/packages/backend-common/src/util/ContainerRunner.ts +++ b/packages/backend-common/src/util/ContainerRunner.ts @@ -16,6 +16,21 @@ import { Writable } from 'stream'; +/** + * Allows defining access credentials for a registry + * Follows dockerode auth configuration: + * {@link https://github.com/apocas/dockerode?tab=readme-ov-file#pull-from-private-repos} + * + * @public + */ +export interface DockerAuthentication { + username?: string; + password?: string; + auth?: string; + email?: string; + serveraddress?: string; +} + /** * Options passed to the {@link ContainerRunner.runContainer} method. * @@ -31,6 +46,7 @@ export type RunContainerOptions = { envVars?: Record; pullImage?: boolean; defaultUser?: boolean; + authentication?: DockerAuthentication; }; /** diff --git a/packages/backend-common/src/util/DockerContainerRunner.test.ts b/packages/backend-common/src/util/DockerContainerRunner.test.ts index 737bf3d178..dde4e48113 100644 --- a/packages/backend-common/src/util/DockerContainerRunner.test.ts +++ b/packages/backend-common/src/util/DockerContainerRunner.test.ts @@ -83,6 +83,28 @@ describe('DockerContainerRunner', () => { expect(mockDocker.run).toHaveBeenCalled(); }); + it('should pull the docker container with authentication', async () => { + await containerTaskApi.runContainer({ + imageName, + args, + authentication: { + auth: 'aaaaaaaaa', + }, + }); + + expect(mockDocker.pull).toHaveBeenCalledWith( + imageName, + { + authconfig: { + auth: 'aaaaaaaaa', + }, + }, + expect.any(Function), + ); + + expect(mockDocker.run).toHaveBeenCalled(); + }); + it('should not pull the docker container when pullImage is false', async () => { await containerTaskApi.runContainer({ imageName, diff --git a/packages/backend-common/src/util/DockerContainerRunner.ts b/packages/backend-common/src/util/DockerContainerRunner.ts index 986470eb98..675b618cab 100644 --- a/packages/backend-common/src/util/DockerContainerRunner.ts +++ b/packages/backend-common/src/util/DockerContainerRunner.ts @@ -47,6 +47,7 @@ export class DockerContainerRunner implements ContainerRunner { envVars = {}, pullImage = true, defaultUser = false, + authentication, } = options; // Show a better error message when Docker is unavailable. @@ -61,13 +62,17 @@ export class DockerContainerRunner implements ContainerRunner { if (pullImage) { await new Promise((resolve, reject) => { - this.dockerClient.pull(imageName, {}, (err, stream) => { - if (err) return reject(err); - stream.pipe(logStream, { end: false }); - stream.on('end', () => resolve()); - stream.on('error', (error: Error) => reject(error)); - return undefined; - }); + this.dockerClient.pull( + imageName, + { authconfig: authentication }, + (err, stream) => { + if (err) return reject(err); + stream.pipe(logStream, { end: false }); + stream.on('end', () => resolve()); + stream.on('error', (error: Error) => reject(error)); + return undefined; + }, + ); }); } From 5fad80cf78cfeccba52c5135956231d5f62c582b Mon Sep 17 00:00:00 2001 From: secustor Date: Thu, 4 Apr 2024 19:26:30 +0200 Subject: [PATCH 034/107] docs(packages/backend-common): changeset grammar Signed-off-by: secustor --- .changeset/tame-pianos-hunt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/tame-pianos-hunt.md b/.changeset/tame-pianos-hunt.md index b19f69a8b9..3ab3e88623 100644 --- a/.changeset/tame-pianos-hunt.md +++ b/.changeset/tame-pianos-hunt.md @@ -2,4 +2,4 @@ '@backstage/backend-common': minor --- -Allow to provide authentification which in turn allows usage of private registries +Allow providing authentication which in turn allows usage of private registries From a0f55a1217073f43c13a744d803ca11113bdbd42 Mon Sep 17 00:00:00 2001 From: secustor Date: Thu, 4 Apr 2024 19:37:46 +0200 Subject: [PATCH 035/107] docs(packages/backend-common): fix api report Signed-off-by: secustor --- packages/backend-common/api-report.md | 15 +++++++++++++++ packages/backend-common/src/util/index.ts | 6 +++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index 55cb3b34dc..be9d3f5658 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -305,6 +305,20 @@ export type DatabaseManagerOptions = { logger?: LoggerService; }; +// @public +export interface DockerAuthentication { + // (undocumented) + auth?: string; + // (undocumented) + email?: string; + // (undocumented) + password?: string; + // (undocumented) + serveraddress?: string; + // (undocumented) + username?: string; +} + // @public export class DockerContainerRunner implements ContainerRunner { constructor(options: { dockerClient: Docker }); @@ -740,6 +754,7 @@ export type RunContainerOptions = { envVars?: Record; pullImage?: boolean; defaultUser?: boolean; + authentication?: DockerAuthentication; }; export { SearchOptions }; diff --git a/packages/backend-common/src/util/index.ts b/packages/backend-common/src/util/index.ts index 3e7b762519..5767653253 100644 --- a/packages/backend-common/src/util/index.ts +++ b/packages/backend-common/src/util/index.ts @@ -14,7 +14,11 @@ * limitations under the License. */ -export type { ContainerRunner, RunContainerOptions } from './ContainerRunner'; +export type { + ContainerRunner, + RunContainerOptions, + DockerAuthentication, +} from './ContainerRunner'; export { DockerContainerRunner } from './DockerContainerRunner'; export type { KubernetesContainerRunnerOptions, From 5b02d00f2e149adbbb303c124faa19e0dc992c46 Mon Sep 17 00:00:00 2001 From: secustor Date: Thu, 4 Apr 2024 21:54:45 +0200 Subject: [PATCH 036/107] refactor(packages/backend-common): allow supplying generic options to pull images Signed-off-by: secustor --- packages/backend-common/api-report.md | 31 ++++++++++--------- .../src/util/ContainerRunner.ts | 18 ++++++----- .../src/util/DockerContainerRunner.test.ts | 6 ++-- .../src/util/DockerContainerRunner.ts | 20 +++++------- packages/backend-common/src/util/index.ts | 2 +- 5 files changed, 40 insertions(+), 37 deletions(-) diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index be9d3f5658..888bc1639c 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -305,20 +305,6 @@ export type DatabaseManagerOptions = { logger?: LoggerService; }; -// @public -export interface DockerAuthentication { - // (undocumented) - auth?: string; - // (undocumented) - email?: string; - // (undocumented) - password?: string; - // (undocumented) - serveraddress?: string; - // (undocumented) - username?: string; -} - // @public export class DockerContainerRunner implements ContainerRunner { constructor(options: { dockerClient: Docker }); @@ -656,6 +642,21 @@ export { PluginDatabaseManager }; export { PluginEndpointDiscovery }; +// @public +export interface PullOptions { + // (undocumented) + [key: string]: unknown; + // (undocumented) + authconfig?: { + username?: string; + password?: string; + auth?: string; + email?: string; + serveraddress?: string; + [key: string]: unknown; + }; +} + // @public export type ReaderFactory = (options: { config: Config; @@ -754,7 +755,7 @@ export type RunContainerOptions = { envVars?: Record; pullImage?: boolean; defaultUser?: boolean; - authentication?: DockerAuthentication; + pullOptions?: PullOptions; }; export { SearchOptions }; diff --git a/packages/backend-common/src/util/ContainerRunner.ts b/packages/backend-common/src/util/ContainerRunner.ts index 11d75bcd8d..351a5da613 100644 --- a/packages/backend-common/src/util/ContainerRunner.ts +++ b/packages/backend-common/src/util/ContainerRunner.ts @@ -23,12 +23,16 @@ import { Writable } from 'stream'; * * @public */ -export interface DockerAuthentication { - username?: string; - password?: string; - auth?: string; - email?: string; - serveraddress?: string; +export interface PullOptions { + authconfig?: { + username?: string; + password?: string; + auth?: string; + email?: string; + serveraddress?: string; + [key: string]: unknown; + }; + [key: string]: unknown; } /** @@ -46,7 +50,7 @@ export type RunContainerOptions = { envVars?: Record; pullImage?: boolean; defaultUser?: boolean; - authentication?: DockerAuthentication; + pullOptions?: PullOptions; }; /** diff --git a/packages/backend-common/src/util/DockerContainerRunner.test.ts b/packages/backend-common/src/util/DockerContainerRunner.test.ts index dde4e48113..f5d0e18480 100644 --- a/packages/backend-common/src/util/DockerContainerRunner.test.ts +++ b/packages/backend-common/src/util/DockerContainerRunner.test.ts @@ -87,8 +87,10 @@ describe('DockerContainerRunner', () => { await containerTaskApi.runContainer({ imageName, args, - authentication: { - auth: 'aaaaaaaaa', + pullOptions: { + authconfig: { + auth: 'aaaaaaaaa', + }, }, }); diff --git a/packages/backend-common/src/util/DockerContainerRunner.ts b/packages/backend-common/src/util/DockerContainerRunner.ts index 675b618cab..89a17fff51 100644 --- a/packages/backend-common/src/util/DockerContainerRunner.ts +++ b/packages/backend-common/src/util/DockerContainerRunner.ts @@ -47,7 +47,7 @@ export class DockerContainerRunner implements ContainerRunner { envVars = {}, pullImage = true, defaultUser = false, - authentication, + pullOptions = {}, } = options; // Show a better error message when Docker is unavailable. @@ -62,17 +62,13 @@ export class DockerContainerRunner implements ContainerRunner { if (pullImage) { await new Promise((resolve, reject) => { - this.dockerClient.pull( - imageName, - { authconfig: authentication }, - (err, stream) => { - if (err) return reject(err); - stream.pipe(logStream, { end: false }); - stream.on('end', () => resolve()); - stream.on('error', (error: Error) => reject(error)); - return undefined; - }, - ); + this.dockerClient.pull(imageName, pullOptions, (err, stream) => { + if (err) return reject(err); + stream.pipe(logStream, { end: false }); + stream.on('end', () => resolve()); + stream.on('error', (error: Error) => reject(error)); + return undefined; + }); }); } diff --git a/packages/backend-common/src/util/index.ts b/packages/backend-common/src/util/index.ts index 5767653253..39bade08be 100644 --- a/packages/backend-common/src/util/index.ts +++ b/packages/backend-common/src/util/index.ts @@ -17,7 +17,7 @@ export type { ContainerRunner, RunContainerOptions, - DockerAuthentication, + PullOptions, } from './ContainerRunner'; export { DockerContainerRunner } from './DockerContainerRunner'; export type { From af8e0e63315da46021d287d28cce62ee0ad2bbb2 Mon Sep 17 00:00:00 2001 From: Joe Van Alstyne Date: Fri, 5 Apr 2024 15:12:30 +0900 Subject: [PATCH 037/107] Update plugins/catalog-backend-module-backstage-openapi/config.d.ts Co-authored-by: Aramis Sennyey <159921952+aramissennyeydd@users.noreply.github.com> Signed-off-by: Joe Van Alstyne --- .../config.d.ts | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/plugins/catalog-backend-module-backstage-openapi/config.d.ts b/plugins/catalog-backend-module-backstage-openapi/config.d.ts index b7f197ca48..e403010951 100644 --- a/plugins/catalog-backend-module-backstage-openapi/config.d.ts +++ b/plugins/catalog-backend-module-backstage-openapi/config.d.ts @@ -28,17 +28,10 @@ export interface Config { /** * Options to ovveride the provided entity's default metadata and spec properties */ - entityOverrides?: { - metadata?: { - name?: string; - title?: string; - }; - spec?: { - type?: string; - lifecycle?: string; - owner?: string; - }; - }; + /** + * Properties to override on the final entity object. + */ + entityOverrides?: object; }; }; }; From b422f1e5b03e5e6f463f38baa0bd7807dba1ab49 Mon Sep 17 00:00:00 2001 From: ishikawa-pro Date: Fri, 5 Apr 2024 19:18:57 +0900 Subject: [PATCH 038/107] feat: change link column on cloudbuild plugin Signed-off-by: ishikawa-pro --- .../WorkflowRunsTable/WorkflowRunsTable.tsx | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx index 5dc9005126..15dc31b730 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx @@ -48,11 +48,18 @@ const generatedColumns: TableColumn[] = [ field: 'id', type: 'numeric', width: '150px', - render: (row: Partial) => ( - - {row.id?.substring(0, 8)} - - ), + render: (row: Partial) => { + const LinkWrapper = () => { + const routeLink = useRouteRef(buildRouteRef); + return ( + + {row.id?.substring(0, 8)} + + ); + }; + + return ; + }, }, { title: 'Trigger Name', @@ -67,18 +74,11 @@ const generatedColumns: TableColumn[] = [ field: 'source', highlight: true, width: '200px', - render: (row: Partial) => { - const LinkWrapper = () => { - const routeLink = useRouteRef(buildRouteRef); - return ( - - {row.message} - - ); - }; - - return ; - }, + render: (row: Partial) => ( + + {row.message} + + ), }, { title: 'Ref', From 4be63350464338f69cb152fbf994a87b71a4e3fe Mon Sep 17 00:00:00 2001 From: ishikawa-pro Date: Fri, 5 Apr 2024 19:19:12 +0900 Subject: [PATCH 039/107] add: changesets for cloudbuild plugin Signed-off-by: ishikawa-pro --- .changeset/lovely-flowers-promise.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/lovely-flowers-promise.md diff --git a/.changeset/lovely-flowers-promise.md b/.changeset/lovely-flowers-promise.md new file mode 100644 index 0000000000..71c34bb8b6 --- /dev/null +++ b/.changeset/lovely-flowers-promise.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cloudbuild': minor +--- + +Changed the column that serves as a hyperlink from SOURCE to BUILD. From d6b80d823763cea345071d8830f56f9c19fa672f Mon Sep 17 00:00:00 2001 From: Karl Haworth <58607256+karlhaworth@users.noreply.github.com> Date: Fri, 5 Apr 2024 10:06:39 -0400 Subject: [PATCH 040/107] Update plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx Co-authored-by: Patrik Oldsberg Signed-off-by: Karl Haworth <58607256+karlhaworth@users.noreply.github.com> --- .../components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx index c72c64df15..4947e3639f 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx @@ -67,7 +67,7 @@ export const handleAuthRequest = ({ authCallback, }: { legacyIncludeCookies?: boolean; - authCallback: any; + authCallback: Props['authCallback']; }): HandleRequest => { let cookies = {}; if (legacyIncludeCookies) { From 147b15bd6dafd6f9d28b8acc34557536d32f5900 Mon Sep 17 00:00:00 2001 From: Karl Haworth <58607256+karlhaworth@users.noreply.github.com> Date: Fri, 5 Apr 2024 10:07:27 -0400 Subject: [PATCH 041/107] Update plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx Co-authored-by: Patrik Oldsberg Signed-off-by: Karl Haworth <58607256+karlhaworth@users.noreply.github.com> --- .../components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx index 4947e3639f..f5b0014974 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx @@ -59,7 +59,6 @@ export type ApolloEndpointProps = { type Props = { endpoints: ApolloEndpointProps[]; authCallback?: () => Promise; - apiHolder?: ApiHolder; }; export const handleAuthRequest = ({ From bd13a562fa4fefddc3fe17a0445f1feefefc2c74 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Fri, 5 Apr 2024 10:08:12 -0400 Subject: [PATCH 042/107] remove unused Signed-off-by: Karl Haworth --- .../components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx index f5b0014974..6238885a29 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx @@ -22,7 +22,6 @@ import { makeStyles } from '@material-ui/core/styles'; import { JSONObject } from '@apollo/explorer/src/helpers/types'; import { ApolloExplorer } from '@apollo/explorer/react'; import { Content } from '@backstage/core-components'; -import { ApiHolder } from '@backstage/core-plugin-api'; import { HandleRequest } from '@apollo/explorer/src/helpers/postMessageRelayHelpers'; const useStyles = makeStyles(theme => ({ From 04164bdfeffafcdf41f59ef97233e1b9a4c0cc92 Mon Sep 17 00:00:00 2001 From: Karl Haworth <58607256+karlhaworth@users.noreply.github.com> Date: Fri, 5 Apr 2024 10:10:25 -0400 Subject: [PATCH 043/107] Update plugins/apollo-explorer/api-report.md Co-authored-by: Patrik Oldsberg Signed-off-by: Karl Haworth <58607256+karlhaworth@users.noreply.github.com> --- plugins/apollo-explorer/api-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/apollo-explorer/api-report.md b/plugins/apollo-explorer/api-report.md index bbd220ab49..5f010946c4 100644 --- a/plugins/apollo-explorer/api-report.md +++ b/plugins/apollo-explorer/api-report.md @@ -30,7 +30,7 @@ export const apolloExplorerPlugin: BackstagePlugin< // @public export type AuthCallback = (options: { apiHolder: ApiHolder; -}) => Promise; +}) => Promise<{ token: string }>; // @public export type EndpointProps = { From 6ecacd3ffec0a25663803337363ad59d0d189906 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Fri, 5 Apr 2024 10:14:13 -0400 Subject: [PATCH 044/107] =?UTF-8?q?This'll=20need=20an=20update=20for=20th?= =?UTF-8?q?e=20return=20type=20tweak,=20but=20you=20can=20also=20skip=20pa?= =?UTF-8?q?ssing=20{}=20here,=20mainly=20just=20confusing=20to=20the=20rea?= =?UTF-8?q?der=20=F0=9F=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Karl Haworth --- .../components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx index 6238885a29..7cb6957aae 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx @@ -84,7 +84,7 @@ export const handleAuthRequest = ({ ...options, headers: { ...options.headers, - Authorization: `Bearer ${await authCallback({})}`, + Authorization: `Bearer ${await authCallback()}`, }, ...cookies, }); From a1e39ffd2a711b6eb3129c497b2e2b11f059e429 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Fri, 5 Apr 2024 10:38:42 -0400 Subject: [PATCH 045/107] update for the return type tweak Signed-off-by: Karl Haworth --- .../ApolloExplorerBrowser.tsx | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx index 7cb6957aae..680e3964ca 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx @@ -84,7 +84,9 @@ export const handleAuthRequest = ({ ...options, headers: { ...options.headers, - Authorization: `Bearer ${await authCallback()}`, + ...(authCallback && { + Authorization: `Bearer ${await authCallback()}`, + }), }, ...cookies, }); @@ -112,14 +114,10 @@ export const ApolloExplorerBrowser = ({ endpoints, authCallback }: Props) => { From c3bcd080801f9947d889b79c91698a7840c52b65 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Fri, 5 Apr 2024 10:39:46 -0400 Subject: [PATCH 046/107] remove cookies Signed-off-by: Karl Haworth --- .../ApolloExplorerBrowser.tsx | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx index 680e3964ca..e50b4847a2 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx @@ -61,25 +61,11 @@ type Props = { }; export const handleAuthRequest = ({ - legacyIncludeCookies, authCallback, }: { - legacyIncludeCookies?: boolean; authCallback: Props['authCallback']; }): HandleRequest => { - let cookies = {}; - if (legacyIncludeCookies) { - cookies = { credentials: 'include' }; - } else if (legacyIncludeCookies !== undefined) { - cookies = { credentials: 'omit' }; - } else { - cookies = {}; - } - - const handleRequestWithCookiePref: HandleRequest = async ( - endpointUrl, - options, - ) => + const handleRequest: HandleRequest = async (endpointUrl, options) => fetch(endpointUrl, { ...options, headers: { @@ -88,9 +74,8 @@ export const handleAuthRequest = ({ Authorization: `Bearer ${await authCallback()}`, }), }, - ...cookies, }); - return handleRequestWithCookiePref; + return handleRequest; }; export const ApolloExplorerBrowser = ({ endpoints, authCallback }: Props) => { @@ -115,7 +100,6 @@ export const ApolloExplorerBrowser = ({ endpoints, authCallback }: Props) => { className={classes.explorer} graphRef={endpoints[tabIndex].graphRef} handleRequest={handleAuthRequest({ - legacyIncludeCookies: false, authCallback: authCallback, })} persistExplorerState={endpoints[tabIndex].persistExplorerState} From 63adc945239824c3b9a54c14cb3943162755ad26 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Fri, 5 Apr 2024 12:02:07 -0400 Subject: [PATCH 047/107] update api-report Signed-off-by: Karl Haworth --- plugins/apollo-explorer/api-report.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/apollo-explorer/api-report.md b/plugins/apollo-explorer/api-report.md index 5f010946c4..a009c99aca 100644 --- a/plugins/apollo-explorer/api-report.md +++ b/plugins/apollo-explorer/api-report.md @@ -28,9 +28,9 @@ export const apolloExplorerPlugin: BackstagePlugin< >; // @public -export type AuthCallback = (options: { - apiHolder: ApiHolder; -}) => Promise<{ token: string }>; +export type AuthCallback = (options: { apiHolder: ApiHolder }) => Promise<{ + token: string; +}>; // @public export type EndpointProps = { From 970fb4955caab4fd7fd9fd88e0f218e768a8ed17 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Fri, 5 Apr 2024 12:02:33 -0400 Subject: [PATCH 048/107] update types and use of authcallback Signed-off-by: Karl Haworth --- .../ApolloExplorerBrowser/ApolloExplorerBrowser.tsx | 4 ++-- .../src/components/ApolloExplorerPage/ApolloExplorerPage.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx index e50b4847a2..d0c90708a1 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx @@ -57,7 +57,7 @@ export type ApolloEndpointProps = { type Props = { endpoints: ApolloEndpointProps[]; - authCallback?: () => Promise; + authCallback?: () => Promise<{ token: string }>; }; export const handleAuthRequest = ({ @@ -71,7 +71,7 @@ export const handleAuthRequest = ({ headers: { ...options.headers, ...(authCallback && { - Authorization: `Bearer ${await authCallback()}`, + Authorization: `Bearer ${(await authCallback()).token}`, }), }, }); diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx index fbbced24d1..b9d25a1a06 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx @@ -48,7 +48,7 @@ export type EndpointProps = { */ export type AuthCallback = (options: { apiHolder: ApiHolder; -}) => Promise; +}) => Promise<{ token: string }>; type Props = { title?: string | undefined; From 3f422fbd66bc0262d9df60c7f8c5a6ca5fa182c0 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Fri, 5 Apr 2024 14:33:44 -0400 Subject: [PATCH 049/107] add `authCallback` to `EndpointProps` Signed-off-by: Karl Haworth --- .../ApolloExplorerBrowser.tsx | 33 ++++++++----------- .../ApolloExplorerPage/ApolloExplorerPage.tsx | 15 +++------ 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx index d0c90708a1..d276774003 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx @@ -19,10 +19,11 @@ import Divider from '@material-ui/core/Divider'; import Tab from '@material-ui/core/Tab'; import Tabs from '@material-ui/core/Tabs'; import { makeStyles } from '@material-ui/core/styles'; -import { JSONObject } from '@apollo/explorer/src/helpers/types'; import { ApolloExplorer } from '@apollo/explorer/react'; import { Content } from '@backstage/core-components'; import { HandleRequest } from '@apollo/explorer/src/helpers/postMessageRelayHelpers'; +import { EndpointProps } from '../ApolloExplorerPage'; +import { useApiHolder } from '@backstage/core-plugin-api'; const useStyles = makeStyles(theme => ({ tabs: { @@ -39,24 +40,8 @@ const useStyles = makeStyles(theme => ({ }, })); -export type ApolloEndpointProps = { - title: string; - graphRef: string; - persistExplorerState?: boolean; - initialState?: { - document?: string; - variables?: JSONObject; - headers?: Record; - displayOptions: { - docsPanelState?: 'open' | 'closed'; - showHeadersAndEnvVars?: boolean; - theme?: 'dark' | 'light'; - }; - }; -}; - type Props = { - endpoints: ApolloEndpointProps[]; + endpoints: EndpointProps[]; authCallback?: () => Promise<{ token: string }>; }; @@ -78,10 +63,18 @@ export const handleAuthRequest = ({ return handleRequest; }; -export const ApolloExplorerBrowser = ({ endpoints, authCallback }: Props) => { +export const ApolloExplorerBrowser = ({ endpoints }: Props) => { const classes = useStyles(); const [tabIndex, setTabIndex] = useState(0); + const apiHolder = useApiHolder(); + + const getAuthCallback = (index: number) => { + const authCallback = endpoints[index].authCallback; + if (authCallback === undefined) return undefined; + return () => authCallback({ apiHolder }); + }; + return (
{ className={classes.explorer} graphRef={endpoints[tabIndex].graphRef} handleRequest={handleAuthRequest({ - authCallback: authCallback, + authCallback: getAuthCallback(tabIndex), })} persistExplorerState={endpoints[tabIndex].persistExplorerState} initialState={endpoints[tabIndex].initialState} diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx index b9d25a1a06..53b6a54194 100644 --- a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx @@ -18,7 +18,7 @@ import React from 'react'; import { Content, Header, Page } from '@backstage/core-components'; import { ApolloExplorerBrowser } from '../ApolloExplorerBrowser'; import { JSONObject } from '@apollo/explorer/src/helpers/types'; -import { ApiHolder, useApiHolder } from '@backstage/core-plugin-api'; +import { ApiHolder } from '@backstage/core-plugin-api'; /** * Export types to be used with {@link @backstage/apollo-explorer#ApolloExplorerPage}. @@ -28,6 +28,7 @@ import { ApiHolder, useApiHolder } from '@backstage/core-plugin-api'; export type EndpointProps = { title: string; graphRef: string; + authCallback?: AuthCallback; persistExplorerState?: boolean; initialState?: { document?: string; @@ -54,24 +55,16 @@ type Props = { title?: string | undefined; subtitle?: string | undefined; endpoints: EndpointProps[]; - authCallback?: AuthCallback; }; export const ApolloExplorerPage = (props: Props) => { - const { title, subtitle, endpoints, authCallback } = props; - - const apiHolder = useApiHolder(); + const { title, subtitle, endpoints } = props; return (
- authCallback({ apiHolder }) : undefined - } - /> + ); From dde72a55077a5522d200594587f0e957c9ff2d55 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Fri, 5 Apr 2024 14:34:01 -0400 Subject: [PATCH 050/107] update api report Signed-off-by: Karl Haworth --- plugins/apollo-explorer/api-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/apollo-explorer/api-report.md b/plugins/apollo-explorer/api-report.md index a009c99aca..5371bc7219 100644 --- a/plugins/apollo-explorer/api-report.md +++ b/plugins/apollo-explorer/api-report.md @@ -16,7 +16,6 @@ export const ApolloExplorerPage: (props: { title?: string | undefined; subtitle?: string | undefined; endpoints: EndpointProps[]; - authCallback?: AuthCallback | undefined; }) => JSX_2.Element; // @public @@ -36,6 +35,7 @@ export type AuthCallback = (options: { apiHolder: ApiHolder }) => Promise<{ export type EndpointProps = { title: string; graphRef: string; + authCallback?: AuthCallback; persistExplorerState?: boolean; initialState?: { document?: string; From 8ea42d759e040ff3f22f9fefdf20d01171994780 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Fri, 5 Apr 2024 14:34:10 -0400 Subject: [PATCH 051/107] update readme Signed-off-by: Karl Haworth --- plugins/apollo-explorer/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/apollo-explorer/README.md b/plugins/apollo-explorer/README.md index 258675f82d..b26f157635 100644 --- a/plugins/apollo-explorer/README.md +++ b/plugins/apollo-explorer/README.md @@ -74,11 +74,11 @@ Once you authenticate, your graph is ready to use ๐Ÿš€ If you need to utilize an ApiRef to supply a token to Apollo, you may do so using an ApiHolder. -In `packages/app/src/App.tsx` perform the following modifications from above. The import `ssoAuthApiRef` is used as an example and does not exist. +In `packages/app/src/App.tsx` perform the following modifications from above. The import `ssoAuthApiRef` is used as an example and **does not exist**. ```typescript import { ApolloExplorerPage, EndpointProps } from '@backstage/plugin-apollo-explorer'; -import { ssoAuthApiRef } from '@backstage/devkit'; +import { ssoAuthApiRef } from '@companyxyz/devkit'; import { ApiHolder } from '@backstage/core-plugin-api'; async function authCallback(options: { apiHolder: ApiHolder }): Promise { From 342a6a9827fc6401173d2ed9399a53d1d0c044e6 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Fri, 5 Apr 2024 15:22:54 -0400 Subject: [PATCH 052/107] update readme with proper example Signed-off-by: Karl Haworth --- plugins/apollo-explorer/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/apollo-explorer/README.md b/plugins/apollo-explorer/README.md index b26f157635..bc06612cab 100644 --- a/plugins/apollo-explorer/README.md +++ b/plugins/apollo-explorer/README.md @@ -81,7 +81,7 @@ import { ApolloExplorerPage, EndpointProps } from '@backstage/plugin-apollo-expl import { ssoAuthApiRef } from '@companyxyz/devkit'; import { ApiHolder } from '@backstage/core-plugin-api'; -async function authCallback(options: { apiHolder: ApiHolder }): Promise { +async function authCallback(options: { apiHolder: ApiHolder }): Promise<{token: string}> { const sso = options.apiHolder.get(ssoAuthApiRef) return await sso.getToken() } @@ -96,9 +96,9 @@ const routes = ( endpoints={[{ title: 'Github', graphRef: 'my-github-graph-ref@current', + authCallback: authCallback }]} /> } - authCallback={authCallback} /> ``` From d1122256a3869f68490a29cd1abde2550bbc5302 Mon Sep 17 00:00:00 2001 From: parmar-abhinav Date: Sat, 6 Apr 2024 16:36:38 +0530 Subject: [PATCH 053/107] Add examples for gitlab:projectDeployToken:create scaffolder action & improve related tests Signed-off-by: parmar-abhinav --- .changeset/tender-penguins-matter.md | 5 + ...bProjectDeployTokenAction.examples.test.ts | 179 ++++++++++++++++++ ...GitlabProjectDeployTokenAction.examples.ts | 109 +++++++++++ .../createGitlabProjectDeployTokenAction.ts | 2 + 4 files changed, 295 insertions(+) create mode 100644 .changeset/tender-penguins-matter.md create mode 100644 plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.test.ts create mode 100644 plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.ts diff --git a/.changeset/tender-penguins-matter.md b/.changeset/tender-penguins-matter.md new file mode 100644 index 0000000000..5245e251c8 --- /dev/null +++ b/.changeset/tender-penguins-matter.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +--- + +Add examples for `gitlab:projectDeployToken:create` scaffolder action & improve related tests diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.test.ts new file mode 100644 index 0000000000..dd3b694670 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.test.ts @@ -0,0 +1,179 @@ +/* + * 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 { createGitlabProjectDeployTokenAction } from './createGitlabProjectDeployTokenAction'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { ScmIntegrations } from '@backstage/integration'; +import { ConfigReader } from '@backstage/config'; +import yaml from 'yaml'; +import { examples } from './createGitlabProjectDeployTokenAction.examples'; + +const mockGitlabClient = { + ProjectDeployTokens: { + add: jest.fn(), + }, +}; +jest.mock('@gitbeaker/node', () => ({ + Gitlab: class { + constructor() { + return mockGitlabClient; + } + }, +})); + +describe('gitlab:create-deploy-token', () => { + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'gitlab.com', + token: 'tokenlols', + apiBaseUrl: 'https://api.gitlab.com', + }, + { + host: 'hosted.gitlab.com', + apiBaseUrl: 'https://api.hosted.gitlab.com', + }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + const action = createGitlabProjectDeployTokenAction({ integrations }); + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '123', + name: 'tokenname', + username: 'tokenuser', + scopes: ['read_repository'], + }, + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it(`Should ${examples[0].description}`, async () => { + mockGitlabClient.ProjectDeployTokens.add.mockResolvedValue({ + token: 'TOKEN', + username: 'User', + }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[0].example).steps[0].input, + }); + + expect(mockGitlabClient.ProjectDeployTokens.add).toHaveBeenCalledWith( + '456', + 'tokenname', + undefined, + { username: undefined }, + ); + + expect(mockContext.output).toHaveBeenCalledWith('deploy_token', 'TOKEN'); + expect(mockContext.output).toHaveBeenCalledWith('user', 'User'); + }); + + it(`Should ${examples[1].description}`, async () => { + mockGitlabClient.ProjectDeployTokens.add.mockResolvedValue({ + token: 'TOKEN', + username: 'User', + }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[1].example).steps[0].input, + }); + + expect(mockGitlabClient.ProjectDeployTokens.add).toHaveBeenCalledWith( + '789', + 'tokenname', + ['read_registry', 'write_repository'], + { username: undefined }, + ); + + expect(mockContext.output).toHaveBeenCalledWith('deploy_token', 'TOKEN'); + expect(mockContext.output).toHaveBeenCalledWith('user', 'User'); + }); + + it(`Should ${examples[2].description}`, async () => { + mockGitlabClient.ProjectDeployTokens.add.mockResolvedValue({ + token: 'TOKEN', + username: 'User', + }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[2].example).steps[0].input, + }); + + expect(mockGitlabClient.ProjectDeployTokens.add).toHaveBeenCalledWith( + '101112', + 'my-custom-token', + undefined, + { username: undefined }, + ); + + expect(mockContext.output).toHaveBeenCalledWith('deploy_token', 'TOKEN'); + expect(mockContext.output).toHaveBeenCalledWith('user', 'User'); + }); + + it(`Should ${examples[3].description}`, async () => { + mockGitlabClient.ProjectDeployTokens.add.mockResolvedValue({ + token: 'TOKEN', + username: 'User', + }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[3].example).steps[0].input, + }); + + expect(mockGitlabClient.ProjectDeployTokens.add).toHaveBeenCalledWith( + 42, + 'tokenname', + undefined, + { username: undefined }, + ); + + expect(mockContext.output).toHaveBeenCalledWith('deploy_token', 'TOKEN'); + expect(mockContext.output).toHaveBeenCalledWith('user', 'User'); + }); + + it(`Should ${examples[4].description}`, async () => { + mockGitlabClient.ProjectDeployTokens.add.mockResolvedValue({ + token: 'TOKEN', + username: 'User', + }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[4].example).steps[0].input, + }); + + expect(mockGitlabClient.ProjectDeployTokens.add).toHaveBeenCalledWith( + 42, + 'tokenname', + undefined, + { username: 'tokenuser' }, + ); + + expect(mockContext.output).toHaveBeenCalledWith('deploy_token', 'TOKEN'); + expect(mockContext.output).toHaveBeenCalledWith('user', 'User'); + }); +}); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.ts new file mode 100644 index 0000000000..326747d45a --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.ts @@ -0,0 +1,109 @@ +/* + * 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 { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Create a GitLab project deploy token with minimal options.', + example: yaml.stringify({ + steps: [ + { + id: 'createDeployToken', + action: 'gitlab:projectDeployToken:create', + name: 'Create GitLab Project Deploy Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '456', + name: 'tokenname', + }, + }, + ], + }), + }, + { + description: 'Create a GitLab project deploy token with custom scopes.', + example: yaml.stringify({ + steps: [ + { + id: 'createDeployToken', + action: 'gitlab:projectDeployToken:create', + name: 'Create GitLab Project Deploy Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '789', + name: 'tokenname', + scopes: ['read_registry', 'write_repository'], + }, + }, + ], + }), + }, + { + description: 'Create a GitLab project deploy token with a specified name.', + example: yaml.stringify({ + steps: [ + { + id: 'createDeployToken', + action: 'gitlab:projectDeployToken:create', + name: 'Create GitLab Project Deploy Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '101112', + name: 'my-custom-token', + }, + }, + ], + }), + }, + { + description: + 'Create a GitLab project deploy token with a numeric project ID.', + example: yaml.stringify({ + steps: [ + { + id: 'createDeployToken', + action: 'gitlab:projectDeployToken:create', + name: 'Create GitLab Project Deploy Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 42, + name: 'tokenname', + }, + }, + ], + }), + }, + + { + description: 'Create a GitLab project deploy token with a custom username', + example: yaml.stringify({ + steps: [ + { + id: 'createDeployToken', + action: 'gitlab:projectDeployToken:create', + name: 'Create GitLab Project Deploy Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 42, + name: 'tokenname', + username: 'tokenuser', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts index 1665d23b39..87d4314b6f 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts @@ -22,6 +22,7 @@ import commonGitlabConfig from '../commonGitlabConfig'; import { getToken } from '../util'; import { InputError } from '@backstage/errors'; import { z } from 'zod'; +import { examples } from './createGitlabProjectDeployTokenAction.examples'; /** * Creates a `gitlab:projectDeployToken:create` Scaffolder action. @@ -35,6 +36,7 @@ export const createGitlabProjectDeployTokenAction = (options: { const { integrations } = options; return createTemplateAction({ id: 'gitlab:projectDeployToken:create', + examples, schema: { input: commonGitlabConfig.merge( z.object({ From 5f1d385489409a782d9dd416565545c4bb01ad5a Mon Sep 17 00:00:00 2001 From: Timothy Deakin Date: Sun, 7 Apr 2024 05:29:51 +0100 Subject: [PATCH 054/107] feat: add support aws govcloud (us) Signed-off-by: Timothy Deakin --- .../src/helpers.test.ts | 20 ++++++++++++------- .../src/helpers.ts | 16 ++++++++++++--- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts b/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts index cb103debb0..0bbcf9b5c1 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts @@ -26,7 +26,13 @@ import { makeProfileInfo, provisionKeyCache } from './helpers'; jest.mock('crypto'); const cryptoMock = crypto as jest.Mocked; -describe('helpers', () => { +describe.each([ + ['eu-west-1', 'https://public-keys.auth.elb.eu-west-1.amazonaws.com/kid'], + [ + 'us-gov-west-1', + 'https://s3-us-gov-west-1.amazonaws.com/aws-elb-public-keys-prod-us-gov-west-1/kid', + ], +])('helpers', (region, url) => { const server = setupServer(); setupRequestMockHandlers(server); @@ -37,7 +43,7 @@ describe('helpers', () => { jest.clearAllMocks(); server.use( http.get( - 'https://public-keys.auth.elb.eu-west-1.amazonaws.com/kid', + url, () => new HttpResponse( `-----BEGIN PUBLIC KEY----- @@ -51,12 +57,12 @@ yOlxJ2VW88mLAQGJ7HPAvOdylxZsItMnzCuqNzZvie8m/NJsOjhDncVkrw== }); it('should create a key', () => { - const getKey = provisionKeyCache('eu-west-1', nodeCache); + const getKey = provisionKeyCache(region, nodeCache); expect(getKey).toBeDefined(); }); it('should return a key from cache', async () => { - const getKey = provisionKeyCache('eu-west-1', nodeCache); + const getKey = provisionKeyCache(region, nodeCache); cryptoMock.createPublicKey.mockReturnValueOnce('key'); nodeCache.get = jest.fn().mockReturnValue('key'); @@ -67,7 +73,7 @@ yOlxJ2VW88mLAQGJ7HPAvOdylxZsItMnzCuqNzZvie8m/NJsOjhDncVkrw== }); it('should update cache if key is not found', async () => { - const getKey = provisionKeyCache('eu-west-1', nodeCache); + const getKey = provisionKeyCache(region, nodeCache); nodeCache.get = jest.fn().mockReturnValue(undefined); jest.spyOn(nodeCache, 'set'); @@ -80,7 +86,7 @@ yOlxJ2VW88mLAQGJ7HPAvOdylxZsItMnzCuqNzZvie8m/NJsOjhDncVkrw== }); it('should throw error if key is not found', async () => { - const getKey = provisionKeyCache('eu-west-1', nodeCache); + const getKey = provisionKeyCache(region, nodeCache); nodeCache.get = jest.fn().mockReturnValue(undefined); cryptoMock.createPublicKey.mockReturnValue(undefined); @@ -91,7 +97,7 @@ yOlxJ2VW88mLAQGJ7HPAvOdylxZsItMnzCuqNzZvie8m/NJsOjhDncVkrw== }); it('should throw if key is not present in request header', async () => { - const getKey = provisionKeyCache('eu-west-1', nodeCache); + const getKey = provisionKeyCache(region, nodeCache); nodeCache.get = jest.fn().mockReturnValue(undefined); diff --git a/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts b/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts index e846b2484e..1af02ce9ec 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts @@ -70,6 +70,17 @@ export const makeProfileInfo = ( }; }; +const getPublicKeyEndpoint = (region: string) => { + const commercialEndpoint = `https://public-keys.auth.elb.${encodeURIComponent( + region, + )}.amazonaws.com/`; + const govEndpoint = `https://s3-${encodeURIComponent( + region, + )}.amazonaws.com/aws-elb-public-keys-prod-${encodeURIComponent(region)}/`; + + return region.startsWith('us-gov') ? govEndpoint : commercialEndpoint; +}; + export const provisionKeyCache = (region: string, keyCache: NodeCache) => { return async (header: JWTHeaderParameters): Promise => { if (!header.kid) { @@ -79,10 +90,9 @@ export const provisionKeyCache = (region: string, keyCache: NodeCache) => { if (optionalCacheKey) { return crypto.createPublicKey(optionalCacheKey); } + const keyText: string = await fetch( - `https://public-keys.auth.elb.${encodeURIComponent( - region, - )}.amazonaws.com/${encodeURIComponent(header.kid)}`, + getPublicKeyEndpoint(region) + header.kid, ).then(response => response.text()); const keyValue = crypto.createPublicKey(keyText); From f286d59f036f43c5b9ee588994248b4197c2d346 Mon Sep 17 00:00:00 2001 From: Timothy Deakin Date: Sun, 7 Apr 2024 05:48:18 +0100 Subject: [PATCH 055/107] chore: add changeset Signed-off-by: Timothy Deakin --- .changeset/neat-weeks-wait.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/neat-weeks-wait.md diff --git a/.changeset/neat-weeks-wait.md b/.changeset/neat-weeks-wait.md new file mode 100644 index 0000000000..5fe26cba7c --- /dev/null +++ b/.changeset/neat-weeks-wait.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-aws-alb-provider': minor +--- + +Added support for AWS GovCloud (US) regions From 0fb178e84abda8dd5a507f5c8b3354a74e0a5724 Mon Sep 17 00:00:00 2001 From: parmar-abhinav Date: Sun, 7 Apr 2024 19:01:56 +0530 Subject: [PATCH 056/107] Add examples for publish:gerrit:review scaffolder action & improve related tests Signed-off-by: parmar-abhinav --- .changeset/mighty-humans-tan.md | 5 + .../src/actions/gerritReview.examples.test.ts | 245 ++++++++++++++++++ .../src/actions/gerritReview.examples.ts | 126 +++++++++ .../src/actions/gerritReview.ts | 2 + 4 files changed, 378 insertions(+) create mode 100644 .changeset/mighty-humans-tan.md create mode 100644 plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.test.ts create mode 100644 plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.ts diff --git a/.changeset/mighty-humans-tan.md b/.changeset/mighty-humans-tan.md new file mode 100644 index 0000000000..24e209a701 --- /dev/null +++ b/.changeset/mighty-humans-tan.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gerrit': minor +--- + +Add examples for publish:gerrit:review scaffolder action & improve related tests diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.test.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.test.ts new file mode 100644 index 0000000000..d1bc594d54 --- /dev/null +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.test.ts @@ -0,0 +1,245 @@ +/* + * 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. + */ + +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + commitAndPushRepo: jest.fn(), + }; +}); + +import { createPublishGerritReviewAction } from './gerritReview'; +import { ScmIntegrations } from '@backstage/integration'; +import { ConfigReader } from '@backstage/config'; +import { commitAndPushRepo } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import yaml from 'yaml'; +import { examples } from './gerritReview.examples'; + +describe('publish:gerrit:review', () => { + const config = new ConfigReader({ + integrations: { + gerrit: [ + { + host: 'gerrithost.org', + username: 'gerrituser', + password: 'usertoken', + }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + const action = createPublishGerritReviewAction({ integrations, config }); + const mockContext = createMockActionContext({ + input: { + repoUrl: + 'gerrithost.org?owner=owner&workspace=parent&project=project&repo=repo', + gitCommitMessage: 'Review from backstage', + }, + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it(`Should ${examples[0].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[0].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: {}, + branch: 'master', + remoteRef: 'refs/for/master', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/master', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[1].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[1].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: { + email: undefined, + name: 'Test User', + }, + branch: 'master', + remoteRef: 'refs/for/master', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/master', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[2].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[2].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: { + email: 'test.user@example.com', + name: 'Test User', + }, + branch: 'master', + remoteRef: 'refs/for/master', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/master', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[3].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[3].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: {}, + branch: 'develop', + remoteRef: 'refs/for/develop', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/develop', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[4].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[4].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: `${mockContext.workspacePath}/src`, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: {}, + branch: 'master', + remoteRef: 'refs/for/master', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/master', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[5].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[5].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: `${mockContext.workspacePath}/src`, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: { + email: 'test.user@example.com', + name: 'Test User', + }, + branch: 'develop', + remoteRef: 'refs/for/develop', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/develop', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); +}); diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.ts new file mode 100644 index 0000000000..fc01fd1ce3 --- /dev/null +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.ts @@ -0,0 +1,126 @@ +/* + * 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 { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Creates a new Gerrit review with minimal options', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with gitAuthorName', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + gitAuthorName: 'Test User', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with gitAuthorEmail', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with custom branch', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + branch: 'develop', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with custom sourcePath', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + sourcePath: './src', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with all properties', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + branch: 'develop', + sourcePath: './src', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts index bd8d0321ab..b4f844b08f 100644 --- a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts @@ -24,6 +24,7 @@ import { getRepoSourceDirectory, parseRepoUrl, } from '@backstage/plugin-scaffolder-node'; +import { examples } from './gerritReview.examples'; const generateGerritChangeId = (): string => { const changeId = crypto.randomBytes(20).toString('hex'); @@ -50,6 +51,7 @@ export function createPublishGerritReviewAction(options: { }>({ id: 'publish:gerrit:review', description: 'Creates a new Gerrit review.', + examples, schema: { input: { type: 'object', From c8080ec419c75274239513194f2b2a7c8f629462 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 16:18:07 +0000 Subject: [PATCH 057/107] chore(deps): update dependency webpack to v5.91.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- storybook/yarn.lock | 140 ++++++++++++++++++++++---------------------- yarn.lock | 132 ++++++++++++++++++++--------------------- 2 files changed, 136 insertions(+), 136 deletions(-) diff --git a/storybook/yarn.lock b/storybook/yarn.lock index 70f86d7e7f..5d414b5ac3 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -3250,13 +3250,13 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/ast@npm:1.11.6, @webassemblyjs/ast@npm:^1.11.5": - version: 1.11.6 - resolution: "@webassemblyjs/ast@npm:1.11.6" +"@webassemblyjs/ast@npm:1.12.1, @webassemblyjs/ast@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/ast@npm:1.12.1" dependencies: "@webassemblyjs/helper-numbers": 1.11.6 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 - checksum: 38ef1b526ca47c210f30975b06df2faf1a8170b1636ce239fc5738fc231ce28389dd61ecedd1bacfc03cbe95b16d1af848c805652080cb60982836eb4ed2c6cf + checksum: 31bcc64147236bd7b1b6d29d1f419c1f5845c785e1e42dc9e3f8ca2e05a029e9393a271b84f3a5bff2a32d35f51ff59e2181a6e5f953fe88576acd6750506202 languageName: node linkType: hard @@ -3274,10 +3274,10 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/helper-buffer@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/helper-buffer@npm:1.11.6" - checksum: b14d0573bf680d22b2522e8a341ec451fddd645d1f9c6bd9012ccb7e587a2973b86ab7b89fe91e1c79939ba96095f503af04369a3b356c8023c13a5893221644 +"@webassemblyjs/helper-buffer@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/helper-buffer@npm:1.12.1" + checksum: c3ffb723024130308db608e86e2bdccd4868bbb62dffb0a9a1530606496f79c87f8565bd8e02805ce64912b71f1a70ee5fb00307258b0c082c3abf961d097eca languageName: node linkType: hard @@ -3299,15 +3299,15 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/helper-wasm-section@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/helper-wasm-section@npm:1.11.6" +"@webassemblyjs/helper-wasm-section@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/helper-wasm-section@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 - "@webassemblyjs/helper-buffer": 1.11.6 + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 - "@webassemblyjs/wasm-gen": 1.11.6 - checksum: b2cf751bf4552b5b9999d27bbb7692d0aca75260140195cb58ea6374d7b9c2dc69b61e10b211a0e773f66209c3ddd612137ed66097e3684d7816f854997682e9 + "@webassemblyjs/wasm-gen": 1.12.1 + checksum: c19810cdd2c90ff574139b6d8c0dda254d42d168a9e5b3d353d1bc085f1d7164ccd1b3c05592a45a939c47f7e403dc8d03572bb686642f06a3d02932f6f0bc8f languageName: node linkType: hard @@ -3336,68 +3336,68 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/wasm-edit@npm:^1.11.5": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-edit@npm:1.11.6" +"@webassemblyjs/wasm-edit@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-edit@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 - "@webassemblyjs/helper-buffer": 1.11.6 + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 - "@webassemblyjs/helper-wasm-section": 1.11.6 - "@webassemblyjs/wasm-gen": 1.11.6 - "@webassemblyjs/wasm-opt": 1.11.6 - "@webassemblyjs/wasm-parser": 1.11.6 - "@webassemblyjs/wast-printer": 1.11.6 - checksum: 29ce75870496d6fad864d815ebb072395a8a3a04dc9c3f4e1ffdc63fc5fa58b1f34304a1117296d8240054cfdbc38aca88e71fb51483cf29ffab0a61ef27b481 + "@webassemblyjs/helper-wasm-section": 1.12.1 + "@webassemblyjs/wasm-gen": 1.12.1 + "@webassemblyjs/wasm-opt": 1.12.1 + "@webassemblyjs/wasm-parser": 1.12.1 + "@webassemblyjs/wast-printer": 1.12.1 + checksum: ae23642303f030af888d30c4ef37b08dfec7eab6851a9575a616e65d1219f880d9223913a39056dd654e49049d76e97555b285d1f7e56935047abf578cce0692 languageName: node linkType: hard -"@webassemblyjs/wasm-gen@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-gen@npm:1.11.6" +"@webassemblyjs/wasm-gen@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-gen@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 + "@webassemblyjs/ast": 1.12.1 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 "@webassemblyjs/ieee754": 1.11.6 "@webassemblyjs/leb128": 1.11.6 "@webassemblyjs/utf8": 1.11.6 - checksum: a645a2eecbea24833c3260a249704a7f554ef4a94c6000984728e94bb2bc9140a68dfd6fd21d5e0bbb09f6dfc98e083a45760a83ae0417b41a0196ff6d45a23a + checksum: 5787626bb7f0b033044471ddd00ce0c9fe1ee4584e8b73e232051e3a4c99ba1a102700d75337151c8b6055bae77eefa4548960c610a5e4a504e356bd872138ff languageName: node linkType: hard -"@webassemblyjs/wasm-opt@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-opt@npm:1.11.6" +"@webassemblyjs/wasm-opt@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-opt@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 - "@webassemblyjs/helper-buffer": 1.11.6 - "@webassemblyjs/wasm-gen": 1.11.6 - "@webassemblyjs/wasm-parser": 1.11.6 - checksum: b4557f195487f8e97336ddf79f7bef40d788239169aac707f6eaa2fa5fe243557c2d74e550a8e57f2788e70c7ae4e7d32f7be16101afe183d597b747a3bdd528 + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 + "@webassemblyjs/wasm-gen": 1.12.1 + "@webassemblyjs/wasm-parser": 1.12.1 + checksum: 0e8fa8a0645304a1e18ff40d3db5a2e9233ebaa169b19fcc651d6fc9fe2cac0ce092ddee927318015ae735d9cd9c5d97c0cafb6a51dcd2932ac73587b62df991 languageName: node linkType: hard -"@webassemblyjs/wasm-parser@npm:1.11.6, @webassemblyjs/wasm-parser@npm:^1.11.5": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-parser@npm:1.11.6" +"@webassemblyjs/wasm-parser@npm:1.12.1, @webassemblyjs/wasm-parser@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-parser@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 + "@webassemblyjs/ast": 1.12.1 "@webassemblyjs/helper-api-error": 1.11.6 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 "@webassemblyjs/ieee754": 1.11.6 "@webassemblyjs/leb128": 1.11.6 "@webassemblyjs/utf8": 1.11.6 - checksum: 8200a8d77c15621724a23fdabe58d5571415cda98a7058f542e670ea965dd75499f5e34a48675184947c66f3df23adf55df060312e6d72d57908e3f049620d8a + checksum: 176015de3551ac068cd4505d837414f258d9ade7442bd71efb1232fa26c9f6d7d4e11a5c816caeed389943f409af7ebff6899289a992d7a70343cb47009d21a8 languageName: node linkType: hard -"@webassemblyjs/wast-printer@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/wast-printer@npm:1.11.6" +"@webassemblyjs/wast-printer@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wast-printer@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 + "@webassemblyjs/ast": 1.12.1 "@xtuc/long": 4.2.2 - checksum: d2fa6a4c427325ec81463e9c809aa6572af6d47f619f3091bf4c4a6fc34f1da3df7caddaac50b8e7a457f8784c62cd58c6311b6cb69b0162ccd8d4c072f79cf8 + checksum: 2974b5dda8d769145ba0efd886ea94a601e61fb37114c14f9a9a7606afc23456799af652ac3052f284909bd42edc3665a76bc9b50f95f0794c053a8a1757b713 languageName: node linkType: hard @@ -5357,13 +5357,13 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.15.0": - version: 5.15.0 - resolution: "enhanced-resolve@npm:5.15.0" +"enhanced-resolve@npm:^5.16.0": + version: 5.16.0 + resolution: "enhanced-resolve@npm:5.16.0" dependencies: graceful-fs: ^4.2.4 tapable: ^2.2.0 - checksum: fbd8cdc9263be71cc737aa8a7d6c57b43d6aa38f6cc75dde6fcd3598a130cc465f979d2f4d01bb3bf475acb43817749c79f8eef9be048683602ca91ab52e4f11 + checksum: ccfd01850ecf2aa51e8554d539973319ff7d8a539ef1e0ba3460a0ccad6223c4ef6e19165ee64161b459cd8a48df10f52af4434c60023c65fde6afa32d475f7e languageName: node linkType: hard @@ -6387,10 +6387,10 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": - version: 4.2.10 - resolution: "graceful-fs@npm:4.2.10" - checksum: 3f109d70ae123951905d85032ebeae3c2a5a7a997430df00ea30df0e3a6c60cf6689b109654d6fdacd28810a053348c4d14642da1d075049e6be1ba5216218da +"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 languageName: node linkType: hard @@ -11628,13 +11628,13 @@ __metadata: languageName: node linkType: hard -"watchpack@npm:^2.2.0, watchpack@npm:^2.4.0": - version: 2.4.0 - resolution: "watchpack@npm:2.4.0" +"watchpack@npm:^2.2.0, watchpack@npm:^2.4.1": + version: 2.4.1 + resolution: "watchpack@npm:2.4.1" dependencies: glob-to-regexp: ^0.4.1 graceful-fs: ^4.1.2 - checksum: 23d4bc58634dbe13b86093e01c6a68d8096028b664ab7139d58f0c37d962d549a940e98f2f201cecdabd6f9c340338dc73ef8bf094a2249ef582f35183d1a131 + checksum: 5b0179348655dcdf19cac7cb4ff923fdc024d630650c0bf6bec8899cf47c60e19d4f810a88dba692ed0e7f684cf0fcffea86efdbf6c35d81f031e328043b7fab languageName: node linkType: hard @@ -11747,24 +11747,24 @@ __metadata: linkType: hard "webpack@npm:^5.73.0": - version: 5.90.3 - resolution: "webpack@npm:5.90.3" + version: 5.91.0 + resolution: "webpack@npm:5.91.0" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.5 - "@webassemblyjs/ast": ^1.11.5 - "@webassemblyjs/wasm-edit": ^1.11.5 - "@webassemblyjs/wasm-parser": ^1.11.5 + "@webassemblyjs/ast": ^1.12.1 + "@webassemblyjs/wasm-edit": ^1.12.1 + "@webassemblyjs/wasm-parser": ^1.12.1 acorn: ^8.7.1 acorn-import-assertions: ^1.9.0 browserslist: ^4.21.10 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^5.15.0 + enhanced-resolve: ^5.16.0 es-module-lexer: ^1.2.1 eslint-scope: 5.1.1 events: ^3.2.0 glob-to-regexp: ^0.4.1 - graceful-fs: ^4.2.9 + graceful-fs: ^4.2.11 json-parse-even-better-errors: ^2.3.1 loader-runner: ^4.2.0 mime-types: ^2.1.27 @@ -11772,14 +11772,14 @@ __metadata: schema-utils: ^3.2.0 tapable: ^2.1.1 terser-webpack-plugin: ^5.3.10 - watchpack: ^2.4.0 + watchpack: ^2.4.1 webpack-sources: ^3.2.3 peerDependenciesMeta: webpack-cli: optional: true bin: webpack: bin/webpack.js - checksum: de0c824ac220f41cc1153ac33e081d46260b104c4f2fda26f011cdf7a73f74cc091f288cb1fc16f88a36e35bac44e0aa85fc9922fdf3109dfb361f46b20f3fcc + checksum: f1073715dbb1ed5c070affef293d800a867708bcbc5aba4d8baee87660e0cf53c55966a6f36fab078d1d6c9567cdcd0a9086bdfb607cab87ea68c6449791b9a3 languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index 2df04a207e..d45efdaf4b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20470,13 +20470,13 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/ast@npm:1.11.6, @webassemblyjs/ast@npm:^1.11.5": - version: 1.11.6 - resolution: "@webassemblyjs/ast@npm:1.11.6" +"@webassemblyjs/ast@npm:1.12.1, @webassemblyjs/ast@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/ast@npm:1.12.1" dependencies: "@webassemblyjs/helper-numbers": 1.11.6 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 - checksum: 38ef1b526ca47c210f30975b06df2faf1a8170b1636ce239fc5738fc231ce28389dd61ecedd1bacfc03cbe95b16d1af848c805652080cb60982836eb4ed2c6cf + checksum: 31bcc64147236bd7b1b6d29d1f419c1f5845c785e1e42dc9e3f8ca2e05a029e9393a271b84f3a5bff2a32d35f51ff59e2181a6e5f953fe88576acd6750506202 languageName: node linkType: hard @@ -20494,10 +20494,10 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/helper-buffer@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/helper-buffer@npm:1.11.6" - checksum: b14d0573bf680d22b2522e8a341ec451fddd645d1f9c6bd9012ccb7e587a2973b86ab7b89fe91e1c79939ba96095f503af04369a3b356c8023c13a5893221644 +"@webassemblyjs/helper-buffer@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/helper-buffer@npm:1.12.1" + checksum: c3ffb723024130308db608e86e2bdccd4868bbb62dffb0a9a1530606496f79c87f8565bd8e02805ce64912b71f1a70ee5fb00307258b0c082c3abf961d097eca languageName: node linkType: hard @@ -20519,15 +20519,15 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/helper-wasm-section@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/helper-wasm-section@npm:1.11.6" +"@webassemblyjs/helper-wasm-section@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/helper-wasm-section@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 - "@webassemblyjs/helper-buffer": 1.11.6 + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 - "@webassemblyjs/wasm-gen": 1.11.6 - checksum: b2cf751bf4552b5b9999d27bbb7692d0aca75260140195cb58ea6374d7b9c2dc69b61e10b211a0e773f66209c3ddd612137ed66097e3684d7816f854997682e9 + "@webassemblyjs/wasm-gen": 1.12.1 + checksum: c19810cdd2c90ff574139b6d8c0dda254d42d168a9e5b3d353d1bc085f1d7164ccd1b3c05592a45a939c47f7e403dc8d03572bb686642f06a3d02932f6f0bc8f languageName: node linkType: hard @@ -20556,68 +20556,68 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/wasm-edit@npm:^1.11.5": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-edit@npm:1.11.6" +"@webassemblyjs/wasm-edit@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-edit@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 - "@webassemblyjs/helper-buffer": 1.11.6 + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 - "@webassemblyjs/helper-wasm-section": 1.11.6 - "@webassemblyjs/wasm-gen": 1.11.6 - "@webassemblyjs/wasm-opt": 1.11.6 - "@webassemblyjs/wasm-parser": 1.11.6 - "@webassemblyjs/wast-printer": 1.11.6 - checksum: 29ce75870496d6fad864d815ebb072395a8a3a04dc9c3f4e1ffdc63fc5fa58b1f34304a1117296d8240054cfdbc38aca88e71fb51483cf29ffab0a61ef27b481 + "@webassemblyjs/helper-wasm-section": 1.12.1 + "@webassemblyjs/wasm-gen": 1.12.1 + "@webassemblyjs/wasm-opt": 1.12.1 + "@webassemblyjs/wasm-parser": 1.12.1 + "@webassemblyjs/wast-printer": 1.12.1 + checksum: ae23642303f030af888d30c4ef37b08dfec7eab6851a9575a616e65d1219f880d9223913a39056dd654e49049d76e97555b285d1f7e56935047abf578cce0692 languageName: node linkType: hard -"@webassemblyjs/wasm-gen@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-gen@npm:1.11.6" +"@webassemblyjs/wasm-gen@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-gen@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 + "@webassemblyjs/ast": 1.12.1 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 "@webassemblyjs/ieee754": 1.11.6 "@webassemblyjs/leb128": 1.11.6 "@webassemblyjs/utf8": 1.11.6 - checksum: a645a2eecbea24833c3260a249704a7f554ef4a94c6000984728e94bb2bc9140a68dfd6fd21d5e0bbb09f6dfc98e083a45760a83ae0417b41a0196ff6d45a23a + checksum: 5787626bb7f0b033044471ddd00ce0c9fe1ee4584e8b73e232051e3a4c99ba1a102700d75337151c8b6055bae77eefa4548960c610a5e4a504e356bd872138ff languageName: node linkType: hard -"@webassemblyjs/wasm-opt@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-opt@npm:1.11.6" +"@webassemblyjs/wasm-opt@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-opt@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 - "@webassemblyjs/helper-buffer": 1.11.6 - "@webassemblyjs/wasm-gen": 1.11.6 - "@webassemblyjs/wasm-parser": 1.11.6 - checksum: b4557f195487f8e97336ddf79f7bef40d788239169aac707f6eaa2fa5fe243557c2d74e550a8e57f2788e70c7ae4e7d32f7be16101afe183d597b747a3bdd528 + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 + "@webassemblyjs/wasm-gen": 1.12.1 + "@webassemblyjs/wasm-parser": 1.12.1 + checksum: 0e8fa8a0645304a1e18ff40d3db5a2e9233ebaa169b19fcc651d6fc9fe2cac0ce092ddee927318015ae735d9cd9c5d97c0cafb6a51dcd2932ac73587b62df991 languageName: node linkType: hard -"@webassemblyjs/wasm-parser@npm:1.11.6, @webassemblyjs/wasm-parser@npm:^1.11.5": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-parser@npm:1.11.6" +"@webassemblyjs/wasm-parser@npm:1.12.1, @webassemblyjs/wasm-parser@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-parser@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 + "@webassemblyjs/ast": 1.12.1 "@webassemblyjs/helper-api-error": 1.11.6 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 "@webassemblyjs/ieee754": 1.11.6 "@webassemblyjs/leb128": 1.11.6 "@webassemblyjs/utf8": 1.11.6 - checksum: 8200a8d77c15621724a23fdabe58d5571415cda98a7058f542e670ea965dd75499f5e34a48675184947c66f3df23adf55df060312e6d72d57908e3f049620d8a + checksum: 176015de3551ac068cd4505d837414f258d9ade7442bd71efb1232fa26c9f6d7d4e11a5c816caeed389943f409af7ebff6899289a992d7a70343cb47009d21a8 languageName: node linkType: hard -"@webassemblyjs/wast-printer@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/wast-printer@npm:1.11.6" +"@webassemblyjs/wast-printer@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wast-printer@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 + "@webassemblyjs/ast": 1.12.1 "@xtuc/long": 4.2.2 - checksum: d2fa6a4c427325ec81463e9c809aa6572af6d47f619f3091bf4c4a6fc34f1da3df7caddaac50b8e7a457f8784c62cd58c6311b6cb69b0162ccd8d4c072f79cf8 + checksum: 2974b5dda8d769145ba0efd886ea94a601e61fb37114c14f9a9a7606afc23456799af652ac3052f284909bd42edc3665a76bc9b50f95f0794c053a8a1757b713 languageName: node linkType: hard @@ -26232,13 +26232,13 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.15.0": - version: 5.15.0 - resolution: "enhanced-resolve@npm:5.15.0" +"enhanced-resolve@npm:^5.16.0": + version: 5.16.0 + resolution: "enhanced-resolve@npm:5.16.0" dependencies: graceful-fs: ^4.2.4 tapable: ^2.2.0 - checksum: fbd8cdc9263be71cc737aa8a7d6c57b43d6aa38f6cc75dde6fcd3598a130cc465f979d2f4d01bb3bf475acb43817749c79f8eef9be048683602ca91ab52e4f11 + checksum: ccfd01850ecf2aa51e8554d539973319ff7d8a539ef1e0ba3460a0ccad6223c4ef6e19165ee64161b459cd8a48df10f52af4434c60023c65fde6afa32d475f7e languageName: node linkType: hard @@ -45516,13 +45516,13 @@ __metadata: languageName: node linkType: hard -"watchpack@npm:^2.4.0": - version: 2.4.0 - resolution: "watchpack@npm:2.4.0" +"watchpack@npm:^2.4.1": + version: 2.4.1 + resolution: "watchpack@npm:2.4.1" dependencies: glob-to-regexp: ^0.4.1 graceful-fs: ^4.1.2 - checksum: 23d4bc58634dbe13b86093e01c6a68d8096028b664ab7139d58f0c37d962d549a940e98f2f201cecdabd6f9c340338dc73ef8bf094a2249ef582f35183d1a131 + checksum: 5b0179348655dcdf19cac7cb4ff923fdc024d630650c0bf6bec8899cf47c60e19d4f810a88dba692ed0e7f684cf0fcffea86efdbf6c35d81f031e328043b7fab languageName: node linkType: hard @@ -45697,24 +45697,24 @@ __metadata: linkType: hard "webpack@npm:^5, webpack@npm:^5.70.0": - version: 5.90.2 - resolution: "webpack@npm:5.90.2" + version: 5.91.0 + resolution: "webpack@npm:5.91.0" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.5 - "@webassemblyjs/ast": ^1.11.5 - "@webassemblyjs/wasm-edit": ^1.11.5 - "@webassemblyjs/wasm-parser": ^1.11.5 + "@webassemblyjs/ast": ^1.12.1 + "@webassemblyjs/wasm-edit": ^1.12.1 + "@webassemblyjs/wasm-parser": ^1.12.1 acorn: ^8.7.1 acorn-import-assertions: ^1.9.0 browserslist: ^4.21.10 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^5.15.0 + enhanced-resolve: ^5.16.0 es-module-lexer: ^1.2.1 eslint-scope: 5.1.1 events: ^3.2.0 glob-to-regexp: ^0.4.1 - graceful-fs: ^4.2.9 + graceful-fs: ^4.2.11 json-parse-even-better-errors: ^2.3.1 loader-runner: ^4.2.0 mime-types: ^2.1.27 @@ -45722,14 +45722,14 @@ __metadata: schema-utils: ^3.2.0 tapable: ^2.1.1 terser-webpack-plugin: ^5.3.10 - watchpack: ^2.4.0 + watchpack: ^2.4.1 webpack-sources: ^3.2.3 peerDependenciesMeta: webpack-cli: optional: true bin: webpack: bin/webpack.js - checksum: 4af55f314c3610e0b17afd01960c4cf9d8d90c87a58ef7d7dc7a0a019f48e2bba4eff63b02d9da56fc61df5b04af0d66b3fa4ec82937a780d37a64db84c643fe + checksum: f1073715dbb1ed5c070affef293d800a867708bcbc5aba4d8baee87660e0cf53c55966a6f36fab078d1d6c9567cdcd0a9086bdfb607cab87ea68c6449791b9a3 languageName: node linkType: hard From 0dfd660752f72abb6f922f54fa9cbb1c205999b9 Mon Sep 17 00:00:00 2001 From: Timothy Deakin Date: Mon, 8 Apr 2024 20:08:16 +0100 Subject: [PATCH 058/107] chore: update changeset change to patch as the package is < 1.0 Signed-off-by: Timothy Deakin --- .changeset/neat-weeks-wait.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/neat-weeks-wait.md b/.changeset/neat-weeks-wait.md index 5fe26cba7c..c16b91fd2f 100644 --- a/.changeset/neat-weeks-wait.md +++ b/.changeset/neat-weeks-wait.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-auth-backend-module-aws-alb-provider': minor +'@backstage/plugin-auth-backend-module-aws-alb-provider': patch --- Added support for AWS GovCloud (US) regions From 6206039bb17a0369676e7e26c856197005b7467a Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Tue, 9 Apr 2024 15:18:59 +0300 Subject: [PATCH 059/107] fix: entity owner relation resolution in notifications use relations instead `spec.owner` field Signed-off-by: Heikki Hellgren --- .changeset/weak-feet-whisper.md | 5 ++ .../src/service/router.ts | 46 +++++++------------ 2 files changed, 22 insertions(+), 29 deletions(-) create mode 100644 .changeset/weak-feet-whisper.md diff --git a/.changeset/weak-feet-whisper.md b/.changeset/weak-feet-whisper.md new file mode 100644 index 0000000000..1d2e4013eb --- /dev/null +++ b/.changeset/weak-feet-whisper.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications-backend': patch +--- + +Fix entity owner resolution in notifications diff --git a/plugins/notifications-backend/src/service/router.ts b/plugins/notifications-backend/src/service/router.ts index ea988d851b..ac50847033 100644 --- a/plugins/notifications-backend/src/service/router.ts +++ b/plugins/notifications-backend/src/service/router.ts @@ -28,6 +28,7 @@ import { isGroupEntity, isUserEntity, RELATION_HAS_MEMBER, + RELATION_OWNED_BY, RELATION_PARENT_OF, stringifyEntityRef, } from '@backstage/catalog-model'; @@ -99,17 +100,13 @@ export async function createRouter( return []; } + const fields = ['kind', 'metadata.name', 'metadata.namespace', 'relations']; + const refs = Array.isArray(entityRef) ? entityRef : [entityRef]; const entities = await catalogClient.getEntitiesByRefs( { entityRefs: refs, - fields: [ - 'kind', - 'metadata.name', - 'metadata.namespace', - 'relations', - 'spec.owner', - ], + fields, }, { token }, ); @@ -122,29 +119,17 @@ export async function createRouter( return [stringifyEntityRef(entity)]; } else if (isGroupEntity(entity) && entity.relations) { const users = entity.relations - .filter( - relation => - relation.type === RELATION_HAS_MEMBER && relation.targetRef, - ) + .filter(relation => relation.type === RELATION_HAS_MEMBER) .map(r => r.targetRef); const childGroupRefs = entity.relations - .filter( - relation => - relation.type === RELATION_PARENT_OF && relation.targetRef, - ) + .filter(relation => relation.type === RELATION_PARENT_OF) .map(r => r.targetRef); const childGroups = await catalogClient.getEntitiesByRefs( { entityRefs: childGroupRefs, - fields: [ - 'kind', - 'metadata.name', - 'metadata.namespace', - 'relations', - 'spec.owner', - ], + fields, }, { token }, ); @@ -152,13 +137,16 @@ export async function createRouter( childGroups.items.map(mapEntity), ); return [...users, ...childGroupUsers.flat(2)]; - } else if (!isGroupEntity(entity) && entity.spec?.owner) { - const owner = await catalogClient.getEntityByRef( - entity.spec.owner as string, - { token }, - ); - if (owner) { - return mapEntity(owner); + } else if (entity.relations) { + const ownerRef = entity.relations.find( + relation => relation.type === RELATION_OWNED_BY, + )?.targetRef; + + if (ownerRef) { + const owner = await catalogClient.getEntityByRef(ownerRef, { token }); + if (owner) { + return mapEntity(owner); + } } } From 2c50516d51a883e46afb70f65658794eb67bd0b6 Mon Sep 17 00:00:00 2001 From: Phil Kuang Date: Tue, 9 Apr 2024 17:48:36 -0400 Subject: [PATCH 060/107] fix(cookieAuth): prefer issuing cookies against target host instead of origin Signed-off-by: Phil Kuang --- .changeset/curly-bottles-complain.md | 5 +++++ .../implementations/httpAuth/httpAuthServiceFactory.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/curly-bottles-complain.md diff --git a/.changeset/curly-bottles-complain.md b/.changeset/curly-bottles-complain.md new file mode 100644 index 0000000000..c83a3921e2 --- /dev/null +++ b/.changeset/curly-bottles-complain.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +Fix auth cookie issuance for split backend deployments by preferring to set it against the request target host instead of origin diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts index fe927eaa5d..d6f5ceefa8 100644 --- a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -232,7 +232,7 @@ class DefaultHttpAuthService implements HttpAuthService { const externalBaseUrlStr = await this.#discovery.getExternalBaseUrl( this.#pluginId, ); - const externalBaseUrl = new URL(origin ?? externalBaseUrlStr); + const externalBaseUrl = new URL(externalBaseUrlStr ?? origin); const secure = externalBaseUrl.protocol === 'https:' || From e003e0ec87bebe60744bb671fdd12bf7eef43c9c Mon Sep 17 00:00:00 2001 From: Marek Libra Date: Thu, 28 Mar 2024 09:37:43 +0100 Subject: [PATCH 061/107] fix(notifications): export notificationSeverities for reuse The ordered array of constants is exported by the notifications-common for reusability by other plugins. Signed-off-by: Marek Libra --- .changeset/moody-pianos-notice.md | 6 +++++ .../config/vocabularies/Backstage/accept.txt | 1 + .../database/DatabaseNotificationsStore.ts | 14 +++------- plugins/notifications-common/api-report.md | 3 +++ plugins/notifications-common/src/constants.ts | 26 +++++++++++++++++++ plugins/notifications-common/src/index.ts | 1 + 6 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 .changeset/moody-pianos-notice.md create mode 100644 plugins/notifications-common/src/constants.ts diff --git a/.changeset/moody-pianos-notice.md b/.changeset/moody-pianos-notice.md new file mode 100644 index 0000000000..beb686fb6b --- /dev/null +++ b/.changeset/moody-pianos-notice.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-notifications-backend': patch +'@backstage/plugin-notifications-common': patch +--- + +The ordered list of notifications' severities is exported by notifications-common for reusability. diff --git a/.github/vale/config/vocabularies/Backstage/accept.txt b/.github/vale/config/vocabularies/Backstage/accept.txt index 043728013f..b525d7e48e 100644 --- a/.github/vale/config/vocabularies/Backstage/accept.txt +++ b/.github/vale/config/vocabularies/Backstage/accept.txt @@ -475,3 +475,4 @@ Zolotusky zoomable zsh scrollable +severities diff --git a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts index f4f1f174be..ae548a9892 100644 --- a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts +++ b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts @@ -25,6 +25,7 @@ import { import { Notification, NotificationSeverity, + notificationSeverities, } from '@backstage/plugin-notifications-common'; import { Knex } from 'knex'; @@ -49,16 +50,9 @@ const NOTIFICATION_COLUMNS = [ 'saved', ]; -const severities: NotificationSeverity[] = [ - 'critical', - 'high', - 'normal', - 'low', -]; - export const normalizeSeverity = (input?: string): NotificationSeverity => { let lower = (input ?? 'normal').toLowerCase() as NotificationSeverity; - if (severities.indexOf(lower) < 0) { + if (notificationSeverities.indexOf(lower) < 0) { lower = 'normal'; } return lower; @@ -219,8 +213,8 @@ export class DatabaseNotificationsStore implements NotificationsStore { } // or match both if undefined if (options.minimumSeverity !== undefined) { - const idx = severities.indexOf(options.minimumSeverity); - const equalOrHigher = severities.slice(0, idx + 1); + const idx = notificationSeverities.indexOf(options.minimumSeverity); + const equalOrHigher = notificationSeverities.slice(0, idx + 1); query.whereIn('severity', equalOrHigher); } diff --git a/plugins/notifications-common/api-report.md b/plugins/notifications-common/api-report.md index bd01aa7f5a..bdcd202ed3 100644 --- a/plugins/notifications-common/api-report.md +++ b/plugins/notifications-common/api-report.md @@ -39,6 +39,9 @@ export type NotificationReadSignal = { notification_ids: string[]; }; +// @public +export const notificationSeverities: NotificationSeverity[]; + // @public (undocumented) export type NotificationSeverity = 'critical' | 'high' | 'normal' | 'low'; diff --git a/plugins/notifications-common/src/constants.ts b/plugins/notifications-common/src/constants.ts new file mode 100644 index 0000000000..3c0610737c --- /dev/null +++ b/plugins/notifications-common/src/constants.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2024 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 { NotificationSeverity } from './types'; + +/** Ordered list of severities used by the Notifications. + * + * @public */ +export const notificationSeverities: NotificationSeverity[] = [ + 'critical', + 'high', + 'normal', + 'low', +]; diff --git a/plugins/notifications-common/src/index.ts b/plugins/notifications-common/src/index.ts index 8d9f26f07a..7d74c75be8 100644 --- a/plugins/notifications-common/src/index.ts +++ b/plugins/notifications-common/src/index.ts @@ -21,3 +21,4 @@ */ export * from './types'; +export * from './constants'; From cfefd94354d9281f88e64d30537503182c05b365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 10 Apr 2024 13:54:51 +0200 Subject: [PATCH 062/107] update the sign-in resolver docs for the new backend system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelรถw --- docs/auth/identity-resolver--old.md | 379 ++++++++++++++++++++ docs/auth/identity-resolver.md | 519 +++++++++++++++------------- 2 files changed, 649 insertions(+), 249 deletions(-) create mode 100644 docs/auth/identity-resolver--old.md diff --git a/docs/auth/identity-resolver--old.md b/docs/auth/identity-resolver--old.md new file mode 100644 index 0000000000..c1a207484a --- /dev/null +++ b/docs/auth/identity-resolver--old.md @@ -0,0 +1,379 @@ +--- +id: identity-resolver--old +title: Sign-in Identities and Resolvers (Old Backend System) +description: An introduction to Backstage user identities and sign-in resolvers in the old backend system +--- + +:::info +This documentation is written for the old backend which has been replaced by +[the new backend system](../backend-system/index.md), being the default since +Backstage [version 1.24](../releases/v1.24.0.md). If have migrated to the new +backend system, you may want to read [its own article](./identity-resolver.md) +instead. +::: + +By default, every Backstage auth provider is configured only for the use-case of +access delegation. This enables Backstage to request resources and actions from +external systems on behalf of the user, for example re-triggering a build in CI. + +If you want to use an auth provider to sign in users, you need to explicitly configure +it have sign-in enabled and also tell it how the external identities should +be mapped to user identities within Backstage. + +## Quick Start + +> See [providers](../reference/plugin-auth-backend.providers.md) +> for a full list of auth providers and their built-in sign-in resolvers. + +Backstage projects created with `npx @backstage/create-app` come configured with a +sign-in resolver for GitHub guest access. This resolver makes all users share +a single "guest" identity and is only intended as a minimum requirement to quickly +get up and running. You can replace `github` for any of the other providers if you need. + +This resolver should not be used in production, as it uses a single shared identity, +and has no restrictions on who is able to sign-in. Be sure to read through the rest +of this page to understand the Backstage identity system once you need to install +a resolver for your production environment. + +The guest resolver can be useful for testing purposes too, and it looks like this: + +```ts +signIn: { + resolver(_, ctx) { + const userRef = 'user:default/guest' + return ctx.issueToken({ + claims: { + sub: userRef, + ent: [userRef], + }, + }), + }, +}, +``` + +## Backstage User Identity + +A user identity within Backstage is built up from two pieces of information, a +user [entity reference](../features/software-catalog/references.md), and a +set of ownership entity references. +When a user signs in, a Backstage token is generated with these two pieces of information, +which is then used to identify the user within the Backstage ecosystem. + +The user entity reference should uniquely identify the logged in user in Backstage. +It is encouraged that a matching user entity also exists within the Software Catalog, +but it is not required. If the user entity exists in the catalog it can be used to +store additional data about the user. There may even be some plugins that require +this for them to be able to function. + +The ownership references are also entity references, and it is likewise +encouraged that these entities exist within the catalog, but it is not a requirement. +The ownership references are used to determine what the user owns, as a set +of references that the user claims ownership though. For example, a user +Jane (`user:default/jane`) might have the ownership references `user:default/jane`, +`group:default/team-a`, and `group:default/admins`. Given these ownership claims, +any entity that is marked as owned by either of `user:jane`, `team-a`, or `admins` would +be considered owned by Jane. + +The ownership claims often contain the user entity reference itself, but it is not +required. It is also worth noting that the ownership claims can also be used to +resolve other relations similar to ownership, such as a claim for a `maintainer` or +`operator` status. + +The Backstage token that encapsulates the user identity is a JWT. The user entity +reference is stored in the `sub` claim of the payload, while the ownership references +are stored in a custom `ent` claim. Both the user and ownership references should +always be full entity references, as opposed to shorthands like just `jane` or `user:jane`. + +## Sign-in Resolvers + +Signing in a user into Backstage requires a mapping of the user identity from the +third-party auth provider to a Backstage user identity. This mapping can vary quite +a lot between different organizations and auth providers, and because of that there's +no default way to resolve user identities. The auth provider that one wants to use +for sign-in must instead be configured with a sign-in resolver, which is a function +that is responsible for creating this user identity mapping. + +The input to the sign-in resolver function is the result of a successful log in with +the given auth provider, as well as a context object that contains various helpers +for looking up users and issuing tokens. There are also a number of built-in sign-in +resolvers that can be used, which are covered a bit further down. + +Note that while it possible to configure multiple auth providers to be used for sign-in, +you should take care when doing so. It is best to make sure that the different auth +providers either do not have any user overlap, or that any users that are able to log +in with multiple providers always end up with the same Backstage identity. + +### Custom Resolver Example + +Let's look at an example of a custom sign-in resolver for the Google auth provider. +This all typically happens within your `packages/backend/src/plugins/auth.ts` file, +which is responsible for setting up and configuring the auth backend plugin. + +You provide the resolver as part of the options you pass when creating a new auth +provider factory. This means you need to replace the default Google provider with +one that you create. Be sure to also include the existing `defaultAuthProviderFactories` +if you want to keep all of the built-in auth providers installed. + +Now let's look at the example, with the rest of the commentary being made with in +the code comments: + +```ts +// File: packages/backend/src/plugins/auth.ts +import { + createRouter, + providers, + defaultAuthProviderFactories, +} from '@backstage/plugin-auth-backend'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + return await createRouter({ + ...env, + providerFactories: { + ...defaultAuthProviderFactories, + google: providers.google.create({ + signIn: { + resolver: async (info, ctx) => { + const { + profile: { email }, + } = info; + // Profiles are not always guaranteed to to have an email address. + // You can also find more provider-specific information in `info.result`. + // It typically contains a `fullProfile` object as well as ID and/or access + // tokens that you can use for additional lookups. + if (!email) { + throw new Error('User profile contained no email'); + } + + // You can add your own custom validation logic here. + // Logins can be prevented by throwing an error like the one above. + myEmailValidator(email); + + // This example resolver simply uses the local part of the email as the name. + const [name] = email.split('@'); + + // This helper function handles sign-in by looking up a user in the catalog. + // The lookup can be done either by reference, annotations, or custom filters. + // + // The helper also issues a token for the user, using the standard group + // membership logic to determine the ownership references of the user. + return ctx.signInWithCatalogUser({ + entityRef: { name }, + }); + }, + }, + }), + }, + }); +} +``` + +### Built-in Resolvers + +You don't always have to write your own custom resolver. The auth backend plugin provides +built-in resolvers for many of the common sign-in patterns. You access these via the `resolvers` +property of each of the auth provider integrations. For example, the Google provider has +a built in resolver that works just like the one we defined above: + +```ts +// File: packages/backend/src/plugins/auth.ts +export default async function createPlugin( + // ... + return await createRouter({ + // ... + providerFactories: { + // ... + google: providers.google.create({ + signIn: { + resolver: providers.google.resolvers.emailLocalPartMatchingUserEntityName(), + }, + }); + } + }) +) +``` + +There are also other options, like the this one that looks up a user +by matching the `google.com/email` annotation of user entities in the catalog: + +```ts +providers.google.create({ + signIn: { + resolver: providers.google.resolvers.emailMatchingUserEntityAnnotation(), + }, +}); +``` + +## Custom Ownership Resolution + +If you want to have more control over the membership resolution and token generation +that happens during sign-in you can replace `ctx.signInWithCatalogUser` with a set +of lower-level calls: + +```ts +// File: packages/backend/src/plugins/auth.ts +import { getDefaultOwnershipEntityRefs } from '@backstage/plugin-auth-backend'; + +export default async function createPlugin( + // ... + return await createRouter({ + // ... + providerFactories: { + // ... + google: async ({ profile: { email } }, ctx) => { + if (!email) { + throw new Error('User profile contained no email'); + } + + // This step calls the catalog to look up a user entity. You could for example + // replace it with a call to a different external system. + const { entity } = await ctx.findCatalogUser({ + annotations: { + 'acme.org/email': email, + }, + }); + + // In this step we extract the ownership references from the user entity using + // the standard logic. It uses a reference to the entity itself, as well as the + // target of each `memberOf` relation where the target is of the kind `Group`. + // + // If you replace the catalog lookup with something that does not return + // an entity you will need to replace this step as well. + // + // You might also replace it if you for example want to filter out certain groups. + // + // Note that `getDefaultOwnershipEntityRefs` only includes groups to which the + // user has a direct MEMBER_OF relationship. It's perfectly fine to include + // groups that the user is transitively part of in the claims array, but the + // catalog doesn't currently provide a direct way of accessing this list of + // groups. + const ownershipRefs = getDefaultOwnershipEntityRefs(entity); + + // The last step is to issue the token, where we might provide more options in the future. + return ctx.issueToken({ + claims: { + sub: stringifyEntityRef(entity), + ent: ownershipRefs, + }, + }); + }; + } + }) +) +``` + +## Sign-In without Users in the Catalog + +While populating the catalog with organizational data unlocks more powerful ways +to browse your software ecosystem, it might not always be a viable or prioritized +option. However, even if you do not have user entities populated in your catalog, you +can still sign in users. As there are currently no built-in sign-in resolvers for +this scenario you will need to implement your own. + +Signing in a user that doesn't exist in the catalog is as simple as skipping the +catalog lookup step from the above example. Rather than looking up the user, we +instead immediately issue a token using whatever information is available. One caveat +is that it can be tricky to determine the ownership references, although it can +be achieved for example through a lookup to an external service. You typically +want to at least use the user itself as a lone ownership reference. + +Because we no longer use the catalog as an allow-list of users, it is often important +that you limit what users are allowed to sign in. This could be a simple email domain +check like in the example below, or you might for example look up the GitHub organizations +that the user belongs to using the user access token in the provided result object. + +```ts +// File: packages/backend/src/plugins/auth.ts +import { createRouter, providers } from '@backstage/plugin-auth-backend'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; +import { + stringifyEntityRef, + DEFAULT_NAMESPACE, +} from '@backstage/catalog-model'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + return await createRouter({ + ...env, + providerFactories: { + google: providers.google.create({ + signIn: { + resolver: async ({ profile }, ctx) => { + if (!profile.email) { + throw new Error( + 'Login failed, user profile does not contain an email', + ); + } + // Split the email into the local part and the domain. + const [localPart, domain] = profile.email.split('@'); + + // Next we verify the email domain. It is recommended to include this + // kind of check if you don't look up the user in an external service. + if (domain !== 'acme.org') { + throw new Error( + `Login failed, this email ${profile.email} does not belong to the expected domain`, + ); + } + + // By using `stringifyEntityRef` we ensure that the reference is formatted correctly + const userEntity = stringifyEntityRef({ + kind: 'User', + name: localPart, + namespace: DEFAULT_NAMESPACE, + }); + return ctx.issueToken({ + claims: { + sub: userEntity, + ent: [userEntity], + }, + }); + }, + }, + }), + }, + }); +} +``` + +## AuthHandler + +Similar to a custom sign-in resolver, you can also write a custom auth handler +function which is used to verify and convert the auth response into the profile +that will be presented to the user. This is where you can customize things like +display name and profile picture. + +This is also the place where you can do authorization and validation of the user +and throw errors if the user should not be allowed access in Backstage. + +```ts +// File: packages/backend/src/plugins/auth.ts +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + return await createRouter({ + ... + providerFactories: { + google: providers.google.create({ + authHandler: async ({ + fullProfile // Type: passport.Profile, + idToken // Type: (Optional) string, + }) => { + // Custom validation code goes here + return { + profile: { + email, + picture, + displayName, + } + }; + } + }) + } + }) +} +``` diff --git a/docs/auth/identity-resolver.md b/docs/auth/identity-resolver.md index 0a626ef175..aedba5a9c2 100644 --- a/docs/auth/identity-resolver.md +++ b/docs/auth/identity-resolver.md @@ -4,6 +4,14 @@ title: Sign-in Identities and Resolvers description: An introduction to Backstage user identities and sign-in resolvers --- +:::info +This documentation is written for [the new backend +system](../backend-system/index.md) which is the default since Backstage +[version 1.24](../releases/v1.24.0.md). If you are still on the old backend +system, you may want to read [its own article](./identity-resolver--old.md) +instead. +::: + By default, every Backstage auth provider is configured only for the use-case of access delegation. This enables Backstage to request resources and actions from external systems on behalf of the user, for example re-triggering a build in CI. @@ -14,42 +22,24 @@ be mapped to user identities within Backstage. ## Quick Start -> See [providers](../reference/plugin-auth-backend.providers.md) -> for a full list of auth providers and their built-in sign-in resolvers. +Backstage projects created with `npx @backstage/create-app` come configured with +a [guest auth provider](https://backstage.io/docs/auth/guest/provider). This +provider makes all users share a single "guest" identity. This is useful for +testing purposes and quickly getting started locally, but is not safe for use in +production and that particular provider will refuse to work there. -Backstage projects created with `npx @backstage/create-app` come configured with a -sign-in resolver for GitHub guest access. This resolver makes all users share -a single "guest" identity and is only intended as a minimum requirement to quickly -get up and running. You can replace `github` for any of the other providers if you need. - -This resolver should not be used in production, as it uses a single shared identity, -and has no restrictions on who is able to sign-in. Be sure to read through the rest -of this page to understand the Backstage identity system once you need to install -a resolver for your production environment. - -The guest resolver can be useful for testing purposes too, and it looks like this: - -```ts -signIn: { - resolver(_, ctx) { - const userRef = 'user:default/guest' - return ctx.issueToken({ - claims: { - sub: userRef, - ent: [userRef], - }, - }), - }, -}, -``` +Because of this, one of the early things you want to do when standing up your +Backstage instance is to choose a production ready auth provider. See [the auth +overview page](./index.md) for a full list of providers and how to install and +configure them. ## Backstage User Identity -A user identity within Backstage is built up from two pieces of information, a -user [entity reference](../features/software-catalog/references.md), and a -set of ownership entity references. -When a user signs in, a Backstage token is generated with these two pieces of information, -which is then used to identify the user within the Backstage ecosystem. +A user identity within Backstage is built up from two main pieces of +information: a user [entity +reference](../features/software-catalog/references.md), and a set of ownership +references. When a user signs in, a Backstage token is generated which is then +used to identify the user within the Backstage ecosystem. The user entity reference should uniquely identify the logged in user in Backstage. It is encouraged that a matching user entity also exists within the Software Catalog, @@ -71,10 +61,13 @@ required. It is also worth noting that the ownership claims can also be used to resolve other relations similar to ownership, such as a claim for a `maintainer` or `operator` status. -The Backstage token that encapsulates the user identity is a JWT. The user entity -reference is stored in the `sub` claim of the payload, while the ownership references -are stored in a custom `ent` claim. Both the user and ownership references should -always be full entity references, as opposed to shorthands like just `jane` or `user:jane`. +The Backstage token that encapsulates the user identity is a JWT. The user +entity reference is stored in the `sub` claim of the payload, while the +ownership references are stored in a custom `ent` claim in the old backend +system but instead is made available through a user info API endpoint on the +auth backend in the new system. Both the user and ownership references should +always be full entity references, as opposed to shorthands like just `jane` or +`user:jane`. ## Sign-in Resolvers @@ -90,116 +83,156 @@ the given auth provider, as well as a context object that contains various helpe for looking up users and issuing tokens. There are also a number of built-in sign-in resolvers that can be used, which are covered a bit further down. -Note that while it possible to configure multiple auth providers to be used for sign-in, -you should take care when doing so. It is best to make sure that the different auth -providers either do not have any user overlap, or that any users that are able to log -in with multiple providers always end up with the same Backstage identity. +Note that while it possible to configure multiple auth providers to be used for +sign-in, you should take care when doing so. It is best to make sure that the +different auth providers either do not have any user overlap, or that any users +that are able to log in with multiple providers always end up with the same +Backstage identity. For most organizations, it makes the most sense to provide +only one sign-in method. -### Custom Resolver Example +### Using Builtin Resolvers -Let's look at an example of a custom sign-in resolver for the Google auth provider. -This all typically happens within your `packages/backend/src/plugins/auth.ts` file, -which is responsible for setting up and configuring the auth backend plugin. +Most auth providers come with a set of builtin sign in providers that you can +choose from. They target the most common use cases, and if they fit your needs, +you can pick one or more of them without having to write any code at all. You +still have to make a choice - as mentioned above, even if there are a set of +builtins, none of them are selected by default. -You provide the resolver as part of the options you pass when creating a new auth -provider factory. This means you need to replace the default Google provider with -one that you create. Be sure to also include the existing `defaultAuthProviderFactories` -if you want to keep all of the built-in auth providers installed. +You set up builtin sign in resolvers using [your app-config](../conf/index.md), +next to the respective provider's configuration. Here's an example for Microsoft +Azure: -Now let's look at the example, with the rest of the commentary being made with in -the code comments: +```yaml title="in e.g. app-config.yaml" +auth: + environment: development + providers: + microsoft: + development: + clientId: ${AZURE_CLIENT_ID} + clientSecret: ${AZURE_CLIENT_SECRET} + tenantId: ${AZURE_TENANT_ID} + signIn: + resolvers: + - resolver: emailMatchingUserEntityAnnotation + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName +``` + +Note that in this instance it lists several resolvers, which means that the +framework will try them one by one until one succeeds. If none of them do, the +sign in attempt is rejected. + +To find the list of available resolvers, consult the documentation of the +respective provider. + +### Building Custom Resolvers + +If the builtins don't work for you, you can also provide a completely custom +sign-in resolver, through code. If you follow the installation instructions of +[one of the available providers](./index.md), you will likely have added a +dependency to your backend along with a line of code and some configuration. + +Using GitHub as an example, this is the relevant parts of the backend code: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +backend.add(import('@backstage/plugin-auth-backend-module-github-provider')); +``` + +When you want to supply a custom sign-in resolver, as a general pattern you +remove that last import and instead construct your own provider using the +facilities from the same package. You can leave the config unchanged from +before. + +```ts title="in packages/backend/src/index.ts" +/* highlight-add-start */ +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { githubAuthenticator } from '@backstage/plugin-auth-backend-module-github-provider'; +import { + authProvidersExtensionPoint, + createOAuthProviderFactory, +} from '@backstage/plugin-auth-node'; + +const customAuth = createBackendModule({ + // This ID must be exactly "auth" because that's the plugin it targets + pluginId: 'auth', + // This ID must be unique, but can be anything + moduleId: 'custom-auth-provider', + register(reg) { + reg.registerInit({ + deps: { providers: authProvidersExtensionPoint }, + async init({ providers }) { + providers.registerProvider({ + // This ID must match the actual provider config, e.g. addressing + // auth.providers.github means that this must be "github". + providerId: 'github', + // Use createProxyAuthProviderFactory instead if it's one of the proxy + // based providers rather than an OAuth based one + factory: createOAuthProviderFactory({ + authenticator: githubAuthenticator, + async signInResolver(info, ctx) { + /********************************************************************* + * Custom resolver code goes here, see farther down in this article! * + * "info" is the sign in result from the upstream (github here), and * + * "ctx" contains useful utilities for token issuance etc. * + *********************************************************************/ + }, + }), + }); + }, + }); + }, +}); +/* highlight-add-end */ + +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-remove-next-line */ +backend.add(import('@backstage/plugin-auth-backend-module-github-provider')); +/* highlight-add-next-line */ +backend.add(customAuth); +``` + +The `createOAuthProviderFactory` / `createProxyAuthProviderFactory` functions +have additional options for profile and state transforms - not covered here, but +good to know about if you need them. + +So what would the body of a typical sign in resolver callback look like? Here's +an example: ```ts -// File: packages/backend/src/plugins/auth.ts -import { - createRouter, - providers, - defaultAuthProviderFactories, -} from '@backstage/plugin-auth-backend'; -import { Router } from 'express'; -import { PluginEnvironment } from '../types'; +// ... +async signInResolver(info, ctx) { + const { profile: { email } } = info; -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - return await createRouter({ - ...env, - providerFactories: { - ...defaultAuthProviderFactories, - google: providers.google.create({ - signIn: { - resolver: async (info, ctx) => { - const { - profile: { email }, - } = info; - // Profiles are not always guaranteed to to have an email address. - // You can also find more provider-specific information in `info.result`. - // It typically contains a `fullProfile` object as well as ID and/or access - // tokens that you can use for additional lookups. - if (!email) { - throw new Error('User profile contained no email'); - } + // Profiles are not always guaranteed to to have an email address. + // You can also find more provider-specific information in `info.result`. + // It typically contains a `fullProfile` object as well as ID and/or access + // tokens that you can use for additional lookups. + if (!email) { + throw new Error('User profile contained no email'); + } - // You can add your own custom validation logic here. - // Logins can be prevented by throwing an error like the one above. - myEmailValidator(email); + // You can add your own custom validation logic here. + // Logins can be prevented by throwing an error like the one above. + myEmailValidator(email); - // This example resolver simply uses the local part of the email as the name. - const [name] = email.split('@'); + // This example resolver simply uses the local part of the email as the name. + const [name] = email.split('@'); - // This helper function handles sign-in by looking up a user in the catalog. - // The lookup can be done either by reference, annotations, or custom filters. - // - // The helper also issues a token for the user, using the standard group - // membership logic to determine the ownership references of the user. - return ctx.signInWithCatalogUser({ - entityRef: { name }, - }); - }, - }, - }), - }, + // This helper function handles sign-in by looking up a user in the catalog. + // The lookup can be done either by reference, annotations, or custom filters. + // + // The helper also issues a token for the user, using the standard group + // membership logic to determine the ownership references of the user. + // + // There are a number of other methods on the ctx, feel free to explore them! + return ctx.signInWithCatalogUser({ + entityRef: { name }, }); } ``` -### Built-in Resolvers - -You don't always have to write your own custom resolver. The auth backend plugin provides -built-in resolvers for many of the common sign-in patterns. You access these via the `resolvers` -property of each of the auth provider integrations. For example, the Google provider has -a built in resolver that works just like the one we defined above: - -```ts -// File: packages/backend/src/plugins/auth.ts -export default async function createPlugin( - // ... - return await createRouter({ - // ... - providerFactories: { - // ... - google: providers.google.create({ - signIn: { - resolver: providers.google.resolvers.emailLocalPartMatchingUserEntityName(), - }, - }); - } - }) -) -``` - -There are also other options, like the this one that looks up a user -by matching the `google.com/email` annotation of user entities in the catalog: - -```ts -providers.google.create({ - signIn: { - resolver: providers.google.resolvers.emailMatchingUserEntityAnnotation(), - }, -}); -``` - -## Custom Ownership Resolution +### Custom Ownership Resolution If you want to have more control over the membership resolution and token generation that happens during sign-in you can replace `ctx.signInWithCatalogUser` with a set @@ -209,55 +242,48 @@ of lower-level calls: // File: packages/backend/src/plugins/auth.ts import { getDefaultOwnershipEntityRefs } from '@backstage/plugin-auth-backend'; -export default async function createPlugin( - // ... - return await createRouter({ - // ... - providerFactories: { - // ... - google: async ({ profile: { email } }, ctx) => { - if (!email) { - throw new Error('User profile contained no email'); - } +// ... +async signInResolver({ profile: { email} }, ctx) { + if (!email) { + throw new Error('User profile contained no email'); + } - // This step calls the catalog to look up a user entity. You could for example - // replace it with a call to a different external system. - const { entity } = await ctx.findCatalogUser({ - annotations: { - 'acme.org/email': email, - }, - }); + // This step calls the catalog to look up a user entity. You could for example + // replace it with a call to a different external system. + const { entity } = await ctx.findCatalogUser({ + annotations: { + 'acme.org/email': email, + }, + }); - // In this step we extract the ownership references from the user entity using - // the standard logic. It uses a reference to the entity itself, as well as the - // target of each `memberOf` relation where the target is of the kind `Group`. - // - // If you replace the catalog lookup with something that does not return - // an entity you will need to replace this step as well. - // - // You might also replace it if you for example want to filter out certain groups. - // - // Note that `getDefaultOwnershipEntityRefs` only includes groups to which the - // user has a direct MEMBER_OF relationship. It's perfectly fine to include - // groups that the user is transitively part of in the claims array, but the - // catalog doesn't currently provide a direct way of accessing this list of - // groups. - const ownershipRefs = getDefaultOwnershipEntityRefs(entity); + // In this step we extract the ownership references from the user entity using + // the standard logic. It uses a reference to the entity itself, as well as the + // target of each `memberOf` relation where the target is of the kind `Group`. + // + // If you replace the catalog lookup with something that does not return + // an entity you will need to replace this step as well. + // + // You might also replace it if you for example want to filter out certain groups. + // + // Note that `getDefaultOwnershipEntityRefs` only includes groups to which the + // user has a direct MEMBER_OF relationship. It's perfectly fine to include + // groups that the user is transitively part of in the claims array, but the + // catalog doesn't currently provide a direct way of accessing this list of + // groups. + const ownershipRefs = getDefaultOwnershipEntityRefs(entity); - // The last step is to issue the token, where we might provide more options in the future. - return ctx.issueToken({ - claims: { - sub: stringifyEntityRef(entity), - ent: ownershipRefs, - }, - }); - }; - } - }) -) + // The last step is to issue the token, where we might provide more options in the + // future. + return ctx.issueToken({ + claims: { + sub: stringifyEntityRef(entity), + ent: ownershipRefs, + }, + }); +} ``` -## Sign-In without Users in the Catalog +### Sign-In without Users in the Catalog While populating the catalog with organizational data unlocks more powerful ways to browse your software ecosystem, it might not always be a viable or prioritized @@ -278,63 +304,44 @@ check like in the example below, or you might for example look up the GitHub org that the user belongs to using the user access token in the provided result object. ```ts -// File: packages/backend/src/plugins/auth.ts -import { createRouter, providers } from '@backstage/plugin-auth-backend'; -import { Router } from 'express'; -import { PluginEnvironment } from '../types'; -import { - stringifyEntityRef, - DEFAULT_NAMESPACE, -} from '@backstage/catalog-model'; +import { stringifyEntityRef, DEFAULT_NAMESPACE } from '@backstage/catalog-model'; -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - return await createRouter({ - ...env, - providerFactories: { - google: providers.google.create({ - signIn: { - resolver: async ({ profile }, ctx) => { - if (!profile.email) { - throw new Error( - 'Login failed, user profile does not contain an email', - ); - } - // Split the email into the local part and the domain. - const [localPart, domain] = profile.email.split('@'); +// ... +async signInResolver({ profile }, ctx) { + if (!profile.email) { + throw new Error( + 'Login failed, user profile does not contain an email', + ); + } + // Split the email into the local part and the domain. + const [localPart, domain] = profile.email.split('@'); - // Next we verify the email domain. It is recommended to include this - // kind of check if you don't look up the user in an external service. - if (domain !== 'acme.org') { - throw new Error( - `Login failed, this email ${profile.email} does not belong to the expected domain`, - ); - } + // Next we verify the email domain. It is recommended to include this + // kind of check if you don't look up the user in an external service. + if (domain !== 'acme.org') { + throw new Error( + `Login failed, '${profile.email}' does not belong to the expected domain`, + ); + } - // By using `stringifyEntityRef` we ensure that the reference is formatted correctly - const userEntity = stringifyEntityRef({ - kind: 'User', - name: localPart, - namespace: DEFAULT_NAMESPACE, - }); - return ctx.issueToken({ - claims: { - sub: userEntity, - ent: [userEntity], - }, - }); - }, - }, - }), + // By using `stringifyEntityRef` we ensure that the reference is formatted correctly + const userEntity = stringifyEntityRef({ + kind: 'User', + name: localPart, + namespace: DEFAULT_NAMESPACE, + }); + return ctx.issueToken({ + claims: { + sub: userEntity, + ent: [userEntity], }, }); } ``` -## AuthHandler +## Profile Transforms -Similar to a custom sign-in resolver, you can also write a custom auth handler +Similar to a custom sign-in resolver, you can also write a custom profile transform function which is used to verify and convert the auth response into the profile that will be presented to the user. This is where you can customize things like display name and profile picture. @@ -343,29 +350,43 @@ This is also the place where you can do authorization and validation of the user and throw errors if the user should not be allowed access in Backstage. ```ts -// File: packages/backend/src/plugins/auth.ts -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - return await createRouter({ - ... - providerFactories: { - google: providers.google.create({ - authHandler: async ({ - fullProfile // Type: passport.Profile, - idToken // Type: (Optional) string, - }) => { - // Custom validation code goes here - return { - profile: { - email, - picture, - displayName, - } - }; - } - }) - } - }) -} +const customAuth = createBackendModule({ + // This ID must be exactly "auth" because that's the plugin it targets + pluginId: 'auth', + // This ID must be unique, but can be anything + moduleId: 'custom-auth-provider', + register(reg) { + reg.registerInit({ + deps: { providers: authProvidersExtensionPoint }, + async init({ providers }) { + providers.registerProvider({ + // This ID must match the actual provider config, e.g. addressing + // auth.providers.github means that this must be "github". + providerId: 'github', + // Use createProxyAuthProviderFactory instead if it's one of the proxy + // based providers rather than an OAuth based one + factory: createOAuthProviderFactory({ + authenticator: githubAuthenticator, + async profileTransform(result, ctx) { + /********************************************************************** + * Custom transform code goes here! * + * "info" is the sign in result from the upstream (github here), and * + * "ctx" contains useful utilities. * + **********************************************************************/ + return { + profile: { + email, + picture, + displayName, + }, + }; + }, + }), + }); + }, + }); + }, +}); ``` + +Remember to `backend.add` the created module just like above. From 9a41a7bfa8030340f9eeaa2c3e0c89e3924ca021 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Fri, 1 Mar 2024 10:27:11 +0200 Subject: [PATCH 063/107] chore: migrate to new backend in local development additionally allow defining custom sidebar item for dev app page. Signed-off-by: Heikki Hellgren --- .changeset/light-eggs-switch.md | 5 + .changeset/rude-hats-bow.md | 8 + packages/dev-utils/api-report.md | 3 + packages/dev-utils/src/devApp/render.tsx | 40 +++-- plugins/notifications-backend/dev/index.ts | 64 ++++++++ plugins/notifications-backend/package.json | 5 + plugins/notifications-backend/src/run.ts | 32 ---- .../src/service/standaloneServer.ts | 150 ------------------ plugins/notifications/dev/index.tsx | 9 +- plugins/signals-backend/dev/index.ts | 59 +++++++ plugins/signals-backend/package.json | 2 + plugins/signals-backend/src/run.ts | 32 ---- .../src/service/standaloneServer.ts | 112 ------------- plugins/signals/dev/index.tsx | 31 ++-- yarn.lock | 7 + 15 files changed, 212 insertions(+), 347 deletions(-) create mode 100644 .changeset/light-eggs-switch.md create mode 100644 .changeset/rude-hats-bow.md create mode 100644 plugins/notifications-backend/dev/index.ts delete mode 100644 plugins/notifications-backend/src/run.ts delete mode 100644 plugins/notifications-backend/src/service/standaloneServer.ts create mode 100644 plugins/signals-backend/dev/index.ts delete mode 100644 plugins/signals-backend/src/run.ts delete mode 100644 plugins/signals-backend/src/service/standaloneServer.ts diff --git a/.changeset/light-eggs-switch.md b/.changeset/light-eggs-switch.md new file mode 100644 index 0000000000..3fbb77b0d8 --- /dev/null +++ b/.changeset/light-eggs-switch.md @@ -0,0 +1,5 @@ +--- +'@backstage/dev-utils': patch +--- + +Allow defining custom side bar item for page diff --git a/.changeset/rude-hats-bow.md b/.changeset/rude-hats-bow.md new file mode 100644 index 0000000000..0bd84617c0 --- /dev/null +++ b/.changeset/rude-hats-bow.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-notifications-backend': patch +'@backstage/plugin-signals-backend': patch +'@backstage/plugin-notifications': patch +'@backstage/plugin-signals': patch +--- + +Migrate signals and notifications to the new backend in local development diff --git a/packages/dev-utils/api-report.md b/packages/dev-utils/api-report.md index 3f21ba5502..c44f7328b9 100644 --- a/packages/dev-utils/api-report.md +++ b/packages/dev-utils/api-report.md @@ -14,6 +14,7 @@ import { GridProps } from '@material-ui/core/Grid'; import { IconComponent } from '@backstage/core-plugin-api'; import { PropsWithChildren } from 'react'; import { ReactNode } from 'react'; +import { RouteRef } from '@backstage/core-plugin-api'; // @public export function createDevApp(): DevAppBuilder; @@ -42,6 +43,8 @@ export type DevAppPageOptions = { children?: JSX.Element; title?: string; icon?: IconComponent; + sideBarItem?: JSX.Element; + routeRef?: RouteRef; }; // @public (undocumented) diff --git a/packages/dev-utils/src/devApp/render.tsx b/packages/dev-utils/src/devApp/render.tsx index 79834cddc8..1b57a4b9b7 100644 --- a/packages/dev-utils/src/devApp/render.tsx +++ b/packages/dev-utils/src/devApp/render.tsx @@ -44,7 +44,7 @@ import { } from '@backstage/integration-react'; import Box from '@material-ui/core/Box'; import BookmarkIcon from '@material-ui/icons/Bookmark'; -import React, { ComponentType, ReactNode, PropsWithChildren } from 'react'; +import React, { ComponentType, PropsWithChildren, ReactNode } from 'react'; import { createRoutesFromChildren, Route } from 'react-router-dom'; import { SidebarThemeSwitcher } from './SidebarThemeSwitcher'; import 'react-dom'; @@ -80,6 +80,9 @@ export type DevAppPageOptions = { children?: JSX.Element; title?: string; icon?: IconComponent; + sideBarItem?: JSX.Element; + + routeRef?: RouteRef; }; /** @@ -141,7 +144,9 @@ export class DevAppBuilder { this.defaultPage = path; } - if (opts.title) { + if (opts.sideBarItem) { + this.sidebarItems.push(opts.sideBarItem); + } else if (opts.title) { this.sidebarItems.push( , ); } - this.routes.push( - , - ); + + if (opts.routeRef) { + const Elem = () => <>{opts.element}; + attachComponentData(Elem, 'core.mountPoint', opts.routeRef); + + this.routes.push( + } + children={opts.children} + />, + ); + } else { + this.routes.push( + , + ); + } return this; } diff --git a/plugins/notifications-backend/dev/index.ts b/plugins/notifications-backend/dev/index.ts new file mode 100644 index 0000000000..987f984dcb --- /dev/null +++ b/plugins/notifications-backend/dev/index.ts @@ -0,0 +1,64 @@ +/* + * Copyright 2024 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 { createBackend } from '@backstage/backend-defaults'; +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { notificationService } from '@backstage/plugin-notifications-node'; + +const notificationsDebug = createBackendPlugin({ + pluginId: 'notifications-debug', + register(env) { + env.registerInit({ + deps: { + notifications: notificationService, + lifecycle: coreServices.lifecycle, + }, + async init({ notifications, lifecycle }) { + let interval: NodeJS.Timeout | undefined; + lifecycle.addStartupHook(async () => { + interval = setInterval(async () => { + await notifications.send({ + recipients: { + type: 'entity', + entityRef: 'user:development/guest', + }, + payload: { title: 'Test notification' }, + }); + }, 5000); + }); + + lifecycle.addShutdownHook(async () => { + if (interval) { + clearInterval(interval); + } + }); + }, + }); + }, +}); + +const backend = createBackend(); +backend.add(import('@backstage/plugin-events-backend/alpha')); +backend.add(import('@backstage/plugin-signals-backend')); +backend.add(import('@backstage/plugin-auth-backend')); +backend.add(import('@backstage/plugin-auth-backend-module-guest-provider')); +backend.add(import('../src')); +backend.add(notificationsDebug); + +backend.start(); diff --git a/plugins/notifications-backend/package.json b/plugins/notifications-backend/package.json index 15297856fb..cdb7642301 100644 --- a/plugins/notifications-backend/package.json +++ b/plugins/notifications-backend/package.json @@ -51,8 +51,13 @@ "yn": "^4.0.0" }, "devDependencies": { + "@backstage/backend-defaults": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-auth-backend": "workspace:^", + "@backstage/plugin-auth-backend-module-guest-provider": "workspace:^", + "@backstage/plugin-events-backend": "workspace:^", + "@backstage/plugin-signals-backend": "workspace:^", "@types/express": "^4.17.6", "@types/supertest": "^2.0.8", "msw": "^1.0.0", diff --git a/plugins/notifications-backend/src/run.ts b/plugins/notifications-backend/src/run.ts deleted file mode 100644 index d299ed23e9..0000000000 --- a/plugins/notifications-backend/src/run.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 { getRootLogger } from '@backstage/backend-common'; -import yn from 'yn'; -import { startStandaloneServer } from './service/standaloneServer'; - -const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007; -const enableCors = yn(process.env.PLUGIN_CORS, { default: false }); -const logger = getRootLogger(); - -startStandaloneServer({ port, enableCors, logger }).catch(err => { - logger.error(err); - process.exit(1); -}); - -process.on('SIGINT', () => { - logger.info('CTRL+C pressed; exiting.'); - process.exit(0); -}); diff --git a/plugins/notifications-backend/src/service/standaloneServer.ts b/plugins/notifications-backend/src/service/standaloneServer.ts deleted file mode 100644 index 5445d9b6b4..0000000000 --- a/plugins/notifications-backend/src/service/standaloneServer.ts +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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 { - createLegacyAuthAdapters, - createServiceBuilder, - HostDiscovery, - loadBackendConfig, - PluginDatabaseManager, - ServerTokenManager, -} from '@backstage/backend-common'; -import { Server } from 'http'; -import { Logger } from 'winston'; -import { createRouter } from './router'; -import Knex from 'knex'; -import { IdentityApi } from '@backstage/plugin-auth-node'; -import { Request } from 'express'; -import { - CatalogApi, - CatalogRequestOptions, - GetEntitiesByRefsRequest, -} from '@backstage/catalog-client'; -import { DefaultSignalsService } from '@backstage/plugin-signals-node'; -import { - EventParams, - EventsService, - EventsServiceSubscribeOptions, -} from '@backstage/plugin-events-node'; -import { - AuthService, - HttpAuthService, - UserInfoService, -} from '@backstage/backend-plugin-api'; - -export interface ServerOptions { - port: number; - enableCors: boolean; - logger: Logger; -} - -export async function startStandaloneServer( - options: ServerOptions, -): Promise { - const logger = options.logger.child({ service: 'notifications-backend' }); - logger.debug('Starting application server...'); - - const config = await loadBackendConfig({ logger, argv: process.argv }); - const db = Knex(config.get('backend.database')); - - const tokenManager = ServerTokenManager.fromConfig(config, { - logger, - }); - const discovery = HostDiscovery.fromConfig(config); - - const dbMock: PluginDatabaseManager = { - async getClient() { - return db; - }, - }; - - const catalogApi = { - async getEntitiesByRefs( - _request: GetEntitiesByRefsRequest, - __options?: CatalogRequestOptions, - ) { - return { - items: [ - { - apiVersion: 'backstage.io/v1alpha1', - kind: 'User', - metadata: { name: 'user', namespace: 'default' }, - spec: {}, - }, - ], - }; - }, - } as Partial as CatalogApi; - - const identityMock: IdentityApi = { - async getIdentity({ request }: { request: Request }) { - const token = request.headers.authorization?.split(' ')[1]; - return { - identity: { - type: 'user', - ownershipEntityRefs: [], - userEntityRef: 'user:default/guest', - }, - token: token || 'no-token', - }; - }, - }; - - const mockSubscribers: EventsServiceSubscribeOptions[] = []; - const events: EventsService = { - async publish(params: EventParams): Promise { - mockSubscribers.forEach(sub => sub.onEvent(params)); - }, - async subscribe(subscription: EventsServiceSubscribeOptions) { - mockSubscribers.push(subscription); - }, - }; - - const signalService = DefaultSignalsService.create({ events }); - // TODO: Move to use services instead this hack - const { auth, httpAuth, userInfo } = createLegacyAuthAdapters< - any, - { auth: AuthService; httpAuth: HttpAuthService; userInfo: UserInfoService } - >({ - identity: identityMock, - tokenManager, - discovery, - }); - - const router = await createRouter({ - logger, - database: dbMock, - catalog: catalogApi, - discovery, - signals: signalService, - auth, - httpAuth, - userInfo, - }); - - let service = createServiceBuilder(module) - .setPort(options.port) - .addRouter('/notifications', router); - if (options.enableCors) { - service = service.enableCors({ origin: 'http://localhost:3000' }); - } - - return await service.start().catch(err => { - logger.error(err); - process.exit(1); - }); -} - -module.hot?.accept(); diff --git a/plugins/notifications/dev/index.tsx b/plugins/notifications/dev/index.tsx index f4ea31f4ab..27bfe23842 100644 --- a/plugins/notifications/dev/index.tsx +++ b/plugins/notifications/dev/index.tsx @@ -16,12 +16,17 @@ import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; import { notificationsPlugin } from '../src/plugin'; +import { NotificationsPage } from '../src/components/NotificationsPage'; +import { NotificationsSidebarItem } from '../src'; +import { rootRouteRef } from '../src/routes'; +// TODO: How to sign in here as guest user? createDevApp() .registerPlugin(notificationsPlugin) .addPage({ - element:
, - title: 'Root Page', + element: , path: '/notifications', + sideBarItem: , + routeRef: rootRouteRef, }) .render(); diff --git a/plugins/signals-backend/dev/index.ts b/plugins/signals-backend/dev/index.ts new file mode 100644 index 0000000000..ae98e54eed --- /dev/null +++ b/plugins/signals-backend/dev/index.ts @@ -0,0 +1,59 @@ +/* + * Copyright 2024 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 { createBackend } from '@backstage/backend-defaults'; +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { signalService } from '@backstage/plugin-signals-node'; + +const signalDebug = createBackendPlugin({ + pluginId: 'signals-debug', + register(env) { + env.registerInit({ + deps: { + signals: signalService, + lifecycle: coreServices.lifecycle, + }, + async init({ signals, lifecycle }) { + let interval: NodeJS.Timeout | undefined; + lifecycle.addStartupHook(async () => { + interval = setInterval(async () => { + await signals.publish<{ date: string }>({ + channel: 'debug', + message: { date: new Date().toISOString() }, + recipients: { type: 'broadcast' }, + }); + }, 1000); + }); + + lifecycle.addShutdownHook(async () => { + if (interval) { + clearInterval(interval); + } + }); + }, + }); + }, +}); + +const backend = createBackend(); +backend.add(import('@backstage/plugin-events-backend/alpha')); +backend.add(import('../src')); +backend.add(signalDebug); + +backend.start(); diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json index 24682829e8..923b4bb150 100644 --- a/plugins/signals-backend/package.json +++ b/plugins/signals-backend/package.json @@ -45,7 +45,9 @@ "yn": "^4.0.0" }, "devDependencies": { + "@backstage/backend-defaults": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-events-backend": "workspace:^", "@types/supertest": "^2.0.8", "msw": "^1.0.0", "supertest": "^6.2.4" diff --git a/plugins/signals-backend/src/run.ts b/plugins/signals-backend/src/run.ts deleted file mode 100644 index d299ed23e9..0000000000 --- a/plugins/signals-backend/src/run.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 { getRootLogger } from '@backstage/backend-common'; -import yn from 'yn'; -import { startStandaloneServer } from './service/standaloneServer'; - -const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007; -const enableCors = yn(process.env.PLUGIN_CORS, { default: false }); -const logger = getRootLogger(); - -startStandaloneServer({ port, enableCors, logger }).catch(err => { - logger.error(err); - process.exit(1); -}); - -process.on('SIGINT', () => { - logger.info('CTRL+C pressed; exiting.'); - process.exit(0); -}); diff --git a/plugins/signals-backend/src/service/standaloneServer.ts b/plugins/signals-backend/src/service/standaloneServer.ts deleted file mode 100644 index efb7ecedee..0000000000 --- a/plugins/signals-backend/src/service/standaloneServer.ts +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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 { - createServiceBuilder, - HostDiscovery, - loadBackendConfig, -} from '@backstage/backend-common'; -import { Server } from 'http'; -import { Logger } from 'winston'; -import { createRouter } from './router'; -import { DefaultSignalsService } from '@backstage/plugin-signals-node'; -import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; -import { - EventParams, - EventsService, - EventsServiceSubscribeOptions, -} from '@backstage/plugin-events-node'; -import { - BackstageCredentials, - BackstageUserInfo, - UserInfoService, -} from '@backstage/backend-plugin-api'; - -export interface ServerOptions { - port: number; - enableCors: boolean; - logger: Logger; -} - -export async function startStandaloneServer( - options: ServerOptions, -): Promise { - const logger = options.logger.child({ service: 'signals-backend' }); - logger.debug('Starting application server...'); - const config = await loadBackendConfig({ logger, argv: process.argv }); - const discovery = HostDiscovery.fromConfig(config); - - const identity = DefaultIdentityClient.create({ - discovery, - issuer: await discovery.getExternalBaseUrl('auth'), - }); - - const mockSubscribers: EventsServiceSubscribeOptions[] = []; - const events: EventsService = { - async publish(params: EventParams): Promise { - mockSubscribers.forEach(sub => sub.onEvent(params)); - }, - async subscribe(subscription: EventsServiceSubscribeOptions) { - mockSubscribers.push(subscription); - }, - }; - - const signals = DefaultSignalsService.create({ - events, - }); - - const userInfo: UserInfoService = { - async getUserInfo(_: BackstageCredentials): Promise { - return { - userEntityRef: 'user:default/guest', - ownershipEntityRefs: ['user:default/guest'], - }; - }, - }; - - const router = await createRouter({ - logger, - identity, - events, - discovery, - userInfo, - }); - - let service = createServiceBuilder(module) - .setPort(options.port) - .addRouter('/signals', router); - if (options.enableCors) { - service = service.enableCors({ origin: 'http://localhost:3000' }); - } - - let server: Promise; - try { - server = service.start(); - - setInterval(() => { - signals.publish({ - recipients: { type: 'broadcast' }, - channel: 'test', - message: { hello: 'world' }, - }); - }, 5000); - } catch (err) { - logger.error(err); - process.exit(1); - } - return server; -} - -module.hot?.accept(); diff --git a/plugins/signals/dev/index.tsx b/plugins/signals/dev/index.tsx index 2b22424eee..629c820a8e 100644 --- a/plugins/signals/dev/index.tsx +++ b/plugins/signals/dev/index.tsx @@ -16,20 +16,33 @@ import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; import { signalsPlugin } from '../src/plugin'; -import { Content, Header, Page } from '@backstage/core-components'; +import { CodeSnippet, Content, Header, Page } from '@backstage/core-components'; import Typography from '@material-ui/core/Typography'; +import { useSignal } from '@backstage/plugin-signals-react'; + +const SignalsDebugPage = () => { + const { lastSignal } = useSignal('debug'); + return ( + +
+ + Last signal: + + {lastSignal ? ( + + ) : ( + 'Not received' + )} + + + + ); +}; createDevApp() .registerPlugin(signalsPlugin) .addPage({ title: 'Debug', - element: ( - -
- - TODO - - - ), + element: , }) .render(); diff --git a/yarn.lock b/yarn.lock index bff13e8dd1..e392282e15 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7899,6 +7899,7 @@ __metadata: resolution: "@backstage/plugin-notifications-backend@workspace:plugins/notifications-backend" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" @@ -7906,10 +7907,14 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/plugin-auth-backend": "workspace:^" + "@backstage/plugin-auth-backend-module-guest-provider": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" + "@backstage/plugin-events-backend": "workspace:^" "@backstage/plugin-events-node": "workspace:^" "@backstage/plugin-notifications-common": "workspace:^" "@backstage/plugin-notifications-node": "workspace:^" + "@backstage/plugin-signals-backend": "workspace:^" "@backstage/plugin-signals-node": "workspace:^" "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 @@ -9276,10 +9281,12 @@ __metadata: resolution: "@backstage/plugin-signals-backend@workspace:plugins/signals-backend" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" + "@backstage/plugin-events-backend": "workspace:^" "@backstage/plugin-events-node": "workspace:^" "@backstage/plugin-signals-node": "workspace:^" "@backstage/types": "workspace:^" From 282f62f49001da10760771b64cde0cc80b200be3 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Fri, 8 Mar 2024 08:11:56 +0200 Subject: [PATCH 064/107] chore: use code snippet for signal debugging Signed-off-by: Heikki Hellgren --- packages/dev-utils/api-report.md | 4 +- packages/dev-utils/src/devApp/render.tsx | 38 ++++++------------- plugins/notifications-backend/dev/index.ts | 3 +- .../src/service/router.ts | 6 ++- plugins/notifications/dev/index.tsx | 7 +--- 5 files changed, 19 insertions(+), 39 deletions(-) diff --git a/packages/dev-utils/api-report.md b/packages/dev-utils/api-report.md index c44f7328b9..d30df29200 100644 --- a/packages/dev-utils/api-report.md +++ b/packages/dev-utils/api-report.md @@ -14,7 +14,6 @@ import { GridProps } from '@material-ui/core/Grid'; import { IconComponent } from '@backstage/core-plugin-api'; import { PropsWithChildren } from 'react'; import { ReactNode } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; // @public export function createDevApp(): DevAppBuilder; @@ -43,8 +42,7 @@ export type DevAppPageOptions = { children?: JSX.Element; title?: string; icon?: IconComponent; - sideBarItem?: JSX.Element; - routeRef?: RouteRef; + sidebarItem?: JSX.Element; }; // @public (undocumented) diff --git a/packages/dev-utils/src/devApp/render.tsx b/packages/dev-utils/src/devApp/render.tsx index 1b57a4b9b7..26fd96052b 100644 --- a/packages/dev-utils/src/devApp/render.tsx +++ b/packages/dev-utils/src/devApp/render.tsx @@ -80,9 +80,7 @@ export type DevAppPageOptions = { children?: JSX.Element; title?: string; icon?: IconComponent; - sideBarItem?: JSX.Element; - - routeRef?: RouteRef; + sidebarItem?: JSX.Element; }; /** @@ -144,8 +142,8 @@ export class DevAppBuilder { this.defaultPage = path; } - if (opts.sideBarItem) { - this.sidebarItems.push(opts.sideBarItem); + if (opts.sidebarItem) { + this.sidebarItems.push(opts.sidebarItem); } else if (opts.title) { this.sidebarItems.push( <>{opts.element}; - attachComponentData(Elem, 'core.mountPoint', opts.routeRef); - - this.routes.push( - } - children={opts.children} - />, - ); - } else { - this.routes.push( - , - ); - } + this.routes.push( + , + ); return this; } diff --git a/plugins/notifications-backend/dev/index.ts b/plugins/notifications-backend/dev/index.ts index 987f984dcb..fe35606dd2 100644 --- a/plugins/notifications-backend/dev/index.ts +++ b/plugins/notifications-backend/dev/index.ts @@ -35,8 +35,7 @@ const notificationsDebug = createBackendPlugin({ interval = setInterval(async () => { await notifications.send({ recipients: { - type: 'entity', - entityRef: 'user:development/guest', + type: 'broadcast', }, payload: { title: 'Test notification' }, }); diff --git a/plugins/notifications-backend/src/service/router.ts b/plugins/notifications-backend/src/service/router.ts index 0bce3d4bb3..4c38d2ba2a 100644 --- a/plugins/notifications-backend/src/service/router.ts +++ b/plugins/notifications-backend/src/service/router.ts @@ -470,7 +470,7 @@ export async function createRouter( if (!recipients || !title) { logger.error(`Invalid notification request received`); - throw new InputError(); + throw new InputError(`Invalid notification request received`); } const origin = credentials.principal.subject; @@ -496,8 +496,10 @@ export async function createRouter( try { users = await getUsersForEntityRef(entityRef); } catch (e) { - throw new InputError(); + logger.error(`Failed to resolve notification receivers: ${e}`); + throw new InputError('Failed to resolve notification receivers', e); } + const userNotifications = await sendUserNotifications( baseNotification, users, diff --git a/plugins/notifications/dev/index.tsx b/plugins/notifications/dev/index.tsx index 27bfe23842..1406f55b59 100644 --- a/plugins/notifications/dev/index.tsx +++ b/plugins/notifications/dev/index.tsx @@ -15,10 +15,8 @@ */ import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; -import { notificationsPlugin } from '../src/plugin'; -import { NotificationsPage } from '../src/components/NotificationsPage'; +import { NotificationsPage, notificationsPlugin } from '../src/plugin'; import { NotificationsSidebarItem } from '../src'; -import { rootRouteRef } from '../src/routes'; // TODO: How to sign in here as guest user? createDevApp() @@ -26,7 +24,6 @@ createDevApp() .addPage({ element: , path: '/notifications', - sideBarItem: , - routeRef: rootRouteRef, + sidebarItem: , }) .render(); From 2706c3b181a08c9c31370cb12f2b06ed9451e094 Mon Sep 17 00:00:00 2001 From: Phil Kuang Date: Wed, 10 Apr 2024 16:06:23 -0400 Subject: [PATCH 065/107] fix(cookieAuth): set cookie against request host instead of origin Signed-off-by: Phil Kuang --- .../implementations/httpAuth/httpAuthServiceFactory.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts index d6f5ceefa8..d7de0ae4ea 100644 --- a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -225,14 +225,12 @@ class DefaultHttpAuthService implements HttpAuthService { priority: 'high'; sameSite: 'none' | 'lax'; }> { - const originHeader = req.headers.origin; - const origin = - !originHeader || originHeader === 'null' ? undefined : originHeader; + const requestBaseUrl = `${req.protocol}://${req.hostname}`; const externalBaseUrlStr = await this.#discovery.getExternalBaseUrl( this.#pluginId, ); - const externalBaseUrl = new URL(externalBaseUrlStr ?? origin); + const externalBaseUrl = new URL(requestBaseUrl ?? externalBaseUrlStr); const secure = externalBaseUrl.protocol === 'https:' || From f28242025e29066478364b511ade883fedc31d5d Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Thu, 21 Mar 2024 07:41:02 +0100 Subject: [PATCH 066/107] feat: support login for the development app this fixes the local development issue with new backend system where the user is not logged in thus resulting 401 errors from all api endpoints. adds possibility to also add other login providers for testing plugins independently. Signed-off-by: Heikki Hellgren --- .changeset/light-eggs-switch.md | 2 +- packages/dev-utils/api-report.md | 11 ++++- .../SidebarSignOutButton.tsx | 44 +++++++++++++++++++ .../components/SidebarSignOutButton/index.ts | 16 +++++++ packages/dev-utils/src/components/index.ts | 1 + packages/dev-utils/src/devApp/render.test.tsx | 3 +- packages/dev-utils/src/devApp/render.tsx | 40 +++++++++++++++-- plugins/notifications/dev/index.tsx | 3 +- plugins/signals-backend/dev/index.ts | 2 + plugins/signals-backend/package.json | 2 + yarn.lock | 2 + 11 files changed, 117 insertions(+), 9 deletions(-) create mode 100644 packages/dev-utils/src/components/SidebarSignOutButton/SidebarSignOutButton.tsx create mode 100644 packages/dev-utils/src/components/SidebarSignOutButton/index.ts diff --git a/.changeset/light-eggs-switch.md b/.changeset/light-eggs-switch.md index 3fbb77b0d8..26934f155e 100644 --- a/.changeset/light-eggs-switch.md +++ b/.changeset/light-eggs-switch.md @@ -2,4 +2,4 @@ '@backstage/dev-utils': patch --- -Allow defining custom side bar item for page +Allow defining custom sidebar item for page and login for the development app diff --git a/packages/dev-utils/api-report.md b/packages/dev-utils/api-report.md index d30df29200..0a5b3d10e8 100644 --- a/packages/dev-utils/api-report.md +++ b/packages/dev-utils/api-report.md @@ -13,7 +13,9 @@ import { Entity } from '@backstage/catalog-model'; import { GridProps } from '@material-ui/core/Grid'; import { IconComponent } from '@backstage/core-plugin-api'; import { PropsWithChildren } from 'react'; +import { default as React_2 } from 'react'; import { ReactNode } from 'react'; +import { SignInProviderConfig } from '@backstage/core-components'; // @public export function createDevApp(): DevAppBuilder; @@ -22,6 +24,8 @@ export function createDevApp(): DevAppBuilder; export class DevAppBuilder { addPage(opts: DevAppPageOptions): DevAppBuilder; addRootChild(node: ReactNode): DevAppBuilder; + addSidebarItem(sidebarItem: JSX.Element): DevAppBuilder; + addSignInProvider(provider: SignInProviderConfig): this; addThemes(themes: AppTheme[]): this; build(): ComponentType>; registerApi< @@ -42,7 +46,6 @@ export type DevAppPageOptions = { children?: JSX.Element; title?: string; icon?: IconComponent; - sidebarItem?: JSX.Element; }; // @public (undocumented) @@ -51,4 +54,10 @@ export const EntityGridItem: ( entity: Entity; }, ) => JSX.Element; + +// @public +export const SidebarSignOutButton: (props: { + icon?: IconComponent; + text?: string; +}) => React_2.JSX.Element; ``` diff --git a/packages/dev-utils/src/components/SidebarSignOutButton/SidebarSignOutButton.tsx b/packages/dev-utils/src/components/SidebarSignOutButton/SidebarSignOutButton.tsx new file mode 100644 index 0000000000..9cfe888d4d --- /dev/null +++ b/packages/dev-utils/src/components/SidebarSignOutButton/SidebarSignOutButton.tsx @@ -0,0 +1,44 @@ +/* + * Copyright 2024 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 { SidebarItem } from '@backstage/core-components'; +import LockIcon from '@material-ui/icons/Lock'; +import { + IconComponent, + identityApiRef, + useApi, +} from '@backstage/core-plugin-api'; + +/** + * Button for sidebar that signs out user + * + * @public + */ +export const SidebarSignOutButton = (props: { + icon?: IconComponent; + text?: string; +}) => { + const identityApi = useApi(identityApiRef); + + return ( + identityApi.signOut()} + icon={props.icon ?? LockIcon} + text={props.text ?? 'Sign Out'} + /> + ); +}; diff --git a/packages/dev-utils/src/components/SidebarSignOutButton/index.ts b/packages/dev-utils/src/components/SidebarSignOutButton/index.ts new file mode 100644 index 0000000000..6182e1fa12 --- /dev/null +++ b/packages/dev-utils/src/components/SidebarSignOutButton/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './SidebarSignOutButton'; diff --git a/packages/dev-utils/src/components/index.ts b/packages/dev-utils/src/components/index.ts index d71b424a34..8959b6e7b1 100644 --- a/packages/dev-utils/src/components/index.ts +++ b/packages/dev-utils/src/components/index.ts @@ -15,3 +15,4 @@ */ export * from './EntityGridItem'; +export * from './SidebarSignOutButton'; diff --git a/packages/dev-utils/src/devApp/render.test.tsx b/packages/dev-utils/src/devApp/render.test.tsx index 2da6ef370a..7fc0024cc3 100644 --- a/packages/dev-utils/src/devApp/render.test.tsx +++ b/packages/dev-utils/src/devApp/render.test.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { createDevApp } from './render'; -import { useApi, configApiRef } from '@backstage/core-plugin-api'; +import { configApiRef, useApi } from '@backstage/core-plugin-api'; const anyEnv = (process.env = { ...process.env }) as any; @@ -28,6 +28,7 @@ describe('DevAppBuilder', () => { context: 'test', data: { app: { title: 'Test App' }, + backend: { baseUrl: 'http://localhost' }, }, }, ]; diff --git a/packages/dev-utils/src/devApp/render.tsx b/packages/dev-utils/src/devApp/render.tsx index 26fd96052b..3b3c993a6b 100644 --- a/packages/dev-utils/src/devApp/render.tsx +++ b/packages/dev-utils/src/devApp/render.tsx @@ -25,6 +25,8 @@ import { SidebarPage, SidebarSpace, SidebarSpacer, + SignInPage, + SignInProviderConfig, } from '@backstage/core-components'; import { AnyApiFactory, @@ -48,6 +50,7 @@ import React, { ComponentType, PropsWithChildren, ReactNode } from 'react'; import { createRoutesFromChildren, Route } from 'react-router-dom'; import { SidebarThemeSwitcher } from './SidebarThemeSwitcher'; import 'react-dom'; +import { SidebarSignOutButton } from '../components'; let ReactDOMPromise: Promise< typeof import('react-dom') | typeof import('react-dom/client') @@ -80,7 +83,6 @@ export type DevAppPageOptions = { children?: JSX.Element; title?: string; icon?: IconComponent; - sidebarItem?: JSX.Element; }; /** @@ -95,6 +97,7 @@ export class DevAppBuilder { private readonly rootChildren = new Array(); private readonly routes = new Array(); private readonly sidebarItems = new Array(); + private readonly signInProviders = new Array(); private defaultPage?: string; private themes?: Array; @@ -129,6 +132,16 @@ export class DevAppBuilder { return this; } + /** + * Adds a new sidebar item to the dev app. + * + * Useful for adding only sidebar items without a corresponding page. + */ + addSidebarItem(sidebarItem: JSX.Element): DevAppBuilder { + this.sidebarItems.push(sidebarItem); + return this; + } + /** * Adds a page component along with accompanying sidebar item. * @@ -142,9 +155,7 @@ export class DevAppBuilder { this.defaultPage = path; } - if (opts.sidebarItem) { - this.sidebarItems.push(opts.sidebarItem); - } else if (opts.title) { + if (opts.title) { this.sidebarItems.push( { + return ( + + ); + }, + }, bindRoutes: ({ bind }) => { for (const plugin of this.plugins ?? []) { const targets: Record> = {}; @@ -221,6 +252,7 @@ export class DevAppBuilder { + {this.routes} diff --git a/plugins/notifications/dev/index.tsx b/plugins/notifications/dev/index.tsx index 1406f55b59..f4d9176a70 100644 --- a/plugins/notifications/dev/index.tsx +++ b/plugins/notifications/dev/index.tsx @@ -18,12 +18,11 @@ import { createDevApp } from '@backstage/dev-utils'; import { NotificationsPage, notificationsPlugin } from '../src/plugin'; import { NotificationsSidebarItem } from '../src'; -// TODO: How to sign in here as guest user? createDevApp() .registerPlugin(notificationsPlugin) .addPage({ element: , path: '/notifications', - sidebarItem: , }) + .addSidebarItem() .render(); diff --git a/plugins/signals-backend/dev/index.ts b/plugins/signals-backend/dev/index.ts index ae98e54eed..39021a9fcd 100644 --- a/plugins/signals-backend/dev/index.ts +++ b/plugins/signals-backend/dev/index.ts @@ -53,6 +53,8 @@ const signalDebug = createBackendPlugin({ const backend = createBackend(); backend.add(import('@backstage/plugin-events-backend/alpha')); +backend.add(import('@backstage/plugin-auth-backend')); +backend.add(import('@backstage/plugin-auth-backend-module-guest-provider')); backend.add(import('../src')); backend.add(signalDebug); diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json index 923b4bb150..a6ebb228e4 100644 --- a/plugins/signals-backend/package.json +++ b/plugins/signals-backend/package.json @@ -47,6 +47,8 @@ "devDependencies": { "@backstage/backend-defaults": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-auth-backend": "workspace:^", + "@backstage/plugin-auth-backend-module-guest-provider": "workspace:^", "@backstage/plugin-events-backend": "workspace:^", "@types/supertest": "^2.0.8", "msw": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index e392282e15..893930d505 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9285,6 +9285,8 @@ __metadata: "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" + "@backstage/plugin-auth-backend": "workspace:^" + "@backstage/plugin-auth-backend-module-guest-provider": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" "@backstage/plugin-events-backend": "workspace:^" "@backstage/plugin-events-node": "workspace:^" From 1e851d01911253410977e54e201c310c125f7ae6 Mon Sep 17 00:00:00 2001 From: Joe Van Alstyne Date: Thu, 11 Apr 2024 15:10:09 +0900 Subject: [PATCH 067/107] build: add lodash to @backstage/plugin-catalog-backend-module-backstage-openapi dependencies Signed-off-by: Joe Van Alstyne --- plugins/catalog-backend-module-backstage-openapi/package.json | 1 + yarn.lock | 1 + 2 files changed, 2 insertions(+) diff --git a/plugins/catalog-backend-module-backstage-openapi/package.json b/plugins/catalog-backend-module-backstage-openapi/package.json index c4a26902d2..45bb3e3d7b 100644 --- a/plugins/catalog-backend-module-backstage-openapi/package.json +++ b/plugins/catalog-backend-module-backstage-openapi/package.json @@ -39,6 +39,7 @@ "@backstage/errors": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", "cross-fetch": "^4.0.0", + "lodash": "^4.17.21", "openapi-merge": "^1.3.2", "uuid": "^9.0.0" }, diff --git a/yarn.lock b/yarn.lock index 1834eb2cf6..34c3fefed3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5473,6 +5473,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" cross-fetch: ^4.0.0 + lodash: ^4.17.21 openapi-merge: ^1.3.2 openapi3-ts: ^3.1.2 uuid: ^9.0.0 From ff346bdb6a3400e97b85c8b27bf828b06744d500 Mon Sep 17 00:00:00 2001 From: Joe Van Alstyne Date: Thu, 11 Apr 2024 15:12:07 +0900 Subject: [PATCH 068/107] refactor: use lodash.merge to setup plugin-catalog-backend-module-backstage-openapi config Signed-off-by: Joe Van Alstyne --- .../InternalOpenApiDocumentationProvider.ts | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts b/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts index d55cb05a6d..bef0626830 100644 --- a/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts +++ b/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts @@ -38,7 +38,8 @@ import { DiscoveryService, LoggerService, } from '@backstage/backend-plugin-api'; -import * as uuid from 'uuid'; +import uuid from 'uuid'; +import lodash from 'lodash'; import { PluginTaskScheduler, TaskRunner } from '@backstage/backend-tasks'; const HTTP_VERBS: (keyof PathItemObject)[] = [ @@ -229,22 +230,26 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider { const pluginsToMerge = this.config.getStringArray( 'catalog.providers.backstageOpenapi.plugins', ); + const configToMerge = this.config.getOptional( + 'catalog.providers.backstageOpenapi.entityOverrides', + ); - const getOverride = (key: string, fallbackValue: string = '') => { - return ( - this.config.getOptionalString( - `catalog.providers.backstageOpenapi.entityOverrides.${key}`, - ) ?? fallbackValue - ); + const baseConfig = { + metadata: { + name: 'internal_backstage_plugin', + title: 'Default Backstage API', + }, + spec: { + owner: 'backstage', + lifecycle: 'production', + }, }; logger.info(`Loading specs from ${pluginsToMerge}.`); - const documentationEntity: ApiEntity = { + const requiredConfig = { apiVersion: 'backstage.io/v1beta1', kind: 'API', metadata: { - name: getOverride('metadata.name', 'backstage_openapi_doc'), - title: getOverride('metadata.title', 'Backstage API Documentation'), annotations: { [ANNOTATION_LOCATION]: 'internal-package:@backstage/plugin-catalog-backend-module-backstage-openapi', @@ -253,9 +258,7 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider { }, }, spec: { - type: getOverride('spec.type', 'openapi'), - lifecycle: getOverride('spec.lifecycle', 'production'), - owner: getOverride('spec.owner', 'backstage'), + type: 'openapi', definition: JSON.stringify( await loadSpecs({ baseUrl: this.config.getString('backend.baseUrl'), @@ -267,6 +270,15 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider { ), }, }; + + // Overwrite base config with options from config file. + const mergedConfig = lodash.merge(baseConfig, configToMerge); + // Overwite mergedConfig with requiredConfig (i.e., spec.type and spec.definition) to avoid bad configuration. + const documentationEntity = lodash.merge( + mergedConfig, + requiredConfig, + ) as ApiEntity; + await this.connection?.applyMutation({ type: 'full', entities: [ From 6102b73bb3085ba7655c72c4eb05a47816584c6b Mon Sep 17 00:00:00 2001 From: Joe Van Alstyne Date: Thu, 11 Apr 2024 15:18:21 +0900 Subject: [PATCH 069/107] refactor: update baseConfig strings Signed-off-by: Joe Van Alstyne --- .../src/InternalOpenApiDocumentationProvider.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts b/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts index bef0626830..971a5fbc47 100644 --- a/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts +++ b/plugins/catalog-backend-module-backstage-openapi/src/InternalOpenApiDocumentationProvider.ts @@ -236,12 +236,12 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider { const baseConfig = { metadata: { - name: 'internal_backstage_plugin', - title: 'Default Backstage API', + name: 'internal_backstage_openapi_doc', + title: 'Backstage API', }, spec: { - owner: 'backstage', lifecycle: 'production', + owner: 'backstage', }, }; @@ -271,8 +271,9 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider { }, }; - // Overwrite base config with options from config file. + // Overwrite baseConfig with options from config file. const mergedConfig = lodash.merge(baseConfig, configToMerge); + // Overwite mergedConfig with requiredConfig (i.e., spec.type and spec.definition) to avoid bad configuration. const documentationEntity = lodash.merge( mergedConfig, From ec471d3023743986039d3eed02938b070dd7095a Mon Sep 17 00:00:00 2001 From: Joe Van Alstyne Date: Thu, 11 Apr 2024 19:58:47 +0900 Subject: [PATCH 070/107] remove redundant comment in config Signed-off-by: Joe Van Alstyne --- plugins/catalog-backend-module-backstage-openapi/config.d.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/catalog-backend-module-backstage-openapi/config.d.ts b/plugins/catalog-backend-module-backstage-openapi/config.d.ts index e403010951..376c702999 100644 --- a/plugins/catalog-backend-module-backstage-openapi/config.d.ts +++ b/plugins/catalog-backend-module-backstage-openapi/config.d.ts @@ -25,9 +25,6 @@ export interface Config { * A list of plugins, whose OpenAPI specs you want to collate in `InternalOpenApiDocumentationProvider`. */ plugins: string[]; - /** - * Options to ovveride the provided entity's default metadata and spec properties - */ /** * Properties to override on the final entity object. */ From 438245968b10daa91937ed52417e6e6263c71427 Mon Sep 17 00:00:00 2001 From: Phil Kuang Date: Thu, 11 Apr 2024 09:00:42 -0400 Subject: [PATCH 071/107] refactor(cookieAuth): set cookie domain against discovery base url Signed-off-by: Phil Kuang --- .../implementations/httpAuth/httpAuthServiceFactory.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts index d7de0ae4ea..c85ba6e4b3 100644 --- a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -218,19 +218,19 @@ class DefaultHttpAuthService implements HttpAuthService { return { expiresAt }; } - async #getCookieOptions(req: Request): Promise<{ + async #getCookieOptions(_req: Request): Promise<{ domain: string; httpOnly: true; secure: boolean; priority: 'high'; sameSite: 'none' | 'lax'; }> { - const requestBaseUrl = `${req.protocol}://${req.hostname}`; - + // TODO: eventually we should read from `${req.protocol}://${req.hostname}` + // once https://github.com/backstage/backstage/issues/24169 has landed const externalBaseUrlStr = await this.#discovery.getExternalBaseUrl( this.#pluginId, ); - const externalBaseUrl = new URL(requestBaseUrl ?? externalBaseUrlStr); + const externalBaseUrl = new URL(externalBaseUrlStr); const secure = externalBaseUrl.protocol === 'https:' || From fae9638d6553cee5e802b46076a8544eff61ffab Mon Sep 17 00:00:00 2001 From: parmar-abhinav Date: Thu, 11 Apr 2024 19:40:24 +0530 Subject: [PATCH 072/107] Add examples for scaffolder action. Signed-off-by: parmar-abhinav --- .changeset/wet-buttons-buy.md | 5 + .../package.json | 1 + .../src/actions/run/yeoman.examples.test.ts | 115 ++++++++++++++++++ .../src/actions/run/yeoman.examples.ts | 87 +++++++++++++ .../src/actions/run/yeoman.ts | 2 + yarn.lock | 1 + 6 files changed, 211 insertions(+) create mode 100644 .changeset/wet-buttons-buy.md create mode 100644 plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.test.ts create mode 100644 plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.ts diff --git a/.changeset/wet-buttons-buy.md b/.changeset/wet-buttons-buy.md new file mode 100644 index 0000000000..522be0fc54 --- /dev/null +++ b/.changeset/wet-buttons-buy.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-yeoman': minor +--- + +Add examples for `run:yeoman` scaffolder action. diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index 1f82a64962..92de03b93d 100644 --- a/plugins/scaffolder-backend-module-yeoman/package.json +++ b/plugins/scaffolder-backend-module-yeoman/package.json @@ -45,6 +45,7 @@ "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", "@backstage/types": "workspace:^", "winston": "^3.2.1", + "yaml": "^2.0.0", "yeoman-environment": "^3.9.1" }, "devDependencies": { diff --git a/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.test.ts b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.test.ts new file mode 100644 index 0000000000..4875089090 --- /dev/null +++ b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.test.ts @@ -0,0 +1,115 @@ +/* + * 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 { yeomanRun } from './yeomanRun'; + +jest.mock('./yeomanRun'); + +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import os from 'os'; +import { createRunYeomanAction } from './yeoman'; +import type { ActionContext } from '@backstage/plugin-scaffolder-node'; +import { JsonObject } from '@backstage/types'; +import yaml from 'yaml'; +import { examples } from './yeoman.examples'; + +describe('run:yeoman', () => { + const mockTmpDir = os.tmpdir(); + + let mockContext: ActionContext<{ + namespace: string; + args?: string[]; + options?: JsonObject; + }>; + + const action = createRunYeomanAction(); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it(`should ${examples[0].description}`, async () => { + const namespace = yaml.parse(examples[0].example).steps[0].input.namespace; + const input = yaml.parse(examples[0].example).steps[0].input; + mockContext = createMockActionContext({ + input: input, + workspacePath: mockTmpDir, + }); + + await action.handler(mockContext); + expect(yeomanRun).toHaveBeenCalledWith( + mockTmpDir, + namespace, + undefined, + undefined, + ); + }); + + it(`should ${examples[1].description}`, async () => { + const namespace = yaml.parse(examples[1].example).steps[0].input.namespace; + const input = yaml.parse(examples[1].example).steps[0].input; + const args: string[] = yaml.parse(examples[1].example).steps[0].input.args; + mockContext = createMockActionContext({ + input: input, + workspacePath: mockTmpDir, + }); + + await action.handler(mockContext); + expect(yeomanRun).toHaveBeenCalledWith( + mockTmpDir, + namespace, + args, + undefined, + ); + }); + + it(`should ${examples[2].description}`, async () => { + const namespace = yaml.parse(examples[2].example).steps[0].input.namespace; + const input = yaml.parse(examples[2].example).steps[0].input; + const options = yaml.parse(examples[2].example).steps[0].input.options; + mockContext = createMockActionContext({ + input: input, + workspacePath: mockTmpDir, + }); + + await action.handler(mockContext); + expect(yeomanRun).toHaveBeenCalledWith( + mockTmpDir, + namespace, + undefined, + options, + ); + }); + + it(`should ${examples[3].description}`, async () => { + const namespace = yaml.parse(examples[3].example).steps[0].input.namespace; + const input = yaml.parse(examples[3].example).steps[0].input; + const options = yaml.parse(examples[3].example).steps[0].input.options; + const args: string[] = yaml.parse(examples[1].example).steps[0].input.args; + mockContext = createMockActionContext({ + input: input, + workspacePath: mockTmpDir, + }); + + await action.handler(mockContext); + expect(yeomanRun).toHaveBeenCalledWith( + mockTmpDir, + namespace, + args, + options, + ); + }); +}); diff --git a/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.ts b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.ts new file mode 100644 index 0000000000..067cd71fab --- /dev/null +++ b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.ts @@ -0,0 +1,87 @@ +/* + * 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 { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Run a Yeoman generator with minimal options', + example: yaml.stringify({ + steps: [ + { + id: 'run:yeoman', + action: 'run:yeoman', + name: 'Running a yeoman generator', + input: { + namespace: 'node:app', + }, + }, + ], + }), + }, + { + description: + 'Run a yeoman generator with arguments to pass on to Yeoman for templating', + example: yaml.stringify({ + steps: [ + { + id: 'run:yeoman', + action: 'run:yeoman', + name: 'Running a yeoman generator', + input: { + namespace: 'node:app', + args: ['arg1', 'arg2'], + }, + }, + ], + }), + }, + { + description: + 'Run a yeoman generator with options to pass on to Yeoman for templating', + example: yaml.stringify({ + steps: [ + { + id: 'run:yeoman', + action: 'run:yeoman', + name: 'Running a yeoman generator', + input: { + namespace: 'node:app', + options: { option1: 'value1', option2: 'value2' }, + }, + }, + ], + }), + }, + { + description: 'Run a yeoman generator with all options', + example: yaml.stringify({ + steps: [ + { + id: 'run:yeoman', + action: 'run:yeoman', + name: 'Running a yeoman generator', + input: { + namespace: 'node:app', + args: ['arg1', 'arg2'], + options: { option1: 'value1', option2: 'value2' }, + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.ts b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.ts index 62d62807ae..a8bbbf945d 100644 --- a/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.ts +++ b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.ts @@ -17,6 +17,7 @@ import { JsonObject } from '@backstage/types'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { yeomanRun } from './yeomanRun'; +import { examples } from './yeoman.examples'; /** * Creates a `run:yeoman` Scaffolder action. @@ -35,6 +36,7 @@ export function createRunYeomanAction() { }>({ id: 'run:yeoman', description: 'Runs Yeoman on an installed Yeoman generator', + examples, schema: { input: { type: 'object', diff --git a/yarn.lock b/yarn.lock index dffbf4f6d3..07a752711f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8719,6 +8719,7 @@ __metadata: "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" "@backstage/types": "workspace:^" winston: ^3.2.1 + yaml: ^2.0.0 yeoman-environment: ^3.9.1 languageName: unknown linkType: soft From 0702291e8f95312e72b85f49e153c4c0238cc7eb Mon Sep 17 00:00:00 2001 From: parmar-abhinav Date: Thu, 11 Apr 2024 19:52:13 +0530 Subject: [PATCH 073/107] chore: updated changeset description as per review feedback Signed-off-by: parmar-abhinav --- .changeset/mighty-humans-tan.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/mighty-humans-tan.md b/.changeset/mighty-humans-tan.md index 24e209a701..cc3a35ccba 100644 --- a/.changeset/mighty-humans-tan.md +++ b/.changeset/mighty-humans-tan.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder-backend-module-gerrit': minor --- -Add examples for publish:gerrit:review scaffolder action & improve related tests +Add examples for `publish:gerrit:review` scaffolder action & improve related tests From 01a7024f5dde6154a3da4fdde18ed8366ec97cc7 Mon Sep 17 00:00:00 2001 From: Yash Oswal Date: Fri, 12 Apr 2024 10:31:12 +0530 Subject: [PATCH 074/107] microsite: add feedback plugin to plugins directory Signed-off-by: Yash Oswal --- microsite/data/plugins/feedback.yaml | 10 ++++++++++ microsite/static/img/plugin-feedback-logo.svg | 1 + 2 files changed, 11 insertions(+) create mode 100644 microsite/data/plugins/feedback.yaml create mode 100644 microsite/static/img/plugin-feedback-logo.svg diff --git a/microsite/data/plugins/feedback.yaml b/microsite/data/plugins/feedback.yaml new file mode 100644 index 0000000000..8e8e00165e --- /dev/null +++ b/microsite/data/plugins/feedback.yaml @@ -0,0 +1,10 @@ +--- +title: Feedback +author: Red Hat +authorUrl: https://redhat.com +category: Quality +description: A plugin for collecting user feedbacks for your application. # Max 170 characters +documentation: https://github.com/janus-idp/backstage-plugins/tree/main/plugins/feedback#readme +iconUrl: /img/plugin-feedback-logo.svg +npmPackageName: '@janus-idp/backstage-plugin-feedback' +addedDate: '2024-04-09' diff --git a/microsite/static/img/plugin-feedback-logo.svg b/microsite/static/img/plugin-feedback-logo.svg new file mode 100644 index 0000000000..bd8014f9c7 --- /dev/null +++ b/microsite/static/img/plugin-feedback-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file From 70e962ceaf6f7ee3e8f3abfec9207a52fbfdf5e8 Mon Sep 17 00:00:00 2001 From: Sebastian Poxhofer Date: Fri, 12 Apr 2024 11:09:18 +0200 Subject: [PATCH 075/107] Update .changeset/tame-pianos-hunt.md Co-authored-by: Vincenzo Scamporlino Signed-off-by: Sebastian Poxhofer --- .changeset/tame-pianos-hunt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/tame-pianos-hunt.md b/.changeset/tame-pianos-hunt.md index 3ab3e88623..2799a3a1da 100644 --- a/.changeset/tame-pianos-hunt.md +++ b/.changeset/tame-pianos-hunt.md @@ -2,4 +2,4 @@ '@backstage/backend-common': minor --- -Allow providing authentication which in turn allows usage of private registries +Added `pullOptions` to `DockerContainerRunner#runContainer` method to pass down options when pulling an image. From 42770dab28085ba2a5696b3b73251a5ff8ffd414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Sat, 13 Apr 2024 10:11:39 +0200 Subject: [PATCH 076/107] address review comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelรถw --- docs/auth/identity-resolver.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/docs/auth/identity-resolver.md b/docs/auth/identity-resolver.md index aedba5a9c2..b09b47a572 100644 --- a/docs/auth/identity-resolver.md +++ b/docs/auth/identity-resolver.md @@ -16,9 +16,11 @@ By default, every Backstage auth provider is configured only for the use-case of access delegation. This enables Backstage to request resources and actions from external systems on behalf of the user, for example re-triggering a build in CI. -If you want to use an auth provider to sign in users, you need to explicitly configure -it have sign-in enabled and also tell it how the external identities should -be mapped to user identities within Backstage. +If you want to use an auth provider to sign in users, you need to explicitly +configure it have sign-in enabled and also tell it how the external identities +should be mapped to user identities within Backstage. You do this by either +choosing a built-in sign in resolver, or supplying your own. Both methods are +listed below. ## Quick Start @@ -99,21 +101,20 @@ still have to make a choice - as mentioned above, even if there are a set of builtins, none of them are selected by default. You set up builtin sign in resolvers using [your app-config](../conf/index.md), -next to the respective provider's configuration. Here's an example for Microsoft -Azure: +next to the respective provider's configuration. Here's an example for GitHub: ```yaml title="in e.g. app-config.yaml" auth: environment: development providers: - microsoft: + github: development: - clientId: ${AZURE_CLIENT_ID} - clientSecret: ${AZURE_CLIENT_SECRET} - tenantId: ${AZURE_TENANT_ID} + clientId: ${AUTH_GITHUB_CLIENT_ID} + clientSecret: ${AUTH_GITHUB_CLIENT_SECRET} + enterpriseInstanceUrl: ${AUTH_GITHUB_ENTERPRISE_INSTANCE_URL} signIn: resolvers: - - resolver: emailMatchingUserEntityAnnotation + - resolver: usernameMatchingUserEntityName - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName ``` @@ -122,8 +123,9 @@ Note that in this instance it lists several resolvers, which means that the framework will try them one by one until one succeeds. If none of them do, the sign in attempt is rejected. -To find the list of available resolvers, consult the documentation of the -respective provider. +The list of available resolvers is different for each provider, since they often +depend on the information model returned from the upstream provider service. +Consult the documentation of the respective provider to find the list. ### Building Custom Resolvers From 2ce31b3954ee4693ea7bba14965f23b8b5188280 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 11 Apr 2024 22:27:14 +0200 Subject: [PATCH 077/107] config-loader: trim strings when reading env vars Signed-off-by: Patrik Oldsberg --- .changeset/chatty-parrots-trade.md | 13 ++++++++ packages/config-loader/api-report.md | 1 - .../src/sources/ConfigSources.ts | 8 +++++ .../src/sources/transform/apply.test.ts | 31 ++++++++++++++++++- .../src/sources/transform/apply.ts | 6 ++-- 5 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 .changeset/chatty-parrots-trade.md diff --git a/.changeset/chatty-parrots-trade.md b/.changeset/chatty-parrots-trade.md new file mode 100644 index 0000000000..149fc3b2e1 --- /dev/null +++ b/.changeset/chatty-parrots-trade.md @@ -0,0 +1,13 @@ +--- +'@backstage/config-loader': minor +--- + +The default environment variable substitution function will now trim whitespace characters from the substituted value. This alleviates bugs where whitespace characters are mistakenly included in environment variables. + +If you depend on the old behavior, you can override the default substitution function with your own, for example: + +```ts +ConfigSources.default({ + substitutionFunc: async name => process.env[name], +}); +``` diff --git a/packages/config-loader/api-report.md b/packages/config-loader/api-report.md index 66572dd960..bc8f217bbb 100644 --- a/packages/config-loader/api-report.md +++ b/packages/config-loader/api-report.md @@ -25,7 +25,6 @@ export interface BaseConfigSourcesOptions { remote?: Pick; // (undocumented) rootDir?: string; - // (undocumented) substitutionFunc?: EnvFunc; // (undocumented) watch?: boolean; diff --git a/packages/config-loader/src/sources/ConfigSources.ts b/packages/config-loader/src/sources/ConfigSources.ts index 03fc6d83d6..ecff39da2d 100644 --- a/packages/config-loader/src/sources/ConfigSources.ts +++ b/packages/config-loader/src/sources/ConfigSources.ts @@ -74,6 +74,14 @@ export interface BaseConfigSourcesOptions { watch?: boolean; rootDir?: string; remote?: Pick; + + /** + * A custom substitution function that overrides the default one. + * + * @remarks + * The substitution function handles syntax like `${MY_ENV_VAR}` in configuration values. + * The default substitution will read the value from the environment and trim whitespace. + */ substitutionFunc?: SubstitutionFunc; } diff --git a/packages/config-loader/src/sources/transform/apply.test.ts b/packages/config-loader/src/sources/transform/apply.test.ts index 9f1dfbc672..3e5a4bd5e6 100644 --- a/packages/config-loader/src/sources/transform/apply.test.ts +++ b/packages/config-loader/src/sources/transform/apply.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { applyConfigTransforms } from './apply'; +import { applyConfigTransforms, createConfigTransformer } from './apply'; describe('applyConfigTransforms', () => { it('should apply no transforms to input', async () => { @@ -84,3 +84,32 @@ describe('applyConfigTransforms', () => { }); }); }); + +describe('createConfigTransformer', () => { + const origEnv = process.env; + process.env = { + ...process.env, + SECRET: 'my-secret', + PADDED_SECRET: ' \nmy-space \t', + }; + + afterAll(() => { + process.env = origEnv; + }); + + it('should substitute environment variables', async () => { + const transformer = createConfigTransformer({}); + + await expect( + transformer({ + testAlone: '${SECRET}', + testMiddle: 'hello ${SECRET}!', + testSpace: 'hello ${PADDED_SECRET}!', + }), + ).resolves.toEqual({ + testAlone: 'my-secret', + testMiddle: 'hello my-secret!', + testSpace: 'hello my-space!', + }); + }); +}); diff --git a/packages/config-loader/src/sources/transform/apply.ts b/packages/config-loader/src/sources/transform/apply.ts index 48d9c5a1e8..89ca647a1a 100644 --- a/packages/config-loader/src/sources/transform/apply.ts +++ b/packages/config-loader/src/sources/transform/apply.ts @@ -105,8 +105,10 @@ export function createConfigTransformer(options: { substitutionFunc?: SubstitutionFunc; readFile?(path: string): Promise; }): ConfigTransformer { - const { substitutionFunc = async name => process.env[name], readFile } = - options; + const { + substitutionFunc = async name => process.env[name]?.trim(), + readFile, + } = options; const substitutionTransform = createSubstitutionTransform(substitutionFunc); const transforms = [substitutionTransform]; if (readFile) { From ed5c901fd86db06b891a64efd62e30a7dcdf2a62 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Sat, 13 Apr 2024 13:59:22 +0200 Subject: [PATCH 078/107] fix: no `undefined` class name used at `MarkdownContent` if no custom class name was provided Signed-off-by: Patrick Jungermann --- .changeset/lemon-months-press.md | 5 ++++ .../MarkdownContent/MarkdownContent.test.tsx | 30 +++++++++++++++++++ .../MarkdownContent/MarkdownContent.tsx | 2 +- 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 .changeset/lemon-months-press.md diff --git a/.changeset/lemon-months-press.md b/.changeset/lemon-months-press.md new file mode 100644 index 0000000000..ecefc64daa --- /dev/null +++ b/.changeset/lemon-months-press.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +No `undefined` class name used at `MarkdownContent` if no custom class name was provided. diff --git a/packages/core-components/src/components/MarkdownContent/MarkdownContent.test.tsx b/packages/core-components/src/components/MarkdownContent/MarkdownContent.test.tsx index 4f28da0118..d9d82437e4 100644 --- a/packages/core-components/src/components/MarkdownContent/MarkdownContent.test.tsx +++ b/packages/core-components/src/components/MarkdownContent/MarkdownContent.test.tsx @@ -45,6 +45,36 @@ describe('', () => { ).toBeInTheDocument(); }); + it('Render MarkdownContent component without custom class', async () => { + await renderInTestApp( + , + ); + const content = screen.getByText('https://example.com', { selector: 'p' }); + + expect( + Array.from(content.parentElement?.classList?.values() ?? []).map(cls => + cls.replace(/-\d+$/, ''), + ), + ).toEqual(['BackstageMarkdownContent-markdown']); + }); + + it('Render MarkdownContent component with custom class', async () => { + await renderInTestApp( + , + ); + const content = screen.getByText('https://example.com', { selector: 'p' }); + + expect( + Array.from(content.parentElement?.classList?.values() ?? []).map(cls => + cls.replace(/-\d+$/, ''), + ), + ).toEqual(['BackstageMarkdownContent-markdown', 'custom-class']); + }); + it('render MarkdownContent component with CodeSnippet for code blocks', async () => { await renderInTestApp( , diff --git a/packages/core-components/src/components/MarkdownContent/MarkdownContent.tsx b/packages/core-components/src/components/MarkdownContent/MarkdownContent.tsx index b422a62b6c..f536b20106 100644 --- a/packages/core-components/src/components/MarkdownContent/MarkdownContent.tsx +++ b/packages/core-components/src/components/MarkdownContent/MarkdownContent.tsx @@ -127,7 +127,7 @@ export function MarkdownContent(props: Props) { return ( Date: Sat, 13 Apr 2024 15:50:52 +0200 Subject: [PATCH 079/107] yarn.lock: stick to existing version of csstype Signed-off-by: Patrik Oldsberg --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 85cbdfbdb3..0bac998445 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24781,9 +24781,9 @@ __metadata: linkType: hard "csstype@npm:^3.0.2, csstype@npm:^3.1.2, csstype@npm:^3.1.3": - version: 3.1.3 - resolution: "csstype@npm:3.1.3" - checksum: 8db785cc92d259102725b3c694ec0c823f5619a84741b5c7991b8ad135dfaa66093038a1cc63e03361a6cd28d122be48f2106ae72334e067dd619a51f49eddf7 + version: 3.0.9 + resolution: "csstype@npm:3.0.9" + checksum: 199f9af7e673f9f188525c3102a329d637ff46c52f6385a4427ff5cb17adcb736189150170a7af7c5701d18d7704bdad130273f4aa7e44c6c4f9967e6115dc93 languageName: node linkType: hard From 42738859dd5d725941b7956ff573d9e5ce8b6e8b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 13 Apr 2024 15:56:08 +0200 Subject: [PATCH 080/107] Update .changeset/lovely-flowers-promise.md Signed-off-by: Patrik Oldsberg --- .changeset/lovely-flowers-promise.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/lovely-flowers-promise.md b/.changeset/lovely-flowers-promise.md index 71c34bb8b6..5a778d903f 100644 --- a/.changeset/lovely-flowers-promise.md +++ b/.changeset/lovely-flowers-promise.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-cloudbuild': minor +'@backstage/plugin-cloudbuild': patch --- Changed the column that serves as a hyperlink from SOURCE to BUILD. From 4eb66c43fe8f0eac6ce0dba140826ed753dbd352 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 13 Apr 2024 16:00:52 +0200 Subject: [PATCH 081/107] cli: fix type error from webpack bump Signed-off-by: Patrik Oldsberg --- packages/cli/src/lib/bundler/backend.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/lib/bundler/backend.ts b/packages/cli/src/lib/bundler/backend.ts index 3094450d4b..598b77bc51 100644 --- a/packages/cli/src/lib/bundler/backend.ts +++ b/packages/cli/src/lib/bundler/backend.ts @@ -30,7 +30,7 @@ export async function serveBackend(options: BackendServeOptions) { // not include dependencies in node_modules. So we set it here at runtime as well. (process.env as { NODE_ENV: string }).NODE_ENV = 'development'; - const compiler = webpack(config, (err: Error | undefined) => { + const compiler = webpack(config, (err: Error | null) => { if (err) { console.error(err); } else console.log('Build succeeded'); From 13a85bbe0584128d989b3c3630c44d46868f61c2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 14:37:10 +0000 Subject: [PATCH 082/107] chore(deps): update dependency @playwright/test to v1.43.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/yarn.lock b/yarn.lock index c9483840d0..457478c597 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14678,13 +14678,13 @@ __metadata: linkType: hard "@playwright/test@npm:^1.32.3": - version: 1.43.0 - resolution: "@playwright/test@npm:1.43.0" + version: 1.43.1 + resolution: "@playwright/test@npm:1.43.1" dependencies: - playwright: 1.43.0 + playwright: 1.43.1 bin: playwright: cli.js - checksum: c7c0c6e8fde4e9dceea22d48384642b78c3d539fb0512edeaa581dc4dc07cedfd166dba92c5e9e69a378b7fd63362b142450dbdd5c9b65d76c4def162a5c470d + checksum: f9db387b488a03125e5dc22dd7ffed9c661d1f2428188912a35a2235b3bd9d826b390e7600d04998639994f5a96695b9dc9034ca9cb59e261d2fdee93a60df3f languageName: node linkType: hard @@ -38132,27 +38132,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.43.0": - version: 1.43.0 - resolution: "playwright-core@npm:1.43.0" +"playwright-core@npm:1.43.1": + version: 1.43.1 + resolution: "playwright-core@npm:1.43.1" bin: playwright-core: cli.js - checksum: b35265d356d87eb4114997e6af985ee3cb5a473f15a465d6e02834288a55f0cae4233a18178658389ff443f92405e020815fc165274d2262c3ca1c2b5be948cf + checksum: 7c96b3a4a4bce2ee22c3cd680c9b0bb9e4bf07ee4b51d1e9a7f47a6489c7b0b960d4b550e530b8f41d1ffeadd26c7c6bb626ae8689dfd90dce1cb8e35ae78ff7 languageName: node linkType: hard -"playwright@npm:1.43.0": - version: 1.43.0 - resolution: "playwright@npm:1.43.0" +"playwright@npm:1.43.1": + version: 1.43.1 + resolution: "playwright@npm:1.43.1" dependencies: fsevents: 2.3.2 - playwright-core: 1.43.0 + playwright-core: 1.43.1 dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: edd4ef9644398c197d20e957cf2a5e5a95d7e0144f3c971923e709247f5b48551bf6168c74b34909f263ab96fac6e49466b65a9cd1349ad400dabd4b8b364acf + checksum: de9db021f93018a18275bbb5af09ebf1804aa0534f47578b35b440064abc774509740205802824afc94a99fc84dd55ffe9e215718ad3ecc691b251ab3882b096 languageName: node linkType: hard From b48c678877492a1d27a54739d833655bd16bf78f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 14:40:44 +0000 Subject: [PATCH 083/107] fix(deps): update docusaurus monorepo to v3.2.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- microsite/yarn.lock | 392 ++++++++++++++++++++++---------------------- 1 file changed, 192 insertions(+), 200 deletions(-) diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 6e5aba85c8..a8e4699105 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -509,7 +509,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.22.7, @babel/parser@npm:^7.23.9": +"@babel/parser@npm:^7.23.9": version: 7.23.9 resolution: "@babel/parser@npm:7.23.9" bin: @@ -1689,9 +1689,9 @@ __metadata: languageName: node linkType: hard -"@docusaurus/core@npm:3.1.1, @docusaurus/core@npm:^3.1.1": - version: 3.1.1 - resolution: "@docusaurus/core@npm:3.1.1" +"@docusaurus/core@npm:3.2.1, @docusaurus/core@npm:^3.1.1": + version: 3.2.1 + resolution: "@docusaurus/core@npm:3.2.1" dependencies: "@babel/core": ^7.23.3 "@babel/generator": ^7.23.3 @@ -1703,14 +1703,13 @@ __metadata: "@babel/runtime": ^7.22.6 "@babel/runtime-corejs3": ^7.22.6 "@babel/traverse": ^7.22.8 - "@docusaurus/cssnano-preset": 3.1.1 - "@docusaurus/logger": 3.1.1 - "@docusaurus/mdx-loader": 3.1.1 + "@docusaurus/cssnano-preset": 3.2.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/mdx-loader": 3.2.1 "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-common": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 - "@slorber/static-site-generator-webpack-plugin": ^4.0.7 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 "@svgr/webpack": ^6.5.1 autoprefixer: ^10.4.14 babel-loader: ^9.1.3 @@ -1731,6 +1730,7 @@ __metadata: detect-port: ^1.5.1 escape-html: ^1.0.3 eta: ^2.2.0 + eval: ^0.1.8 file-loader: ^6.2.0 fs-extra: ^11.1.1 html-minifier-terser: ^7.2.0 @@ -1739,6 +1739,7 @@ __metadata: leven: ^3.1.0 lodash: ^4.17.21 mini-css-extract-plugin: ^2.7.6 + p-map: ^4.0.0 postcss: ^8.4.26 postcss-loader: ^7.3.3 prompts: ^2.4.2 @@ -1767,41 +1768,39 @@ __metadata: react-dom: ^18.0.0 bin: docusaurus: bin/docusaurus.mjs - checksum: a35851dd6dc5ff5d2c8a8efb36b9875dc33a9e067a4677e5c9437a8635970e55a3cf14bb6eba9c9e356f4189283fb401b39423d497eb17bb09a16dd0ed84b1da + checksum: 9267f08b41240cb9d399abbd8a41ff66e0082551284325db3f17fcce9643bef81d06564797a7cc4c528fe8bde2858c20666e74a0308f3ecc80f3be1dbee14bb5 languageName: node linkType: hard -"@docusaurus/cssnano-preset@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/cssnano-preset@npm:3.1.1" +"@docusaurus/cssnano-preset@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/cssnano-preset@npm:3.2.1" dependencies: cssnano-preset-advanced: ^5.3.10 postcss: ^8.4.26 postcss-sort-media-queries: ^4.4.1 tslib: ^2.6.0 - checksum: 562d96c2ff60826459c255831cd57b12393e6f41b3827c499d43d00ec1887fbeebfea7c68aa72d9e56a5d64419847d11a5d66021acb4f1e3ce4c87b781f33954 + checksum: ee23a1229d23732d936fe1d68732d1305abf0132b43a398336fee500504a3e7566d3b0c6222f89f565e24e68e00e353765e0cbbab5611a3b35ecf88305558b6d languageName: node linkType: hard -"@docusaurus/logger@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/logger@npm:3.1.1" +"@docusaurus/logger@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/logger@npm:3.2.1" dependencies: chalk: ^4.1.2 tslib: ^2.6.0 - checksum: d9673035a7eff14c1820b6c07a07e92a21e7f8e824305a784250d025c79bf9cfc51d0e6007b7660da4f810b78793572d382db48033201902c335c916d735433b + checksum: 9d5db5253eda98871563faddb5318bcb6b17ddf5882ababad4803d526917844819751e84ee8028e794fd5507646db6409f9041fd7f41b7f7971015df11cc6376 languageName: node linkType: hard -"@docusaurus/mdx-loader@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/mdx-loader@npm:3.1.1" +"@docusaurus/mdx-loader@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/mdx-loader@npm:3.2.1" dependencies: - "@babel/parser": ^7.22.7 - "@babel/traverse": ^7.22.8 - "@docusaurus/logger": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 "@mdx-js/mdx": ^3.0.0 "@slorber/remark-comment": ^1.0.0 escape-html: ^1.0.3 @@ -1826,16 +1825,16 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: e6b2483b20db41c8264c47edc42e2a738239fbad9b69eb520c7dab421dc2cde4f73f6ec871ccf277dfbc285ae9b202af892771ce800c4ce56739bff6c4c3c231 + checksum: 4609faf2d8b76085a3aa86ac5ca4ac3b3420e3cfd796f1b39c46f368c82b3db0db5b1308646cf35fdad0a1f6f088d367116eb0e2a8c3fa728ed886ee37516476 languageName: node linkType: hard -"@docusaurus/module-type-aliases@npm:3.1.1, @docusaurus/module-type-aliases@npm:^3.1.1": - version: 3.1.1 - resolution: "@docusaurus/module-type-aliases@npm:3.1.1" +"@docusaurus/module-type-aliases@npm:3.2.1, @docusaurus/module-type-aliases@npm:^3.1.1": + version: 3.2.1 + resolution: "@docusaurus/module-type-aliases@npm:3.2.1" dependencies: "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/types": 3.1.1 + "@docusaurus/types": 3.2.1 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" @@ -1845,19 +1844,19 @@ __metadata: peerDependencies: react: "*" react-dom: "*" - checksum: 937e52b57af5e459df26621dba57a1e399c48ebb1bc0fe10450c0238a79ef76d26a69ba9a42317e236d50bbd6c3e0fbb10fe97f8153373331947b90125aeee38 + checksum: 37b4a40f9afebbe76e350c10c857737b544c141a988462436904ae16993a52e4429018d406e2f55ad57a533e5a108dd7cdb903434abb84721deeec0d5f195d80 languageName: node linkType: hard "@docusaurus/plugin-client-redirects@npm:^3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-client-redirects@npm:3.1.1" + version: 3.2.1 + resolution: "@docusaurus/plugin-client-redirects@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/logger": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-common": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 eta: ^2.2.0 fs-extra: ^11.1.1 lodash: ^4.17.21 @@ -1865,21 +1864,21 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 48a101b88e0f537323cb54c0de6d0a711f7987358699929f0bba17ae60038205a154b2ce179e1a1e065d2732186d23b53f4a1922ca8d875f6aea364abf77bdd7 + checksum: 84f031a9f660028cf745ad4f3b8ea8820e34fdabed75321b06a8145078b3b8c496369c902dc3f46a2bb973cfaaa433474a9891bd836494ff72c65258fa67b64c languageName: node linkType: hard -"@docusaurus/plugin-content-blog@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-content-blog@npm:3.1.1" +"@docusaurus/plugin-content-blog@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-content-blog@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/logger": 3.1.1 - "@docusaurus/mdx-loader": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-common": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/mdx-loader": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 cheerio: ^1.0.0-rc.12 feed: ^4.2.2 fs-extra: ^11.1.1 @@ -1893,21 +1892,22 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 8680e47cc1250cd0c0987c7471e8679860d867de5bf3917e0088185cfa4f5abdb7a847f652cea7c61afbce9dad8bb3cd9f8924b13b064087eab4f9654a9de05d + checksum: d95147a28aad832cd2dc39af634e1902a8a36f958dd2ff5fa6eaa47b574b58df42609a64da823951826f647337ad35c1f1c8be8a0a085913e192936f38839413 languageName: node linkType: hard -"@docusaurus/plugin-content-docs@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-content-docs@npm:3.1.1" +"@docusaurus/plugin-content-docs@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-content-docs@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/logger": 3.1.1 - "@docusaurus/mdx-loader": 3.1.1 - "@docusaurus/module-type-aliases": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/mdx-loader": 3.2.1 + "@docusaurus/module-type-aliases": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 "@types/react-router-config": ^5.0.7 combine-promises: ^1.1.0 fs-extra: ^11.1.1 @@ -1919,133 +1919,133 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 1d96477ca575e01e3e2de080075f07a7f35da7a839632d2ad2d06bf3b651fbd91dd4e70861bb16e1ccb8b2a99f0602461f4c181c04557e0a98ece1b5e5ba61de + checksum: c182466c3ff513b36a8975a3899b07ffc4b227ab45ef69eacc0a77119d6f0cd6a0727a3e886cfcf4a56e4f522f64e1e6a2647ddc57eb8493b93c03240b1d9b39 languageName: node linkType: hard -"@docusaurus/plugin-content-pages@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-content-pages@npm:3.1.1" +"@docusaurus/plugin-content-pages@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-content-pages@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/mdx-loader": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/mdx-loader": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 fs-extra: ^11.1.1 tslib: ^2.6.0 webpack: ^5.88.1 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: ccb9c58802b56c79f2b9bc4445dad316e50438fea995c2a6543637c472c4c2ccfbe3984abb462a1359bce3e3dfad84fecf6e4faab8e242dac4182146043ea005 + checksum: 3cce99f8aa863b97cbb54a50b448073222a0678528b09f5bec2196e73ec4740f412f8675ed05d283ff672756a5d3005f7a1e4d8c8f882cd0d6d5691cbccb604c languageName: node linkType: hard -"@docusaurus/plugin-debug@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-debug@npm:3.1.1" +"@docusaurus/plugin-debug@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-debug@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils": 3.2.1 fs-extra: ^11.1.1 react-json-view-lite: ^1.2.0 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 843780bf7eb57d41d198832ad9a7a53e45302c2a10f0221a77c4340e3b1c1dd4e92f77f2ecae3fdb8eef0aed1b7314f2ce1c8323fe25eec759bcde10e0e50149 + checksum: b3fb1c8935463afb97f233042692c247d4147c03e18ef9fb37fbf0c46d4adaefa4af0d5c357025992dadfe7b83a9fd3754946b8947bfb8b9535dca390a3668d0 languageName: node linkType: hard -"@docusaurus/plugin-google-analytics@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-google-analytics@npm:3.1.1" +"@docusaurus/plugin-google-analytics@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-google-analytics@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 4efcaf9f95353485965e299a971e761b3dadac1370d6d8a6582d653535ce76e36b6788283aa1a6dfd7f55ac64fca3d7e97239f94a5163e4cf192a5c2854b1d61 + checksum: e1e881fd6adbe408029257d526759b9217f7d70e5e068c7e9241a5f0c3050b0fa46acfeb4f8a23c3f36e1739d0a3d810642d69c6648ff6801ce13b646e44e6c1 languageName: node linkType: hard -"@docusaurus/plugin-google-gtag@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-google-gtag@npm:3.1.1" +"@docusaurus/plugin-google-gtag@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-google-gtag@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 "@types/gtag.js": ^0.0.12 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 65ede5352fa16492b23ac37343eb62f4855c4e306ce07552f3257894ddc2329a6244d371bf989bd034cd685965ef8c667d87322497e475d1e54f014fa44225f1 + checksum: b7758289d8453e98baf95d41e754c1e4c8fd5b1c000ba444c4bdf13fc97674a3cddf3215b6406266729e23898641b5bae297c5422c5bd079ef04773fa5a15c1b languageName: node linkType: hard -"@docusaurus/plugin-google-tag-manager@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-google-tag-manager@npm:3.1.1" +"@docusaurus/plugin-google-tag-manager@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-google-tag-manager@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 9a1a014a39da0e5ef234c0eb427b7d97b59fd797152c24e05c13a6a11db4269a0223ad474d17714d02a3ad14a97a9072b6757554b3f274b5f0480d7409749a7c + checksum: 82355aed046b12ce0fead68339e24a3c6f2f517bc2b80c9c26c502cc49d86c1b6d0f797d5269d1d5e73ac78fd748c8a2f4528f7f3feee1137ae8e73876426426 languageName: node linkType: hard -"@docusaurus/plugin-sitemap@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-sitemap@npm:3.1.1" +"@docusaurus/plugin-sitemap@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-sitemap@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/logger": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-common": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 fs-extra: ^11.1.1 sitemap: ^7.1.1 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 69b584dc9143b816a06eac7bbd13501c201c24dadd339dfd18179f7a7ddcabfe76640fd87ab14f73f624916e74b7192eee5f3aca7e745f2d6a92b5754c8d7bb3 + checksum: b2e4c4fddd0fbdd4a6a4c93a0f9c16b1294162146eb9911ce378f33d70396f08dfa98d92aed133bba2a8df2b1710c257bf00c0657933ee6cd9c5edb36c8054dc languageName: node linkType: hard "@docusaurus/preset-classic@npm:^3.1.1": - version: 3.1.1 - resolution: "@docusaurus/preset-classic@npm:3.1.1" + version: 3.2.1 + resolution: "@docusaurus/preset-classic@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/plugin-content-blog": 3.1.1 - "@docusaurus/plugin-content-docs": 3.1.1 - "@docusaurus/plugin-content-pages": 3.1.1 - "@docusaurus/plugin-debug": 3.1.1 - "@docusaurus/plugin-google-analytics": 3.1.1 - "@docusaurus/plugin-google-gtag": 3.1.1 - "@docusaurus/plugin-google-tag-manager": 3.1.1 - "@docusaurus/plugin-sitemap": 3.1.1 - "@docusaurus/theme-classic": 3.1.1 - "@docusaurus/theme-common": 3.1.1 - "@docusaurus/theme-search-algolia": 3.1.1 - "@docusaurus/types": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/plugin-content-blog": 3.2.1 + "@docusaurus/plugin-content-docs": 3.2.1 + "@docusaurus/plugin-content-pages": 3.2.1 + "@docusaurus/plugin-debug": 3.2.1 + "@docusaurus/plugin-google-analytics": 3.2.1 + "@docusaurus/plugin-google-gtag": 3.2.1 + "@docusaurus/plugin-google-tag-manager": 3.2.1 + "@docusaurus/plugin-sitemap": 3.2.1 + "@docusaurus/theme-classic": 3.2.1 + "@docusaurus/theme-common": 3.2.1 + "@docusaurus/theme-search-algolia": 3.2.1 + "@docusaurus/types": 3.2.1 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: c0fba593e9d1670ea21b6caefe297ee35ca22f6b8bc63037d8f3fa652d62516494d0a557f8949520424d01a4e92b563800599ec16a1a33655324b42d5f15c55a + checksum: 343c896f22bffbda9db4af7d652588f353c5f60336e545eb07be0dfe9bc29ca04a3978d88d5a8b3fa7caafc56a48b341349ffd08006885fa0d4de216cfdc5401 languageName: node linkType: hard @@ -2061,22 +2061,22 @@ __metadata: languageName: node linkType: hard -"@docusaurus/theme-classic@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/theme-classic@npm:3.1.1" +"@docusaurus/theme-classic@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/theme-classic@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/mdx-loader": 3.1.1 - "@docusaurus/module-type-aliases": 3.1.1 - "@docusaurus/plugin-content-blog": 3.1.1 - "@docusaurus/plugin-content-docs": 3.1.1 - "@docusaurus/plugin-content-pages": 3.1.1 - "@docusaurus/theme-common": 3.1.1 - "@docusaurus/theme-translations": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-common": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/mdx-loader": 3.2.1 + "@docusaurus/module-type-aliases": 3.2.1 + "@docusaurus/plugin-content-blog": 3.2.1 + "@docusaurus/plugin-content-docs": 3.2.1 + "@docusaurus/plugin-content-pages": 3.2.1 + "@docusaurus/theme-common": 3.2.1 + "@docusaurus/theme-translations": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 "@mdx-js/react": ^3.0.0 clsx: ^2.0.0 copy-text-to-clipboard: ^3.2.0 @@ -2093,21 +2093,21 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 8d64676351408e0a378bf9b226cb9cc8f52c8b1f1e03811431de0c7af2aa80445a825267933a4c44ee92d6a975a549c47f4d28798d99cfc0b731f4c4e38f0ba3 + checksum: 7b38e47e9334ba6ad84f6432ec9ae81caad7f6c630b2a332617b0f32f1559b0e56f3d8857c732da62d1d7213ad0f493853bf18b1707a2f8d8bcccef32f1d81a1 languageName: node linkType: hard -"@docusaurus/theme-common@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/theme-common@npm:3.1.1" +"@docusaurus/theme-common@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/theme-common@npm:3.2.1" dependencies: - "@docusaurus/mdx-loader": 3.1.1 - "@docusaurus/module-type-aliases": 3.1.1 - "@docusaurus/plugin-content-blog": 3.1.1 - "@docusaurus/plugin-content-docs": 3.1.1 - "@docusaurus/plugin-content-pages": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-common": 3.1.1 + "@docusaurus/mdx-loader": 3.2.1 + "@docusaurus/module-type-aliases": 3.2.1 + "@docusaurus/plugin-content-blog": 3.2.1 + "@docusaurus/plugin-content-docs": 3.2.1 + "@docusaurus/plugin-content-pages": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" @@ -2119,22 +2119,22 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: ba7d2c4032c8d7f822e77bd39a77f712f258e9d4aa44aac75a72ad27c0eaa7400746025ba59e445c9c1b083d2ae02802a759361d67e80b9f7295521520ada1bc + checksum: 13de70293476e05f1b52c2d99a1b26c73bf99ac92aba3c8ddc413b5336725d2b54c56c167d12244fdb0b518ee9cdecbbfb3258fb8cc91272e9b795361b131fbb languageName: node linkType: hard -"@docusaurus/theme-search-algolia@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/theme-search-algolia@npm:3.1.1" +"@docusaurus/theme-search-algolia@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/theme-search-algolia@npm:3.2.1" dependencies: "@docsearch/react": ^3.5.2 - "@docusaurus/core": 3.1.1 - "@docusaurus/logger": 3.1.1 - "@docusaurus/plugin-content-docs": 3.1.1 - "@docusaurus/theme-common": 3.1.1 - "@docusaurus/theme-translations": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/plugin-content-docs": 3.2.1 + "@docusaurus/theme-common": 3.2.1 + "@docusaurus/theme-translations": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 algoliasearch: ^4.18.0 algoliasearch-helper: ^3.13.3 clsx: ^2.0.0 @@ -2146,23 +2146,23 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 42686e29faf14c482161eb399b1bc9960322f61298b2e6694d1b89374b2f4c352147b2299cf830abb0db8a9eba0bf5d342adfd1ad71101d1aad17f0955856145 + checksum: befbb86bf309f2b770ae21bc1d5c91eb6e840a5a72858cdfd3b21dbabadd1738d6d427ada7745f9d3424bb1a6e01839e20bf35c15a4c13d59b63d259e52de5df languageName: node linkType: hard -"@docusaurus/theme-translations@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/theme-translations@npm:3.1.1" +"@docusaurus/theme-translations@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/theme-translations@npm:3.2.1" dependencies: fs-extra: ^11.1.1 tslib: ^2.6.0 - checksum: 4fbf12aef4b6e49182b5fd6ee0c357b4cd1811490713a7cddeb7714eacebf1972dac10f3bb4ee56f6c5e62c297a9a7a17f4e3724e56ad28fa8125073e0c3258e + checksum: 43bdb90d143576d2e8eb56bfe2c9daa0e4250cdb2dcfd10096b86466e6ee253548ac5ef2f9a4986a5bc9a573d118fe4695ee5004f0ef00b57b720dac7f124337 languageName: node linkType: hard -"@docusaurus/types@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/types@npm:3.1.1" +"@docusaurus/types@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/types@npm:3.2.1" dependencies: "@mdx-js/mdx": ^3.0.0 "@types/history": ^4.7.11 @@ -2176,13 +2176,13 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 5041bca00cc887cc3ac8dd8c0895cc778dced2943b2d026fe7d1b8828756257093ad3df05706f344e91710b054f9df0e56d2d369a448472ec173bd81c4a8956f + checksum: 4f19e162bff627675df160ae5c33c6063646050c4de5c9698018fbd9d198300b9ce7a7333e4d1b369b42cfa42296dc9fb36547e4e37664d594deb08639e6b620 languageName: node linkType: hard -"@docusaurus/utils-common@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/utils-common@npm:3.1.1" +"@docusaurus/utils-common@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/utils-common@npm:3.2.1" dependencies: tslib: ^2.6.0 peerDependencies: @@ -2190,28 +2190,30 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: 787d930456e4034f7f57186172ad5d214c2473d135ec8c12cf19af8fc64e87eb35a684137e8b813f61e224243c7e3d122c6c646cb20e12ef216048be6a817f44 + checksum: bc0b7e74bc29134dbdb7fbc2e8f9f39f0f460923a07d0ccd7f0542088e92c47faf06bdbd253b7ba2b9250b0869118a3b7bf3faa3a075a2a35f5f8545eb3345f2 languageName: node linkType: hard -"@docusaurus/utils-validation@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/utils-validation@npm:3.1.1" +"@docusaurus/utils-validation@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/utils-validation@npm:3.2.1" dependencies: - "@docusaurus/logger": 3.1.1 - "@docusaurus/utils": 3.1.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 joi: ^17.9.2 js-yaml: ^4.1.0 tslib: ^2.6.0 - checksum: 57d348a4bb2ecac34d84676674c3dc78d6e2821487d5c8a0b9945cab7a4362db5ee2ad084e4bb031b5c4ea674c5136c35090abea2272f57f3b25473c3b1680de + checksum: c7b5142083c8e4798c7f6aa1f7a06bc2e93e8e08a8a7a2c5eaf24aa6939e12e401f180f02164764805c40ec0f7179479e0ee98a935c2cb77037ca73ab33d80fd languageName: node linkType: hard -"@docusaurus/utils@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/utils@npm:3.1.1" +"@docusaurus/utils@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/utils@npm:3.2.1" dependencies: - "@docusaurus/logger": 3.1.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/utils-common": 3.2.1 "@svgr/webpack": ^6.5.1 escape-string-regexp: ^4.0.0 file-loader: ^6.2.0 @@ -2223,6 +2225,7 @@ __metadata: js-yaml: ^4.1.0 lodash: ^4.17.21 micromatch: ^4.0.5 + prompts: ^2.4.2 resolve-pathname: ^3.0.0 shelljs: ^0.8.5 tslib: ^2.6.0 @@ -2233,7 +2236,7 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: 45c39767d1adcc793515109edcb6cfbecd9cf5f979d5dda95a729809b9c30f6288fa5adba757ce131b91b3d77ff24bb7e06ad1b0011d37b45be0035b76ed7ba3 + checksum: ea862b178e303b49e644e77a663df6e42909632022918b77dc1ee69c4de46dde3f210052b1063e96a820e1443141f70e44aa51372f2bf9cfde65e080ea639889 languageName: node linkType: hard @@ -2521,17 +2524,6 @@ __metadata: languageName: node linkType: hard -"@slorber/static-site-generator-webpack-plugin@npm:^4.0.7": - version: 4.0.7 - resolution: "@slorber/static-site-generator-webpack-plugin@npm:4.0.7" - dependencies: - eval: ^0.1.8 - p-map: ^4.0.0 - webpack-sources: ^3.2.2 - checksum: a1e1d8b22dd51059524993f3fdd6861db10eb950debc389e5dd650702287fa2004eace03e6bc8f25b977bd7bc01d76a50aa271cbb73c58a8ec558945d728f307 - languageName: node - linkType: hard - "@spotify/prettier-config@npm:^15.0.0": version: 15.0.0 resolution: "@spotify/prettier-config@npm:15.0.0" @@ -11731,7 +11723,7 @@ __metadata: languageName: node linkType: hard -"webpack-sources@npm:^3.2.2, webpack-sources@npm:^3.2.3": +"webpack-sources@npm:^3.2.3": version: 3.2.3 resolution: "webpack-sources@npm:3.2.3" checksum: 989e401b9fe3536529e2a99dac8c1bdc50e3a0a2c8669cbafad31271eadd994bc9405f88a3039cd2e29db5e6d9d0926ceb7a1a4e7409ece021fe79c37d9c4607 From b3c2c9f16a91642865a717ec5a40c7ce9e24160f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 Apr 2024 16:34:53 +0000 Subject: [PATCH 084/107] chore(deps): update dependency jest-date-mock to v1.0.9 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 836e2e31a3..c332ad1f3e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -31917,9 +31917,9 @@ __metadata: linkType: hard "jest-date-mock@npm:^1.0.8": - version: 1.0.8 - resolution: "jest-date-mock@npm:1.0.8" - checksum: 7b012870440b0df742d0b651435b91625dbbf02d916633a0c70c7deb5d5087f9aadc59847602312368826325909e70e95cd412896a0c9ee1d5ac382000bf5ef9 + version: 1.0.9 + resolution: "jest-date-mock@npm:1.0.9" + checksum: 4f8c4914348c59c4b3951577276dfea6f714fa24d032a774225f41288da1a191cfe14f95e1ba59dcc0db8cf1c9f7d3a1581b18ade6fc7b63118b04166a127c0a languageName: node linkType: hard From 56ce1b0a81182ce46c864a645c74c1be15d0e149 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 13 Apr 2024 16:51:30 +0200 Subject: [PATCH 085/107] scaffolder-backend-module-gitlap: remove use of jest-date-mock Signed-off-by: Patrik Oldsberg --- plugins/scaffolder-backend-module-gitlab/package.json | 3 +-- .../src/actions/createGitlabIssueAction.test.ts | 7 ++++--- yarn.lock | 8 -------- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitlab/package.json b/plugins/scaffolder-backend-module-gitlab/package.json index ff23e39a9e..38f94193ea 100644 --- a/plugins/scaffolder-backend-module-gitlab/package.json +++ b/plugins/scaffolder-backend-module-gitlab/package.json @@ -60,7 +60,6 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", - "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", - "jest-date-mock": "^1.0.8" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" } } diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabIssueAction.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabIssueAction.test.ts index 7298a502b6..feea436a1e 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabIssueAction.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabIssueAction.test.ts @@ -18,7 +18,6 @@ import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test- import { createGitlabIssueAction, IssueType } from './createGitlabIssueAction'; import { ConfigReader } from '@backstage/core-app-api'; import { ScmIntegrations } from '@backstage/integration'; -import { advanceTo, clear } from 'jest-date-mock'; const mockGitlabClient = { Issues: { @@ -36,11 +35,13 @@ jest.mock('@gitbeaker/rest', () => ({ describe('gitlab:issues:create', () => { beforeEach(() => { jest.clearAllMocks(); - advanceTo(new Date(1988, 5, 3, 12, 0, 0)); // Set the desired date and time + jest.useFakeTimers({ + now: new Date(1988, 5, 3, 12, 0, 0), + }); }); afterEach(() => { - clear(); // Reset the date mock after each test + jest.useRealTimers(); }); const config = new ConfigReader({ diff --git a/yarn.lock b/yarn.lock index c332ad1f3e..b03d2d78ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8661,7 +8661,6 @@ __metadata: "@gitbeaker/core": ^35.8.0 "@gitbeaker/node": ^35.8.0 "@gitbeaker/rest": ^39.25.0 - jest-date-mock: ^1.0.8 luxon: ^3.0.0 yaml: ^2.0.0 zod: ^3.22.4 @@ -31916,13 +31915,6 @@ __metadata: languageName: node linkType: hard -"jest-date-mock@npm:^1.0.8": - version: 1.0.9 - resolution: "jest-date-mock@npm:1.0.9" - checksum: 4f8c4914348c59c4b3951577276dfea6f714fa24d032a774225f41288da1a191cfe14f95e1ba59dcc0db8cf1c9f7d3a1581b18ade6fc7b63118b04166a127c0a - languageName: node - linkType: hard - "jest-diff@npm:^29.2.0, jest-diff@npm:^29.7.0": version: 29.7.0 resolution: "jest-diff@npm:29.7.0" From f9fb95adae6cbb8112a3e6df70c4110934e45292 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 15:01:40 +0000 Subject: [PATCH 086/107] chore(deps): update dependency @testing-library/react to v15.0.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 836e2e31a3..82c0b95df1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18058,8 +18058,8 @@ __metadata: linkType: hard "@testing-library/react@npm:^15.0.0": - version: 15.0.1 - resolution: "@testing-library/react@npm:15.0.1" + version: 15.0.2 + resolution: "@testing-library/react@npm:15.0.2" dependencies: "@babel/runtime": ^7.12.5 "@testing-library/dom": ^10.0.0 @@ -18067,7 +18067,7 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 9992087563279bc975e5be69c0d380ecee84eb9e5c5e474b8b01b95804477ecae0978c61ded15821335d926fec058ab6c23442150584b0f19bee72c561ad19b7 + checksum: 32be030a5540164403f3cd8d6f46ad907119b2bc0a0df43ce6b925cdd520d5003298d06af1ee94d7bd764f294d74e802b6509caf2cf10afc77e67407baa9c1fb languageName: node linkType: hard From 69b844be33b5ab78146f525632d23d5a8cad9b63 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 15:03:59 +0000 Subject: [PATCH 087/107] fix(deps): update dependency graphql-voyager to v1.3.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 679 ++++++++++++++++-------------------------------------- 1 file changed, 196 insertions(+), 483 deletions(-) diff --git a/yarn.lock b/yarn.lock index 836e2e31a3..cbffddcb09 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3192,7 +3192,7 @@ __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.13.10, @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.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @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": +"@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.13.10, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @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.2, @babel/runtime@npm:^7.23.9, @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.24.4 resolution: "@babel/runtime@npm:7.24.4" dependencies: @@ -10729,7 +10729,7 @@ __metadata: languageName: node linkType: hard -"@emotion/babel-plugin@npm:^11.11.0": +"@emotion/babel-plugin@npm:^11.10.5, @emotion/babel-plugin@npm:^11.11.0": version: 11.11.0 resolution: "@emotion/babel-plugin@npm:11.11.0" dependencies: @@ -10748,7 +10748,7 @@ __metadata: languageName: node linkType: hard -"@emotion/cache@npm:^11.11.0": +"@emotion/cache@npm:^11.10.5, @emotion/cache@npm:^11.11.0": version: 11.11.0 resolution: "@emotion/cache@npm:11.11.0" dependencies: @@ -10784,7 +10784,7 @@ __metadata: languageName: node linkType: hard -"@emotion/is-prop-valid@npm:^1.1.0, @emotion/is-prop-valid@npm:^1.2.2": +"@emotion/is-prop-valid@npm:^1.1.0, @emotion/is-prop-valid@npm:^1.2.0, @emotion/is-prop-valid@npm:^1.2.2": version: 1.2.2 resolution: "@emotion/is-prop-valid@npm:1.2.2" dependencies: @@ -10807,6 +10807,30 @@ __metadata: languageName: node linkType: hard +"@emotion/react@npm:11.10.5": + version: 11.10.5 + resolution: "@emotion/react@npm:11.10.5" + dependencies: + "@babel/runtime": ^7.18.3 + "@emotion/babel-plugin": ^11.10.5 + "@emotion/cache": ^11.10.5 + "@emotion/serialize": ^1.1.1 + "@emotion/use-insertion-effect-with-fallbacks": ^1.0.0 + "@emotion/utils": ^1.2.0 + "@emotion/weak-memoize": ^0.3.0 + hoist-non-react-statics: ^3.3.1 + peerDependencies: + "@babel/core": ^7.0.0 + react: ">=16.8.0" + peerDependenciesMeta: + "@babel/core": + optional: true + "@types/react": + optional: true + checksum: 32b67b28e9b6d6c53b970072680697f04c2521441050bdeb19a1a7f0164af549b4dad39ff375eda1b6a3cf1cc86ba2c6fa55460ec040e6ebbca3e9ec58353cf7 + languageName: node + linkType: hard + "@emotion/react@npm:^11.10.5": version: 11.11.4 resolution: "@emotion/react@npm:11.11.4" @@ -10828,7 +10852,7 @@ __metadata: languageName: node linkType: hard -"@emotion/serialize@npm:^1.1.2, @emotion/serialize@npm:^1.1.3, @emotion/serialize@npm:^1.1.4": +"@emotion/serialize@npm:^1.1.1, @emotion/serialize@npm:^1.1.2, @emotion/serialize@npm:^1.1.3, @emotion/serialize@npm:^1.1.4": version: 1.1.4 resolution: "@emotion/serialize@npm:1.1.4" dependencies: @@ -10848,6 +10872,29 @@ __metadata: languageName: node linkType: hard +"@emotion/styled@npm:11.10.5": + version: 11.10.5 + resolution: "@emotion/styled@npm:11.10.5" + dependencies: + "@babel/runtime": ^7.18.3 + "@emotion/babel-plugin": ^11.10.5 + "@emotion/is-prop-valid": ^1.2.0 + "@emotion/serialize": ^1.1.1 + "@emotion/use-insertion-effect-with-fallbacks": ^1.0.0 + "@emotion/utils": ^1.2.0 + peerDependencies: + "@babel/core": ^7.0.0 + "@emotion/react": ^11.0.0-rc.0 + react: ">=16.8.0" + peerDependenciesMeta: + "@babel/core": + optional: true + "@types/react": + optional: true + checksum: 1cec5f6aeb227a7255141031e8594f38ad83902413472aae0a46c27e5f9769c01e23c1ad39adee408d8a2168a697464314d1a0c4f50b31a5d25ea506b2d7bbc8 + languageName: node + linkType: hard + "@emotion/styled@npm:^11.10.5": version: 11.11.5 resolution: "@emotion/styled@npm:11.11.5" @@ -10889,7 +10936,7 @@ __metadata: languageName: node linkType: hard -"@emotion/use-insertion-effect-with-fallbacks@npm:^1.0.1": +"@emotion/use-insertion-effect-with-fallbacks@npm:^1.0.0, @emotion/use-insertion-effect-with-fallbacks@npm:^1.0.1": version: 1.0.1 resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.0.1" peerDependencies: @@ -10898,14 +10945,14 @@ __metadata: languageName: node linkType: hard -"@emotion/utils@npm:^1.2.1": +"@emotion/utils@npm:^1.2.0, @emotion/utils@npm:^1.2.1": version: 1.2.1 resolution: "@emotion/utils@npm:1.2.1" checksum: e0b44be0705b56b079c55faff93952150be69e79b660ae70ddd5b6e09fc40eb1319654315a9f34bb479d7f4ec94be6068c061abbb9e18b9778ae180ad5d97c73 languageName: node linkType: hard -"@emotion/weak-memoize@npm:^0.3.1": +"@emotion/weak-memoize@npm:^0.3.0, @emotion/weak-memoize@npm:^0.3.1": version: 0.3.1 resolution: "@emotion/weak-memoize@npm:0.3.1" checksum: b2be47caa24a8122622ea18cd2d650dbb4f8ad37b636dc41ed420c2e082f7f1e564ecdea68122b546df7f305b159bf5ab9ffee872abd0f052e687428459af594 @@ -11296,56 +11343,6 @@ __metadata: languageName: node linkType: hard -"@f/animate@npm:^1.0.1": - version: 1.0.1 - resolution: "@f/animate@npm:1.0.1" - dependencies: - "@f/elapsed-time": ^1.0.0 - "@f/raf": ^1.0.0 - "@f/tween": ^1.0.0 - checksum: 660b44d297b1a6e5e28c48438633e00ded40f8e51adb4bfb26fc809b60c8c056f567f2e61f4f842c8fd2cf8a85dffaa1c2502bd0963eb926135f2d66d9f997db - languageName: node - linkType: hard - -"@f/elapsed-time@npm:^1.0.0": - version: 1.0.0 - resolution: "@f/elapsed-time@npm:1.0.0" - dependencies: - "@f/timestamp": ^1.0.0 - checksum: 5934d24a667bae4e0089408aa362c0ee1503945adf73ca0ff0d09fed33d62d070f0323eb9a54f42c37bd0545330a0f63da13319f66cc89fef59b8917a3278b5f - languageName: node - linkType: hard - -"@f/map-obj@npm:^1.2.2": - version: 1.2.2 - resolution: "@f/map-obj@npm:1.2.2" - checksum: d67db6074e1daa7a3c0f8c2e54094bff48b54d11817fddc886631dd8a17586d0040e7116282a374cc1d3d643d05862d49a1062ea5b2d03b9069507c09ae888a4 - languageName: node - linkType: hard - -"@f/raf@npm:^1.0.0": - version: 1.0.3 - resolution: "@f/raf@npm:1.0.3" - checksum: 800344caf4c649c0bcdefd4febbf3f0eed96bb9b7e54b5bc6eebd7d781c9e6d98ba22fb39da41474080d97ac21916bd1e82051558b43dabcbbf410d2dd0899c1 - languageName: node - linkType: hard - -"@f/timestamp@npm:^1.0.0": - version: 1.0.0 - resolution: "@f/timestamp@npm:1.0.0" - checksum: 8c37acb40cf67952309a214be2ddfd5c4f6634a414efc47406e8d1c1624e74662f584f6b48f3382c742f256aea1537e730e74c6078e52be3a28d0624cc7306a0 - languageName: node - linkType: hard - -"@f/tween@npm:^1.0.0": - version: 1.0.1 - resolution: "@f/tween@npm:1.0.1" - dependencies: - "@f/map-obj": ^1.2.2 - checksum: e37155c43875becc9eca8425b8dc83e64a78fa327738b33fcb3946418369568aa77007ade39591991379187381da829702e5cb84729dd2a0bc3bb4b7c94e4f2b - languageName: node - linkType: hard - "@faker-js/faker@npm:5.5.3": version: 5.5.3 resolution: "@faker-js/faker@npm:5.5.3" @@ -12695,44 +12692,6 @@ __metadata: languageName: node linkType: hard -"@material-ui/core@npm:^3.9.3": - version: 3.9.4 - resolution: "@material-ui/core@npm:3.9.4" - dependencies: - "@babel/runtime": ^7.2.0 - "@material-ui/system": ^3.0.0-alpha.0 - "@material-ui/utils": ^3.0.0-alpha.2 - "@types/jss": ^9.5.6 - "@types/react-transition-group": ^2.0.8 - brcast: ^3.0.1 - classnames: ^2.2.5 - csstype: ^2.5.2 - debounce: ^1.1.0 - deepmerge: ^3.0.0 - dom-helpers: ^3.2.1 - hoist-non-react-statics: ^3.2.1 - is-plain-object: ^2.0.4 - jss: ^9.8.7 - jss-camel-case: ^6.0.0 - jss-default-unit: ^8.0.2 - jss-global: ^3.0.0 - jss-nested: ^6.0.1 - jss-props-sort: ^6.0.0 - jss-vendor-prefixer: ^7.0.0 - normalize-scroll-left: ^0.1.2 - popper.js: ^1.14.1 - prop-types: ^15.6.0 - react-event-listener: ^0.6.2 - react-transition-group: ^2.2.1 - recompose: 0.28.0 - 0.30.0 - warning: ^4.0.1 - peerDependencies: - react: ^16.3.0 - react-dom: ^16.3.0 - checksum: c3923bfba4ef4449fbdcd37712ec0d11393ffa396c575a05b5f9530ca1e714028882d39402eb6918dad49f2eb1c53b261cfd0f2dfed494c2dfd96ee335336b44 - languageName: node - linkType: hard - "@material-ui/core@npm:^4.12.2, @material-ui/core@npm:^4.12.4, @material-ui/core@npm:^4.9.13": version: 4.12.4 resolution: "@material-ui/core@npm:4.12.4" @@ -12911,21 +12870,6 @@ __metadata: languageName: node linkType: hard -"@material-ui/system@npm:^3.0.0-alpha.0": - version: 3.0.0-alpha.2 - resolution: "@material-ui/system@npm:3.0.0-alpha.2" - dependencies: - "@babel/runtime": ^7.2.0 - deepmerge: ^3.0.0 - prop-types: ^15.6.0 - warning: ^4.0.1 - peerDependencies: - react: ^16.3.0 - react-dom: ^16.3.0 - checksum: 3aacb8b4afe2a820844b90905cfcd86ab934108cd719f11713ee46f8a4da30cb8c50e86219e1440b3c6dd333a09d4123cd1990d9c51862c1d56ec2b36e4d7ded - languageName: node - linkType: hard - "@material-ui/system@npm:^4.12.2": version: 4.12.2 resolution: "@material-ui/system@npm:4.12.2" @@ -12969,20 +12913,6 @@ __metadata: languageName: node linkType: hard -"@material-ui/utils@npm:^3.0.0-alpha.2": - version: 3.0.0-alpha.3 - resolution: "@material-ui/utils@npm:3.0.0-alpha.3" - dependencies: - "@babel/runtime": ^7.2.0 - prop-types: ^15.6.0 - react-is: ^16.6.3 - peerDependencies: - react: ^16.3.0 - react-dom: ^16.3.0 - checksum: 589a16245338c374b604a793d9f7a05bd932c9710f78261e46176b74a61d5d308b3e36dab688988ee5177d689c53d9e9da4649eca009ea11d8aac948db27af50 - languageName: node - linkType: hard - "@material-ui/utils@npm:^4.11.2, @material-ui/utils@npm:^4.11.3, @material-ui/utils@npm:^4.7.1": version: 4.11.3 resolution: "@material-ui/utils@npm:4.11.3" @@ -13194,6 +13124,29 @@ __metadata: languageName: node linkType: hard +"@mui/base@npm:5.0.0-alpha.112": + version: 5.0.0-alpha.112 + resolution: "@mui/base@npm:5.0.0-alpha.112" + dependencies: + "@babel/runtime": ^7.20.7 + "@emotion/is-prop-valid": ^1.2.0 + "@mui/types": ^7.2.3 + "@mui/utils": ^5.11.2 + "@popperjs/core": ^2.11.6 + clsx: ^1.2.1 + prop-types: ^15.8.1 + react-is: ^18.2.0 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: fd19240ac16859d62f057fd80261fc4e0dbc960a648b601bd7beaeb44b88c059f654b0989f33cea655ad61106832bffa0cd8446730c1be7671b6cde383dbce80 + languageName: node + linkType: hard + "@mui/base@npm:5.0.0-beta.40": version: 5.0.0-beta.40 resolution: "@mui/base@npm:5.0.0-beta.40" @@ -13216,13 +13169,92 @@ __metadata: languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.15": +"@mui/core-downloads-tracker@npm:^5.11.2, @mui/core-downloads-tracker@npm:^5.15.15": version: 5.15.15 resolution: "@mui/core-downloads-tracker@npm:5.15.15" checksum: 3e99a04e03f66d5fa5f0c23cdce0f9fa2331ba08c99a75dc2347ccaa1c6ed520153e04aaeb0d613c9dca099a3e6242558a6284c33d93f95cc65e3243b17860bc languageName: node linkType: hard +"@mui/icons-material@npm:5.11.0": + version: 5.11.0 + resolution: "@mui/icons-material@npm:5.11.0" + dependencies: + "@babel/runtime": ^7.20.6 + peerDependencies: + "@mui/material": ^5.0.0 + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 764c1185b3432f0228f3c5217b0e218b10f106fa96d305dfc62c0ef5afd2a7a087b0d664fd0a8171282e195c18d3ee073d5f037901a2bed1a1519a70fbb0501c + languageName: node + linkType: hard + +"@mui/lab@npm:5.0.0-alpha.114": + version: 5.0.0-alpha.114 + resolution: "@mui/lab@npm:5.0.0-alpha.114" + dependencies: + "@babel/runtime": ^7.20.7 + "@mui/base": 5.0.0-alpha.112 + "@mui/system": ^5.11.2 + "@mui/types": ^7.2.3 + "@mui/utils": ^5.11.2 + clsx: ^1.2.1 + prop-types: ^15.8.1 + react-is: ^18.2.0 + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@mui/material": ^5.0.0 + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@types/react": + optional: true + checksum: 0b6441e7f7a69e2a6910f044ef2a222462a219f61e3a05c023484508e7f14a5fe6baeddf08b37bceab357c7cb0eed90324ac42ecd8e59a6eb6e1c801ea01504a + languageName: node + linkType: hard + +"@mui/material@npm:5.11.2": + version: 5.11.2 + resolution: "@mui/material@npm:5.11.2" + dependencies: + "@babel/runtime": ^7.20.7 + "@mui/base": 5.0.0-alpha.112 + "@mui/core-downloads-tracker": ^5.11.2 + "@mui/system": ^5.11.2 + "@mui/types": ^7.2.3 + "@mui/utils": ^5.11.2 + "@types/react-transition-group": ^4.4.5 + clsx: ^1.2.1 + csstype: ^3.1.1 + prop-types: ^15.8.1 + react-is: ^18.2.0 + react-transition-group: ^4.4.5 + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@types/react": + optional: true + checksum: 4f2baa4b4d8f7842b081e9e919172020f7055e33c24af36c5a458eac1a76ff3e896651fdf21daa523a68ac0bfb3670864c1b4dec9fae6d8fadf2b602f14f95ea + languageName: node + linkType: hard + "@mui/material@npm:^5.12.2": version: 5.15.15 resolution: "@mui/material@npm:5.15.15" @@ -13325,7 +13357,7 @@ __metadata: languageName: node linkType: hard -"@mui/system@npm:^5.15.15": +"@mui/system@npm:^5.11.2, @mui/system@npm:^5.15.15": version: 5.15.15 resolution: "@mui/system@npm:5.15.15" dependencies: @@ -13353,7 +13385,7 @@ __metadata: languageName: node linkType: hard -"@mui/types@npm:^7.2.14": +"@mui/types@npm:^7.2.14, @mui/types@npm:^7.2.3": version: 7.2.14 resolution: "@mui/types@npm:7.2.14" peerDependencies: @@ -13365,7 +13397,7 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.14.15, @mui/utils@npm:^5.15.14": +"@mui/utils@npm:^5.11.2, @mui/utils@npm:^5.14.15, @mui/utils@npm:^5.15.14": version: 5.15.14 resolution: "@mui/utils@npm:5.15.14" dependencies: @@ -14862,7 +14894,7 @@ __metadata: languageName: node linkType: hard -"@popperjs/core@npm:^2.11.8": +"@popperjs/core@npm:^2.11.6, @popperjs/core@npm:^2.11.8": version: 2.11.8 resolution: "@popperjs/core@npm:2.11.8" checksum: e5c69fdebf52a4012f6a1f14817ca8e9599cb1be73dd1387e1785e2ed5e5f0862ff817f420a87c7fc532add1f88a12e25aeb010ffcbdc98eace3d55ce2139cf0 @@ -19047,16 +19079,6 @@ __metadata: languageName: node linkType: hard -"@types/jss@npm:^9.5.6": - version: 9.5.8 - resolution: "@types/jss@npm:9.5.8" - dependencies: - csstype: ^2.0.0 - indefinite-observable: ^1.0.1 - checksum: 6e51707529a15f2f5ff94555ecb555d29427fd10c4f3d2d29474934292e365c2dfaa4ad30b2ab46946201cbca7f6e8df56513a22fc6ceca10a979db8338935c5 - languageName: node - linkType: hard - "@types/keyv@npm:*, @types/keyv@npm:^3.1.1": version: 3.1.4 resolution: "@types/keyv@npm:3.1.4" @@ -19555,16 +19577,7 @@ __metadata: languageName: node linkType: hard -"@types/react-transition-group@npm:^2.0.8": - version: 2.9.2 - resolution: "@types/react-transition-group@npm:2.9.2" - dependencies: - "@types/react": "*" - checksum: 6f30fffc221339de90bd3e999f32328618cfaedfcaa501603f5ddc5bed1c2dbaa0d51347c3a25e5f8fd3041c671aabd2b7bfbcad611a7636adcd9da4e0666fa5 - languageName: node - linkType: hard - -"@types/react-transition-group@npm:^4.2.0, @types/react-transition-group@npm:^4.4.10": +"@types/react-transition-group@npm:^4.2.0, @types/react-transition-group@npm:^4.4.10, @types/react-transition-group@npm:^4.4.5": version: 4.4.10 resolution: "@types/react-transition-group@npm:4.4.10" dependencies: @@ -22511,13 +22524,6 @@ __metadata: languageName: node linkType: hard -"brcast@npm:^3.0.1": - version: 3.0.2 - resolution: "brcast@npm:3.0.2" - checksum: 7abae42088c6ffad9ff9e0fc756607a1764e299d737b3007fa49a73a38b3fda1e51362713f645db7991878ca388de94942011188450324c3debd08509315fa94 - languageName: node - linkType: hard - "breakword@npm:^1.0.5": version: 1.0.5 resolution: "breakword@npm:1.0.5" @@ -23087,13 +23093,6 @@ __metadata: languageName: node linkType: hard -"change-emitter@npm:^0.1.2": - version: 0.1.6 - resolution: "change-emitter@npm:0.1.6" - checksum: 0ed494ba9901ca56ea6f942668fd294465c334a9a0981dca96da5aea5e387c0023a630d7c658c1b532d203db54c928ddca2564e434b4a8b7f6d39155d09db255 - languageName: node - linkType: hard - "char-regex@npm:^1.0.2": version: 1.0.2 resolution: "char-regex@npm:1.0.2" @@ -23398,17 +23397,6 @@ __metadata: languageName: node linkType: hard -"clipboard@npm:^2.0.4": - version: 2.0.11 - resolution: "clipboard@npm:2.0.11" - dependencies: - good-listener: ^1.2.2 - select: ^1.1.2 - tiny-emitter: ^2.0.0 - checksum: 413055a6038e43898e0e895216b58ed54fbf386f091cb00188875ef35b186cefbd258acdf4cb4b0ac87cbc00de936f41b45dde9fe1fd1a57f7babb28363b8748 - languageName: node - linkType: hard - "cliui@npm:7.0.4, cliui@npm:^7.0.2": version: 7.0.4 resolution: "cliui@npm:7.0.4" @@ -23851,9 +23839,9 @@ __metadata: languageName: node linkType: hard -"commonmark@npm:^0.29.0": - version: 0.29.3 - resolution: "commonmark@npm:0.29.3" +"commonmark@npm:0.30.0": + version: 0.30.0 + resolution: "commonmark@npm:0.30.0" dependencies: entities: ~2.0 mdurl: ~1.0.1 @@ -23861,7 +23849,7 @@ __metadata: string.prototype.repeat: ^0.2.0 bin: commonmark: bin/commonmark - checksum: 892b603aeffea6a04770ce24979fc4024d2d92ca6d5146353398faab15be980af6802f3d7b35357400b870e752a9f80b766fed5c09ca063a2951c8c26013876c + checksum: 39f05d6d0f471aa345487d45199809233f29f857630780fde23661356f1f31970f67328934895d3062e01524674785981837c3b6f4303b63d8c9bff8fa99ec83 languageName: node linkType: hard @@ -24250,13 +24238,6 @@ __metadata: languageName: node linkType: hard -"core-js@npm:^1.0.0": - version: 1.2.7 - resolution: "core-js@npm:1.2.7" - checksum: 0b76371bfa98708351cde580f9287e2360d2209920e738ae950ae74ad08639a2e063541020bf666c28778956fc356ed9fe56d962129c88a87a6a4a0612526c75 - languageName: node - linkType: hard - "core-js@npm:^2.4.0, core-js@npm:^2.5.0": version: 2.6.12 resolution: "core-js@npm:2.6.12" @@ -24709,15 +24690,6 @@ __metadata: languageName: node linkType: hard -"css-vendor@npm:^0.3.8": - version: 0.3.8 - resolution: "css-vendor@npm:0.3.8" - dependencies: - is-in-browser: ^1.0.2 - checksum: 0a2e0cd0d4adbfdb6236950e7f9697b8a9b294eb2ae7c95996a95d273d2a63316ce793cb4654ae048aa3c129327124d2a29aada9935a0c284f9cc341c2768c8a - languageName: node - linkType: hard - "css-vendor@npm:^2.0.8": version: 2.0.8 resolution: "css-vendor@npm:2.0.8" @@ -24852,17 +24824,17 @@ __metadata: languageName: node linkType: hard -"csstype@npm:^2.0.0, csstype@npm:^2.5.2, csstype@npm:^2.6.7": +"csstype@npm:^2.5.2, csstype@npm:^2.6.7": version: 2.6.21 resolution: "csstype@npm:2.6.21" checksum: 2ce8bc832375146eccdf6115a1f8565a27015b74cce197c35103b4494955e9516b246140425ad24103864076aa3e1257ac9bab25a06c8d931dd87a6428c9dccf languageName: node linkType: hard -"csstype@npm:^3.0.2, csstype@npm:^3.1.2, csstype@npm:^3.1.3": - version: 3.0.9 - resolution: "csstype@npm:3.0.9" - checksum: 199f9af7e673f9f188525c3102a329d637ff46c52f6385a4427ff5cb17adcb736189150170a7af7c5701d18d7704bdad130273f4aa7e44c6c4f9967e6115dc93 +"csstype@npm:^3.0.2, csstype@npm:^3.1.1, csstype@npm:^3.1.2, csstype@npm:^3.1.3": + version: 3.1.3 + resolution: "csstype@npm:3.1.3" + checksum: 8db785cc92d259102725b3c694ec0c823f5619a84741b5c7991b8ad135dfaa66093038a1cc63e03361a6cd28d122be48f2106ae72334e067dd619a51f49eddf7 languageName: node linkType: hard @@ -25220,7 +25192,7 @@ __metadata: languageName: node linkType: hard -"debounce@npm:^1.1.0, debounce@npm:^1.2.0": +"debounce@npm:^1.2.0": version: 1.2.1 resolution: "debounce@npm:1.2.1" checksum: 682a89506d9e54fb109526f4da255c5546102fbb8e3ae75eef3b04effaf5d4853756aee97475cd4650641869794e44f410eeb20ace2b18ea592287ab2038519e @@ -25396,13 +25368,6 @@ __metadata: languageName: node linkType: hard -"deepmerge@npm:^3.0.0": - version: 3.3.0 - resolution: "deepmerge@npm:3.3.0" - checksum: 4322195389e0170a0443c07b36add19b90249802c4b47b96265fdc5f5d8beddf491d5e50cbc5bfd65f85ccf76598173083863c202f5463b3b667aca8be75d5ac - languageName: node - linkType: hard - "deepmerge@npm:^4.2.2, deepmerge@npm:^4.3.1, deepmerge@npm:~4.3.0": version: 4.3.1 resolution: "deepmerge@npm:4.3.1" @@ -25536,13 +25501,6 @@ __metadata: languageName: node linkType: hard -"delegate@npm:^3.1.2": - version: 3.2.0 - resolution: "delegate@npm:3.2.0" - checksum: d943058fe05897228b158cbd1bab05164df28c8f54127873231d6b03b0a5acc1b3ee1f98ac70ccc9b79cd84aa47118a7de111fee2923753491583905069da27d - languageName: node - linkType: hard - "delegates@npm:^1.0.0": version: 1.0.0 resolution: "delegates@npm:1.0.0" @@ -25850,15 +25808,6 @@ __metadata: languageName: node linkType: hard -"dom-helpers@npm:^3.2.1, dom-helpers@npm:^3.4.0": - version: 3.4.0 - resolution: "dom-helpers@npm:3.4.0" - dependencies: - "@babel/runtime": ^7.1.2 - checksum: 58d9f1c4a96daf77eddc63ae1236b826e1cddd6db66bbf39b18d7e21896d99365b376593352d52a60969d67fa4a8dbef26adc1439fa2c1b355efa37cacbaf637 - languageName: node - linkType: hard - "dom-helpers@npm:^5.0.1": version: 5.1.4 resolution: "dom-helpers@npm:5.1.4" @@ -26287,7 +26236,7 @@ __metadata: languageName: node linkType: hard -"encoding@npm:^0.1.11, encoding@npm:^0.1.12, encoding@npm:^0.1.13": +"encoding@npm:^0.1.12, encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" dependencies: @@ -28219,21 +28168,6 @@ __metadata: languageName: node linkType: hard -"fbjs@npm:^0.8.1": - version: 0.8.18 - resolution: "fbjs@npm:0.8.18" - dependencies: - core-js: ^1.0.0 - isomorphic-fetch: ^2.1.1 - loose-envify: ^1.0.0 - object-assign: ^4.1.0 - promise: ^7.1.1 - setimmediate: ^1.0.5 - ua-parser-js: ^0.7.30 - checksum: 668731b946a765908c9cbe51d5160f973abb78004b3d122587c3e930e3e1ddcc0ce2b17f2a8637dc9d733e149aa580f8d3035a35cc2d3bc78b78f1b19aab90e2 - languageName: node - linkType: hard - "fbjs@npm:^3.0.0, fbjs@npm:^3.0.1": version: 3.0.4 resolution: "fbjs@npm:3.0.4" @@ -29375,15 +29309,6 @@ __metadata: languageName: node linkType: hard -"good-listener@npm:^1.2.2": - version: 1.2.2 - resolution: "good-listener@npm:1.2.2" - dependencies: - delegate: ^3.1.2 - checksum: f39fb82c4e41524f56104cfd2d7aef1a88e72f3f75139115fbdf98cc7d844e0c1b39218b2e83438c6188727bf904ed78c7f0f2feff67b32833bc3af7f0202b33 - languageName: node - linkType: hard - "google-auth-library@npm:^9.0.0, google-auth-library@npm:^9.6.3": version: 9.7.0 resolution: "google-auth-library@npm:9.7.0" @@ -29604,23 +29529,22 @@ __metadata: linkType: hard "graphql-voyager@npm:^1.0.0-rc.31": - version: 1.0.0-rc.31 - resolution: "graphql-voyager@npm:1.0.0-rc.31" + version: 1.3.0 + resolution: "graphql-voyager@npm:1.3.0" dependencies: - "@f/animate": ^1.0.1 - "@material-ui/core": ^3.9.3 - classnames: ^2.2.6 - clipboard: ^2.0.4 - commonmark: ^0.29.0 - lodash: ^4.17.10 - prop-types: ^15.7.2 - svg-pan-zoom: ^3.6.0 - viz.js: 2.1.2 + "@emotion/react": 11.10.5 + "@emotion/styled": 11.10.5 + "@mui/icons-material": 5.11.0 + "@mui/lab": 5.0.0-alpha.114 + "@mui/material": 5.11.2 + commonmark: 0.30.0 + lodash: 4.17.21 + svg-pan-zoom: 3.6.1 peerDependencies: - graphql: ">=14.0.0" - react: ">=15.4.2" - react-dom: ">=15.4.2" - checksum: 80e826eeb42d286540447723ea35a463a3a155287914a45e24b69f31617d8ca74c0c43bdaa64123bf4ed046e68f7e31feca7661c06288551040f3e5b96c48fed + graphql: ">=16.5.0" + react: ">=18.0.0" + react-dom: ">=18.0.0" + checksum: 664d8adb932e3d72189e24dfb09fe364cc0e2852ab615eddeac250d9b4a0e6130a5ea363aec87c516b3c134c070c4c15999ccedec89f57afd554e600c6d4ca34 languageName: node linkType: hard @@ -29961,14 +29885,7 @@ __metadata: languageName: node linkType: hard -"hoist-non-react-statics@npm:^2.3.1": - version: 2.5.5 - resolution: "hoist-non-react-statics@npm:2.5.5" - checksum: ee2d05e5c7e1398ad84a15b0327f66bd78f38a8e0015e852f954b36434e32eb7e942d5357505020a3a1147f247b165bf1e69d72393e3accab67cafdafeb86230 - languageName: node - linkType: hard - -"hoist-non-react-statics@npm:^3.0.0, hoist-non-react-statics@npm:^3.2.1, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": +"hoist-non-react-statics@npm:^3.0.0, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2" dependencies: @@ -30358,7 +30275,7 @@ __metadata: languageName: node linkType: hard -"hyphenate-style-name@npm:^1.0.2, hyphenate-style-name@npm:^1.0.3": +"hyphenate-style-name@npm:^1.0.3": version: 1.0.3 resolution: "hyphenate-style-name@npm:1.0.3" checksum: e333f610e7cb32210861ff8c55f99582cdc39e4737903936a7eb61702c98f8db45f33d54f9d230221fabc4d321b2ab8382b8af50d24a1eba21916f2edddd7b85 @@ -30552,15 +30469,6 @@ __metadata: languageName: node linkType: hard -"indefinite-observable@npm:^1.0.1": - version: 1.0.2 - resolution: "indefinite-observable@npm:1.0.2" - dependencies: - symbol-observable: 1.2.0 - checksum: 69a337967f48fca18989f9d68ad98c7220ed9b499bf00330ff72669a9583cb7f8e82f801da10720f720edf1313f427c77ce793350bdc413c952cec8ce112fc12 - languageName: node - linkType: hard - "indent-string@npm:^4.0.0": version: 4.0.0 resolution: "indent-string@npm:4.0.0" @@ -31377,7 +31285,7 @@ __metadata: languageName: node linkType: hard -"is-stream@npm:^1.0.1, is-stream@npm:^1.1.0": +"is-stream@npm:^1.1.0": version: 1.1.0 resolution: "is-stream@npm:1.1.0" checksum: 063c6bec9d5647aa6d42108d4c59723d2bd4ae42135a2d4db6eadbd49b7ea05b750fd69d279e5c7c45cf9da753ad2c00d8978be354d65aa9f6bb434969c6a2ae @@ -31597,16 +31505,6 @@ __metadata: languageName: node linkType: hard -"isomorphic-fetch@npm:^2.1.1": - version: 2.2.1 - resolution: "isomorphic-fetch@npm:2.2.1" - dependencies: - node-fetch: ^1.0.1 - whatwg-fetch: ">=0.10.0" - checksum: bb5daa7c3785d6742f4379a81e55b549a469503f7c9bf9411b48592e86632cf5e8fe8ea878dba185c0f33eb7c510c23abdeb55aebfdf5d3c70f031ced68c5424 - languageName: node - linkType: hard - "isomorphic-form-data@npm:^2.0.0": version: 2.0.0 resolution: "isomorphic-form-data@npm:2.0.0" @@ -32927,46 +32825,6 @@ __metadata: languageName: node linkType: hard -"jss-camel-case@npm:^6.0.0": - version: 6.1.0 - resolution: "jss-camel-case@npm:6.1.0" - dependencies: - hyphenate-style-name: ^1.0.2 - peerDependencies: - jss: ^9.7.0 - checksum: f20ad892cddc30241b5127d648233b513ce57b2a6ed2f710cd995510f8d06e1418cd8f6e8e50dc6bd60b2e8a35159bfdeb40143938e0f2cdc19fd39279953789 - languageName: node - linkType: hard - -"jss-default-unit@npm:^8.0.2": - version: 8.0.2 - resolution: "jss-default-unit@npm:8.0.2" - peerDependencies: - jss: ^9.4.0 - checksum: 5277c5ccc3d56f5c137d6d65f0fc36d15eb22ef08b5949e887ee75e9f4f25197e25f2a99706b70a2828cee010fd8ed7484fb1bb2086fe327f2b24b1bdcc22abb - languageName: node - linkType: hard - -"jss-global@npm:^3.0.0": - version: 3.0.0 - resolution: "jss-global@npm:3.0.0" - peerDependencies: - jss: ^9.0.0 - checksum: e3fa80d8251ba5f183d9b0b4416d64e8f5d285cfdb595cc600daf1a1366b67bca573939bb71d98b6596bf4d6f2c95711cf53a358af3d63cd7945dbb434c6547b - languageName: node - linkType: hard - -"jss-nested@npm:^6.0.1": - version: 6.0.1 - resolution: "jss-nested@npm:6.0.1" - dependencies: - warning: ^3.0.0 - peerDependencies: - jss: ^9.0.0 - checksum: 437bdacc559be0b4b5bc1faa2bc77b5c6cf14733fefbf73a34bb7335786b9f08e4e79b3d73cf83b386959adcd8fa9d725877912e96d9a0921ed38baa1a69b8d9 - languageName: node - linkType: hard - "jss-plugin-camel-case@npm:^10.10.0, jss-plugin-camel-case@npm:^10.5.1": version: 10.10.0 resolution: "jss-plugin-camel-case@npm:10.10.0" @@ -33041,26 +32899,6 @@ __metadata: languageName: node linkType: hard -"jss-props-sort@npm:^6.0.0": - version: 6.0.0 - resolution: "jss-props-sort@npm:6.0.0" - peerDependencies: - jss: ^9.0.0 - checksum: 82a04f625a2f2b3a71b2fcb00b1ed0478137c83dc47c323d24c7ea88d08c9ea295b061f99cf264db133fef3435366d6da594724f7713e0415dc50b4eff2aeb53 - languageName: node - linkType: hard - -"jss-vendor-prefixer@npm:^7.0.0": - version: 7.0.0 - resolution: "jss-vendor-prefixer@npm:7.0.0" - dependencies: - css-vendor: ^0.3.8 - peerDependencies: - jss: ^9.0.0 - checksum: 8ec3608711833e79da7ccfffd8177e752f16093589fa28d3a24ec19e6588fbc6a07cc5cacf59ef4c111ab1d0fb72e07b88cb3444eb8c0c6ed4cc8107da984633 - languageName: node - linkType: hard - "jss@npm:10.10.0, jss@npm:^10.10.0, jss@npm:^10.5.1, jss@npm:~10.10.0": version: 10.10.0 resolution: "jss@npm:10.10.0" @@ -33073,17 +32911,6 @@ __metadata: languageName: node linkType: hard -"jss@npm:^9.8.7": - version: 9.8.7 - resolution: "jss@npm:9.8.7" - dependencies: - is-in-browser: ^1.1.3 - symbol-observable: ^1.1.0 - warning: ^3.0.0 - checksum: ebb264cc893fb8c17a0277875947f8f72e01f5be991bf7f61a39abb861e1276e75ee402fdd2be9ce827af839a1a08bd81ad86a4e108d57fd7d7ebb2361837a53 - languageName: node - linkType: hard - "jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.5": version: 3.3.5 resolution: "jsx-ast-utils@npm:3.3.5" @@ -36087,16 +35914,6 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^1.0.1": - version: 1.7.3 - resolution: "node-fetch@npm:1.7.3" - dependencies: - encoding: ^0.1.11 - is-stream: ^1.0.1 - checksum: 3bb0528c05d541316ebe52770d71ee25a6dce334df4231fd55df41a644143e07f068637488c18a5b0c43f05041dbd3346752f9e19b50df50569a802484544d5b - languageName: node - linkType: hard - "node-fetch@npm:^2.6.0, node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.12, node-fetch@npm:^2.6.5, node-fetch@npm:^2.6.7, node-fetch@npm:^2.6.9, node-fetch@npm:^2.7.0": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" @@ -36377,13 +36194,6 @@ __metadata: languageName: node linkType: hard -"normalize-scroll-left@npm:^0.1.2": - version: 0.1.2 - resolution: "normalize-scroll-left@npm:0.1.2" - checksum: 817d5a659ba6f14f458cd03a5a0f98ec2a9d7e6c63c160f2db164827b87bb77c0237752890a18d11054fe628907493c5f4d8914907585ec9fbba3de26d2a6815 - languageName: node - linkType: hard - "normalize-url@npm:^4.1.0": version: 4.5.1 resolution: "normalize-url@npm:4.5.1" @@ -38189,13 +37999,6 @@ __metadata: languageName: node linkType: hard -"popper.js@npm:^1.14.1": - version: 1.16.1 - resolution: "popper.js@npm:1.16.1" - checksum: c56ae5001ec50a77ee297a8061a0221d99d25c7348d2e6bcd3e45a0d0f32a1fd81bca29d46cb0d4bdf13efb77685bd6a0ce93f9eb3c608311a461f945fffedbe - languageName: node - linkType: hard - "portfinder@npm:1.0.28": version: 1.0.28 resolution: "portfinder@npm:1.0.28" @@ -38962,7 +38765,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:15.x, prop-types@npm:^15.0.0, prop-types@npm:^15.5.10, prop-types@npm:^15.5.7, prop-types@npm:^15.5.8, prop-types@npm:^15.6.0, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": +"prop-types@npm:15.x, prop-types@npm:^15.0.0, prop-types@npm:^15.5.10, prop-types@npm:^15.5.7, prop-types@npm:^15.5.8, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -39588,19 +39391,6 @@ __metadata: languageName: node linkType: hard -"react-event-listener@npm:^0.6.2": - version: 0.6.6 - resolution: "react-event-listener@npm:0.6.6" - dependencies: - "@babel/runtime": ^7.2.0 - prop-types: ^15.6.0 - warning: ^4.0.1 - peerDependencies: - react: ^16.3.0 - checksum: 0287e0ae8cbf0a4c03889ffc2b745f5494b3edea0f4667357d709f5646dd78c7289ce305b6f473ec6ac5789f8a937c86b7e543d0249f0bf787bccdb1eab7ecd0 - languageName: node - linkType: hard - "react-fast-compare@npm:^3.1.1": version: 3.2.0 resolution: "react-fast-compare@npm:3.2.0" @@ -39715,7 +39505,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^16.10.2, react-is@npm:^16.12.0, react-is@npm:^16.13.1, react-is@npm:^16.6.3, react-is@npm:^16.7.0, react-is@npm:^16.8.0, react-is@npm:^16.8.6": +"react-is@npm:^16.10.2, react-is@npm:^16.12.0, react-is@npm:^16.13.1, react-is@npm:^16.7.0, react-is@npm:^16.8.0, react-is@npm:^16.8.6": version: 16.13.1 resolution: "react-is@npm:16.13.1" checksum: f7a19ac3496de32ca9ae12aa030f00f14a3d45374f1ceca0af707c831b2a6098ef0d6bdae51bd437b0a306d7f01d4677fcc8de7c0d331eb47ad0f46130e53c5f @@ -39751,7 +39541,7 @@ __metadata: languageName: node linkType: hard -"react-lifecycles-compat@npm:^3.0.2, react-lifecycles-compat@npm:^3.0.4": +"react-lifecycles-compat@npm:^3.0.4": version: 3.0.4 resolution: "react-lifecycles-compat@npm:3.0.4" checksum: a904b0fc0a8eeb15a148c9feb7bc17cec7ef96e71188280061fc340043fd6d8ee3ff233381f0e8f95c1cf926210b2c4a31f38182c8f35ac55057e453d6df204f @@ -40070,21 +39860,6 @@ __metadata: languageName: node linkType: hard -"react-transition-group@npm:^2.2.1": - version: 2.9.0 - resolution: "react-transition-group@npm:2.9.0" - dependencies: - dom-helpers: ^3.4.0 - loose-envify: ^1.4.0 - prop-types: ^15.6.2 - react-lifecycles-compat: ^3.0.4 - peerDependencies: - react: ">=15.0.0" - react-dom: ">=15.0.0" - checksum: d8c9e50aabdc2cfc324e5cdb0ad1c6eecb02e1c0cd007b26d5b30ccf49015e900683dd489348c71fba4055858308d9ba7019e0d37d0e8d37bd46ed098788f670 - languageName: node - linkType: hard - "react-transition-group@npm:^4.0.0, react-transition-group@npm:^4.4.0, react-transition-group@npm:^4.4.5": version: 4.4.5 resolution: "react-transition-group@npm:4.4.5" @@ -40387,22 +40162,6 @@ __metadata: languageName: node linkType: hard -"recompose@npm:0.28.0 - 0.30.0": - version: 0.30.0 - resolution: "recompose@npm:0.30.0" - dependencies: - "@babel/runtime": ^7.0.0 - change-emitter: ^0.1.2 - fbjs: ^0.8.1 - hoist-non-react-statics: ^2.3.1 - react-lifecycles-compat: ^3.0.2 - symbol-observable: ^1.0.4 - peerDependencies: - react: ^0.14.0 || ^15.0.0 || ^16.0.0 - checksum: 18e58252336d0628b22db1e38407d32e836648e6d5c9453ba37c9f8030138b3429ee3952b053a13b60311f8b60893b207a761466bb293083542db0cf317b7a41 - languageName: node - linkType: hard - "recursive-readdir@npm:^2.2.2": version: 2.2.3 resolution: "recursive-readdir@npm:2.2.3" @@ -41594,13 +41353,6 @@ __metadata: languageName: node linkType: hard -"select@npm:^1.1.2": - version: 1.1.2 - resolution: "select@npm:1.1.2" - checksum: 4346151e94f226ea6131e44e68e6d837f3fdee64831b756dd657cc0b02f4cb5107f867cb34a1d1216ab7737d0bf0645d44546afb030bbd8d64e891f5e4c4814e - languageName: node - linkType: hard - "selfsigned@npm:^2.0.0, selfsigned@npm:^2.4.1": version: 2.4.1 resolution: "selfsigned@npm:2.4.1" @@ -43299,7 +43051,7 @@ __metadata: languageName: node linkType: hard -"svg-pan-zoom@npm:^3.6.0": +"svg-pan-zoom@npm:3.6.1": version: 3.6.1 resolution: "svg-pan-zoom@npm:3.6.1" checksum: 500b99378d321315e1668067ef6a73af3f61f9adfab75a575b21d2d216cb446def61d60ad12265203463cca9bef56b090f00e48118fa9b7f0ffa1c691e4c1621 @@ -43422,7 +43174,7 @@ __metadata: languageName: node linkType: hard -"symbol-observable@npm:1.2.0, symbol-observable@npm:^1.0.4, symbol-observable@npm:^1.1.0": +"symbol-observable@npm:^1.0.4": version: 1.2.0 resolution: "symbol-observable@npm:1.2.0" checksum: 48ffbc22e3d75f9853b3ff2ae94a44d84f386415110aea5effc24d84c502e03a4a6b7a8f75ebaf7b585780bda34eb5d6da3121f826a6f93398429d30032971b6 @@ -43800,13 +43552,6 @@ __metadata: languageName: node linkType: hard -"tiny-emitter@npm:^2.0.0": - version: 2.1.0 - resolution: "tiny-emitter@npm:2.1.0" - checksum: fbcfb5145751a0e3b109507a828eb6d6d4501352ab7bb33eccef46e22e9d9ad3953158870a6966a59e57ab7c3f9cfac7cab8521db4de6a5e757012f4677df2dd - languageName: node - linkType: hard - "tiny-invariant@npm:^1.0.6, tiny-invariant@npm:^1.3.1": version: 1.3.1 resolution: "tiny-invariant@npm:1.3.1" @@ -45543,13 +45288,6 @@ __metadata: languageName: node linkType: hard -"viz.js@npm:2.1.2": - version: 2.1.2 - resolution: "viz.js@npm:2.1.2" - checksum: 299e5a8519a472e0e98197c5f39c0ca6f3f6c4642b6ae007ed888fea998d82455c7ae0118d09cb888bfd2c46ebe3b03d7ce321a4eef1c822a5f5719d3a6ef3bb - languageName: node - linkType: hard - "vlq@npm:^0.2.1": version: 0.2.3 resolution: "vlq@npm:0.2.3" @@ -45628,24 +45366,6 @@ __metadata: languageName: node linkType: hard -"warning@npm:^3.0.0": - version: 3.0.0 - resolution: "warning@npm:3.0.0" - dependencies: - loose-envify: ^1.0.0 - checksum: c9f99a12803aab81b29858e7dc3415bf98b41baee3a4c3acdeb680d98c47b6e17490f1087dccc54432deed5711a5ce0ebcda2b27e9b5eb054c32ae50acb4419c - languageName: node - linkType: hard - -"warning@npm:^4.0.1": - version: 4.0.3 - resolution: "warning@npm:4.0.3" - dependencies: - loose-envify: ^1.0.0 - checksum: 4f2cb6a9575e4faf71ddad9ad1ae7a00d0a75d24521c193fa464f30e6b04027bd97aa5d9546b0e13d3a150ab402eda216d59c1d0f2d6ca60124d96cd40dfa35c - languageName: node - linkType: hard - "watchpack@npm:^2.4.1": version: 2.4.1 resolution: "watchpack@npm:2.4.1" @@ -45899,13 +45619,6 @@ __metadata: languageName: node linkType: hard -"whatwg-fetch@npm:>=0.10.0": - version: 3.6.19 - resolution: "whatwg-fetch@npm:3.6.19" - checksum: 2896bc9ca867ea514392c73e2a272f65d5c4916248fe0837a9df5b1b92f247047bc76cf7c29c28a01ac6c5fb4314021d2718958c8a08292a96d56f72b2f56806 - languageName: node - linkType: hard - "whatwg-mimetype@npm:^2.3.0": version: 2.3.0 resolution: "whatwg-mimetype@npm:2.3.0" From 064534d84df020615de52ca177d67bd1f40bb512 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 13 Apr 2024 17:10:14 +0200 Subject: [PATCH 088/107] microsite: add name for inline yaml loader plugin Signed-off-by: Patrik Oldsberg --- microsite/docusaurus.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/microsite/docusaurus.config.js b/microsite/docusaurus.config.js index 99be57788c..bea4b50e05 100644 --- a/microsite/docusaurus.config.js +++ b/microsite/docusaurus.config.js @@ -95,6 +95,7 @@ module.exports = { plugins: [ 'docusaurus-plugin-sass', () => ({ + name: 'yaml-loader', configureWebpack() { return { module: { From 2559302b944dfdf344dd9b068d4942e29646a21a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 15:24:30 +0000 Subject: [PATCH 089/107] chore(deps): update dependency eslint-plugin-testing-library to v6.2.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 bb2b5cd6fb..268cb5e70a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27073,13 +27073,13 @@ __metadata: linkType: hard "eslint-plugin-testing-library@npm:^6.0.0": - version: 6.2.0 - resolution: "eslint-plugin-testing-library@npm:6.2.0" + version: 6.2.1 + resolution: "eslint-plugin-testing-library@npm:6.2.1" dependencies: "@typescript-eslint/utils": ^5.58.0 peerDependencies: eslint: ^7.5.0 || ^8.0.0 - checksum: 7af7e0a1eee44c6ba65ce2ae99f8e46ce709a319f4cce778bb0af2dda5828d78f3a81e8989c7b691a8b9b9fef102b56136209aac700038b9e64794600b0d12db + checksum: 27c6aa32bfaba83f3d7c1477ebe75cd9ab414e8ecac8c10da18ed237fe6827df4ab1194addca7a259bfbdca1d929d88e93ed847c388f8882cbb83b84fb831e3f languageName: node linkType: hard From 1328adbcc0c4416fd81b30044339132b2f3bb850 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 13 Apr 2024 17:26:49 +0200 Subject: [PATCH 090/107] Update .changeset/tame-pianos-hunt.md Signed-off-by: Patrik Oldsberg --- .changeset/tame-pianos-hunt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/tame-pianos-hunt.md b/.changeset/tame-pianos-hunt.md index 2799a3a1da..74475291ef 100644 --- a/.changeset/tame-pianos-hunt.md +++ b/.changeset/tame-pianos-hunt.md @@ -1,5 +1,5 @@ --- -'@backstage/backend-common': minor +'@backstage/backend-common': patch --- Added `pullOptions` to `DockerContainerRunner#runContainer` method to pass down options when pulling an image. From 6d54d938ec32f85fc7cd1681e956562a7574cef0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 13 Apr 2024 17:31:05 +0200 Subject: [PATCH 091/107] yarn.lock: stick to existing version of csstype Signed-off-by: Patrik Oldsberg --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index cbffddcb09..6de143347e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24832,9 +24832,9 @@ __metadata: linkType: hard "csstype@npm:^3.0.2, csstype@npm:^3.1.1, csstype@npm:^3.1.2, csstype@npm:^3.1.3": - version: 3.1.3 - resolution: "csstype@npm:3.1.3" - checksum: 8db785cc92d259102725b3c694ec0c823f5619a84741b5c7991b8ad135dfaa66093038a1cc63e03361a6cd28d122be48f2106ae72334e067dd619a51f49eddf7 + version: 3.0.9 + resolution: "csstype@npm:3.0.9" + checksum: 199f9af7e673f9f188525c3102a329d637ff46c52f6385a4427ff5cb17adcb736189150170a7af7c5701d18d7704bdad130273f4aa7e44c6c4f9967e6115dc93 languageName: node linkType: hard From 7fb5021aeef20d2988a78f028569430fb96eb0e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Sat, 13 Apr 2024 17:59:55 +0200 Subject: [PATCH 092/107] feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelรถw --- docs/auth/identity-resolver--old.md | 2 +- docs/auth/identity-resolver.md | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/auth/identity-resolver--old.md b/docs/auth/identity-resolver--old.md index c1a207484a..267f3e9d3c 100644 --- a/docs/auth/identity-resolver--old.md +++ b/docs/auth/identity-resolver--old.md @@ -9,7 +9,7 @@ This documentation is written for the old backend which has been replaced by [the new backend system](../backend-system/index.md), being the default since Backstage [version 1.24](../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./identity-resolver.md) -instead. +instead. Also, check out [the migration docs](../backend-system/building-backends/08-migrating.md)! ::: By default, every Backstage auth provider is configured only for the use-case of diff --git a/docs/auth/identity-resolver.md b/docs/auth/identity-resolver.md index b09b47a572..39fc13fcb2 100644 --- a/docs/auth/identity-resolver.md +++ b/docs/auth/identity-resolver.md @@ -194,6 +194,13 @@ backend.add(import('@backstage/plugin-auth-backend-module-github-provider')); backend.add(customAuth); ``` +Check out [the naming patterns +article](../backend-system/architecture/07-naming-patterns.md) for what rules +apply regarding how to form valid IDs. In this example we also put the module +declaration directly in `packages/backend/src/index.ts` but that's just for +simplicity. You can place it anywhere you like, including in other packages, and +import from there if you prefer. + The `createOAuthProviderFactory` / `createProxyAuthProviderFactory` functions have additional options for profile and state transforms - not covered here, but good to know about if you need them. @@ -234,6 +241,13 @@ async signInResolver(info, ctx) { } ``` +If you throw an error in the sign in resolver function, the sign in attempt is +immediately rejected, and the error details are presented in the user interface. + +The `ctx` context [has several useful +functions](https://backstage.io/docs/reference/plugin-auth-node.authresolvercontext/) +for issuing tokens in various ways. + ### Custom Ownership Resolution If you want to have more control over the membership resolution and token generation From 068a68c87e4d0d72c09c4a55034c6baddec22fca Mon Sep 17 00:00:00 2001 From: Timothy Deakin Date: Sat, 13 Apr 2024 17:15:10 +0100 Subject: [PATCH 093/107] refactor: cache key endpoint Signed-off-by: Timothy Deakin --- .../src/helpers.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts b/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts index 1af02ce9ec..e4bdf847c4 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts @@ -73,12 +73,16 @@ export const makeProfileInfo = ( const getPublicKeyEndpoint = (region: string) => { const commercialEndpoint = `https://public-keys.auth.elb.${encodeURIComponent( region, - )}.amazonaws.com/`; + )}.amazonaws.com`; const govEndpoint = `https://s3-${encodeURIComponent( region, - )}.amazonaws.com/aws-elb-public-keys-prod-${encodeURIComponent(region)}/`; + )}.amazonaws.com/aws-elb-public-keys-prod-${encodeURIComponent(region)}`; - return region.startsWith('us-gov') ? govEndpoint : commercialEndpoint; + if (region.startsWith('us-gov')) { + return govEndpoint; + } + + return commercialEndpoint; }; export const provisionKeyCache = (region: string, keyCache: NodeCache) => { @@ -92,7 +96,7 @@ export const provisionKeyCache = (region: string, keyCache: NodeCache) => { } const keyText: string = await fetch( - getPublicKeyEndpoint(region) + header.kid, + `${getPublicKeyEndpoint(region)}/${encodeURIComponent(header.kid)}`, ).then(response => response.text()); const keyValue = crypto.createPublicKey(keyText); From bb58c9adac7416e9e49c263f36e40d603a56a158 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 16:15:18 +0000 Subject: [PATCH 094/107] fix(deps): update dependency @codemirror/view to v6.26.3 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 637ea72fa7..b38bdc416c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10620,13 +10620,13 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.23.0": - version: 6.26.2 - resolution: "@codemirror/view@npm:6.26.2" + version: 6.26.3 + resolution: "@codemirror/view@npm:6.26.3" dependencies: "@codemirror/state": ^6.4.0 style-mod: ^4.1.0 w3c-keyname: ^2.2.4 - checksum: d996983362cce28e19094b9b9caccc4c136eb6bc42d673636d81c77064995ce93c5241af35e9236ef84fd8b4289c253c01280ce6f570a82ddc2432aebe458033 + checksum: fdee35fb5e0bbba7b6f1a9b43a865880911bbfafd30360da5dda21b35f81ba2d080ff66b6c3d94dbe946b6b7ec98a76208786360b8f030ef10bcb054b816de05 languageName: node linkType: hard From f8cc8ccaa777b9a9c19bb1322563dcec624117d7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 16:16:07 +0000 Subject: [PATCH 095/107] fix(deps): update dependency @swc/helpers to v0.5.9 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 637ea72fa7..1f92a252a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17864,11 +17864,11 @@ __metadata: linkType: hard "@swc/helpers@npm:^0.5.0": - version: 0.5.8 - resolution: "@swc/helpers@npm:0.5.8" + version: 0.5.9 + resolution: "@swc/helpers@npm:0.5.9" dependencies: tslib: ^2.4.0 - checksum: 001bb4ef9c59083fd4325e295f800b6ef61b8a2109424060a7dcc73b3c01c6ecbbf90a53db05fddf33025c301d1350e425798dc6d4ffc685f9b1051ad3177dae + checksum: ef2f076560711adbc37157e796046c358dc5c91716ce2ddc8d1a6d4a71e0769e145b28d1d1c7689c57d1087509b40646af84e15d623cade7ab653ebf50270bda languageName: node linkType: hard From 4300d18da8d1281e16c0ff4a0b2331eac225265d Mon Sep 17 00:00:00 2001 From: Timothy Deakin Date: Sat, 13 Apr 2024 18:08:22 +0100 Subject: [PATCH 096/107] refactor: endpoint return Signed-off-by: Timothy Deakin --- .../src/helpers.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts b/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts index e4bdf847c4..24026e2c9c 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts @@ -71,18 +71,15 @@ export const makeProfileInfo = ( }; const getPublicKeyEndpoint = (region: string) => { - const commercialEndpoint = `https://public-keys.auth.elb.${encodeURIComponent( - region, - )}.amazonaws.com`; - const govEndpoint = `https://s3-${encodeURIComponent( - region, - )}.amazonaws.com/aws-elb-public-keys-prod-${encodeURIComponent(region)}`; - if (region.startsWith('us-gov')) { - return govEndpoint; + return `https://s3-${encodeURIComponent( + region, + )}.amazonaws.com/aws-elb-public-keys-prod-${encodeURIComponent(region)}`; } - return commercialEndpoint; + return `https://public-keys.auth.elb.${encodeURIComponent( + region, + )}.amazonaws.com`; }; export const provisionKeyCache = (region: string, keyCache: NodeCache) => { From 0935078ae804846fd3023b11e394efa4c637ad65 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 17:16:11 +0000 Subject: [PATCH 097/107] fix(deps): update dependency qs to v6.12.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 598dde6c2a..21c25b2ef4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38990,11 +38990,11 @@ __metadata: linkType: hard "qs@npm:^6.10.1, qs@npm:^6.10.2, qs@npm:^6.11.0, qs@npm:^6.11.2, qs@npm:^6.9.1, qs@npm:^6.9.4, qs@npm:^6.9.6": - version: 6.12.0 - resolution: "qs@npm:6.12.0" + version: 6.12.1 + resolution: "qs@npm:6.12.1" dependencies: side-channel: ^1.0.6 - checksum: ba007fb2488880b9c6c3df356fe6888b9c1f4c5127552edac214486cfe83a332de09a5c40d490d79bb27bef977ba1085a8497512ff52eaac72e26564f77ce908 + checksum: aa761d99e65b6936ba2dd2187f2d9976afbcda38deb3ff1b3fe331d09b0c578ed79ca2abdde1271164b5be619c521ec7db9b34c23f49a074e5921372d16242d5 languageName: node linkType: hard From 905f35cbcf02241e42a495bfcc5023075ab0688a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 17:17:15 +0000 Subject: [PATCH 098/107] fix(deps): update dependency rollup to v4.14.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 128 +++++++++++++++++++++++++++--------------------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/yarn.lock b/yarn.lock index 598dde6c2a..72c0d44b24 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15866,107 +15866,107 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.14.1" +"@rollup/rollup-android-arm-eabi@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.14.2" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-android-arm64@npm:4.14.1" +"@rollup/rollup-android-arm64@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-android-arm64@npm:4.14.2" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-darwin-arm64@npm:4.14.1" +"@rollup/rollup-darwin-arm64@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-darwin-arm64@npm:4.14.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-darwin-x64@npm:4.14.1" +"@rollup/rollup-darwin-x64@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-darwin-x64@npm:4.14.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.14.1" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.14.2" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.14.1" +"@rollup/rollup-linux-arm64-gnu@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.14.2" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.14.1" +"@rollup/rollup-linux-arm64-musl@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.14.2" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-powerpc64le-gnu@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.14.1" - conditions: os=linux & cpu=ppc64le & libc=glibc +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.14.2" + conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.14.1" +"@rollup/rollup-linux-riscv64-gnu@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.14.2" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.14.1" +"@rollup/rollup-linux-s390x-gnu@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.14.2" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.14.1" +"@rollup/rollup-linux-x64-gnu@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.14.2" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.14.1" +"@rollup/rollup-linux-x64-musl@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.14.2" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.14.1" +"@rollup/rollup-win32-arm64-msvc@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.14.2" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.14.1" +"@rollup/rollup-win32-ia32-msvc@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.14.2" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.14.1": - version: 4.14.1 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.14.1" +"@rollup/rollup-win32-x64-msvc@npm:4.14.2": + version: 4.14.2 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.14.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -40947,24 +40947,24 @@ __metadata: linkType: hard "rollup@npm:^4.0.0": - version: 4.14.1 - resolution: "rollup@npm:4.14.1" + version: 4.14.2 + resolution: "rollup@npm:4.14.2" dependencies: - "@rollup/rollup-android-arm-eabi": 4.14.1 - "@rollup/rollup-android-arm64": 4.14.1 - "@rollup/rollup-darwin-arm64": 4.14.1 - "@rollup/rollup-darwin-x64": 4.14.1 - "@rollup/rollup-linux-arm-gnueabihf": 4.14.1 - "@rollup/rollup-linux-arm64-gnu": 4.14.1 - "@rollup/rollup-linux-arm64-musl": 4.14.1 - "@rollup/rollup-linux-powerpc64le-gnu": 4.14.1 - "@rollup/rollup-linux-riscv64-gnu": 4.14.1 - "@rollup/rollup-linux-s390x-gnu": 4.14.1 - "@rollup/rollup-linux-x64-gnu": 4.14.1 - "@rollup/rollup-linux-x64-musl": 4.14.1 - "@rollup/rollup-win32-arm64-msvc": 4.14.1 - "@rollup/rollup-win32-ia32-msvc": 4.14.1 - "@rollup/rollup-win32-x64-msvc": 4.14.1 + "@rollup/rollup-android-arm-eabi": 4.14.2 + "@rollup/rollup-android-arm64": 4.14.2 + "@rollup/rollup-darwin-arm64": 4.14.2 + "@rollup/rollup-darwin-x64": 4.14.2 + "@rollup/rollup-linux-arm-gnueabihf": 4.14.2 + "@rollup/rollup-linux-arm64-gnu": 4.14.2 + "@rollup/rollup-linux-arm64-musl": 4.14.2 + "@rollup/rollup-linux-powerpc64le-gnu": 4.14.2 + "@rollup/rollup-linux-riscv64-gnu": 4.14.2 + "@rollup/rollup-linux-s390x-gnu": 4.14.2 + "@rollup/rollup-linux-x64-gnu": 4.14.2 + "@rollup/rollup-linux-x64-musl": 4.14.2 + "@rollup/rollup-win32-arm64-msvc": 4.14.2 + "@rollup/rollup-win32-ia32-msvc": 4.14.2 + "@rollup/rollup-win32-x64-msvc": 4.14.2 "@types/estree": 1.0.5 fsevents: ~2.3.2 dependenciesMeta: @@ -41002,7 +41002,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: f065ba6ea0ab4271f61bb458afba7d5d36062511929f9d3ec160438c4946d843bf07b8d35d9a8986620fb2aa56990a70c8e968dda5a9baf81a3480023434bdd0 + checksum: ad2c4486e9d76dc8575f13f89cfb16dd4611b5e3527ba80454304fc96b7b9dcf91da98a3318efa7f97320324fdfa15596db2b55cfc39434ebb6e3200c8a75136 languageName: node linkType: hard From 6c7d3e4214afd35ab657c5b0648f37602fd06772 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 18:31:43 +0000 Subject: [PATCH 099/107] fix(deps): update dependency @opensearch-project/opensearch to v2.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 11f48259ab..b9f6c22171 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14600,15 +14600,15 @@ __metadata: linkType: hard "@opensearch-project/opensearch@npm:^2.2.1": - version: 2.6.0 - resolution: "@opensearch-project/opensearch@npm:2.6.0" + version: 2.7.0 + resolution: "@opensearch-project/opensearch@npm:2.7.0" dependencies: aws4: ^1.11.0 debug: ^4.3.1 hpagent: ^1.2.0 ms: ^2.1.3 secure-json-parse: ^2.4.0 - checksum: d958bb83bdf4975f342da9d355aa39f3daaed322fa72fae715501cf760101e3ef50e3e216cab5b008df5f7d7976d5feee7541a6dd9d1f6791ffb01134fafa227 + checksum: 6905373048d3896e158de8a229b1110828cf0cbffee3180fcd98b114a025f11e8938124863106544df09d7aa587b41843e2818fe03f34e33a27abcd1601740fe languageName: node linkType: hard From cfb2b788bc2efc08fea15854fc276fe9149bd12d Mon Sep 17 00:00:00 2001 From: Timothy Deakin Date: Sat, 13 Apr 2024 20:22:53 +0100 Subject: [PATCH 100/107] feat: add eslint rule for top level imports Signed-off-by: Timothy Deakin --- .changeset/sweet-planets-relate.md | 5 +++++ plugins/org-react/.eslintrc.js | 6 +++++- .../components/GroupListPicker/GroupListPickerButton.tsx | 4 +++- 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 .changeset/sweet-planets-relate.md diff --git a/.changeset/sweet-planets-relate.md b/.changeset/sweet-planets-relate.md new file mode 100644 index 0000000000..7697874957 --- /dev/null +++ b/.changeset/sweet-planets-relate.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-org-react': patch +--- + +Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 diff --git a/plugins/org-react/.eslintrc.js b/plugins/org-react/.eslintrc.js index e2a53a6ad2..e487f765b2 100644 --- a/plugins/org-react/.eslintrc.js +++ b/plugins/org-react/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx index f4255a18be..b7a31f89f2 100644 --- a/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx @@ -15,7 +15,9 @@ */ import React from 'react'; -import { makeStyles, Typography, Button } from '@material-ui/core'; +import Typography from '@material-ui/core/Typography'; +import Button from '@material-ui/core/Button'; +import { makeStyles } from '@material-ui/core/styles'; import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown'; import PeopleIcon from '@material-ui/icons/People'; From 0e692cf4227d4a03a81981979669935e945665ca Mon Sep 17 00:00:00 2001 From: Juan Pablo Garcia Ripa Date: Sat, 13 Apr 2024 21:38:00 +0200 Subject: [PATCH 101/107] add mui imports eslint rule Signed-off-by: Juan Pablo Garcia Ripa --- .changeset/rotten-cameras-leave.md | 5 +++++ plugins/scaffolder-react/.eslintrc.js | 6 +++++- .../Form/DescriptionFieldTemplate.tsx | 3 ++- .../ScaffolderField/ScaffolderField.tsx | 3 ++- .../ErrorListTemplate/errorListTemplate.tsx | 16 ++++++-------- .../src/next/components/Stepper/Stepper.tsx | 14 ++++++------- .../next/components/TaskSteps/StepIcon.tsx | 4 +++- .../next/components/TaskSteps/StepTime.tsx | 2 +- .../next/components/TaskSteps/TaskBorder.tsx | 3 ++- .../next/components/TaskSteps/TaskSteps.tsx | 16 +++++++------- .../TemplateCard/CardHeader.test.tsx | 2 +- .../components/TemplateCard/CardHeader.tsx | 2 +- .../next/components/TemplateCard/CardLink.tsx | 2 +- .../components/TemplateCard/TemplateCard.tsx | 21 ++++++++----------- .../TemplateCategoryPicker.tsx | 16 +++++++------- .../TemplateGroups/TemplateGroups.tsx | 2 +- .../DefaultTemplateOutputs.tsx | 3 ++- .../TemplateOutputs/LinkOutputs.tsx | 3 ++- .../TemplateOutputs/TextOutputs.tsx | 2 +- .../src/next/components/Workflow/Workflow.tsx | 2 +- 20 files changed, 65 insertions(+), 62 deletions(-) create mode 100644 .changeset/rotten-cameras-leave.md diff --git a/.changeset/rotten-cameras-leave.md b/.changeset/rotten-cameras-leave.md new file mode 100644 index 0000000000..bd702eebca --- /dev/null +++ b/.changeset/rotten-cameras-leave.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +Added ESLint rule `no-top-level-material-ui-4-imports` to migrate the Material UI imports. diff --git a/plugins/scaffolder-react/.eslintrc.js b/plugins/scaffolder-react/.eslintrc.js index e2a53a6ad2..e487f765b2 100644 --- a/plugins/scaffolder-react/.eslintrc.js +++ b/plugins/scaffolder-react/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/plugins/scaffolder-react/src/next/components/Form/DescriptionFieldTemplate.tsx b/plugins/scaffolder-react/src/next/components/Form/DescriptionFieldTemplate.tsx index 4c86ef0c62..7731cac3f8 100644 --- a/plugins/scaffolder-react/src/next/components/Form/DescriptionFieldTemplate.tsx +++ b/plugins/scaffolder-react/src/next/components/Form/DescriptionFieldTemplate.tsx @@ -16,7 +16,8 @@ import React from 'react'; import { MarkdownContent } from '@backstage/core-components'; -import { makeStyles, Typography } from '@material-ui/core'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; import { DescriptionFieldProps, FormContextType, diff --git a/plugins/scaffolder-react/src/next/components/ScaffolderField/ScaffolderField.tsx b/plugins/scaffolder-react/src/next/components/ScaffolderField/ScaffolderField.tsx index da233eeba0..1bb1656fd0 100644 --- a/plugins/scaffolder-react/src/next/components/ScaffolderField/ScaffolderField.tsx +++ b/plugins/scaffolder-react/src/next/components/ScaffolderField/ScaffolderField.tsx @@ -16,7 +16,8 @@ import React, { PropsWithChildren, ReactElement } from 'react'; import { MarkdownContent } from '@backstage/core-components'; -import { FormControl, makeStyles } from '@material-ui/core'; +import FormControl from '@material-ui/core/FormControl'; +import { makeStyles } from '@material-ui/core/styles'; const useStyles = makeStyles(theme => ({ markdownDescription: { diff --git a/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.tsx b/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.tsx index 9b6920108b..a5310a5806 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.tsx @@ -15,16 +15,12 @@ */ import React from 'react'; import { ErrorListProps } from '@rjsf/utils'; -import { - List, - ListItem, - ListItemIcon, - ListItemText, - Paper, - Theme, - createStyles, - makeStyles, -} from '@material-ui/core'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; +import Paper from '@material-ui/core/Paper'; +import { Theme, createStyles, makeStyles } from '@material-ui/core/styles'; import ErrorIcon from '@material-ui/icons/Error'; const useStyles = makeStyles((_theme: Theme) => diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index d0ce60fd79..62effbd14a 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -15,14 +15,12 @@ */ import { useAnalytics, useApiHolder } from '@backstage/core-plugin-api'; import { JsonValue } from '@backstage/types'; -import { - Stepper as MuiStepper, - Step as MuiStep, - StepLabel as MuiStepLabel, - Button, - makeStyles, - LinearProgress, -} from '@material-ui/core'; +import MuiStepper from '@material-ui/core/Stepper'; +import MuiStep from '@material-ui/core/Step'; +import MuiStepLabel from '@material-ui/core/StepLabel'; +import Button from '@material-ui/core/Button'; +import LinearProgress from '@material-ui/core/LinearProgress'; +import { makeStyles } from '@material-ui/core/styles'; import { type IChangeEvent } from '@rjsf/core'; import { ErrorSchema } from '@rjsf/utils'; import React, { diff --git a/plugins/scaffolder-react/src/next/components/TaskSteps/StepIcon.tsx b/plugins/scaffolder-react/src/next/components/TaskSteps/StepIcon.tsx index 58f2eb9050..c397b09a52 100644 --- a/plugins/scaffolder-react/src/next/components/TaskSteps/StepIcon.tsx +++ b/plugins/scaffolder-react/src/next/components/TaskSteps/StepIcon.tsx @@ -15,7 +15,9 @@ */ import React from 'react'; -import { CircularProgress, makeStyles, StepIconProps } from '@material-ui/core'; +import CircularProgress from '@material-ui/core/CircularProgress'; +import { StepIconProps } from '@material-ui/core/StepIcon'; +import { makeStyles } from '@material-ui/core/styles'; import RemoveCircleOutline from '@material-ui/icons/RemoveCircleOutline'; import PanoramaFishEyeIcon from '@material-ui/icons/PanoramaFishEye'; import classNames from 'classnames'; diff --git a/plugins/scaffolder-react/src/next/components/TaskSteps/StepTime.tsx b/plugins/scaffolder-react/src/next/components/TaskSteps/StepTime.tsx index 14c347fda8..ab236965c2 100644 --- a/plugins/scaffolder-react/src/next/components/TaskSteps/StepTime.tsx +++ b/plugins/scaffolder-react/src/next/components/TaskSteps/StepTime.tsx @@ -17,7 +17,7 @@ import React, { useCallback, useState } from 'react'; import useInterval from 'react-use/esm/useInterval'; import { DateTime, Interval } from 'luxon'; import humanizeDuration from 'humanize-duration'; -import { Typography } from '@material-ui/core'; +import Typography from '@material-ui/core/Typography'; import { useMountEffect } from '@react-hookz/web'; export const StepTime = (props: { diff --git a/plugins/scaffolder-react/src/next/components/TaskSteps/TaskBorder.tsx b/plugins/scaffolder-react/src/next/components/TaskSteps/TaskBorder.tsx index d7a96e3864..a33cdad49e 100644 --- a/plugins/scaffolder-react/src/next/components/TaskSteps/TaskBorder.tsx +++ b/plugins/scaffolder-react/src/next/components/TaskSteps/TaskBorder.tsx @@ -15,7 +15,8 @@ */ import React from 'react'; -import { LinearProgress, makeStyles } from '@material-ui/core'; +import LinearProgress from '@material-ui/core/LinearProgress'; +import { makeStyles } from '@material-ui/core/styles'; const useStyles = makeStyles(theme => ({ failed: { diff --git a/plugins/scaffolder-react/src/next/components/TaskSteps/TaskSteps.tsx b/plugins/scaffolder-react/src/next/components/TaskSteps/TaskSteps.tsx index d74d298778..b391e6fce8 100644 --- a/plugins/scaffolder-react/src/next/components/TaskSteps/TaskSteps.tsx +++ b/plugins/scaffolder-react/src/next/components/TaskSteps/TaskSteps.tsx @@ -14,15 +14,13 @@ * limitations under the License. */ import React from 'react'; -import { - Stepper as MuiStepper, - Step as MuiStep, - StepButton as MuiStepButton, - StepLabel as MuiStepLabel, - StepIconProps, - Box, - Paper, -} from '@material-ui/core'; +import MuiStepper from '@material-ui/core/Stepper'; +import MuiStep from '@material-ui/core/Step'; +import MuiStepButton from '@material-ui/core/StepButton'; +import MuiStepLabel from '@material-ui/core/StepLabel'; +import { StepIconProps } from '@material-ui/core/StepIcon'; +import Box from '@material-ui/core/Box'; +import Paper from '@material-ui/core/Paper'; import { TaskStep } from '@backstage/plugin-scaffolder-common'; import { StepIcon } from './StepIcon'; import { StepTime } from './StepTime'; diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx index 287d813ca7..5aa138340e 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { fireEvent, render } from '@testing-library/react'; import { CardHeader } from './CardHeader'; -import { ThemeProvider } from '@material-ui/core'; +import { ThemeProvider } from '@material-ui/core/styles'; import { lightTheme } from '@backstage/theme'; import { MockStorageApi, diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.tsx index 1180c8f106..467d26ce76 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { Theme, makeStyles, useTheme } from '@material-ui/core'; +import { Theme, makeStyles, useTheme } from '@material-ui/core/styles'; import { ItemCardHeader } from '@backstage/core-components'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { FavoriteEntity } from '@backstage/plugin-catalog-react'; diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/CardLink.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/CardLink.tsx index 839d6c7ac1..263a1356b7 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/CardLink.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/CardLink.tsx @@ -16,7 +16,7 @@ import { IconComponent } from '@backstage/core-plugin-api'; import { Link } from '@backstage/core-components'; -import { makeStyles } from '@material-ui/core'; +import { makeStyles } from '@material-ui/core/styles'; import React from 'react'; interface CardLinkProps { diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx index 2d8ff1e458..4fb2ca0e4a 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx @@ -22,18 +22,15 @@ import { getEntityRelations, } from '@backstage/plugin-catalog-react'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { - Box, - Card, - CardActions, - CardContent, - Chip, - Divider, - Button, - Grid, - makeStyles, - Theme, -} from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Card from '@material-ui/core/Card'; +import CardActions from '@material-ui/core/CardActions'; +import CardContent from '@material-ui/core/CardContent'; +import Chip from '@material-ui/core/Chip'; +import Divider from '@material-ui/core/Divider'; +import Button from '@material-ui/core/Button'; +import Grid from '@material-ui/core/Grid'; +import { makeStyles, Theme } from '@material-ui/core/styles'; import LanguageIcon from '@material-ui/icons/Language'; import React from 'react'; import { CardHeader } from './CardHeader'; diff --git a/plugins/scaffolder-react/src/next/components/TemplateCategoryPicker/TemplateCategoryPicker.tsx b/plugins/scaffolder-react/src/next/components/TemplateCategoryPicker/TemplateCategoryPicker.tsx index 9c85cacfc2..24f8a21109 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCategoryPicker/TemplateCategoryPicker.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCategoryPicker/TemplateCategoryPicker.tsx @@ -17,18 +17,16 @@ import React from 'react'; import capitalize from 'lodash/capitalize'; import { Progress } from '@backstage/core-components'; -import { - Box, - Checkbox, - FormControlLabel, - TextField, - Typography, - makeStyles, -} from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Checkbox from '@material-ui/core/Checkbox'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import TextField from '@material-ui/core/TextField'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; import CheckBoxIcon from '@material-ui/icons/CheckBox'; import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; -import { Autocomplete } from '@material-ui/lab'; +import Autocomplete from '@material-ui/lab/Autocomplete'; import { useEntityTypeFilter } from '@backstage/plugin-catalog-react'; import { alertApiRef, useApi } from '@backstage/core-plugin-api'; diff --git a/plugins/scaffolder-react/src/next/components/TemplateGroups/TemplateGroups.tsx b/plugins/scaffolder-react/src/next/components/TemplateGroups/TemplateGroups.tsx index 800ec67a16..a180ff0e8c 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateGroups/TemplateGroups.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateGroups/TemplateGroups.tsx @@ -21,7 +21,7 @@ import { TemplateEntityV1beta3, } from '@backstage/plugin-scaffolder-common'; import { Progress, Link } from '@backstage/core-components'; -import { Typography } from '@material-ui/core'; +import Typography from '@material-ui/core/Typography'; import { errorApiRef, IconComponent, useApi } from '@backstage/core-plugin-api'; import { TemplateGroupFilter } from '@backstage/plugin-scaffolder-react'; import { TemplateGroup } from '../TemplateGroup/TemplateGroup'; diff --git a/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx b/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx index d3811e5011..7d90623077 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx @@ -18,7 +18,8 @@ import { ScaffolderOutputText, ScaffolderTaskOutput, } from '@backstage/plugin-scaffolder-react'; -import { Box, Paper } from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Paper from '@material-ui/core/Paper'; import React, { useEffect, useMemo, useState } from 'react'; import { LinkOutputs } from './LinkOutputs'; import { TextOutputs } from './TextOutputs'; diff --git a/plugins/scaffolder-react/src/next/components/TemplateOutputs/LinkOutputs.tsx b/plugins/scaffolder-react/src/next/components/TemplateOutputs/LinkOutputs.tsx index 7877653197..59c6c6a49a 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateOutputs/LinkOutputs.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateOutputs/LinkOutputs.tsx @@ -15,7 +15,8 @@ */ import { IconComponent, useApp, useRouteRef } from '@backstage/core-plugin-api'; import { entityRouteRef } from '@backstage/plugin-catalog-react'; -import { Button, makeStyles } from '@material-ui/core'; +import Button from '@material-ui/core/Button'; +import { makeStyles } from '@material-ui/core/styles'; import React from 'react'; import LinkIcon from '@material-ui/icons/Link'; import { parseEntityRef } from '@backstage/catalog-model'; diff --git a/plugins/scaffolder-react/src/next/components/TemplateOutputs/TextOutputs.tsx b/plugins/scaffolder-react/src/next/components/TemplateOutputs/TextOutputs.tsx index 74a5eabb8f..5da1dab476 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateOutputs/TextOutputs.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateOutputs/TextOutputs.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import { IconComponent, useApp } from '@backstage/core-plugin-api'; -import { Button } from '@material-ui/core'; +import Button from '@material-ui/core/Button'; import DescriptionIcon from '@material-ui/icons/Description'; import React from 'react'; import { ScaffolderTaskOutput } from '../../../api'; diff --git a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx index e16af5abb9..9afc18c438 100644 --- a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx +++ b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx @@ -22,7 +22,7 @@ import { Progress, } from '@backstage/core-components'; import { stringifyEntityRef } from '@backstage/catalog-model'; -import { makeStyles } from '@material-ui/core'; +import { makeStyles } from '@material-ui/core/styles'; import { errorApiRef, useAnalytics, useApi } from '@backstage/core-plugin-api'; import { useTemplateParameterSchema } from '../../hooks/useTemplateParameterSchema'; import { Stepper, type StepperProps } from '../Stepper/Stepper'; From ab94179927e3898f3caf85a522775eebc66efcc8 Mon Sep 17 00:00:00 2001 From: Juan Pablo Garcia Ripa Date: Sat, 13 Apr 2024 21:46:41 +0200 Subject: [PATCH 102/107] add miu import rules to signals-react Signed-off-by: Juan Pablo Garcia Ripa --- plugins/signals-react/.eslintrc.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/signals-react/.eslintrc.js b/plugins/signals-react/.eslintrc.js index e2a53a6ad2..e487f765b2 100644 --- a/plugins/signals-react/.eslintrc.js +++ b/plugins/signals-react/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); From 16b2f7a3eb45796705f82538e96389e436955697 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 13 Apr 2024 13:14:30 +0200 Subject: [PATCH 103/107] app-backend: added migration test + fix namespace migration Signed-off-by: Patrik Oldsberg --- .../20240113144027_assets-namespace.js | 8 +- .../src/lib/assets/StaticAssetsStore.ts | 2 +- plugins/app-backend/src/migrations.test.ts | 141 ++++++++++++++++++ 3 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 plugins/app-backend/src/migrations.test.ts diff --git a/plugins/app-backend/migrations/20240113144027_assets-namespace.js b/plugins/app-backend/migrations/20240113144027_assets-namespace.js index b533d35dfa..c39407d08b 100644 --- a/plugins/app-backend/migrations/20240113144027_assets-namespace.js +++ b/plugins/app-backend/migrations/20240113144027_assets-namespace.js @@ -23,7 +23,8 @@ exports.up = async function up(knex) { await knex.schema.alterTable('static_assets_cache', table => { // The namespace is used to allow operations on asset groups, e.g. delete all assets in a namespace table.string('namespace').comment('The namespace of the file'); - table.index('namespace', 'static_asset_cache_namespace_idx'); + table.dropPrimary(); + table.primary(['namespace', 'path']); }); }; @@ -31,8 +32,11 @@ exports.up = async function up(knex) { * @param {import('knex').Knex} knex */ exports.down = async function down(knex) { + await knex.delete().from('static_assets_cache').whereNotNull('namespace'); + await knex.schema.alterTable('static_assets_cache', table => { - table.dropIndex([], 'static_asset_cache_namespace_idx'); + table.dropPrimary(); table.dropColumn('namespace'); + table.primary(['path']); }); }; diff --git a/plugins/app-backend/src/lib/assets/StaticAssetsStore.ts b/plugins/app-backend/src/lib/assets/StaticAssetsStore.ts index 43bd38030f..27573300e7 100644 --- a/plugins/app-backend/src/lib/assets/StaticAssetsStore.ts +++ b/plugins/app-backend/src/lib/assets/StaticAssetsStore.ts @@ -120,7 +120,7 @@ export class StaticAssetsStore implements StaticAssetProvider { content: await asset.content(), namespace: this.#namespace, }) - .onConflict('path') + .onConflict(['namespace', 'path']) .ignore(); } } diff --git a/plugins/app-backend/src/migrations.test.ts b/plugins/app-backend/src/migrations.test.ts new file mode 100644 index 0000000000..8a413559d2 --- /dev/null +++ b/plugins/app-backend/src/migrations.test.ts @@ -0,0 +1,141 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Knex } from 'knex'; +import { TestDatabases } from '@backstage/backend-test-utils'; +import fs from 'fs'; + +const migrationsDir = `${__dirname}/../migrations`; +const migrationsFiles = fs.readdirSync(migrationsDir).sort(); + +async function migrateUpOnce(knex: Knex): Promise { + await knex.migrate.up({ directory: migrationsDir }); +} + +async function migrateDownOnce(knex: Knex): Promise { + await knex.migrate.down({ directory: migrationsDir }); +} + +async function migrateUntilBefore(knex: Knex, target: string): Promise { + const index = migrationsFiles.indexOf(target); + if (index === -1) { + throw new Error(`Migration ${target} not found`); + } + for (let i = 0; i < index; i++) { + await migrateUpOnce(knex); + } +} + +jest.setTimeout(60_000); + +describe('migrations', () => { + const databases = TestDatabases.create(); + + it.each(databases.eachSupportedId())( + '20211229105307_init.js, %p', + async databaseId => { + const knex = await databases.init(databaseId); + + await migrateUntilBefore(knex, '20211229105307_init.js'); + await migrateUpOnce(knex); + + await knex('static_assets_cache').insert({ + path: 'main.js', + content: Buffer.from('some-script'), + last_modified_at: knex.fn.now(), + }); + + await expect(knex('static_assets_cache')).resolves.toEqual([ + { + path: 'main.js', + content: Buffer.from('some-script'), + last_modified_at: expect.anything(), + }, + ]); + + await migrateDownOnce(knex); + + // This looks odd - you might expect a .toThrow at the end but that + // actually is flaky for some reason specifically on sqlite when + // performing multiple runs in sequence + await expect(knex('static_assets_cache')).rejects.toEqual( + expect.anything(), + ); + + await knex.destroy(); + }, + ); + + it.each(databases.eachSupportedId())( + '20240113144027_assets-namespace.js, %p', + async databaseId => { + const knex = await databases.init(databaseId); + + await migrateUntilBefore(knex, '20240113144027_assets-namespace.js'); + + await knex('static_assets_cache').insert({ + path: 'main.js', + content: Buffer.from('some-script'), + last_modified_at: knex.fn.now(), + }); + + await migrateUpOnce(knex); + + await expect(knex('static_assets_cache')).resolves.toEqual([ + { + path: 'main.js', + content: Buffer.from('some-script'), + namespace: 'default', + last_modified_at: expect.anything(), + }, + ]); + + await knex('static_assets_cache').insert({ + path: 'main.js', + content: Buffer.from('other-script'), + namespace: 'other', + last_modified_at: knex.fn.now(), + }); + + await expect(knex('static_assets_cache')).resolves.toEqual([ + { + path: 'main.js', + content: Buffer.from('some-script'), + namespace: 'default', + last_modified_at: expect.anything(), + }, + { + path: 'main.js', + content: Buffer.from('other-script'), + namespace: 'other', + last_modified_at: expect.anything(), + }, + ]); + + await migrateDownOnce(knex); + + await expect(knex('static_assets_cache')).resolves.toEqual([ + { + path: 'main.js', + content: Buffer.from('some-script'), + last_modified_at: expect.anything(), + }, + ]); + + await knex.destroy(); + }, + ); +}); From ef4655546dec86e69c75c5743b58cc4f2f454c1f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 13 Apr 2024 14:03:24 +0200 Subject: [PATCH 104/107] app-backend: always test towards MySQL Signed-off-by: Patrik Oldsberg --- .../app-backend/src/lib/assets/StaticAssetsStore.test.ts | 4 +--- plugins/app-backend/src/setupTests.ts | 6 +++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/app-backend/src/lib/assets/StaticAssetsStore.test.ts b/plugins/app-backend/src/lib/assets/StaticAssetsStore.test.ts index d975751676..41408396fe 100644 --- a/plugins/app-backend/src/lib/assets/StaticAssetsStore.test.ts +++ b/plugins/app-backend/src/lib/assets/StaticAssetsStore.test.ts @@ -36,9 +36,7 @@ function createDatabaseManager( jest.setTimeout(60_000); describe('StaticAssetsStore', () => { - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); it.each(databases.eachSupportedId())( 'should store and retrieve assets, %p', diff --git a/plugins/app-backend/src/setupTests.ts b/plugins/app-backend/src/setupTests.ts index d3232290a7..4ed508a382 100644 --- a/plugins/app-backend/src/setupTests.ts +++ b/plugins/app-backend/src/setupTests.ts @@ -14,4 +14,8 @@ * limitations under the License. */ -export {}; +import { TestDatabases } from '@backstage/backend-test-utils'; + +TestDatabases.setDefaults({ + ids: ['MYSQL_8', 'POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], +}); From cae72e6cdbf276c99604c9d4e2a53d576517bb43 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 14 Apr 2024 12:02:41 +0200 Subject: [PATCH 105/107] app-backend: non-nullable assets store namespace, default to default instead Signed-off-by: Patrik Oldsberg --- .../migrations/20240113144027_assets-namespace.js | 10 ++++++++-- .../app-backend/src/lib/assets/StaticAssetsStore.ts | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/plugins/app-backend/migrations/20240113144027_assets-namespace.js b/plugins/app-backend/migrations/20240113144027_assets-namespace.js index c39407d08b..de6ca2e333 100644 --- a/plugins/app-backend/migrations/20240113144027_assets-namespace.js +++ b/plugins/app-backend/migrations/20240113144027_assets-namespace.js @@ -22,7 +22,10 @@ exports.up = async function up(knex) { await knex.schema.alterTable('static_assets_cache', table => { // The namespace is used to allow operations on asset groups, e.g. delete all assets in a namespace - table.string('namespace').comment('The namespace of the file'); + table + .string('namespace') + .defaultTo('default') + .comment('The namespace of the file'); table.dropPrimary(); table.primary(['namespace', 'path']); }); @@ -32,7 +35,10 @@ exports.up = async function up(knex) { * @param {import('knex').Knex} knex */ exports.down = async function down(knex) { - await knex.delete().from('static_assets_cache').whereNotNull('namespace'); + await knex + .delete() + .from('static_assets_cache') + .whereNot('namespace', 'default'); await knex.schema.alterTable('static_assets_cache', table => { table.dropPrimary(); diff --git a/plugins/app-backend/src/lib/assets/StaticAssetsStore.ts b/plugins/app-backend/src/lib/assets/StaticAssetsStore.ts index 27573300e7..038d5bd9bf 100644 --- a/plugins/app-backend/src/lib/assets/StaticAssetsStore.ts +++ b/plugins/app-backend/src/lib/assets/StaticAssetsStore.ts @@ -50,7 +50,7 @@ export interface StaticAssetsStoreOptions { export class StaticAssetsStore implements StaticAssetProvider { #db: Knex; #logger: Logger; - #namespace: string | null; + #namespace: string; static async create(options: StaticAssetsStoreOptions) { const { database } = options; @@ -68,7 +68,7 @@ export class StaticAssetsStore implements StaticAssetProvider { private constructor(client: Knex, logger: Logger, namespace?: string) { this.#db = client; this.#logger = logger; - this.#namespace = namespace ?? null; + this.#namespace = namespace ?? 'default'; } /** From e6810313d92248e9e4adb6249005e3e654880670 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 14 Apr 2024 12:36:23 +0200 Subject: [PATCH 106/107] app-backend: fix asset store indexing for MySQL Signed-off-by: Patrik Oldsberg --- .../20240113144027_assets-namespace.js | 42 +++++++++++++++++-- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/plugins/app-backend/migrations/20240113144027_assets-namespace.js b/plugins/app-backend/migrations/20240113144027_assets-namespace.js index de6ca2e333..6e94ac1531 100644 --- a/plugins/app-backend/migrations/20240113144027_assets-namespace.js +++ b/plugins/app-backend/migrations/20240113144027_assets-namespace.js @@ -20,29 +20,63 @@ * @param {import('knex').Knex} knex */ exports.up = async function up(knex) { + const isMySQL = knex.client.config.client.includes('mysql'); + await knex.schema.alterTable('static_assets_cache', table => { // The namespace is used to allow operations on asset groups, e.g. delete all assets in a namespace table .string('namespace') .defaultTo('default') .comment('The namespace of the file'); - table.dropPrimary(); - table.primary(['namespace', 'path']); + + if (!isMySQL) { + table.dropPrimary(); + table.primary(['namespace', 'path']); + } }); + + if (isMySQL) { + await knex.schema.raw( + 'drop index static_assets_cache_path_idx on static_assets_cache;', + ); + await knex.schema.raw( + 'create unique index static_assets_cache_path_idx on static_assets_cache(namespace, path(254));', + ); + } }; /** * @param {import('knex').Knex} knex */ exports.down = async function down(knex) { + const isMySQL = knex.client.config.client.includes('mysql'); + await knex .delete() .from('static_assets_cache') .whereNot('namespace', 'default'); + if (isMySQL) { + await knex.schema.raw( + 'drop index static_assets_cache_path_idx on static_assets_cache;', + ); + } + await knex.schema.alterTable('static_assets_cache', table => { - table.dropPrimary(); + if (!isMySQL) { + table.dropPrimary(); + } + table.dropColumn('namespace'); - table.primary(['path']); + + if (!isMySQL) { + table.primary(['path']); + } }); + + if (isMySQL) { + await knex.schema.raw( + 'create unique index static_assets_cache_path_idx on static_assets_cache(path(254));', + ); + } }; From 46d09b8b0fb973242ba244cb4c603254c5d40406 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 14 Apr 2024 12:56:30 +0200 Subject: [PATCH 107/107] Update .changeset/mighty-humans-tan.md Signed-off-by: Patrik Oldsberg --- .changeset/mighty-humans-tan.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/mighty-humans-tan.md b/.changeset/mighty-humans-tan.md index cc3a35ccba..0f079e70e1 100644 --- a/.changeset/mighty-humans-tan.md +++ b/.changeset/mighty-humans-tan.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-scaffolder-backend-module-gerrit': minor +'@backstage/plugin-scaffolder-backend-module-gerrit': patch --- Add examples for `publish:gerrit:review` scaffolder action & improve related tests