From f9efb38a969b66d33601434c7a7296315c4a4093 Mon Sep 17 00:00:00 2001 From: Himanshu Mishra Date: Tue, 10 Aug 2021 21:13:17 +0200 Subject: [PATCH 001/125] scaffolder-backend: remove sample-templates Closes https://github.com/backstage/backstage/issues/6415 Signed-off-by: Himanshu Mishra --- .../create-react-app/skeleton/.gitignore | 23 -- .../create-react-app/skeleton/README.md | 46 ---- .../skeleton/catalog-info.yaml | 12 - .../create-react-app/skeleton/docs/index.md | 0 .../create-react-app/skeleton/mkdocs.yml | 8 - .../create-react-app/skeleton/package.json | 43 ---- .../skeleton/public/favicon.ico | Bin 3870 -> 0 bytes .../skeleton/public/index.html | 43 ---- .../skeleton/public/logo192.png | Bin 5347 -> 0 bytes .../skeleton/public/logo512.png | Bin 9664 -> 0 bytes .../skeleton/public/manifest.json | 25 -- .../skeleton/public/robots.txt | 3 - .../create-react-app/skeleton/src/App.css | 38 --- .../skeleton/src/App.test.tsx | 9 - .../create-react-app/skeleton/src/App.tsx | 26 --- .../create-react-app/skeleton/src/index.css | 13 -- .../create-react-app/skeleton/src/index.tsx | 17 -- .../create-react-app/skeleton/src/logo.svg | 1 - .../skeleton/src/react-app-env.d.ts | 1 - .../skeleton/src/reportWebVitals.ts | 15 -- .../skeleton/src/setupTests.ts | 5 - .../create-react-app/skeleton/tsconfig.json | 26 --- .../create-react-app/template.yaml | 77 ------ .../docs-template/skeleton/catalog-info.yaml | 12 - .../docs-template/skeleton/docs/index.md | 28 --- .../docs-template/skeleton/mkdocs.yml | 8 - .../docs-template/template.yaml | 86 ------- .../pull-request/template.yaml | 77 ------ .../pull-request/template/catalog-info.yaml | 8 - .../sample-templates/rails-demo/template.yaml | 174 -------------- .../template/rails-template-file.rb | 14 -- .../react-ssr-template/skeleton/.editorconfig | 13 -- .../react-ssr-template/skeleton/.eslintignore | 1 - .../react-ssr-template/skeleton/.eslintrc.js | 1 - .../skeleton/.github/workflows/build.yml | 41 ---- .../react-ssr-template/skeleton/.gitignore | 18 -- .../react-ssr-template/skeleton/README.md | 14 -- .../skeleton/babel.config.js | 4 - .../skeleton/catalog-info.yaml | 12 - .../react-ssr-template/skeleton/docs/index.md | 28 --- .../skeleton/jest.config.js | 8 - .../react-ssr-template/skeleton/mkdocs.yml | 8 - .../react-ssr-template/skeleton/next-env.d.ts | 5 - .../skeleton/next.config.js | 3 - .../react-ssr-template/skeleton/package.json | 52 ----- .../skeleton/prettier.config.js | 1 - .../skeleton/public/static/fonts.css | 0 .../skeleton/src/__tests__/index.test.tsx | 13 -- .../skeleton/src/components/Header.tsx | 3 - .../skeleton/src/pages/_app.tsx | 37 --- .../skeleton/src/pages/_document.tsx | 41 ---- .../skeleton/src/pages/api/ping.ts | 5 - .../skeleton/src/pages/index.tsx | 5 - .../react-ssr-template/skeleton/tsconfig.json | 20 -- .../react-ssr-template/template.yaml | 77 ------ .../skeleton/.editorconfig | 10 - .../skeleton/.github/workflows/build.yml | 21 -- .../skeleton/.gitignore | 7 - .../skeleton/Dockerfile | 5 - .../skeleton/README.md | 3 - .../skeleton/SERVICE.marker | 1 - .../skeleton/catalog-info.yaml | 12 - .../skeleton/docs/index.md | 28 --- .../skeleton/mkdocs.yml | 8 - .../springboot-grpc-template/skeleton/pom.xml | 221 ------------------ .../Application.java | 12 - .../GreeterService.java | 19 -- .../src/main/resources/application.properties | 3 - .../skeleton/src/main/resources/banner.txt | 22 -- .../skeleton/src/main/resources/greeter.proto | 17 -- .../ApplicationTest.java | 15 -- .../skeleton/{{cookiecutter.artifact_id}}.sh | 2 - .../springboot-grpc-template/template.yaml | 88 ------- .../v1beta2-demo/template.yaml | 107 --------- .../v1beta2-demo/template/catalog-info.yaml | 12 - 75 files changed, 1861 deletions(-) delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/.gitignore delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/README.md delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/catalog-info.yaml delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/docs/index.md delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/mkdocs.yml delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/package.json delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/favicon.ico delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/index.html delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/logo192.png delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/logo512.png delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/manifest.json delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/robots.txt delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/App.css delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/App.test.tsx delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/App.tsx delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/index.css delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/index.tsx delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/logo.svg delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/react-app-env.d.ts delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/reportWebVitals.ts delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/setupTests.ts delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/tsconfig.json delete mode 100644 plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml delete mode 100644 plugins/scaffolder-backend/sample-templates/docs-template/skeleton/catalog-info.yaml delete mode 100644 plugins/scaffolder-backend/sample-templates/docs-template/skeleton/docs/index.md delete mode 100644 plugins/scaffolder-backend/sample-templates/docs-template/skeleton/mkdocs.yml delete mode 100644 plugins/scaffolder-backend/sample-templates/docs-template/template.yaml delete mode 100644 plugins/scaffolder-backend/sample-templates/pull-request/template.yaml delete mode 100644 plugins/scaffolder-backend/sample-templates/pull-request/template/catalog-info.yaml delete mode 100644 plugins/scaffolder-backend/sample-templates/rails-demo/template.yaml delete mode 100644 plugins/scaffolder-backend/sample-templates/rails-demo/template/rails-template-file.rb delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.editorconfig delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.eslintignore delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.eslintrc.js delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.github/workflows/build.yml delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.gitignore delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/README.md delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/babel.config.js delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/catalog-info.yaml delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/docs/index.md delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/jest.config.js delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/mkdocs.yml delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/next-env.d.ts delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/next.config.js delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/package.json delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/prettier.config.js delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/public/static/fonts.css delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/__tests__/index.test.tsx delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/components/Header.tsx delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/_app.tsx delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/_document.tsx delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/api/ping.ts delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/index.tsx delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/tsconfig.json delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/.editorconfig delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/.github/workflows/build.yml delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/.gitignore delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/Dockerfile delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/README.md delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/SERVICE.marker delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/catalog-info.yaml delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/docs/index.md delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/mkdocs.yml delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/pom.xml delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/java/com/example/{{cookiecutter.java_package_name}}/Application.java delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/java/com/example/{{cookiecutter.java_package_name}}/GreeterService.java delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/resources/application.properties delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/resources/banner.txt delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/resources/greeter.proto delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/test/java/com/example/{{cookiecutter.java_package_name}}/ApplicationTest.java delete mode 100755 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/{{cookiecutter.artifact_id}}.sh delete mode 100644 plugins/scaffolder-backend/sample-templates/springboot-grpc-template/template.yaml delete mode 100644 plugins/scaffolder-backend/sample-templates/v1beta2-demo/template.yaml delete mode 100644 plugins/scaffolder-backend/sample-templates/v1beta2-demo/template/catalog-info.yaml diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/.gitignore b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/.gitignore deleted file mode 100644 index 4d29575de8..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/README.md b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/README.md deleted file mode 100644 index 305d413b8e..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Getting Started with Create React App - -This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). - -## Available Scripts - -In the project directory, you can run: - -### `yarn start` - -Runs the app in the development mode.\ -Open [http://localhost:3000](http://localhost:3000) to view it in the browser. - -The page will reload if you make edits.\ -You will also see any lint errors in the console. - -### `yarn test` - -Launches the test runner in the interactive watch mode.\ -See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. - -### `yarn build` - -Builds the app for production to the `build` folder.\ -It correctly bundles React in production mode and optimizes the build for the best performance. - -The build is minified and the filenames include the hashes.\ -Your app is ready to be deployed! - -See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. - -### `yarn eject` - -**Note: this is a one-way operation. Once you `eject`, you can’t go back!** - -If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. - -Instead, it will copy all the configuration files and the transitive dependencies (`webpack`, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. - -You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. - -## Learn More - -You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). - -To learn React, check out the [React documentation](https://reactjs.org/). diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/catalog-info.yaml b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/catalog-info.yaml deleted file mode 100644 index df23b90b97..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/catalog-info.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: {{cookiecutter.component_id | jsonify}} - description: {{cookiecutter.description | jsonify}} - annotations: - github.com/project-slug: {{cookiecutter.destination.owner + "/" + cookiecutter.destination.repo}} - backstage.io/techdocs-ref: dir:. -spec: - type: website - lifecycle: experimental - owner: {{cookiecutter.owner | jsonify}} diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/docs/index.md b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/docs/index.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/mkdocs.yml b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/mkdocs.yml deleted file mode 100644 index 64f1e9ee8e..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/mkdocs.yml +++ /dev/null @@ -1,8 +0,0 @@ -site_name: {{cookiecutter.component_id | jsonify}} -site_description: {{cookiecutter.description | jsonify}} - -nav: - - Introduction: index.md - -plugins: - - techdocs-core diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/package.json b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/package.json deleted file mode 100644 index 2ce9bf6266..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "{{cookiecutter.component_id}}", - "version": "0.1.0", - "private": true, - "dependencies": { - "@testing-library/jest-dom": "^5.11.4", - "@testing-library/react": "^11.1.0", - "@testing-library/user-event": "^12.1.10", - "@types/jest": "^26.0.15", - "@types/node": "^12.0.0", - "@types/react": "^17.0.0", - "@types/react-dom": "^17.0.0", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-scripts": "4.0.3", - "typescript": "^4.1.2", - "web-vitals": "^1.0.1" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" - }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - } -} diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/favicon.ico b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/favicon.ico deleted file mode 100644 index a11777cc471a4344702741ab1c8a588998b1311a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3870 zcma);c{J4h9>;%nil|2-o+rCuEF-(I%-F}ijC~o(k~HKAkr0)!FCj~d>`RtpD?8b; zXOC1OD!V*IsqUwzbMF1)-gEDD=A573Z-&G7^LoAC9|WO7Xc0Cx1g^Zu0u_SjAPB3vGa^W|sj)80f#V0@M_CAZTIO(t--xg= z!sii`1giyH7EKL_+Wi0ab<)&E_0KD!3Rp2^HNB*K2@PHCs4PWSA32*-^7d{9nH2_E zmC{C*N*)(vEF1_aMamw2A{ZH5aIDqiabnFdJ|y0%aS|64E$`s2ccV~3lR!u<){eS` z#^Mx6o(iP1Ix%4dv`t@!&Za-K@mTm#vadc{0aWDV*_%EiGK7qMC_(`exc>-$Gb9~W!w_^{*pYRm~G zBN{nA;cm^w$VWg1O^^<6vY`1XCD|s_zv*g*5&V#wv&s#h$xlUilPe4U@I&UXZbL z0)%9Uj&@yd03n;!7do+bfixH^FeZ-Ema}s;DQX2gY+7g0s(9;`8GyvPY1*vxiF&|w z>!vA~GA<~JUqH}d;DfBSi^IT*#lrzXl$fNpq0_T1tA+`A$1?(gLb?e#0>UELvljtQ zK+*74m0jn&)5yk8mLBv;=@}c{t0ztT<v;Avck$S6D`Z)^c0(jiwKhQsn|LDRY&w(Fmi91I7H6S;b0XM{e zXp0~(T@k_r-!jkLwd1_Vre^v$G4|kh4}=Gi?$AaJ)3I+^m|Zyj#*?Kp@w(lQdJZf4 z#|IJW5z+S^e9@(6hW6N~{pj8|NO*>1)E=%?nNUAkmv~OY&ZV;m-%?pQ_11)hAr0oAwILrlsGawpxx4D43J&K=n+p3WLnlDsQ$b(9+4 z?mO^hmV^F8MV{4Lx>(Q=aHhQ1){0d*(e&s%G=i5rq3;t{JC zmgbn5Nkl)t@fPH$v;af26lyhH!k+#}_&aBK4baYPbZy$5aFx4}ka&qxl z$=Rh$W;U)>-=S-0=?7FH9dUAd2(q#4TCAHky!$^~;Dz^j|8_wuKc*YzfdAht@Q&ror?91Dm!N03=4=O!a)I*0q~p0g$Fm$pmr$ zb;wD;STDIi$@M%y1>p&_>%?UP($15gou_ue1u0!4(%81;qcIW8NyxFEvXpiJ|H4wz z*mFT(qVx1FKufG11hByuX%lPk4t#WZ{>8ka2efjY`~;AL6vWyQKpJun2nRiZYDij$ zP>4jQXPaP$UC$yIVgGa)jDV;F0l^n(V=HMRB5)20V7&r$jmk{UUIe zVjKroK}JAbD>B`2cwNQ&GDLx8{pg`7hbA~grk|W6LgiZ`8y`{Iq0i>t!3p2}MS6S+ zO_ruKyAElt)rdS>CtF7j{&6rP-#c=7evGMt7B6`7HG|-(WL`bDUAjyn+k$mx$CH;q2Dz4x;cPP$hW=`pFfLO)!jaCL@V2+F)So3}vg|%O*^T1j>C2lx zsURO-zIJC$^$g2byVbRIo^w>UxK}74^TqUiRR#7s_X$e)$6iYG1(PcW7un-va-S&u zHk9-6Zn&>T==A)lM^D~bk{&rFzCi35>UR!ZjQkdSiNX*-;l4z9j*7|q`TBl~Au`5& z+c)*8?#-tgUR$Zd%Q3bs96w6k7q@#tUn`5rj+r@_sAVVLqco|6O{ILX&U-&-cbVa3 zY?ngHR@%l{;`ri%H*0EhBWrGjv!LE4db?HEWb5mu*t@{kv|XwK8?npOshmzf=vZA@ zVSN9sL~!sn?r(AK)Q7Jk2(|M67Uy3I{eRy z_l&Y@A>;vjkWN5I2xvFFTLX0i+`{qz7C_@bo`ZUzDugfq4+>a3?1v%)O+YTd6@Ul7 zAfLfm=nhZ`)P~&v90$&UcF+yXm9sq!qCx3^9gzIcO|Y(js^Fj)Rvq>nQAHI92ap=P z10A4@prk+AGWCb`2)dQYFuR$|H6iDE8p}9a?#nV2}LBCoCf(Xi2@szia7#gY>b|l!-U`c}@ zLdhvQjc!BdLJvYvzzzngnw51yRYCqh4}$oRCy-z|v3Hc*d|?^Wj=l~18*E~*cR_kU z{XsxM1i{V*4GujHQ3DBpl2w4FgFR48Nma@HPgnyKoIEY-MqmMeY=I<%oG~l!f<+FN z1ZY^;10j4M4#HYXP zw5eJpA_y(>uLQ~OucgxDLuf}fVs272FaMxhn4xnDGIyLXnw>Xsd^J8XhcWIwIoQ9} z%FoSJTAGW(SRGwJwb=@pY7r$uQRK3Zd~XbxU)ts!4XsJrCycrWSI?e!IqwqIR8+Jh zlRjZ`UO1I!BtJR_2~7AbkbSm%XQqxEPkz6BTGWx8e}nQ=w7bZ|eVP4?*Tb!$(R)iC z9)&%bS*u(lXqzitAN)Oo=&Ytn>%Hzjc<5liuPi>zC_nw;Z0AE3Y$Jao_Q90R-gl~5 z_xAb2J%eArrC1CN4G$}-zVvCqF1;H;abAu6G*+PDHSYFx@Tdbfox*uEd3}BUyYY-l zTfEsOqsi#f9^FoLO;ChK<554qkri&Av~SIM*{fEYRE?vH7pTAOmu2pz3X?Wn*!ROX ztd54huAk&mFBemMooL33RV-*1f0Q3_(7hl$<#*|WF9P!;r;4_+X~k~uKEqdzZ$5Al zV63XN@)j$FN#cCD;ek1R#l zv%pGrhB~KWgoCj%GT?%{@@o(AJGt*PG#l3i>lhmb_twKH^EYvacVY-6bsCl5*^~L0 zonm@lk2UvvTKr2RS%}T>^~EYqdL1q4nD%0n&Xqr^cK^`J5W;lRRB^R-O8b&HENO||mo0xaD+S=I8RTlIfVgqN@SXDr2&-)we--K7w= zJVU8?Z+7k9dy;s;^gDkQa`0nz6N{T?(A&Iz)2!DEecLyRa&FI!id#5Z7B*O2=PsR0 zEvc|8{NS^)!d)MDX(97Xw}m&kEO@5jqRaDZ!+%`wYOI<23q|&js`&o4xvjP7D_xv@ z5hEwpsp{HezI9!~6O{~)lLR@oF7?J7i>1|5a~UuoN=q&6N}EJPV_GD`&M*v8Y`^2j zKII*d_@Fi$+i*YEW+Hbzn{iQk~yP z>7N{S4)r*!NwQ`(qcN#8SRQsNK6>{)X12nbF`*7#ecO7I)Q$uZsV+xS4E7aUn+U(K baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@ diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/index.html b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/index.html deleted file mode 100644 index aa069f27cb..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - React App - - - -
- - - diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/logo192.png b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/logo192.png deleted file mode 100644 index fc44b0a3796c0e0a64c3d858ca038bd4570465d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5347 zcmZWtbyO6NvR-oO24RV%BvuJ&=?+<7=`LvyB&A_#M7mSDYw1v6DJkiYl9XjT!%$dLEBTQ8R9|wd3008in6lFF3GV-6mLi?MoP_y~}QUnaDCHI#t z7w^m$@6DI)|C8_jrT?q=f8D?0AM?L)Z}xAo^e^W>t$*Y0KlT5=@bBjT9kxb%-KNdk zeOS1tKO#ChhG7%{ApNBzE2ZVNcxbrin#E1TiAw#BlUhXllzhN$qWez5l;h+t^q#Eav8PhR2|T}y5kkflaK`ba-eoE+Z2q@o6P$)=&` z+(8}+-McnNO>e#$Rr{32ngsZIAX>GH??tqgwUuUz6kjns|LjsB37zUEWd|(&O!)DY zQLrq%Y>)Y8G`yYbYCx&aVHi@-vZ3|ebG!f$sTQqMgi0hWRJ^Wc+Ibv!udh_r%2|U) zPi|E^PK?UE!>_4`f`1k4hqqj_$+d!EB_#IYt;f9)fBOumGNyglU(ofY`yHq4Y?B%- zp&G!MRY<~ajTgIHErMe(Z8JG*;D-PJhd@RX@QatggM7+G(Lz8eZ;73)72Hfx5KDOE zkT(m}i2;@X2AT5fW?qVp?@WgN$aT+f_6eo?IsLh;jscNRp|8H}Z9p_UBO^SJXpZew zEK8fz|0Th%(Wr|KZBGTM4yxkA5CFdAj8=QSrT$fKW#tweUFqr0TZ9D~a5lF{)%-tTGMK^2tz(y2v$i%V8XAxIywrZCp=)83p(zIk6@S5AWl|Oa2hF`~~^W zI;KeOSkw1O#TiQ8;U7OPXjZM|KrnN}9arP)m0v$c|L)lF`j_rpG(zW1Qjv$=^|p*f z>)Na{D&>n`jOWMwB^TM}slgTEcjxTlUby89j1)|6ydRfWERn3|7Zd2&e7?!K&5G$x z`5U3uFtn4~SZq|LjFVrz$3iln-+ucY4q$BC{CSm7Xe5c1J<=%Oagztj{ifpaZk_bQ z9Sb-LaQMKp-qJA*bP6DzgE3`}*i1o3GKmo2pn@dj0;He}F=BgINo};6gQF8!n0ULZ zL>kC0nPSFzlcB7p41doao2F7%6IUTi_+!L`MM4o*#Y#0v~WiO8uSeAUNp=vA2KaR&=jNR2iVwG>7t%sG2x_~yXzY)7K& zk3p+O0AFZ1eu^T3s};B%6TpJ6h-Y%B^*zT&SN7C=N;g|#dGIVMSOru3iv^SvO>h4M=t-N1GSLLDqVTcgurco6)3&XpU!FP6Hlrmj}f$ zp95;b)>M~`kxuZF3r~a!rMf4|&1=uMG$;h^g=Kl;H&Np-(pFT9FF@++MMEx3RBsK?AU0fPk-#mdR)Wdkj)`>ZMl#^<80kM87VvsI3r_c@_vX=fdQ`_9-d(xiI z4K;1y1TiPj_RPh*SpDI7U~^QQ?%0&!$Sh#?x_@;ag)P}ZkAik{_WPB4rHyW#%>|Gs zdbhyt=qQPA7`?h2_8T;-E6HI#im9K>au*(j4;kzwMSLgo6u*}-K`$_Gzgu&XE)udQ zmQ72^eZd|vzI)~!20JV-v-T|<4@7ruqrj|o4=JJPlybwMg;M$Ud7>h6g()CT@wXm` zbq=A(t;RJ^{Xxi*Ff~!|3!-l_PS{AyNAU~t{h;(N(PXMEf^R(B+ZVX3 z8y0;0A8hJYp@g+c*`>eTA|3Tgv9U8#BDTO9@a@gVMDxr(fVaEqL1tl?md{v^j8aUv zm&%PX4^|rX|?E4^CkplWWNv*OKM>DxPa z!RJ)U^0-WJMi)Ksc!^ixOtw^egoAZZ2Cg;X7(5xZG7yL_;UJ#yp*ZD-;I^Z9qkP`} zwCTs0*%rIVF1sgLervtnUo&brwz?6?PXRuOCS*JI-WL6GKy7-~yi0giTEMmDs_-UX zo=+nFrW_EfTg>oY72_4Z0*uG>MnXP=c0VpT&*|rvv1iStW;*^={rP1y?Hv+6R6bxFMkxpWkJ>m7Ba{>zc_q zEefC3jsXdyS5??Mz7IET$Kft|EMNJIv7Ny8ZOcKnzf`K5Cd)&`-fTY#W&jnV0l2vt z?Gqhic}l}mCv1yUEy$%DP}4AN;36$=7aNI^*AzV(eYGeJ(Px-j<^gSDp5dBAv2#?; zcMXv#aj>%;MiG^q^$0MSg-(uTl!xm49dH!{X0){Ew7ThWV~Gtj7h%ZD zVN-R-^7Cf0VH!8O)uUHPL2mO2tmE*cecwQv_5CzWeh)ykX8r5Hi`ehYo)d{Jnh&3p z9ndXT$OW51#H5cFKa76c<%nNkP~FU93b5h-|Cb}ScHs@4Q#|}byWg;KDMJ#|l zE=MKD*F@HDBcX@~QJH%56eh~jfPO-uKm}~t7VkHxHT;)4sd+?Wc4* z>CyR*{w@4(gnYRdFq=^(#-ytb^5ESD?x<0Skhb%Pt?npNW1m+Nv`tr9+qN<3H1f<% zZvNEqyK5FgPsQ`QIu9P0x_}wJR~^CotL|n zk?dn;tLRw9jJTur4uWoX6iMm914f0AJfB@C74a;_qRrAP4E7l890P&{v<}>_&GLrW z)klculcg`?zJO~4;BBAa=POU%aN|pmZJn2{hA!d!*lwO%YSIzv8bTJ}=nhC^n}g(ld^rn#kq9Z3)z`k9lvV>y#!F4e{5c$tnr9M{V)0m(Z< z#88vX6-AW7T2UUwW`g<;8I$Jb!R%z@rCcGT)-2k7&x9kZZT66}Ztid~6t0jKb&9mm zpa}LCb`bz`{MzpZR#E*QuBiZXI#<`5qxx=&LMr-UUf~@dRk}YI2hbMsAMWOmDzYtm zjof16D=mc`^B$+_bCG$$@R0t;e?~UkF?7<(vkb70*EQB1rfUWXh$j)R2)+dNAH5%R zEBs^?N;UMdy}V};59Gu#0$q53$}|+q7CIGg_w_WlvE}AdqoS<7DY1LWS9?TrfmcvT zaypmplwn=P4;a8-%l^e?f`OpGb}%(_mFsL&GywhyN(-VROj`4~V~9bGv%UhcA|YW% zs{;nh@aDX11y^HOFXB$a7#Sr3cEtNd4eLm@Y#fc&j)TGvbbMwze zXtekX_wJqxe4NhuW$r}cNy|L{V=t#$%SuWEW)YZTH|!iT79k#?632OFse{+BT_gau zJwQcbH{b}dzKO?^dV&3nTILYlGw{27UJ72ZN){BILd_HV_s$WfI2DC<9LIHFmtyw? zQ;?MuK7g%Ym+4e^W#5}WDLpko%jPOC=aN)3!=8)s#Rnercak&b3ESRX3z{xfKBF8L z5%CGkFmGO@x?_mPGlpEej!3!AMddChabyf~nJNZxx!D&{@xEb!TDyvqSj%Y5@A{}9 zRzoBn0?x}=krh{ok3Nn%e)#~uh;6jpezhA)ySb^b#E>73e*frBFu6IZ^D7Ii&rsiU z%jzygxT-n*joJpY4o&8UXr2s%j^Q{?e-voloX`4DQyEK+DmrZh8A$)iWL#NO9+Y@!sO2f@rI!@jN@>HOA< z?q2l{^%mY*PNx2FoX+A7X3N}(RV$B`g&N=e0uvAvEN1W^{*W?zT1i#fxuw10%~))J zjx#gxoVlXREWZf4hRkgdHx5V_S*;p-y%JtGgQ4}lnA~MBz-AFdxUxU1RIT$`sal|X zPB6sEVRjGbXIP0U+?rT|y5+ev&OMX*5C$n2SBPZr`jqzrmpVrNciR0e*Wm?fK6DY& zl(XQZ60yWXV-|Ps!A{EF;=_z(YAF=T(-MkJXUoX zI{UMQDAV2}Ya?EisdEW;@pE6dt;j0fg5oT2dxCi{wqWJ<)|SR6fxX~5CzblPGr8cb zUBVJ2CQd~3L?7yfTpLNbt)He1D>*KXI^GK%<`bq^cUq$Q@uJifG>p3LU(!H=C)aEL zenk7pVg}0{dKU}&l)Y2Y2eFMdS(JS0}oZUuVaf2+K*YFNGHB`^YGcIpnBlMhO7d4@vV zv(@N}(k#REdul8~fP+^F@ky*wt@~&|(&&meNO>rKDEnB{ykAZ}k>e@lad7to>Ao$B zz<1(L=#J*u4_LB=8w+*{KFK^u00NAmeNN7pr+Pf+N*Zl^dO{LM-hMHyP6N!~`24jd zXYP|Ze;dRXKdF2iJG$U{k=S86l@pytLx}$JFFs8e)*Vi?aVBtGJ3JZUj!~c{(rw5>vuRF$`^p!P8w1B=O!skwkO5yd4_XuG^QVF z`-r5K7(IPSiKQ2|U9+`@Js!g6sfJwAHVd|s?|mnC*q zp|B|z)(8+mxXyxQ{8Pg3F4|tdpgZZSoU4P&9I8)nHo1@)9_9u&NcT^FI)6|hsAZFk zZ+arl&@*>RXBf-OZxhZerOr&dN5LW9@gV=oGFbK*J+m#R-|e6(Loz(;g@T^*oO)0R zN`N=X46b{7yk5FZGr#5&n1!-@j@g02g|X>MOpF3#IjZ_4wg{dX+G9eqS+Es9@6nC7 zD9$NuVJI}6ZlwtUm5cCAiYv0(Yi{%eH+}t)!E^>^KxB5^L~a`4%1~5q6h>d;paC9c zTj0wTCKrhWf+F#5>EgX`sl%POl?oyCq0(w0xoL?L%)|Q7d|Hl92rUYAU#lc**I&^6p=4lNQPa0 znQ|A~i0ip@`B=FW-Q;zh?-wF;Wl5!+q3GXDu-x&}$gUO)NoO7^$BeEIrd~1Dh{Tr` z8s<(Bn@gZ(mkIGnmYh_ehXnq78QL$pNDi)|QcT*|GtS%nz1uKE+E{7jdEBp%h0}%r zD2|KmYGiPa4;md-t_m5YDz#c*oV_FqXd85d@eub?9N61QuYcb3CnVWpM(D-^|CmkL z(F}L&N7qhL2PCq)fRh}XO@U`Yn<?TNGR4L(mF7#4u29{i~@k;pLsgl({YW5`Mo+p=zZn3L*4{JU;++dG9 X@eDJUQo;Ye2mwlRs?y0|+_a0zY+Zo%Dkae}+MySoIppb75o?vUW_?)>@g{U2`ERQIXV zeY$JrWnMZ$QC<=ii4X|@0H8`si75jB(ElJb00HAB%>SlLR{!zO|C9P3zxw_U8?1d8uRZ=({Ga4shyN}3 zAK}WA(ds|``G4jA)9}Bt2Hy0+f3rV1E6b|@?hpGA=PI&r8)ah|)I2s(P5Ic*Ndhn^ z*T&j@gbCTv7+8rpYbR^Ty}1AY)YH;p!m948r#%7x^Z@_-w{pDl|1S4`EM3n_PaXvK z1JF)E3qy$qTj5Xs{jU9k=y%SQ0>8E$;x?p9ayU0bZZeo{5Z@&FKX>}s!0+^>C^D#z z>xsCPvxD3Z=dP}TTOSJhNTPyVt14VCQ9MQFN`rn!c&_p?&4<5_PGm4a;WS&1(!qKE z_H$;dDdiPQ!F_gsN`2>`X}$I=B;={R8%L~`>RyKcS$72ai$!2>d(YkciA^J0@X%G4 z4cu!%Ps~2JuJ8ex`&;Fa0NQOq_nDZ&X;^A=oc1&f#3P1(!5il>6?uK4QpEG8z0Rhu zvBJ+A9RV?z%v?!$=(vcH?*;vRs*+PPbOQ3cdPr5=tOcLqmfx@#hOqX0iN)wTTO21jH<>jpmwRIAGw7`a|sl?9y9zRBh>(_%| zF?h|P7}~RKj?HR+q|4U`CjRmV-$mLW>MScKnNXiv{vD3&2@*u)-6P@h0A`eeZ7}71 zK(w%@R<4lLt`O7fs1E)$5iGb~fPfJ?WxhY7c3Q>T-w#wT&zW522pH-B%r5v#5y^CF zcC30Se|`D2mY$hAlIULL%-PNXgbbpRHgn<&X3N9W!@BUk@9g*P5mz-YnZBb*-$zMM z7Qq}ic0mR8n{^L|=+diODdV}Q!gwr?y+2m=3HWwMq4z)DqYVg0J~^}-%7rMR@S1;9 z7GFj6K}i32X;3*$SmzB&HW{PJ55kT+EI#SsZf}bD7nW^Haf}_gXciYKX{QBxIPSx2Ma? zHQqgzZq!_{&zg{yxqv3xq8YV+`S}F6A>Gtl39_m;K4dA{pP$BW0oIXJ>jEQ!2V3A2 zdpoTxG&V=(?^q?ZTj2ZUpDUdMb)T?E$}CI>r@}PFPWD9@*%V6;4Ag>D#h>!s)=$0R zRXvdkZ%|c}ubej`jl?cS$onl9Tw52rBKT)kgyw~Xy%z62Lr%V6Y=f?2)J|bZJ5(Wx zmji`O;_B+*X@qe-#~`HFP<{8$w@z4@&`q^Q-Zk8JG3>WalhnW1cvnoVw>*R@c&|o8 zZ%w!{Z+MHeZ*OE4v*otkZqz11*s!#s^Gq>+o`8Z5 z^i-qzJLJh9!W-;SmFkR8HEZJWiXk$40i6)7 zZpr=k2lp}SasbM*Nbn3j$sn0;rUI;%EDbi7T1ZI4qL6PNNM2Y%6{LMIKW+FY_yF3) zSKQ2QSujzNMSL2r&bYs`|i2Dnn z=>}c0>a}>|uT!IiMOA~pVT~R@bGlm}Edf}Kq0?*Af6#mW9f9!}RjW7om0c9Qlp;yK z)=XQs(|6GCadQbWIhYF=rf{Y)sj%^Id-ARO0=O^Ad;Ph+ z0?$eE1xhH?{T$QI>0JP75`r)U_$#%K1^BQ8z#uciKf(C701&RyLQWBUp*Q7eyn76} z6JHpC9}R$J#(R0cDCkXoFSp;j6{x{b&0yE@P7{;pCEpKjS(+1RQy38`=&Yxo%F=3y zCPeefABp34U-s?WmU#JJw23dcC{sPPFc2#J$ZgEN%zod}J~8dLm*fx9f6SpO zn^Ww3bt9-r0XaT2a@Wpw;C23XM}7_14#%QpubrIw5aZtP+CqIFmsG4`Cm6rfxl9n5 z7=r2C-+lM2AB9X0T_`?EW&Byv&K?HS4QLoylJ|OAF z`8atBNTzJ&AQ!>sOo$?^0xj~D(;kS$`9zbEGd>f6r`NC3X`tX)sWgWUUOQ7w=$TO&*j;=u%25ay-%>3@81tGe^_z*C7pb9y*Ed^H3t$BIKH2o+olp#$q;)_ zfpjCb_^VFg5fU~K)nf*d*r@BCC>UZ!0&b?AGk_jTPXaSnCuW110wjHPPe^9R^;jo3 zwvzTl)C`Zl5}O2}3lec=hZ*$JnkW#7enKKc)(pM${_$9Hc=Sr_A9Biwe*Y=T?~1CK z6eZ9uPICjy-sMGbZl$yQmpB&`ouS8v{58__t0$JP%i3R&%QR3ianbZqDs<2#5FdN@n5bCn^ZtH992~5k(eA|8|@G9u`wdn7bnpg|@{m z^d6Y`*$Zf2Xr&|g%sai#5}Syvv(>Jnx&EM7-|Jr7!M~zdAyjt*xl;OLhvW-a%H1m0 z*x5*nb=R5u><7lyVpNAR?q@1U59 zO+)QWwL8t zyip?u_nI+K$uh{y)~}qj?(w0&=SE^8`_WMM zTybjG=999h38Yes7}-4*LJ7H)UE8{mE(6;8voE+TYY%33A>S6`G_95^5QHNTo_;Ao ztIQIZ_}49%{8|=O;isBZ?=7kfdF8_@azfoTd+hEJKWE!)$)N%HIe2cplaK`ry#=pV z0q{9w-`i0h@!R8K3GC{ivt{70IWG`EP|(1g7i_Q<>aEAT{5(yD z=!O?kq61VegV+st@XCw475j6vS)_z@efuqQgHQR1T4;|-#OLZNQJPV4k$AX1Uk8Lm z{N*b*ia=I+MB}kWpupJ~>!C@xEN#Wa7V+7{m4j8c?)ChV=D?o~sjT?0C_AQ7B-vxqX30s0I_`2$in86#`mAsT-w?j{&AL@B3$;P z31G4(lV|b}uSDCIrjk+M1R!X7s4Aabn<)zpgT}#gE|mIvV38^ODy@<&yflpCwS#fRf9ZX3lPV_?8@C5)A;T zqmouFLFk;qIs4rA=hh=GL~sCFsXHsqO6_y~*AFt939UYVBSx1s(=Kb&5;j7cSowdE;7()CC2|-i9Zz+_BIw8#ll~-tyH?F3{%`QCsYa*b#s*9iCc`1P1oC26?`g<9))EJ3%xz+O!B3 zZ7$j~To)C@PquR>a1+Dh>-a%IvH_Y7^ys|4o?E%3`I&ADXfC8++hAdZfzIT#%C+Jz z1lU~K_vAm0m8Qk}K$F>|>RPK%<1SI0(G+8q~H zAsjezyP+u!Se4q3GW)`h`NPSRlMoBjCzNPesWJwVTY!o@G8=(6I%4XHGaSiS3MEBK zhgGFv6Jc>L$4jVE!I?TQuwvz_%CyO!bLh94nqK11C2W$*aa2ueGopG8DnBICVUORP zgytv#)49fVXDaR$SukloYC3u7#5H)}1K21=?DKj^U)8G;MS)&Op)g^zR2($<>C*zW z;X7`hLxiIO#J`ANdyAOJle4V%ppa*(+0i3w;8i*BA_;u8gOO6)MY`ueq7stBMJTB; z-a0R>hT*}>z|Gg}@^zDL1MrH+2hsR8 zHc}*9IvuQC^Ju)^#Y{fOr(96rQNPNhxc;mH@W*m206>Lo<*SaaH?~8zg&f&%YiOEG zGiz?*CP>Bci}!WiS=zj#K5I}>DtpregpP_tfZtPa(N<%vo^#WCQ5BTv0vr%Z{)0q+ z)RbfHktUm|lg&U3YM%lMUM(fu}i#kjX9h>GYctkx9Mt_8{@s%!K_EI zScgwy6%_fR?CGJQtmgNAj^h9B#zmaMDWgH55pGuY1Gv7D z;8Psm(vEPiwn#MgJYu4Ty9D|h!?Rj0ddE|&L3S{IP%H4^N!m`60ZwZw^;eg4sk6K{ ziA^`Sbl_4~f&Oo%n;8Ye(tiAdlZKI!Z=|j$5hS|D$bDJ}p{gh$KN&JZYLUjv4h{NY zBJ>X9z!xfDGY z+oh_Z&_e#Q(-}>ssZfm=j$D&4W4FNy&-kAO1~#3Im;F)Nwe{(*75(p=P^VI?X0GFakfh+X-px4a%Uw@fSbmp9hM1_~R>?Z8+ ziy|e9>8V*`OP}4x5JjdWp}7eX;lVxp5qS}0YZek;SNmm7tEeSF*-dI)6U-A%m6YvCgM(}_=k#a6o^%-K4{`B1+}O4x zztDT%hVb;v#?j`lTvlFQ3aV#zkX=7;YFLS$uIzb0E3lozs5`Xy zi~vF+%{z9uLjKvKPhP%x5f~7-Gj+%5N`%^=yk*Qn{`> z;xj&ROY6g`iy2a@{O)V(jk&8#hHACVDXey5a+KDod_Z&}kHM}xt7}Md@pil{2x7E~ zL$k^d2@Ec2XskjrN+IILw;#7((abu;OJii&v3?60x>d_Ma(onIPtcVnX@ELF0aL?T zSmWiL3(dOFkt!x=1O!_0n(cAzZW+3nHJ{2S>tgSK?~cFha^y(l@-Mr2W$%MN{#af8J;V*>hdq!gx=d0h$T7l}>91Wh07)9CTX zh2_ZdQCyFOQ)l(}gft0UZG`Sh2`x-w`5vC2UD}lZs*5 zG76$akzn}Xi))L3oGJ75#pcN=cX3!=57$Ha=hQ2^lwdyU#a}4JJOz6ddR%zae%#4& za)bFj)z=YQela(F#Y|Q#dp}PJghITwXouVaMq$BM?K%cXn9^Y@g43$=O)F&ZlOUom zJiad#dea;-eywBA@e&D6Pdso1?2^(pXiN91?jvcaUyYoKUmvl5G9e$W!okWe*@a<^ z8cQQ6cNSf+UPDx%?_G4aIiybZHHagF{;IcD(dPO!#=u zWfqLcPc^+7Uu#l(Bpxft{*4lv#*u7X9AOzDO z1D9?^jIo}?%iz(_dwLa{ex#T}76ZfN_Z-hwpus9y+4xaUu9cX}&P{XrZVWE{1^0yw zO;YhLEW!pJcbCt3L8~a7>jsaN{V3>tz6_7`&pi%GxZ=V3?3K^U+*ryLSb)8^IblJ0 zSRLNDvIxt)S}g30?s_3NX>F?NKIGrG_zB9@Z>uSW3k2es_H2kU;Rnn%j5qP)!XHKE zPB2mHP~tLCg4K_vH$xv`HbRsJwbZMUV(t=ez;Ec(vyHH)FbfLg`c61I$W_uBB>i^r z&{_P;369-&>23R%qNIULe=1~T$(DA`ev*EWZ6j(B$(te}x1WvmIll21zvygkS%vwG zzkR6Z#RKA2!z!C%M!O>!=Gr0(J0FP=-MN=5t-Ir)of50y10W}j`GtRCsXBakrKtG& zazmITDJMA0C51&BnLY)SY9r)NVTMs);1<=oosS9g31l{4ztjD3#+2H7u_|66b|_*O z;Qk6nalpqdHOjx|K&vUS_6ITgGll;TdaN*ta=M_YtyC)I9Tmr~VaPrH2qb6sd~=AcIxV+%z{E&0@y=DPArw zdV7z(G1hBx7hd{>(cr43^WF%4Y@PXZ?wPpj{OQ#tvc$pABJbvPGvdR`cAtHn)cSEV zrpu}1tJwQ3y!mSmH*uz*x0o|CS<^w%&KJzsj~DU0cLQUxk5B!hWE>aBkjJle8z~;s z-!A=($+}Jq_BTK5^B!`R>!MulZN)F=iXXeUd0w5lUsE5VP*H*oCy(;?S$p*TVvTxwAeWFB$jHyb0593)$zqalVlDX=GcCN1gU0 zlgU)I$LcXZ8Oyc2TZYTPu@-;7<4YYB-``Qa;IDcvydIA$%kHhJKV^m*-zxcvU4viy&Kr5GVM{IT>WRywKQ9;>SEiQD*NqplK-KK4YR`p0@JW)n_{TU3bt0 zim%;(m1=#v2}zTps=?fU5w^(*y)xT%1vtQH&}50ZF!9YxW=&7*W($2kgKyz1mUgfs zfV<*XVVIFnohW=|j+@Kfo!#liQR^x>2yQdrG;2o8WZR+XzU_nG=Ed2rK?ntA;K5B{ z>M8+*A4!Jm^Bg}aW?R?6;@QG@uQ8&oJ{hFixcfEnJ4QH?A4>P=q29oDGW;L;= z9-a0;g%c`C+Ai!UmK$NC*4#;Jp<1=TioL=t^YM)<<%u#hnnfSS`nq63QKGO1L8RzX z@MFDqs1z ztYmxDl@LU)5acvHk)~Z`RW7=aJ_nGD!mOSYD>5Odjn@TK#LY{jf?+piB5AM-CAoT_ z?S-*q7}wyLJzK>N%eMPuFgN)Q_otKP;aqy=D5f!7<=n(lNkYRXVpkB{TAYLYg{|(jtRqYmg$xH zjmq?B(RE4 zQx^~Pt}gxC2~l=K$$-sYy_r$CO(d=+b3H1MB*y_5g6WLaWTXn+TKQ|hNY^>Mp6k*$ zwkovomhu776vQATqT4blf~g;TY(MWCrf^^yfWJvSAB$p5l;jm@o#=!lqw+Lqfq>X= z$6~kxfm7`3q4zUEB;u4qa#BdJxO!;xGm)wwuisj{0y2x{R(IGMrsIzDY9LW>m!Y`= z04sx3IjnYvL<4JqxQ8f7qYd0s2Ig%`ytYPEMKI)s(LD}D@EY>x`VFtqvnADNBdeao zC96X+MxnwKmjpg{U&gP3HE}1=s!lv&D{6(g_lzyF3A`7Jn*&d_kL<;dAFx!UZ>hB8 z5A*%LsAn;VLp>3${0>M?PSQ)9s3}|h2e?TG4_F{}{Cs>#3Q*t$(CUc}M)I}8cPF6% z=+h(Kh^8)}gj(0}#e7O^FQ6`~fd1#8#!}LMuo3A0bN`o}PYsm!Y}sdOz$+Tegc=qT z8x`PH$7lvnhJp{kHWb22l;@7B7|4yL4UOOVM0MP_>P%S1Lnid)+k9{+3D+JFa#Pyf zhVc#&df87APl4W9X)F3pGS>@etfl=_E5tBcVoOfrD4hmVeTY-cj((pkn%n@EgN{0f zwb_^Rk0I#iZuHK!l*lN`ceJn(sI{$Fq6nN& zE<-=0_2WN}m+*ivmIOxB@#~Q-cZ>l136w{#TIJe478`KE7@=a{>SzPHsKLzYAyBQO zAtuuF$-JSDy_S@6GW0MOE~R)b;+0f%_NMrW(+V#c_d&U8Z9+ec4=HmOHw?gdjF(Lu zzra83M_BoO-1b3;9`%&DHfuUY)6YDV21P$C!Rc?mv&{lx#f8oc6?0?x zK08{WP65?#>(vPfA-c=MCY|%*1_<3D4NX zeVTi-JGl2uP_2@0F{G({pxQOXt_d{g_CV6b?jNpfUG9;8yle-^4KHRvZs-_2siata zt+d_T@U$&t*xaD22(fH(W1r$Mo?3dc%Tncm=C6{V9y{v&VT#^1L04vDrLM9qBoZ4@ z6DBN#m57hX7$C(=#$Y5$bJmwA$T8jKD8+6A!-IJwA{WOfs%s}yxUw^?MRZjF$n_KN z6`_bGXcmE#5e4Ym)aQJ)xg3Pg0@k`iGuHe?f(5LtuzSq=nS^5z>vqU0EuZ&75V%Z{ zYyhRLN^)$c6Ds{f7*FBpE;n5iglx5PkHfWrj3`x^j^t z7ntuV`g!9Xg#^3!x)l*}IW=(Tz3>Y5l4uGaB&lz{GDjm2D5S$CExLT`I1#n^lBH7Y zDgpMag@`iETKAI=p<5E#LTkwzVR@=yY|uBVI1HG|8h+d;G-qfuj}-ZR6fN>EfCCW z9~wRQoAPEa#aO?3h?x{YvV*d+NtPkf&4V0k4|L=uj!U{L+oLa(z#&iuhJr3-PjO3R z5s?=nn_5^*^Rawr>>Nr@K(jwkB#JK-=+HqwfdO<+P5byeim)wvqGlP-P|~Nse8=XF zz`?RYB|D6SwS}C+YQv+;}k6$-%D(@+t14BL@vM z2q%q?f6D-A5s$_WY3{^G0F131bbh|g!}#BKw=HQ7mx;Dzg4Z*bTLQSfo{ed{4}NZW zfrRm^Ca$rlE{Ue~uYv>R9{3smwATcdM_6+yWIO z*ZRH~uXE@#p$XTbCt5j7j2=86e{9>HIB6xDzV+vAo&B?KUiMP|ttOElepnl%|DPqL b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/manifest.json b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/manifest.json deleted file mode 100644 index 080d6c77ac..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/robots.txt b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/robots.txt deleted file mode 100644 index e9e57dc4d4..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/App.css b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/App.css deleted file mode 100644 index 74b5e05345..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/App.css +++ /dev/null @@ -1,38 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/App.test.tsx b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/App.test.tsx deleted file mode 100644 index 2a68616d98..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/App.test.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import App from './App'; - -test('renders learn react link', () => { - render(); - const linkElement = screen.getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); -}); diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/App.tsx b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/App.tsx deleted file mode 100644 index a53698aab3..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/App.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import logo from './logo.svg'; -import './App.css'; - -function App() { - return ( - - ); -} - -export default App; diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/index.css b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/index.css deleted file mode 100644 index ec2585e8c0..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/index.css +++ /dev/null @@ -1,13 +0,0 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; -} diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/index.tsx b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/index.tsx deleted file mode 100644 index ef2edf8ea3..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import './index.css'; -import App from './App'; -import reportWebVitals from './reportWebVitals'; - -ReactDOM.render( - - - , - document.getElementById('root') -); - -// If you want to start measuring performance in your app, pass a function -// to log results (for example: reportWebVitals(console.log)) -// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals -reportWebVitals(); diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/logo.svg b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/logo.svg deleted file mode 100644 index 9dfc1c058c..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/react-app-env.d.ts b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/react-app-env.d.ts deleted file mode 100644 index 6431bc5fc6..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/react-app-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/reportWebVitals.ts b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/reportWebVitals.ts deleted file mode 100644 index 49a2a16e0f..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/reportWebVitals.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ReportHandler } from 'web-vitals'; - -const reportWebVitals = (onPerfEntry?: ReportHandler) => { - if (onPerfEntry && onPerfEntry instanceof Function) { - import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { - getCLS(onPerfEntry); - getFID(onPerfEntry); - getFCP(onPerfEntry); - getLCP(onPerfEntry); - getTTFB(onPerfEntry); - }); - } -}; - -export default reportWebVitals; diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/setupTests.ts b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/setupTests.ts deleted file mode 100644 index 8f2609b7b3..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/src/setupTests.ts +++ /dev/null @@ -1,5 +0,0 @@ -// jest-dom adds custom jest matchers for asserting on DOM nodes. -// allows you to do things like: -// expect(element).toHaveTextContent(/react/i) -// learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom'; diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/tsconfig.json b/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/tsconfig.json deleted file mode 100644 index a273b0cfc0..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/skeleton/tsconfig.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], - "allowJs": true, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noFallthroughCasesInSwitch": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx" - }, - "include": [ - "src" - ] -} diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml b/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml deleted file mode 100644 index 664b405f29..0000000000 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml +++ /dev/null @@ -1,77 +0,0 @@ -apiVersion: backstage.io/v1beta2 -kind: Template -metadata: - name: create-react-app-template - title: Create React App Template - description: Create a new CRA website project - tags: - - react - - cra -spec: - owner: web@example.com - type: website - parameters: - - title: Provide some simple information - required: - - component_id - - owner - properties: - component_id: - title: Name - type: string - description: Unique name of the component - description: - title: Description - type: string - description: Help others understand what this website is for. - owner: - title: Owner - type: string - description: Owner of the component - ui:field: OwnerPicker - ui:options: - allowedKinds: - - Group - - title: Choose a location - required: - - repoUrl - properties: - repoUrl: - title: Repository Location - type: string - ui:field: RepoUrlPicker - ui:options: - allowedHosts: - - github.com - steps: - - id: template - name: Fetch Skeleton + Template - action: fetch:cookiecutter - input: - url: ./skeleton - copyWithoutRender: - - .github/workflows/* - values: - component_id: '{{ parameters.component_id }}' - description: '{{ parameters.description }}' - destination: '{{ parseRepoUrl parameters.repoUrl }}' - owner: '{{ parameters.owner }}' - - - id: publish - name: Publish - action: publish:github - input: - allowedHosts: ['github.com'] - description: 'This is {{ parameters.component_id }}' - repoUrl: '{{ parameters.repoUrl }}' - - - id: register - name: Register - action: catalog:register - input: - repoContentsUrl: '{{ steps.publish.output.repoContentsUrl }}' - catalogInfoPath: '/catalog-info.yaml' - - output: - remoteUrl: '{{ steps.publish.output.remoteUrl }}' - entityRef: '{{ steps.register.output.entityRef }}' diff --git a/plugins/scaffolder-backend/sample-templates/docs-template/skeleton/catalog-info.yaml b/plugins/scaffolder-backend/sample-templates/docs-template/skeleton/catalog-info.yaml deleted file mode 100644 index 8f18e06d7e..0000000000 --- a/plugins/scaffolder-backend/sample-templates/docs-template/skeleton/catalog-info.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: {{cookiecutter.name | jsonify}} - description: {{cookiecutter.description | jsonify}} - annotations: - github.com/project-slug: {{cookiecutter.destination.owner + "/" + cookiecutter.destination.repo}} - backstage.io/techdocs-ref: dir:. -spec: - type: documentation - lifecycle: experimental - owner: {{cookiecutter.owner | jsonify}} diff --git a/plugins/scaffolder-backend/sample-templates/docs-template/skeleton/docs/index.md b/plugins/scaffolder-backend/sample-templates/docs-template/skeleton/docs/index.md deleted file mode 100644 index b6f7344334..0000000000 --- a/plugins/scaffolder-backend/sample-templates/docs-template/skeleton/docs/index.md +++ /dev/null @@ -1,28 +0,0 @@ -## {{ cookiecutter.name }} - -{{ cookiecutter.description }} - -## Getting started - -Start write your documentation by adding more markdown (.md) files to this folder (/docs) or replace the content in this file. - -## Table of Contents - -The Table of Contents on the right is generated automatically based on the hierarchy -of headings. Only use one H1 (`#` in Markdown) per file. - -## Site navigation - -For new pages to appear in the left hand navigation you need edit the `mkdocs.yml` -file in root of your repo. The navigation can also link out to other sites. - -Alternatively, if there is no `nav` section in `mkdocs.yml`, a navigation section -will be created for you. However, you will not be able to use alternate titles for -pages, or include links to other sites. - -Note that MkDocs uses `mkdocs.yml`, not `mkdocs.yaml`, although both appear to work. -See also . - -## Support - -That's it. If you need support, reach out in [#docs-like-code](https://discord.com/channels/687207715902193673/714754240933003266) on Discord. diff --git a/plugins/scaffolder-backend/sample-templates/docs-template/skeleton/mkdocs.yml b/plugins/scaffolder-backend/sample-templates/docs-template/skeleton/mkdocs.yml deleted file mode 100644 index 7e1c015f28..0000000000 --- a/plugins/scaffolder-backend/sample-templates/docs-template/skeleton/mkdocs.yml +++ /dev/null @@ -1,8 +0,0 @@ -site_name: {{cookiecutter.name | jsonify}} -site_description: {{cookiecutter.description | jsonify}} - -nav: - - Introduction: index.md - -plugins: - - techdocs-core diff --git a/plugins/scaffolder-backend/sample-templates/docs-template/template.yaml b/plugins/scaffolder-backend/sample-templates/docs-template/template.yaml deleted file mode 100644 index 1e81242e7a..0000000000 --- a/plugins/scaffolder-backend/sample-templates/docs-template/template.yaml +++ /dev/null @@ -1,86 +0,0 @@ -apiVersion: backstage.io/v1beta2 -kind: Template -metadata: - name: docs-template - title: Documentation Template - description: Create a new standalone documentation project - tags: - - recommended - - techdocs - - mkdocs -spec: - owner: backstage/techdocs-core - type: documentation - - parameters: - - title: Fill in some steps - required: - - name - - description - properties: - name: - title: Name - type: string - description: Unique name of the component - ui:autofocus: true - ui:options: - rows: 5 - description: - title: Description - type: string - description: A description for the component - ui:options: - rows: 5 - owner: - title: Owner - type: string - description: Owner of the component - ui:field: OwnerPicker - ui:options: - allowedKinds: - - Group - - title: Choose a location - required: - - repoUrl - properties: - repoUrl: - title: Repository Location - type: string - ui:field: RepoUrlPicker - ui:options: - allowedHosts: - - github.com - - # This template is meant to be used on top of an existing tmeplate. - # By adding the following and fetching from an absolute URL you can - # add in the docs template - steps: - - id: fetch - name: Template Docs Skeleton - action: fetch:cookiecutter - input: - url: ./skeleton - values: - name: '{{ parameters.name }}' - description: '{{ parameters.description }}' - destination: '{{ parseRepoUrl parameters.repoUrl }}' - owner: '{{ parameters.owner }}' - - - id: publish - name: Publish - action: publish:github - input: - allowedHosts: ['github.com'] - description: 'This is {{ parameters.component_id }}' - repoUrl: '{{ parameters.repoUrl }}' - - - id: register - name: Register - action: catalog:register - input: - repoContentsUrl: '{{ steps.publish.output.repoContentsUrl }}' - catalogInfoPath: '/catalog-info.yaml' - - output: - remoteUrl: '{{ steps.publish.output.remoteUrl }}' - entityRef: '{{ steps.register.output.entityRef }}' diff --git a/plugins/scaffolder-backend/sample-templates/pull-request/template.yaml b/plugins/scaffolder-backend/sample-templates/pull-request/template.yaml deleted file mode 100644 index b6de1c29ca..0000000000 --- a/plugins/scaffolder-backend/sample-templates/pull-request/template.yaml +++ /dev/null @@ -1,77 +0,0 @@ -apiVersion: backstage.io/v1beta2 -kind: Template -metadata: - name: pull-request - title: Pull Request Action template - description: scaffolder v1beta2 template demo publishing to PR on existing git repository -spec: - owner: backstage/techdocs-core - type: service - - parameters: - - title: Fill in some steps - required: - - name - properties: - name: - title: Name - type: string - description: Unique name of the component - ui:autofocus: true - ui:options: - rows: 5 - description: - title: Description - type: string - description: Description of the component - targetPath: - title: Target Path in repo - type: string - description: Name of the directory to create in the repository - - title: Choose a location - required: - - repoUrl - properties: - repoUrl: - title: Repository Location - type: string - ui:field: RepoUrlPicker - ui:options: - allowedHosts: - - github.com - - steps: - - id: fetch-base - name: Fetch Base - action: fetch:cookiecutter - input: - url: ./template - values: - name: '{{parameters.name}}' - - - id: fetch-docs - name: Fetch Docs - action: fetch:plain - input: - targetPath: ./community - url: https://github.com/backstage/community/tree/main/backstage-community-sessions - - - id: publish - name: Publish - action: publish:github:pull-request - input: - repoUrl: '{{ parameters.repoUrl }}' - title: 'Create new project: {{parameters.name}}' - branchName: 'create-{{parameters.name}}' - description: | - # New project: {{parameters.name}} - - {{#if parameters.description}} - {{parameters.description}} - {{/if}} - targetPath: '{{#if parameters.targetPath}}{{parameters.targetPath}}{{else}}{{parameters.name}}{{/if}}' - - output: - links: - - url: '{{steps.publish.output.remoteUrl}}' - text: 'Go to PR' diff --git a/plugins/scaffolder-backend/sample-templates/pull-request/template/catalog-info.yaml b/plugins/scaffolder-backend/sample-templates/pull-request/template/catalog-info.yaml deleted file mode 100644 index 04f055bd46..0000000000 --- a/plugins/scaffolder-backend/sample-templates/pull-request/template/catalog-info.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: {{cookiecutter.name | jsonify}} -spec: - type: website - lifecycle: experimental - owner: user:guest diff --git a/plugins/scaffolder-backend/sample-templates/rails-demo/template.yaml b/plugins/scaffolder-backend/sample-templates/rails-demo/template.yaml deleted file mode 100644 index 174c58741b..0000000000 --- a/plugins/scaffolder-backend/sample-templates/rails-demo/template.yaml +++ /dev/null @@ -1,174 +0,0 @@ -apiVersion: backstage.io/v1beta2 -kind: Template -metadata: - name: rails-demo - title: Rails template - description: scaffolder Rails app -spec: - owner: backstage/techdocs-core - type: service - - parameters: - - title: Fill in some steps - required: - - name - - owner - properties: - name: - title: Name - type: string - description: Unique name of the component - ui:autofocus: true - ui:options: - rows: 5 - owner: - title: Owner - type: string - description: Owner of the component - ui:field: OwnerPicker - ui:options: - allowedKinds: - - Group - system: - title: System - type: string - description: System of the component - ui:field: EntityPicker - ui:options: - allowedKinds: - - System - defaultKind: System - - - title: Choose a location - required: - - repoUrl - - dryRun - properties: - repoUrl: - title: Repository Location - type: string - ui:field: RepoUrlPicker - ui:options: - allowedHosts: - - github.com - dryRun: - title: Only perform a dry run, don't publish anything - type: boolean - default: false - railsArguments: - title: arguments to run the rails new command - type: object - properties: - minimal: - title: minimal - description: Preconfigure a minimal rails app - type: boolean - skipBundle: - title: skipBundle - description: Don't run bundle install - type: boolean - skipWebpackInstall: - title: skipWebpackInstall - description: Don't run Webpack install - type: boolean - api: - title: api - description: Preconfigure smaller stack for API only apps - type: boolean - template: - title: template - description: Path to some application template (can be a filesystem path or URL) - type: string - default: './rails-template-file.rb' - webpacker: - title: webpacker - description: 'Preconfigure Webpack with a particular framework (options: react, - vue, angular, elm, stimulus)' - type: string - enum: - - react - - vue - - angular - - elm - - stimulus - database: - title: database - description: 'Preconfigure for selected database (options: mysql/postgresql/sqlite3/oracle/sqlserver/jdbcmysql/jdbcsqlite3/jdbcpostgresql/jdbc)' - type: string - enum: - - mysql - - postgresql - - sqlite3 - - oracle - - sqlserver - - jdbcmysql - - jdbcsqlite3 - - jdbcpostgresql - - jdbc - railsVersion: - title: Rails version in Gemfile - description: 'Set up the application with Gemfile pointing to a specific version - (options: dev, edge, master)' - type: string - enum: - - dev - - edge - - master - - steps: - - id: fetch-base - name: Fetch Base - action: fetch:rails - input: - url: ./template - values: - name: '{{ parameters.name }}' - owner: '{{ parameters.owner }}' - system: '{{ parameters.system }}' - railsArguments: '{{ json parameters.railsArguments }}' - - - name: Write Catalog information - action: catalog:write - input: - component: - apiVersion: 'backstage.io/v1alpha1' - kind: Component - metadata: - name: '{{ parameters.name }}' - annotations: - github.com/project-slug: '{{ projectSlug parameters.repoUrl }}' - spec: - type: service - lifecycle: production - owner: '{{ parameters.owner }}' - - - id: publish - if: '{{ not parameters.dryRun }}' - name: Publish - action: publish:github - input: - allowedHosts: ['github.com'] - description: 'This is {{ parameters.name }}' - repoUrl: '{{ parameters.repoUrl }}' - - - id: register - if: '{{ not parameters.dryRun }}' - name: Register - action: catalog:register - input: - repoContentsUrl: '{{ steps.publish.output.repoContentsUrl }}' - catalogInfoPath: '/catalog-info.yaml' - - - name: Results - if: '{{ parameters.dryRun }}' - action: debug:log - input: - listWorkspace: true - - output: - links: - - title: Repository - url: '{{ steps.publish.output.remoteUrl }}' - - title: Open in catalog - icon: 'catalog' - entityRef: '{{ steps.register.output.entityRef }}' diff --git a/plugins/scaffolder-backend/sample-templates/rails-demo/template/rails-template-file.rb b/plugins/scaffolder-backend/sample-templates/rails-demo/template/rails-template-file.rb deleted file mode 100644 index 90c0d53ddc..0000000000 --- a/plugins/scaffolder-backend/sample-templates/rails-demo/template/rails-template-file.rb +++ /dev/null @@ -1,14 +0,0 @@ -gem_group :development, :test do - gem "rspec" - gem "rspec-rails" -end - -rakefile("example.rake") do - <<-TASK - namespace :example do - task :backstage do - puts "i like backstage!" - end - end - TASK -end diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.editorconfig b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.editorconfig deleted file mode 100644 index 23c3268a0f..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.editorconfig +++ /dev/null @@ -1,13 +0,0 @@ -# editorconfig.org -root = true - -[*] -indent_style = space -indent_size = 2 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.md] -insert_final_newline = false \ No newline at end of file diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.eslintignore b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.eslintignore deleted file mode 100644 index 8b13789179..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.eslintignore +++ /dev/null @@ -1 +0,0 @@ - diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.eslintrc.js b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.eslintrc.js deleted file mode 100644 index 8623614899..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@spotify/web-scripts/config/eslintrc.js'); diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.github/workflows/build.yml b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.github/workflows/build.yml deleted file mode 100644 index 907da7e820..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.github/workflows/build.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Frontend CI - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - - -jobs: - build: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [12.x] - - steps: - - name: checkout code - uses: actions/checkout@v1 - - name: get yarn cache - id: yarn-cache - run: echo "::set-output name=dir::$(yarn cache dir)" - - uses: actions/cache@v2 - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - name: yarn install, build, and test - working-directory: . - run: | - yarn install - yarn build - yarn test - env: - CI: true diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.gitignore b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.gitignore deleted file mode 100644 index 4d1e0d9635..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# See https://help.github.com/ignore-files/ for more about ignoring files. - -# dependencies -/node_modules - -# testing -/coverage -junit.xml - -# build -/build - -# misc -.DS_Store - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/README.md b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/README.md deleted file mode 100644 index 415065179b..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# {{ cookiecutter.component_id }} - -## Description - -{{ cookiecutter.description }} - -## Develop - -```bash -# install dependencies -$ yarn -# start development server -$ yarn dev -``` \ No newline at end of file diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/babel.config.js b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/babel.config.js deleted file mode 100644 index db2d280677..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/babel.config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - plugins: ['babel-plugin-styled-components'], - presets: ['next/babel', '@zeit/next-typescript/babel'], -}; diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/catalog-info.yaml b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/catalog-info.yaml deleted file mode 100644 index df23b90b97..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/catalog-info.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: {{cookiecutter.component_id | jsonify}} - description: {{cookiecutter.description | jsonify}} - annotations: - github.com/project-slug: {{cookiecutter.destination.owner + "/" + cookiecutter.destination.repo}} - backstage.io/techdocs-ref: dir:. -spec: - type: website - lifecycle: experimental - owner: {{cookiecutter.owner | jsonify}} diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/docs/index.md b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/docs/index.md deleted file mode 100644 index 2a0f572ff2..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/docs/index.md +++ /dev/null @@ -1,28 +0,0 @@ -# {{ cookiecutter.component_id }} - -{{ cookiecutter.description }} - -## Getting started - -Start writing your documentation by adding more markdown (.md) files to this folder (/docs) or replace the content in this file. - -## Table of Contents - -The Table of Contents on the right is generated automatically based on the hierarchy -of headings. Only use one H1 (`#` in Markdown) per file. - -## Site navigation - -For new pages to appear in the left hand navigation you need edit the `mkdocs.yml` -file in root of your repo. The navigation can also link out to other sites. - -Alternatively, if there is no `nav` section in `mkdocs.yml`, a navigation section -will be created for you. However, you will not be able to use alternate titles for -pages, or include links to other sites. - -Note that MkDocs uses `mkdocs.yml`, not `mkdocs.yaml`, although both appear to work. -See also . - -## Support - -That's it. If you need support, reach out in [#docs-like-code](https://discord.com/channels/687207715902193673/714754240933003266) on Discord. diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/jest.config.js b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/jest.config.js deleted file mode 100644 index 0dc2a9c0ca..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/jest.config.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - ...require('@spotify/web-scripts/config/jest.config.js'), - testEnvironment: 'jsdom', - testPathIgnorePatterns: ['/node_modules/', '/build/'], - transform: { - '^.+\\.tsx?$': 'babel-jest', - }, -}; diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/mkdocs.yml b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/mkdocs.yml deleted file mode 100644 index 64f1e9ee8e..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/mkdocs.yml +++ /dev/null @@ -1,8 +0,0 @@ -site_name: {{cookiecutter.component_id | jsonify}} -site_description: {{cookiecutter.description | jsonify}} - -nav: - - Introduction: index.md - -plugins: - - techdocs-core diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/next-env.d.ts b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/next-env.d.ts deleted file mode 100644 index fd10310f68..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/next-env.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// read more about this file here ---> https://github.com/zeit/next.js/blob/canary/docs/basic-features/typescript.md -/* eslint spaced-comment: ["error", "always", { "markers": ["/"] }] */ - -/// -/// diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/next.config.js b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/next.config.js deleted file mode 100644 index be8b159307..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/next.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - distDir: 'build', -}; diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/package.json b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/package.json deleted file mode 100644 index 75925bf567..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "{{ cookiecutter.component_id }}", - "version": "0.0.0", - "description": "{{ cookiecutter.description }}", - "license": "UNLICENSED", - "scripts": { - "dev": "next", - "build": "next build", - "start": "next start", - "lint": "web-scripts lint --ignore-path=.gitignore", - "test": "web-scripts test --config jest.config.js", - "pretest:ci": "yarn lint", - "test:ci": "yarn test --ci --coverage --reporters=default --reporters=jest-junit" - }, - "dependencies": { - "@zeit/next-typescript": "^1.1.1", - "babel-plugin-styled-components": "^1.10.6", - "next": "^9.1.1", - "react": "^16.8.5", - "react-dom": "^16.8.5", - "styled-components": "^4.3.2" - }, - "devDependencies": { - "@spotify/tsconfig": "^5.0.0", - "@spotify/web-scripts": "^5.0.0", - "@testing-library/react": "^8.0.1", - "@types/node": "^14.14.32", - "@types/react": "^16.8.7", - "@types/react-dom": "^16.8.2", - "@types/styled-components": "^4.1.18", - "husky": "^2.7.0", - "jest-junit": "^8.0.0", - "typescript": "^3.9.2" - }, - "husky": { - "hooks": { - "pre-commit": "web-scripts precommit" - } - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - } -} diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/prettier.config.js b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/prettier.config.js deleted file mode 100644 index 93df970dd6..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/prettier.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@spotify/web-scripts/config/prettier.config.js'); diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/public/static/fonts.css b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/public/static/fonts.css deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/__tests__/index.test.tsx b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/__tests__/index.test.tsx deleted file mode 100644 index 8612ead08f..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/__tests__/index.test.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import { cleanup, render } from '@testing-library/react'; - -import Index from '../pages/index'; - -afterEach(cleanup); - -describe('Index', () => { - it('Says hello', () => { - const { queryByText } = render(); - expect(queryByText('Hello!')).toBeTruthy(); - }); -}); diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/components/Header.tsx b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/components/Header.tsx deleted file mode 100644 index f8ba94310a..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/components/Header.tsx +++ /dev/null @@ -1,3 +0,0 @@ -import React from 'react'; - -export const Header = () =>

Header

; diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/_app.tsx b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/_app.tsx deleted file mode 100644 index a3853e47c9..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/_app.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import App from 'next/app'; -import Head from 'next/head'; -import styled from 'styled-components'; -import { Header } from '../components/Header'; - -const StyledApp = styled.div` - > * { - padding-left: 16px; - padding-right: 16px; - } -`; - -const Main = styled.div` - margin: 2em auto; - height: 85vh; -`; - -class CustomApp extends App { - render() { - const { Component, pageProps } = this.props; - - return ( - - - - -
-
- -
- - ); - } -} - -export default CustomApp; diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/_document.tsx b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/_document.tsx deleted file mode 100644 index 9b01a6a74c..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/_document.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/** - * This file extends the and injects the server side rendered styles into the - * By server-side rendering CSS we avoid visual changes in the layout while loading the JS. - * - * Taken from this example: - * https://github.com/zeit/next.js/tree/master/examples/with-styled-components - */ - -import React from 'react'; -import Document, { DocumentContext, DocumentInitialProps } from 'next/document'; -import { ServerStyleSheet } from 'styled-components'; - -export default class MyDocument extends Document { - static async getInitialProps( - ctx: DocumentContext, - ): Promise { - const sheet = new ServerStyleSheet(); - const originalRenderPage = ctx.renderPage; - - try { - ctx.renderPage = () => - originalRenderPage({ - enhanceApp: (App: any) => (props) => - sheet.collectStyles(), - }); - - const initialProps = await Document.getInitialProps(ctx); - return { - ...initialProps, - styles: ( - <> - {initialProps.styles} - {sheet.getStyleElement()} - - ), - }; - } finally { - sheet.seal(); - } - } -} diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/api/ping.ts b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/api/ping.ts deleted file mode 100644 index 8bc772c182..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/api/ping.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -export default function handle(_: NextApiRequest, res: NextApiResponse) { - res.status(200).send('ok'); -} diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/index.tsx b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/index.tsx deleted file mode 100644 index c01d844f9f..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/src/pages/index.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import React from 'react'; - -const Index = () =>

Hello!

; - -export default Index; diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/tsconfig.json b/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/tsconfig.json deleted file mode 100644 index 03508ff043..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/skeleton/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "@spotify/tsconfig", - "compilerOptions": { - "target": "es5", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": false, - "forceConsistentCasingInFileNames": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve" - }, - "exclude": ["node_modules", "output/node_modules"], - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"] -} diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml b/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml deleted file mode 100644 index 49802a9d62..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml +++ /dev/null @@ -1,77 +0,0 @@ -apiVersion: backstage.io/v1beta2 -kind: Template -metadata: - name: react-ssr-template - title: React SSR Template - description: Create a website powered with Next.js - tags: - - recommended - - react -spec: - owner: web@example.com - type: website - parameters: - - title: Provide some simple information - required: - - component_id - - owner - properties: - component_id: - title: Name - type: string - description: Unique name of the component - description: - title: Description - type: string - description: Help others understand what this website is for. - owner: - title: Owner - type: string - description: Owner of the component - ui:field: OwnerPicker - ui:options: - allowedKinds: - - Group - - title: Choose a location - required: - - repoUrl - properties: - repoUrl: - title: Repository Location - type: string - ui:field: RepoUrlPicker - ui:options: - allowedHosts: - - github.com - steps: - - id: template - name: Fetch Skeleton + Template - action: fetch:cookiecutter - input: - url: ./skeleton - copyWithoutRender: - - .github/workflows/* - values: - component_id: '{{ parameters.component_id }}' - description: '{{ parameters.description }}' - destination: '{{ parseRepoUrl parameters.repoUrl }}' - owner: '{{ parameters.owner }}' - - - id: publish - name: Publish - action: publish:github - input: - allowedHosts: ['github.com'] - description: 'This is {{ parameters.component_id }}' - repoUrl: '{{ parameters.repoUrl }}' - - - id: register - name: Register - action: catalog:register - input: - repoContentsUrl: '{{ steps.publish.output.repoContentsUrl }}' - catalogInfoPath: '/catalog-info.yaml' - - output: - remoteUrl: '{{ steps.publish.output.remoteUrl }}' - entityRef: '{{ steps.register.output.entityRef }}' diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/.editorconfig b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/.editorconfig deleted file mode 100644 index 03eb226ef0..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/.editorconfig +++ /dev/null @@ -1,10 +0,0 @@ -root = true - -[*] -indent_style = space -indent_size = 2 -continuation_indent_size = 4 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/.github/workflows/build.yml b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/.github/workflows/build.yml deleted file mode 100644 index 04e1d10b47..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/.github/workflows/build.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Java CI with Maven - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - java-version: 11 - - name: Build with Maven - run: mvn -B package --file pom.xml diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/.gitignore b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/.gitignore deleted file mode 100644 index 1504daa184..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -target/ -## IntelliJ -.idea -*.iml - -## Temp -dependency-reduced-pom.xml diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/Dockerfile b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/Dockerfile deleted file mode 100644 index 1c8a969c8c..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM openjdk:11-alpine -ENTRYPOINT ["/usr/bin/{{cookiecutter.artifact_id}}.sh"] - -COPY {{cookiecutter.artifact_id}}.sh /usr/bin/{{cookiecutter.artifact_id}}.sh -COPY target/{{cookiecutter.artifact_id}}.jar /usr/share/{{cookiecutter.artifact_id}}/{{cookiecutter.artifact_id}}.jar diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/README.md b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/README.md deleted file mode 100644 index 710b6b557e..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# {{cookiecutter.component_id}} - -{{cookiecutter.description}} diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/SERVICE.marker b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/SERVICE.marker deleted file mode 100644 index 1dcf39a3b3..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/SERVICE.marker +++ /dev/null @@ -1 +0,0 @@ -(This marker file causes Maven to build this artifact as a service) diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/catalog-info.yaml b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/catalog-info.yaml deleted file mode 100644 index 4ddec9c032..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/catalog-info.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: {{cookiecutter.component_id | jsonify}} - description: {{cookiecutter.description | jsonify}} - annotations: - github.com/project-slug: {{cookiecutter.destination.owner + "/" + cookiecutter.destination.repo}} - backstage.io/techdocs-ref: dir:. -spec: - type: service - lifecycle: experimental - owner: {{cookiecutter.owner | jsonify}} diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/docs/index.md b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/docs/index.md deleted file mode 100644 index 5352ef7801..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/docs/index.md +++ /dev/null @@ -1,28 +0,0 @@ -## {{ cookiecutter.component_id }} - -{{ cookiecutter.description }} - -## Getting started - -Start write your documentation by adding more markdown (.md) files to this folder (/docs) or replace the content in this file. - -## Table of Contents - -The Table of Contents on the right is generated automatically based on the hierarchy -of headings. Only use one H1 (`#` in Markdown) per file. - -## Site navigation - -For new pages to appear in the left hand navigation you need edit the `mkdocs.yml` -file in root of your repo. The navigation can also link out to other sites. - -Alternatively, if there is no `nav` section in `mkdocs.yml`, a navigation section -will be created for you. However, you will not be able to use alternate titles for -pages, or include links to other sites. - -Note that MkDocs uses `mkdocs.yml`, not `mkdocs.yaml`, although both appear to work. -See also . - -## Support - -That's it. If you need support, reach out in [#docs-like-code](https://discord.com/channels/687207715902193673/714754240933003266) on Discord. diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/mkdocs.yml b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/mkdocs.yml deleted file mode 100644 index 64f1e9ee8e..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/mkdocs.yml +++ /dev/null @@ -1,8 +0,0 @@ -site_name: {{cookiecutter.component_id | jsonify}} -site_description: {{cookiecutter.description | jsonify}} - -nav: - - Introduction: index.md - -plugins: - - techdocs-core diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/pom.xml b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/pom.xml deleted file mode 100644 index d5e81cf5e0..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/pom.xml +++ /dev/null @@ -1,221 +0,0 @@ - - - 4.0.0 - - - org.springframework.boot - spring-boot-starter-parent - 2.2.4.RELEASE - - - com.example - {{cookiecutter.artifact_id}} - 0.0.1-SNAPSHOT - jar - - {{cookiecutter.artifact_id}} - {{cookiecutter.description}} - - - 11 - ${java.version} - ${java.version} - ${java.version} - UTF-8 - UTF-8 - - - - jcenter - https://jcenter.bintray.com/ - - - - - io.github.lognet - grpc-spring-boot-starter - 3.5.1 - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.apache.tomcat - annotations-api - 6.0.53 - provided - - - - - - ${project.artifactId} - - - kr.motd.maven - os-maven-plugin - 1.4.0.Final - - - - - - maven-compiler-plugin - 3.8.1 - - true - true - - -Xlint:all - - - - - org.xolstice.maven.plugins - protobuf-maven-plugin - 0.6.1 - - - ${project.basedir}/src/main/resources - - com.google.protobuf:protoc:3.9.1:exe:${os.detected.classifier} - - grpc-java - - io.grpc:protoc-gen-grpc-java:1.13.1:exe:${os.detected.classifier} - - - - - - compile - compile-custom - - - - - - - - maven-failsafe-plugin - 2.22.2 - - - **/*IT.java - **/integrationtests/*.java - **/it/**/*.java - - - - - - - com.coveo - fmt-maven-plugin - 2.8 - - - - format - - - - - - org.jacoco - jacoco-maven-plugin - 0.8.5 - - - - prepare-agent - report - - - - - - maven-enforcer-plugin - - - enforce - - enforce - - - - - - - - - - - - maven-jar-plugin - - - true - - ${start-class} - true - true - - - - ${project.version}-${buildTimestamp}-${buildNumber} - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - build-info - - build-info - - - - - - maven-source-plugin - - - attach-sources - - jar - - - - - - maven-javadoc-plugin - - private - - - - attach-javadocs - - jar - - - - - - - diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/java/com/example/{{cookiecutter.java_package_name}}/Application.java b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/java/com/example/{{cookiecutter.java_package_name}}/Application.java deleted file mode 100644 index 7ead2562d0..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/java/com/example/{{cookiecutter.java_package_name}}/Application.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.{{cookiecutter.java_package_name}}; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/java/com/example/{{cookiecutter.java_package_name}}/GreeterService.java b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/java/com/example/{{cookiecutter.java_package_name}}/GreeterService.java deleted file mode 100644 index 90b8412a04..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/java/com/example/{{cookiecutter.java_package_name}}/GreeterService.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.example.{{cookiecutter.java_package_name}}; - -import com.example.{{cookiecutter.java_package_name}}.proto.GreeterGrpc; -import com.example.{{cookiecutter.java_package_name}}.proto.GreeterOuterClass; -import io.grpc.stub.StreamObserver; -import org.lognet.springboot.grpc.GRpcService; - -@GRpcService -public class GreeterService extends GreeterGrpc.GreeterImplBase { - - @Override - public void sayHello(final GreeterOuterClass.HelloRequest request, - final StreamObserver responseObserver) { - final GreeterOuterClass.HelloReply.Builder replyBuilder = - GreeterOuterClass.HelloReply.newBuilder().setMessage("Hello " + request.getName()); - responseObserver.onNext(replyBuilder.build()); - responseObserver.onCompleted(); - } -} diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/resources/application.properties b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/resources/application.properties deleted file mode 100644 index 03be3b6ebf..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/resources/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -spring.application.name={{cookiecutter.component_id}} -server.port={{cookiecutter.http_port}} -grpc.enableReflection=true diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/resources/banner.txt b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/resources/banner.txt deleted file mode 100644 index 46846ba35e..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/resources/banner.txt +++ /dev/null @@ -1,22 +0,0 @@ -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_GREEN}8${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} -${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} ${AnsiColor.BRIGHT_WHITE} diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/resources/greeter.proto b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/resources/greeter.proto deleted file mode 100644 index 8015d914ee..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/main/resources/greeter.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; - -option java_package = "com.example.{{cookiecutter.java_package_name}}.proto"; - -service Greeter { - rpc SayHello ( HelloRequest) returns ( HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/test/java/com/example/{{cookiecutter.java_package_name}}/ApplicationTest.java b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/test/java/com/example/{{cookiecutter.java_package_name}}/ApplicationTest.java deleted file mode 100644 index 1d7298172a..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/src/test/java/com/example/{{cookiecutter.java_package_name}}/ApplicationTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.example.{{cookiecutter.java_package_name}}; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class ApplicationTest { - - @Test - public void contextLoads() { - } -} diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/{{cookiecutter.artifact_id}}.sh b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/{{cookiecutter.artifact_id}}.sh deleted file mode 100755 index c69b980dc8..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/skeleton/{{cookiecutter.artifact_id}}.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec /usr/bin/java $JVM_DEFAULT_ARGS $JVM_ARGS -jar /usr/share/{{cookiecutter.artifact_id}}/{{cookiecutter.artifact_id}}.jar "$@" diff --git a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/template.yaml b/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/template.yaml deleted file mode 100644 index c306187581..0000000000 --- a/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/template.yaml +++ /dev/null @@ -1,88 +0,0 @@ -apiVersion: backstage.io/v1beta2 -kind: Template -metadata: - name: springboot-template - title: Spring Boot gRPC Service - description: Create a simple microservice using gRPC and Spring Boot Java - tags: - - recommended - - java - - grpc -spec: - owner: service@example.com - type: service - - parameters: - - title: Provide some simple information - required: - - component_id - - owner - - java_package_name - properties: - component_id: - title: Name - type: string - description: Unique name of the component - java_package_name: - title: Java Package Name - type: string - description: Name for the java package. eg (io.backstage.blah) - description: - title: Description - type: string - description: Help others understand what this website is for. - owner: - title: Owner - type: string - description: Owner of the component - ui:field: OwnerPicker - ui:options: - allowedKinds: - - Group - - title: Choose a location - required: - - repoUrl - properties: - repoUrl: - title: Repository Location - type: string - ui:field: RepoUrlPicker - ui:options: - allowedHosts: - - github.com - - steps: - - id: template - name: Fetch Skeleton + Template - action: fetch:cookiecutter - input: - url: ./skeleton - copyWithoutRender: - - .github/workflows/* - values: - component_id: '{{ parameters.component_id }}' - description: '{{ parameters.description }}' - artifact_id: '{{ parameters.component_id }}' - java_package_name: '{{ parameters.java_package_name }}' - owner: '{{ parameters.owner }}' - destination: '{{ parseRepoUrl parameters.repoUrl }}' - http_port: 8080 - - - id: publish - name: Publish - action: publish:github - input: - allowedHosts: ['github.com'] - description: 'This is {{ parameters.component_id }}' - repoUrl: '{{ parameters.repoUrl }}' - - - id: register - name: Register - action: catalog:register - input: - repoContentsUrl: '{{ steps.publish.output.repoContentsUrl }}' - catalogInfoPath: '/catalog-info.yaml' - - output: - remoteUrl: '{{ steps.publish.output.remoteUrl }}' - entityRef: '{{ steps.register.output.entityRef }}' diff --git a/plugins/scaffolder-backend/sample-templates/v1beta2-demo/template.yaml b/plugins/scaffolder-backend/sample-templates/v1beta2-demo/template.yaml deleted file mode 100644 index b3228a20d0..0000000000 --- a/plugins/scaffolder-backend/sample-templates/v1beta2-demo/template.yaml +++ /dev/null @@ -1,107 +0,0 @@ -apiVersion: backstage.io/v1beta2 -kind: Template -metadata: - name: v1beta2-demo - title: Test Action template - description: scaffolder v1beta2 template demo publishing to github -spec: - owner: backstage/techdocs-core - type: service - - parameters: - - title: Fill in some steps - required: - - name - - owner - properties: - name: - title: Name - type: string - description: Unique name of the component - ui:autofocus: true - ui:options: - rows: 5 - owner: - title: Owner - type: string - description: Owner of the component - ui:field: OwnerPicker - ui:options: - allowedKinds: - - Group - system: - title: System - type: string - description: System of the component - ui:field: EntityPicker - ui:options: - allowedKinds: - - System - defaultKind: System - - - title: Choose a location - required: - - repoUrl - - dryRun - properties: - repoUrl: - title: Repository Location - type: string - ui:field: RepoUrlPicker - ui:options: - allowedHosts: - - github.com - dryRun: - title: Only perform a dry run, don't publish anything - type: boolean - default: false - - steps: - - id: fetch-base - name: Fetch Base - action: fetch:cookiecutter - input: - url: ./template - values: - name: '{{ parameters.name }}' - owner: '{{ parameters.owner }}' - system: '{{ parameters.system }}' - destination: '{{ parseRepoUrl parameters.repoUrl }}' - - - id: fetch-docs - name: Fetch Docs - action: fetch:plain - input: - targetPath: ./community - url: https://github.com/backstage/community/tree/main/backstage-community-sessions - - - id: publish - if: '{{ not parameters.dryRun }}' - name: Publish - action: publish:github - input: - allowedHosts: ['github.com'] - description: 'This is {{ parameters.name }}' - repoUrl: '{{ parameters.repoUrl }}' - - - id: register - if: '{{ not parameters.dryRun }}' - name: Register - action: catalog:register - input: - repoContentsUrl: '{{ steps.publish.output.repoContentsUrl }}' - catalogInfoPath: '/catalog-info.yaml' - - - name: Results - if: '{{ parameters.dryRun }}' - action: debug:log - input: - listWorkspace: true - - output: - links: - - title: Repository - url: '{{ steps.publish.output.remoteUrl }}' - - title: Open in catalog - icon: 'catalog' - entityRef: '{{ steps.register.output.entityRef }}' diff --git a/plugins/scaffolder-backend/sample-templates/v1beta2-demo/template/catalog-info.yaml b/plugins/scaffolder-backend/sample-templates/v1beta2-demo/template/catalog-info.yaml deleted file mode 100644 index 02da577b39..0000000000 --- a/plugins/scaffolder-backend/sample-templates/v1beta2-demo/template/catalog-info.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: {{cookiecutter.name | jsonify}} - github.com/project-slug: {{cookiecutter.destination.owner + "/" + cookiecutter.destination.repo}} -spec: - type: website - lifecycle: experimental - owner: {{cookiecutter.owner | jsonify}} -{%- if 'system' in cookiecutter %} - system: {{ cookiecutter.system | jsonify }} -{%- endif %} From 618143c3c78c8cdd9a3e1b19c9ed7681b21b98b2 Mon Sep 17 00:00:00 2001 From: Himanshu Mishra Date: Thu, 12 Aug 2021 08:07:55 +0200 Subject: [PATCH 002/125] scaffolder-backend: changeset about removing sample-templates Signed-off-by: Himanshu Mishra --- .changeset/cuddly-rabbits-look.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cuddly-rabbits-look.md diff --git a/.changeset/cuddly-rabbits-look.md b/.changeset/cuddly-rabbits-look.md new file mode 100644 index 0000000000..421c97bbff --- /dev/null +++ b/.changeset/cuddly-rabbits-look.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Action needed: If you are using the templates located at https://github.com/backstage/backstage/tree/master/ in your Backstage app directly using the URL via the `app-config.yaml`, you should copy over the templates inside your org and import from there. The templates have now been moved to https://github.com/backstage/software-templates. See https://github.com/backstage/backstage/issues/6415 for explanation. From 19f45179a535aa07a961417a1e4bd0832b7c22de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 31 Aug 2021 16:33:17 +0200 Subject: [PATCH 003/125] Bump `passport-saml` to version 3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/fast-actors-grow.md | 16 ++++ app-config.yaml | 1 + plugins/auth-backend/config.d.ts | 2 +- plugins/auth-backend/package.json | 4 +- .../src/providers/saml/provider.ts | 15 +--- yarn.lock | 78 ++++++++----------- 6 files changed, 56 insertions(+), 60 deletions(-) create mode 100644 .changeset/fast-actors-grow.md diff --git a/.changeset/fast-actors-grow.md b/.changeset/fast-actors-grow.md new file mode 100644 index 0000000000..c1da84f744 --- /dev/null +++ b/.changeset/fast-actors-grow.md @@ -0,0 +1,16 @@ +--- +'@backstage/plugin-auth-backend': minor +--- + +Bump `passport-saml` to version 3. This is a breaking change, in that it [now requires](https://github.com/node-saml/passport-saml/pull/548) the `auth.saml.cert` parameter to be set. If you are not using SAML auth, you can ignore this. + +To update your settings, add something similar to the following to your app-config: + +```yaml +auth: + saml: + # ... other settings ... + cert: 'MIICizCCAfQCCQCY8tKaMc0BMjANBgkqh ... W==' +``` + +For more information, see the [library README](https://github.com/node-saml/passport-saml#security-and-signatures). diff --git a/app-config.yaml b/app-config.yaml index 9f365becef..5eef872cab 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -309,6 +309,7 @@ auth: saml: entryPoint: 'http://localhost:7001/' issuer: 'passport-saml' + cert: 'fake-cert-base64' okta: development: clientId: ${AUTH_OKTA_CLIENT_ID} diff --git a/plugins/auth-backend/config.d.ts b/plugins/auth-backend/config.d.ts index e3d626a9df..e1f927dd24 100644 --- a/plugins/auth-backend/config.d.ts +++ b/plugins/auth-backend/config.d.ts @@ -48,7 +48,7 @@ export interface Config { entryPoint: string; logoutUrl?: string; issuer: string; - cert?: string; + cert: string; privateKey?: string; decryptionPvk?: string; signatureAlgorithm?: 'sha256' | 'sha512'; diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index badaafb61c..c037d75f4d 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -64,7 +64,7 @@ "passport-oauth2": "^1.5.0", "passport-okta-oauth": "^0.0.1", "passport-onelogin-oauth": "^0.0.1", - "passport-saml": "^2.0.0", + "passport-saml": "^3.1.2", "uuid": "^8.0.0", "winston": "^3.2.1", "yn": "^4.0.0" @@ -78,7 +78,7 @@ "@types/passport-github2": "^1.2.4", "@types/passport-google-oauth20": "^2.0.3", "@types/passport-microsoft": "^0.0.0", - "@types/passport-saml": "^1.1.2", + "@types/passport-saml": "^1.1.3", "@types/passport-strategy": "^0.2.35", "@types/xml2js": "^0.4.7", "msw": "^0.29.0" diff --git a/plugins/auth-backend/src/providers/saml/provider.ts b/plugins/auth-backend/src/providers/saml/provider.ts index 5b95634414..21e6c9080d 100644 --- a/plugins/auth-backend/src/providers/saml/provider.ts +++ b/plugins/auth-backend/src/providers/saml/provider.ts @@ -119,13 +119,13 @@ export type SamlProviderOptions = {}; export const createSamlProvider = ( _options?: SamlProviderOptions, ): AuthProviderFactory => { - return ({ providerId, globalConfig, config, tokenIssuer, logger }) => { + return ({ providerId, globalConfig, config, tokenIssuer }) => { const opts = { callbackUrl: `${globalConfig.baseUrl}/${providerId}/handler/frame`, entryPoint: config.getString('entryPoint'), logoutUrl: config.getOptionalString('logoutUrl'), issuer: config.getString('issuer'), - cert: config.getOptionalString('cert'), + cert: config.getString('cert'), privateCert: config.getOptionalString('privateKey'), decryptionPvk: config.getOptionalString('decryptionPvk'), signatureAlgorithm: config.getOptionalString('signatureAlgorithm') as @@ -138,17 +138,6 @@ export const createSamlProvider = ( appUrl: globalConfig.appUrl, }; - // passport-saml will return an error if the `cert` key is set, and the value is empty. - // Since we read from config (such as environment variables) an empty string should be equal to being unset. - if (!opts.cert) { - logger.warn( - 'SamlAuthProvider was initialized without a cert configuration parameter. ' + - 'This will soon be required by the underlying passport-saml library, which may soon lead to failures to start the auth backend. ' + - 'Please add an "auth.saml.cert" config parameter.', - ); - delete opts.cert; - } - return new SamlAuthProvider(opts); }; }; diff --git a/yarn.lock b/yarn.lock index e643ac9750..e97c9cb789 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6999,10 +6999,10 @@ "@types/oauth" "*" "@types/passport" "*" -"@types/passport-saml@^1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@types/passport-saml/-/passport-saml-1.1.2.tgz#f32ac2321eb25ec7bdbb1f3a5313b596bb0887e6" - integrity sha512-vpSdcb7V/bFxrvZJwSqnBr0qEqIhtOnwRBxw+Dvq4UkVbEgcCOkxF4tERCCFfA+FP3lp63VCCAifZLQrF5JkXA== +"@types/passport-saml@^1.1.3": + version "1.1.3" + resolved "https://registry.npmjs.org/@types/passport-saml/-/passport-saml-1.1.3.tgz#efc57902a07ebe1ec114d00acd8d990e873813a1" + integrity sha512-4kqfyTN6Ud8xTPIdmsYDOBVs4vQFQRcLWhMcGLYiMBc0sFeC44k0Q8Z8v1TIYTmZUrqaO6rbf78GZXl4xAvCRA== dependencies: "@types/express" "*" "@types/passport" "*" @@ -7888,6 +7888,11 @@ dependencies: tslib "^1.9.3" +"@xmldom/xmldom@^0.7.0", "@xmldom/xmldom@^0.7.2": + version "0.7.3" + resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.3.tgz#55de695f77afd3cc0e5bee0aa900040bc63c0f63" + integrity sha512-8XmJdPut2XGtfFcsNsqEsvMUmAwk7xLq7m+E/GcsU9b5qyFFIsiX4Fvnb5UoQ4wo12Wlm07YFJERoyWUYdbIpw== + "@xobotyi/scrollbar-width@^1.9.5": version "1.9.5" resolved "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz#80224a6919272f405b87913ca13b92929bdf3c4d" @@ -20800,20 +20805,20 @@ passport-onelogin-oauth@^0.0.1: pkginfo "0.2.x" uid2 "0.0.3" -passport-saml@^2.0.0: - version "2.0.5" - resolved "https://registry.npmjs.org/passport-saml/-/passport-saml-2.0.5.tgz#d822225875d0ec640236bf27ad8d5d9436396dea" - integrity sha512-D9OkTZ2hgRHZZFU3BUPKz7PC/khu9jmJtGCoJOQcn8JKR+AW9H/aj1E32VPu/iQbYMXXxEEt4qMhkCZzK9trzw== +passport-saml@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/passport-saml/-/passport-saml-3.1.2.tgz#34a0c2c423d729ce102e69fea9c22040910e6d43" + integrity sha512-EhD3/ofiz1vu7R72i4RskXk/dQG9GyDmXPdHJf5LYB+93B5kvKv5p+5lpZgO3z+Wf3eN0h/tGdGd6noyYdjY6g== dependencies: + "@xmldom/xmldom" "^0.7.2" debug "^4.3.1" - passport-strategy "*" - xml-crypto "^2.0.0" - xml-encryption "1.2.1" + passport-strategy "^1.0.0" + xml-crypto "^2.1.3" + xml-encryption "^1.3.0" xml2js "^0.4.23" xmlbuilder "^15.1.1" - xmldom "0.4.x" -passport-strategy@*, passport-strategy@1.x.x: +passport-strategy@1.x.x, passport-strategy@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= @@ -27527,23 +27532,23 @@ xml-but-prettier@^1.0.1: dependencies: repeat-string "^1.5.2" -xml-crypto@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.0.0.tgz#54cd268ad9d31930afcf7092cbb664258ca9e826" - integrity sha512-/a04qr7RpONRZHOxROZ6iIHItdsQQjN3sj8lJkYDDss8tAkEaAs0VrFjb3tlhmS5snQru5lTs9/5ISSMdPDHlg== +xml-crypto@^2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.1.3.tgz#6a7272b610ea3e4ea7f13e9e4876f1b20cbc32c8" + integrity sha512-MpXZwnn9JK0mNPZ5mnFIbNnQa+8lMGK4NtnX2FlJMfMWR60sJdFO9X72yO6ji068pxixzk53O7x0/iSKh6IhyQ== dependencies: - xmldom "0.1.27" - xpath "0.0.27" + "@xmldom/xmldom" "^0.7.0" + xpath "0.0.32" -xml-encryption@1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/xml-encryption/-/xml-encryption-1.2.1.tgz#e6d18817c4309fd07ca7793cca93c3fd06745baa" - integrity sha512-hn5w3l5p2+nGjlmM0CAhMChDzVGhW+M37jH35Z+GJIipXbn9PUlAIRZ6I5Wm7ynlqZjFrMAr83d/CIp9VZJMTA== +xml-encryption@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/xml-encryption/-/xml-encryption-1.3.0.tgz#4cad44a59bf8bdec76d7865ce0b89e13c09962f4" + integrity sha512-3P8C4egMMxSR1BmsRM+fG16a3WzOuUEQKS2U4c3AZ5v7OseIfdUeVkD8dwxIhuLryFZSRWUL5OP6oqkgU7hguA== dependencies: + "@xmldom/xmldom" "^0.7.0" escape-html "^1.0.3" node-forge "^0.10.0" - xmldom "~0.1.15" - xpath "0.0.27" + xpath "0.0.32" xml-name-validator@^3.0.0: version "3.0.0" @@ -27586,30 +27591,15 @@ xmlchars@^2.2.0: resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xmldom@0.1.27: - version "0.1.27" - resolved "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" - integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= - -xmldom@0.4.x: - version "0.4.0" - resolved "https://registry.npmjs.org/xmldom/-/xmldom-0.4.0.tgz#8771e482a333af44587e30ce026f0998c23f3830" - integrity sha512-2E93k08T30Ugs+34HBSTQLVtpi6mCddaY8uO+pMNk1pqSjV5vElzn4mmh6KLxN3hki8rNcHSYzILoh3TEWORvA== - xmldom@^0.6.0: version "0.6.0" resolved "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz#43a96ecb8beece991cef382c08397d82d4d0c46f" integrity sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg== -xmldom@~0.1.15: - version "0.1.31" - resolved "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz#b76c9a1bd9f0a9737e5a72dc37231cf38375e2ff" - integrity sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ== - -xpath@0.0.27: - version "0.0.27" - resolved "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz#dd3421fbdcc5646ac32c48531b4d7e9d0c2cfa92" - integrity sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ== +xpath@0.0.32: + version "0.0.32" + resolved "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz#1b73d3351af736e17ec078d6da4b8175405c48af" + integrity sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw== xss@^1.0.8: version "1.0.9" From 0a152c9377918a9324622c44b76881b923225c61 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Wed, 1 Sep 2021 07:54:10 -0500 Subject: [PATCH 004/125] Added the HomepageTimer to the new composable Home Page Signed-off-by: Andre Wanlin --- .changeset/late-mangos-allow.md | 5 +++++ .../home/src/components/HomepageCompositionRoot.tsx | 11 +++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 .changeset/late-mangos-allow.md diff --git a/.changeset/late-mangos-allow.md b/.changeset/late-mangos-allow.md new file mode 100644 index 0000000000..82a180c836 --- /dev/null +++ b/.changeset/late-mangos-allow.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-home': patch +--- + +Added the HomepageTimer to the new composable Home Page diff --git a/plugins/home/src/components/HomepageCompositionRoot.tsx b/plugins/home/src/components/HomepageCompositionRoot.tsx index 92232fb387..a6e4f482f8 100644 --- a/plugins/home/src/components/HomepageCompositionRoot.tsx +++ b/plugins/home/src/components/HomepageCompositionRoot.tsx @@ -16,7 +16,12 @@ import React, { ReactNode } from 'react'; import { useOutlet } from 'react-router'; -import { Content, Header, Page } from '@backstage/core-components'; +import { + Content, + Header, + Page, + HomepageTimer, +} from '@backstage/core-components'; export const HomepageCompositionRoot = (props: { title?: string; @@ -26,7 +31,9 @@ export const HomepageCompositionRoot = (props: { const children = props.children ?? outlet; return ( -
+
+ +
{children} ); From dbb952787885875a724c3c190b9a20753b2b4678 Mon Sep 17 00:00:00 2001 From: Dominik Henneke Date: Fri, 3 Sep 2021 10:41:10 +0200 Subject: [PATCH 005/125] Use `ScmIntegrationRegistry#resolveUrl` in the placeholder processors instead of a custom implementation Signed-off-by: Dominik Henneke --- .changeset/perfect-elephants-do.md | 21 +++++++++ .../processors/PlaceholderProcessor.test.ts | 16 +++++++ .../processors/PlaceholderProcessor.ts | 45 +++++++++++-------- .../src/next/NextCatalogBuilder.ts | 6 ++- .../src/service/CatalogBuilder.ts | 6 ++- 5 files changed, 73 insertions(+), 21 deletions(-) create mode 100644 .changeset/perfect-elephants-do.md diff --git a/.changeset/perfect-elephants-do.md b/.changeset/perfect-elephants-do.md new file mode 100644 index 0000000000..d5e4c864d7 --- /dev/null +++ b/.changeset/perfect-elephants-do.md @@ -0,0 +1,21 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Use `ScmIntegrationRegistry#resolveUrl` in the placeholder processors instead of a custom implementation. + +If you manually instantiate the `PlaceholderProcessor` (you most probably don't), add the new required constructor parameter: + +```diff ++ import { ScmIntegrations } from '@backstage/integration'; + // ... ++ const integrations = ScmIntegrations.fromConfig(config); + // ... + new PlaceholderProcessor({ + resolvers: placeholderResolvers, + reader, ++ integrations, + }); +``` + +All custom `PlaceholderResolver` can use the new `resolveUrl` parameter to resolve relative URLs. diff --git a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts index 0254e854e5..3abf051e4e 100644 --- a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts +++ b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts @@ -15,6 +15,8 @@ */ import { UrlReader } from '@backstage/backend-common'; import { Entity } from '@backstage/catalog-model'; +import { ConfigReader } from '@backstage/config'; +import { ScmIntegrations } from '@backstage/integration'; import { jsonPlaceholderResolver, PlaceholderProcessor, @@ -25,6 +27,8 @@ import { yamlPlaceholderResolver, } from './PlaceholderProcessor'; +const integrations = ScmIntegrations.fromConfig(new ConfigReader({})); + describe('PlaceholderProcessor', () => { const read: jest.MockedFunction = jest.fn(); const reader: UrlReader = { read, readTree: jest.fn(), search: jest.fn() }; @@ -44,6 +48,7 @@ describe('PlaceholderProcessor', () => { foo: async () => 'replaced', }, reader, + integrations, }); await expect( processor.preProcessEntity(input, { type: 't', target: 'l' }), @@ -59,6 +64,7 @@ describe('PlaceholderProcessor', () => { upper: upperResolver, }, reader, + integrations, }); await expect( @@ -95,6 +101,7 @@ describe('PlaceholderProcessor', () => { bar: jest.fn(), }, reader, + integrations, }); const entity: Entity = { apiVersion: 'a', @@ -115,6 +122,7 @@ describe('PlaceholderProcessor', () => { bar: jest.fn(), }, reader, + integrations, }); const entity: Entity = { apiVersion: 'a', @@ -134,6 +142,7 @@ describe('PlaceholderProcessor', () => { const processor = new PlaceholderProcessor({ resolvers: { text: textPlaceholderResolver }, reader, + integrations, }); await expect( @@ -169,6 +178,7 @@ describe('PlaceholderProcessor', () => { const processor = new PlaceholderProcessor({ resolvers: { json: jsonPlaceholderResolver }, reader, + integrations, }); await expect( @@ -202,6 +212,7 @@ describe('PlaceholderProcessor', () => { const processor = new PlaceholderProcessor({ resolvers: { yaml: yamlPlaceholderResolver }, reader, + integrations, }); await expect( @@ -235,6 +246,7 @@ describe('PlaceholderProcessor', () => { const processor = new PlaceholderProcessor({ resolvers: { text: textPlaceholderResolver }, reader, + integrations, }); await expect( @@ -272,6 +284,7 @@ describe('PlaceholderProcessor', () => { const processor = new PlaceholderProcessor({ resolvers: { text: textPlaceholderResolver }, reader, + integrations, }); await expect( @@ -311,6 +324,7 @@ describe('PlaceholderProcessor', () => { const processor = new PlaceholderProcessor({ resolvers: { text: textPlaceholderResolver }, reader, + integrations, }); await expect( @@ -345,6 +359,7 @@ describe('yamlPlaceholderResolver', () => { value: './file.yaml', baseUrl: 'https://github.com/backstage/backstage/a/b/catalog-info.yaml', read, + resolveUrl: (url, base) => integrations.resolveUrl({ url, base }), }; beforeEach(() => { @@ -389,6 +404,7 @@ describe('jsonPlaceholderResolver', () => { value: './file.json', baseUrl: 'https://github.com/backstage/backstage/a/b/catalog-info.yaml', read, + resolveUrl: (url, base) => integrations.resolveUrl({ url, base }), }; beforeEach(() => { diff --git a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts index 1b015d7d93..4456405857 100644 --- a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts +++ b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts @@ -17,16 +17,19 @@ import { UrlReader } from '@backstage/backend-common'; import { Entity, LocationSpec } from '@backstage/catalog-model'; import { JsonValue } from '@backstage/config'; +import { ScmIntegrationRegistry } from '@backstage/integration'; import yaml from 'yaml'; import { CatalogProcessor } from './types'; export type ResolverRead = (url: string) => Promise; +export type ResolverResolveUrl = (url: string, base: string) => string; export type ResolverParams = { key: string; value: JsonValue; baseUrl: string; read: ResolverRead; + resolveUrl: ResolverResolveUrl; }; export type PlaceholderResolver = ( @@ -36,6 +39,7 @@ export type PlaceholderResolver = ( type Options = { resolvers: Record; reader: UrlReader; + integrations: ScmIntegrationRegistry; }; /** @@ -103,12 +107,19 @@ export class PlaceholderProcessor implements CatalogProcessor { return this.options.reader.read(url); }; + const resolveUrl = (url: string, base: string): string => + this.options.integrations.resolveUrl({ + url, + base, + }); + return [ await resolver({ key: resolverKey, value: resolverValue, baseUrl: location.target, read, + resolveUrl, }), true, ]; @@ -191,31 +202,27 @@ async function readTextLocation(params: ResolverParams): Promise { } } -function relativeUrl({ key, value, baseUrl }: ResolverParams): string { +function relativeUrl({ + key, + value, + baseUrl, + resolveUrl, +}: ResolverParams): string { if (typeof value !== 'string') { throw new Error( `Placeholder \$${key} expected a string value parameter, in the form of an absolute URL or a relative path`, ); } - let url: URL; try { - // The two-value form of the URL constructor handles relative paths for us - url = new URL(value, baseUrl); - } catch { - try { - // Check whether value is a valid absolute URL on it's own, if not fail. - url = new URL(value); - } catch { - // The only remaining case that isn't support is a relative file path that should be - // resolved using a relative file location. Accessing local file paths can lead to - // path traversal attacks and access to any file on the host system. Implementing this - // would require additional security measures. - throw new Error( - `Placeholder \$${key} could not form a URL out of ${baseUrl} and ${value}`, - ); - } + return resolveUrl(value, baseUrl); + } catch (_) { + // The only remaining case that isn't support is a relative file path that should be + // resolved using a relative file location. Accessing local file paths can lead to + // path traversal attacks and access to any file on the host system. Implementing this + // would require additional security measures. + throw new Error( + `Placeholder \$${key} could not form a URL out of ${baseUrl} and ${value}`, + ); } - - return url.toString(); } diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index ed690d07b6..262df7525e 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -385,7 +385,11 @@ export class NextCatalogBuilder { // These are always there no matter what const processors: CatalogProcessor[] = [ - new PlaceholderProcessor({ resolvers: placeholderResolvers, reader }), + new PlaceholderProcessor({ + resolvers: placeholderResolvers, + reader, + integrations, + }), new BuiltinKindsEntityProcessor(), ]; diff --git a/plugins/catalog-backend/src/service/CatalogBuilder.ts b/plugins/catalog-backend/src/service/CatalogBuilder.ts index 70c1890fbf..e32e071ebc 100644 --- a/plugins/catalog-backend/src/service/CatalogBuilder.ts +++ b/plugins/catalog-backend/src/service/CatalogBuilder.ts @@ -306,7 +306,11 @@ export class CatalogBuilder { // These are always there no matter what const processors: CatalogProcessor[] = [ StaticLocationProcessor.fromConfig(config), - new PlaceholderProcessor({ resolvers: placeholderResolvers, reader }), + new PlaceholderProcessor({ + resolvers: placeholderResolvers, + reader, + integrations, + }), new BuiltinKindsEntityProcessor(), ]; From 49c3f2bbbbeacc798881141321f8e55fbe332286 Mon Sep 17 00:00:00 2001 From: hiba-aldalaty Date: Fri, 3 Sep 2021 09:57:03 +0100 Subject: [PATCH 006/125] Disable Create button in template after initial click Signed-off-by: hiba-aldalaty --- .changeset/sixty-carrots-marry.md | 5 +++++ .../MultistepJsonForm/MultistepJsonForm.tsx | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 .changeset/sixty-carrots-marry.md diff --git a/.changeset/sixty-carrots-marry.md b/.changeset/sixty-carrots-marry.md new file mode 100644 index 0000000000..414c41c645 --- /dev/null +++ b/.changeset/sixty-carrots-marry.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Disable 'Create' button in template after initial click to avoid confusion when there is slowness in template execution diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx b/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx index cdcc22da29..ef7e74f2f1 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx +++ b/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx @@ -112,6 +112,7 @@ export const MultistepJsonForm = ({ widgets, }: Props) => { const [activeStep, setActiveStep] = useState(0); + const [disableCreateButton, setDisableCreateButton] = useState(false); const handleReset = () => { setActiveStep(0); @@ -121,6 +122,10 @@ export const MultistepJsonForm = ({ setActiveStep(Math.min(activeStep + 1, steps.length)); }; const handleBack = () => setActiveStep(Math.max(activeStep - 1, 0)); + const handleCreate = () => { + setDisableCreateButton(true); + onFinish(); + }; return ( <> @@ -174,7 +179,12 @@ export const MultistepJsonForm = ({ - From 1c3dce1db800fc837fc78f36c02c71071a6aa54d Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Sat, 4 Sep 2021 14:16:17 -0500 Subject: [PATCH 007/125] Moved Header and Content to HomePage Signed-off-by: Andre Wanlin --- packages/app/src/App.tsx | 4 +- packages/app/src/components/home/HomePage.tsx | 103 ++++++++++-------- 2 files changed, 59 insertions(+), 48 deletions(-) diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 81dbdf4cac..244bc7aa2a 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -114,9 +114,7 @@ const routes = ( {/* TODO(rubenl): Move this to / once its more mature and components exist */} - }> - - + } /> } /> ( - - - - - - - - - - - ( - - ), - }, - { - label: 'Any', - Component: () => ( - - ), - }, - ]} - /> - - + +
+ +
+ + + + + + + + + + + + ( + + ), + }, + { + label: 'Any', + Component: () => ( + + ), + }, + ]} + /> + + + +
); From 3c1dd8e441059fbaccddc6be8dfb1ebc6f1e9883 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Mon, 6 Sep 2021 09:08:16 -0500 Subject: [PATCH 008/125] Keep using HomepageCompositionRoot Signed-off-by: Andre Wanlin --- packages/app/src/App.tsx | 4 +++- .../src/components/HomepageCompositionRoot.tsx | 15 +-------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 244bc7aa2a..81dbdf4cac 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -114,7 +114,9 @@ const routes = ( {/* TODO(rubenl): Move this to / once its more mature and components exist */} - } /> + }> + + } /> { const outlet = useOutlet(); const children = props.children ?? outlet; - return ( - -
- -
- {children} -
- ); + return
{children}
; }; From f6188773a50db441ca21cd3bdb3893f2d1c2a3d8 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Fri, 3 Sep 2021 16:20:54 +0200 Subject: [PATCH 009/125] search-type: add to storybook Signed-off-by: Vincenzo Scamporlino --- .../SearchType/SearchType.stories.tsx | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 plugins/search/src/components/SearchType/SearchType.stories.tsx diff --git a/plugins/search/src/components/SearchType/SearchType.stories.tsx b/plugins/search/src/components/SearchType/SearchType.stories.tsx new file mode 100644 index 0000000000..24a24fa4cb --- /dev/null +++ b/plugins/search/src/components/SearchType/SearchType.stories.tsx @@ -0,0 +1,44 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React, { useState } from 'react'; +import { MemoryRouter } from 'react-router'; + +import { SearchType } from '../index'; +import { SearchContext } from '../SearchContext'; + +export default { + title: 'Plugins/Search/SearchType', + component: SearchType, +}; + +const values = ['value-1', 'value-2', 'value-3']; + +export const Default = () => { + const [types, setTypes] = useState([]); + + return ( + + {/* @ts-ignore (value requires more than what is used here) */} + + + + + ); +}; From 93a21141f3c161a78309753ac24e5b4b4e849758 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 6 Sep 2021 19:19:48 +0200 Subject: [PATCH 010/125] add .snyk with an ignored vulnerability Signed-off-by: Patrik Oldsberg --- .snyk | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .snyk diff --git a/.snyk b/.snyk new file mode 100644 index 0000000000..732671517a --- /dev/null +++ b/.snyk @@ -0,0 +1,10 @@ +# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. +version: v1.22.1 +# ignores vulnerabilities until expiry date; change duration by modifying expiry date +ignore: + SNYK-JS-ANSIHTML-1296849: + - '@backstage/cli > webpack-dev-server > ansi-html': + reason: Developer tools are not a valid target for ReDoS attacks + expires: 2022-03-06T17:18:55.019Z + created: 2021-09-06T17:18:55.027Z +patch: {} From 7b59d3e395b1d2f665bff04a5bd9babc6c7174e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 6 Sep 2021 22:11:44 +0200 Subject: [PATCH 011/125] add some text about orphaning too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../software-catalog/life-of-an-entity.md | 57 ++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/docs/features/software-catalog/life-of-an-entity.md b/docs/features/software-catalog/life-of-an-entity.md index 3b7b3e8117..2cdf8761be 100644 --- a/docs/features/software-catalog/life-of-an-entity.md +++ b/docs/features/software-catalog/life-of-an-entity.md @@ -183,6 +183,59 @@ The stitching is currently a fixed process, that cannot be modified or extended. This means that any modifications you want to make on the final result, has to happen during ingestion or processing. -## Deletion +## Orphaning -> TODO +As mentioned earlier, entities internally form a graph. The edges go from +processed parent entities, to child entities emitted while processing the +parent. + +The processing loop runs continuously, so these edges are reconsidered over +time. If processing a parent entity no longer emits a given child entity, then +that former edge is severed. If that child has no other edges pointing at it +either, it becomes _orphaned_. The end result is as follows: + +- The stitching process injects a `backstage.io/orphan: 'true'` annotation on + the child entity. +- The child entity is _not_ removed from the catalog, but stays around until + explicitly deleted via the catalog API, or "reclaimed" by the original parent + or another parent starting to reference it. +- The child entity stops being subjected to regular processing, frozen in time. +- The catalog page in Backstage for the child entity detects the new annotation + and informs users about the orphan status. + +Orphaning can occur in several different scenarios. One common cause is that the +end user edited a corresponding catalog catalog-info YAML file removing the +entity's entry, or in the case of a `Location` entity, removed the target row +pointing to the file containing the file. Another common cause is large batch +processors such as the ones that crawl through remote systems looking for +entities, no longer finding something that it used to find before. Maybe the +data was moved, or deleted, in the remote system. So for example when a person +leaves the company an LDAP org discovery processor might leave an orphaned +`User` entity behind. + +> Note that removing a file, or accidentally corrupting a file so that it cannot +> be read successfully, does _not_ lead to orphaning. Hard errors, including the +> inability to find or read a distinct remote, are marked as such on the entity +> to inform the owner that something is wrong. But processing and other +> behaviors continue as usual. + +The reason that the orphaning mechanism exists instead of having an eager +deletion triggered, is safety. Scenarios like these can happen purely by +accident, due to the asynchronous nature of the system and the fallible nature +of humans. In particular when external systems start consuming and relying on +the catalog, the consequences of suddenly dropping entities without your +explicit owner consent could be substantial. The catalog therefore takes the +stance that entities that often were added by direct user action should also be +deleted only by direct user action. + +It is possible to build automated "reaper" systems that finally delete entities +that are orphaned by using the catalog API. This is however not something that's +provided out of the box. + +## Implicit Deletion + +> TODO: Describe the process of entity providers eagerly deleting entities + +## Explicit Deletion + +> TODO: Describe direct deletion via the catalog API From fd799ceb9b96142058e3b1c41fe103aa930d0029 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Sep 2021 04:12:04 +0000 Subject: [PATCH 012/125] chore(deps-dev): bump @types/color from 3.0.1 to 3.0.2 Bumps [@types/color](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/color) from 3.0.1 to 3.0.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/color) --- updated-dependencies: - dependency-name: "@types/color" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c7c260e1bf..5db9fd7589 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6353,9 +6353,9 @@ integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== "@types/color@^3.0.1": - version "3.0.1" - resolved "https://registry.npmjs.org/@types/color/-/color-3.0.1.tgz#2900490ed04da8116c5058cd5dba3572d5a25071" - integrity sha512-oeUWVaAwI+xINDUx+3F2vJkl/vVB03VChFF/Gl3iQCdbcakjuoJyMOba+3BXRtnBhxZ7uBYqQBi9EpLnvSoztA== + version "3.0.2" + resolved "https://registry.npmjs.org/@types/color/-/color-3.0.2.tgz#3779043e782f562aa9157b5fc6bd07e14fd8e7f3" + integrity sha512-INiJl6sfNn8iyC5paxVzqiVUEj2boIlFki02uRTAkKwAj++7aAF+ZfEv/XrIeBa0XI/fTZuDHW8rEEcEVnON+Q== dependencies: "@types/color-convert" "*" From 24f8baabafc7ece537507bc627fadbcf9b962162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 7 Sep 2021 10:57:58 +0200 Subject: [PATCH 013/125] address comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../software-catalog/life-of-an-entity.md | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/docs/features/software-catalog/life-of-an-entity.md b/docs/features/software-catalog/life-of-an-entity.md index 2cdf8761be..9e8a3f0563 100644 --- a/docs/features/software-catalog/life-of-an-entity.md +++ b/docs/features/software-catalog/life-of-an-entity.md @@ -183,6 +183,10 @@ The stitching is currently a fixed process, that cannot be modified or extended. This means that any modifications you want to make on the final result, has to happen during ingestion or processing. +## Errors + +> TODO: Describe how errors are exposed through entities + ## Orphaning As mentioned earlier, entities internally form a graph. The edges go from @@ -199,19 +203,20 @@ either, it becomes _orphaned_. The end result is as follows: - The child entity is _not_ removed from the catalog, but stays around until explicitly deleted via the catalog API, or "reclaimed" by the original parent or another parent starting to reference it. -- The child entity stops being subjected to regular processing, frozen in time. - The catalog page in Backstage for the child entity detects the new annotation and informs users about the orphan status. Orphaning can occur in several different scenarios. One common cause is that the end user edited a corresponding catalog catalog-info YAML file removing the -entity's entry, or in the case of a `Location` entity, removed the target row -pointing to the file containing the file. Another common cause is large batch -processors such as the ones that crawl through remote systems looking for -entities, no longer finding something that it used to find before. Maybe the -data was moved, or deleted, in the remote system. So for example when a person -leaves the company an LDAP org discovery processor might leave an orphaned -`User` entity behind. +entity's entry. In the case of a `Location` parent entity, orphaning can happen +if removing the target line pointing to the file containing the child entity. +Another common cause is large batch processors such as the ones that crawl +through remote systems looking for entities, no longer finding something that it +used to find before. Maybe the data was moved, or deleted, in the remote system. +So for example when a person leaves the company an LDAP org discovery processor +might leave an orphaned `User` entity behind. Note that this only applies to +processors - ingestion that happens using entity providers work differently, +described below. > Note that removing a file, or accidentally corrupting a file so that it cannot > be read successfully, does _not_ lead to orphaning. Hard errors, including the @@ -223,13 +228,13 @@ The reason that the orphaning mechanism exists instead of having an eager deletion triggered, is safety. Scenarios like these can happen purely by accident, due to the asynchronous nature of the system and the fallible nature of humans. In particular when external systems start consuming and relying on -the catalog, the consequences of suddenly dropping entities without your -explicit owner consent could be substantial. The catalog therefore takes the -stance that entities that often were added by direct user action should also be -deleted only by direct user action. +the catalog, there could be substantial consequences to suddenly dropping +entities without explicit owner consent. The catalog therefore takes the stance +that entities that often were added by direct user action should also be deleted +only by direct user action. -It is possible to build automated "reaper" systems that finally delete entities -that are orphaned by using the catalog API. This is however not something that's +It is possible to use the catalog API to build automated "reaper" systems that +finally delete entities that are orphaned. This is however not something that's provided out of the box. ## Implicit Deletion From 0cb28c22e30eb6bce66520149a5b5fb86d98ad92 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 7 Sep 2021 11:55:14 +0200 Subject: [PATCH 014/125] feat: when reading from AzureDevOps strip the root directory as that is how the ZipArchive is returned Signed-off-by: blam --- .../writing-custom-field-extensions.md | 34 ++++++++++++++++ .../src/reading/AzureUrlReader.ts | 1 + .../reading/tree/ReadTreeResponseFactory.ts | 1 + packages/backend-common/src/reading/types.ts | 3 ++ .../src/test-integrations.ts | 40 +++++++++++++++++++ 5 files changed, 79 insertions(+) create mode 100644 docs/features/software-templates/writing-custom-field-extensions.md create mode 100644 plugins/scaffolder-backend/src/test-integrations.ts diff --git a/docs/features/software-templates/writing-custom-field-extensions.md b/docs/features/software-templates/writing-custom-field-extensions.md new file mode 100644 index 0000000000..e32aa4e78d --- /dev/null +++ b/docs/features/software-templates/writing-custom-field-extensions.md @@ -0,0 +1,34 @@ +--- +id: writing-custom-field-extensions +title: Writing Custom Field Extensions +description: How to write your own field extensions +--- + +Collecting input from the user is a very large part of the scaffolding process +and Software Templates as a whole. Sometimes the built in components and fields +just aren't good enough, and sometimes you want to enrich the form that the +users sees with better inputs that fit better. + +This is where `Custom Field Extensions` come in. + +With them you can show your own `React` Components and use them to control the +state of the JSON schema, as well as provide your own validation functions to +validate the data too. + +## Creating a Field Extension + +Field extensions are a way to combine an ID, a `React` Component and a +`validation` function together in a modular way that you can then use to pass to +the `Scaffolder` frontend plugin in your own `App.tsx`. + +You can create your own Field Extension by using the +`createScaffolderFieldExtension` `API` like below: + +```tsx +//packages/app/scaffolder/MyCustomExtension/MyCustomExtension.tsx +export const MyCustomExtension = () => {}; +``` + +```tsx +// packages/app/scaffolder/MyCustomExtension/validation.ts +``` diff --git a/packages/backend-common/src/reading/AzureUrlReader.ts b/packages/backend-common/src/reading/AzureUrlReader.ts index 910e8e04a5..5369306702 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.ts @@ -133,6 +133,7 @@ export class AzureUrlReader implements UrlReader { stream: archiveAzureResponse.body as unknown as Readable, etag: commitSha, filter: options?.filter, + stripFirstDirectory: true, }); } diff --git a/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts b/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts index 5fdd633102..70d8f63af8 100644 --- a/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts +++ b/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts @@ -55,6 +55,7 @@ export class DefaultReadTreeResponseFactory implements ReadTreeResponseFactory { this.workDir, options.etag, options.filter, + options.stripFirstDirectory, ); } } diff --git a/packages/backend-common/src/reading/types.ts b/packages/backend-common/src/reading/types.ts index b7e1ff823f..2d9c305b85 100644 --- a/packages/backend-common/src/reading/types.ts +++ b/packages/backend-common/src/reading/types.ts @@ -182,6 +182,9 @@ export type ReadTreeResponseFactoryOptions = { etag: string; // Filter passed on from the ReadTreeOptions filter?: (path: string, info?: { size: number }) => boolean; + + // Strip the first directory in the readTree response + stripFirstDirectory?: boolean; }; /** @public */ diff --git a/plugins/scaffolder-backend/src/test-integrations.ts b/plugins/scaffolder-backend/src/test-integrations.ts new file mode 100644 index 0000000000..65d84768aa --- /dev/null +++ b/plugins/scaffolder-backend/src/test-integrations.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + loadBackendConfig, + getRootLogger, + UrlReaders, +} from '@backstage/backend-common'; +// import { ScmIntegrations } from '@backstage/integration'; + +const run = async () => { + const root = getRootLogger(); + const config = await loadBackendConfig({ + argv: process.argv, + logger: root, + }); + + // const integrations = ScmIntegrations.fromConfig(config); + const reader = UrlReaders.default({ logger: root, config }); + + console.log( + await reader.readTree( + 'https://dev.azure.com/backstage-verification/test-template-fetch/_git/test-template-fetch', + ), + ); +}; + +run(); From e86adc689210c7cabdc73d90306797e71d2d680d Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 7 Sep 2021 12:00:33 +0200 Subject: [PATCH 015/125] chore: remove unwanted files Signed-off-by: blam --- .../writing-custom-field-extensions.md | 34 ---------------- .../src/test-integrations.ts | 40 ------------------- 2 files changed, 74 deletions(-) delete mode 100644 docs/features/software-templates/writing-custom-field-extensions.md delete mode 100644 plugins/scaffolder-backend/src/test-integrations.ts diff --git a/docs/features/software-templates/writing-custom-field-extensions.md b/docs/features/software-templates/writing-custom-field-extensions.md deleted file mode 100644 index e32aa4e78d..0000000000 --- a/docs/features/software-templates/writing-custom-field-extensions.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -id: writing-custom-field-extensions -title: Writing Custom Field Extensions -description: How to write your own field extensions ---- - -Collecting input from the user is a very large part of the scaffolding process -and Software Templates as a whole. Sometimes the built in components and fields -just aren't good enough, and sometimes you want to enrich the form that the -users sees with better inputs that fit better. - -This is where `Custom Field Extensions` come in. - -With them you can show your own `React` Components and use them to control the -state of the JSON schema, as well as provide your own validation functions to -validate the data too. - -## Creating a Field Extension - -Field extensions are a way to combine an ID, a `React` Component and a -`validation` function together in a modular way that you can then use to pass to -the `Scaffolder` frontend plugin in your own `App.tsx`. - -You can create your own Field Extension by using the -`createScaffolderFieldExtension` `API` like below: - -```tsx -//packages/app/scaffolder/MyCustomExtension/MyCustomExtension.tsx -export const MyCustomExtension = () => {}; -``` - -```tsx -// packages/app/scaffolder/MyCustomExtension/validation.ts -``` diff --git a/plugins/scaffolder-backend/src/test-integrations.ts b/plugins/scaffolder-backend/src/test-integrations.ts deleted file mode 100644 index 65d84768aa..0000000000 --- a/plugins/scaffolder-backend/src/test-integrations.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { - loadBackendConfig, - getRootLogger, - UrlReaders, -} from '@backstage/backend-common'; -// import { ScmIntegrations } from '@backstage/integration'; - -const run = async () => { - const root = getRootLogger(); - const config = await loadBackendConfig({ - argv: process.argv, - logger: root, - }); - - // const integrations = ScmIntegrations.fromConfig(config); - const reader = UrlReaders.default({ logger: root, config }); - - console.log( - await reader.readTree( - 'https://dev.azure.com/backstage-verification/test-template-fetch/_git/test-template-fetch', - ), - ); -}; - -run(); From 6ad8fe1a0adf22eb7b64c82322518b61d6aacb0b Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Tue, 7 Sep 2021 15:08:31 +0200 Subject: [PATCH 016/125] Make ownership card style customizable via custom `theme.getPageTheme()` Signed-off-by: Oliver Sand --- .changeset/lucky-lies-count.md | 5 +++++ .../Cards/OwnershipCard/OwnershipCard.tsx | 14 ++------------ 2 files changed, 7 insertions(+), 12 deletions(-) create mode 100644 .changeset/lucky-lies-count.md diff --git a/.changeset/lucky-lies-count.md b/.changeset/lucky-lies-count.md new file mode 100644 index 0000000000..79e7c09391 --- /dev/null +++ b/.changeset/lucky-lies-count.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-org': patch +--- + +Make ownership card style customizable via custom `theme.getPageTheme()`. diff --git a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx index da7f8381e3..cc0a379ff9 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx +++ b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx @@ -29,7 +29,7 @@ import { isOwnerOf, useEntity, } from '@backstage/plugin-catalog-react'; -import { BackstageTheme, genPageTheme } from '@backstage/theme'; +import { BackstageTheme } from '@backstage/theme'; import { Box, createStyles, @@ -49,16 +49,6 @@ type EntityTypeProps = { count: number; }; -const createPageTheme = ( - theme: BackstageTheme, - shapeKey: string, - colorsKey: string, -) => { - const { colors } = theme.getPageTheme({ themeId: colorsKey }); - const { shape } = theme.getPageTheme({ themeId: shapeKey }); - return genPageTheme(colors, shape).backgroundImage; -}; - const useStyles = makeStyles((theme: BackstageTheme) => createStyles({ card: { @@ -77,7 +67,7 @@ const useStyles = makeStyles((theme: BackstageTheme) => }, entityTypeBox: { background: (props: { type: string }) => - createPageTheme(theme, props.type, props.type), + theme.getPageTheme({ themeId: props.type }).backgroundImage, }, }), ); From 70718686f1a6336072bbd43c1a60cdf7fdf2cad2 Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Tue, 7 Sep 2021 16:17:52 +0200 Subject: [PATCH 017/125] Use correct `Link` in ownership card to avoid a full reload of the app while navigating Signed-off-by: Oliver Sand --- .changeset/sour-bees-pretend.md | 5 +++++ .../src/components/Cards/OwnershipCard/OwnershipCard.tsx | 7 +++---- 2 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 .changeset/sour-bees-pretend.md diff --git a/.changeset/sour-bees-pretend.md b/.changeset/sour-bees-pretend.md new file mode 100644 index 0000000000..748266132c --- /dev/null +++ b/.changeset/sour-bees-pretend.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-org': patch +--- + +Use correct `Link` in ownership card to avoid a full reload of the app while navigating. diff --git a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx index cc0a379ff9..96e7d08c31 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx +++ b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx @@ -18,6 +18,7 @@ import { Entity } from '@backstage/catalog-model'; import { InfoCard, InfoCardVariants, + Link, Progress, ResponseErrorPanel, } from '@backstage/core-components'; @@ -34,13 +35,11 @@ import { Box, createStyles, Grid, - Link, makeStyles, Typography, } from '@material-ui/core'; import qs from 'qs'; import React from 'react'; -import { generatePath } from 'react-router'; import { useAsync } from 'react-use'; type EntityTypeProps = { @@ -86,7 +85,7 @@ const EntityCountTile = ({ const classes = useStyles({ type }); return ( - + ))} From 3d238b028312ae9e56aa46f06ebb78928a8bb07c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 7 Sep 2021 19:41:43 +0200 Subject: [PATCH 018/125] core-plugin-api: switch to using a plain string key for attaching component data Signed-off-by: Patrik Oldsberg --- .changeset/wicked-files-brush.md | 5 ++ .../src/extensions/componentData.test.tsx | 49 ++++++++++++++++++- .../src/extensions/componentData.tsx | 32 +++++++++--- 3 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 .changeset/wicked-files-brush.md diff --git a/.changeset/wicked-files-brush.md b/.changeset/wicked-files-brush.md new file mode 100644 index 0000000000..c4391ba4dd --- /dev/null +++ b/.changeset/wicked-files-brush.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-plugin-api': patch +--- + +Migrated component data attachment method to have better compatibility with component proxies such as `react-hot-loader`. diff --git a/packages/core-plugin-api/src/extensions/componentData.test.tsx b/packages/core-plugin-api/src/extensions/componentData.test.tsx index 49a1d59cc4..6f2694a512 100644 --- a/packages/core-plugin-api/src/extensions/componentData.test.tsx +++ b/packages/core-plugin-api/src/extensions/componentData.test.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { attachComponentData, getComponentData } from './componentData'; -describe('elementData', () => { +describe('componentData', () => { it('should attach a single piece of data', () => { const data = { foo: 'bar' }; const Component = () => null; @@ -59,4 +59,51 @@ describe('elementData', () => { 'Attempted to attach duplicate data "my-data" to component "MyComponent"', ); }); + + describe('works across versions', () => { + it('should should be able to get data from newer versions', () => { + const data = { foo: 'bar' }; + const Component = () => null; + attachComponentData(Component, 'my-data', data); + + const element = ; + expect((element as any).type.__backstage_data.map.get('my-data')).toBe( + data, + ); + }); + + it('should should be able to attach data for newer versions', () => { + const data = { foo: 'bar' }; + const Component = () => null; + (Component as any).__backstage_data = { + map: new Map([['my-data', data]]), + }; + + const element = ; + expect(getComponentData(element, 'my-data')).toBe(data); + }); + + it('should be able to get data from older versions', () => { + const data = { foo: 'bar' }; + const Component = () => null; + attachComponentData(Component, 'my-data', data); + + const element = ; + const container = (global as any)[ + '__@backstage/component-data-store__' + ].get(element.type); + expect(container.map.get('my-data')).toBe(data); + }); + + it('should should be able to attach data for older versions', () => { + const data = { foo: 'bar' }; + const Component = () => null; + (global as any)['__@backstage/component-data-store__'].set(Component, { + map: new Map([['my-data', data]]), + }); + + const element = ; + expect(getComponentData(element, 'my-data')).toBe(data); + }); + }); }); diff --git a/packages/core-plugin-api/src/extensions/componentData.tsx b/packages/core-plugin-api/src/extensions/componentData.tsx index 85527950ab..d28d17d8ca 100644 --- a/packages/core-plugin-api/src/extensions/componentData.tsx +++ b/packages/core-plugin-api/src/extensions/componentData.tsx @@ -21,24 +21,42 @@ type DataContainer = { map: Map; }; -type MaybeComponentNode = ReactNode & { - type?: ComponentType; -}; - -// The store is bridged across versions using the global object +// This method of storing the component data was deprecated in September 2021, it +// will be removed in the future for the reasons described below. const globalStore = getOrCreateGlobalSingleton( 'component-data-store', () => new WeakMap, DataContainer>(), ); +// This key is used to attach component data to the component type (function or class) +// itself. This method is used because it has better compatibility component wrappers +// like react-hot-loader, as opposed to the WeakMap method or using a symbol. +const componentDataKey = '__backstage_data'; + +type ComponentWithData = ComponentType & { + [componentDataKey]?: DataContainer; +}; + +type MaybeComponentNode = ReactNode & { + type?: ComponentWithData; +}; + export function attachComponentData

( component: ComponentType

, type: string, data: unknown, ) { - let container = globalStore.get(component); + const dataComponent = component as ComponentWithData; + + let container = dataComponent[componentDataKey] ?? globalStore.get(component); if (!container) { container = { map: new Map() }; + Object.defineProperty(dataComponent, componentDataKey, { + enumerable: false, + configurable: true, + writable: false, + value: container, + }); globalStore.set(component, container); } @@ -65,7 +83,7 @@ export function getComponentData( return undefined; } - const container = globalStore.get(component); + const container = component[componentDataKey] ?? globalStore.get(component); if (!container) { return undefined; } From 841666a19b9a467024395c73828c50a4ab75bff0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 7 Sep 2021 19:47:20 +0200 Subject: [PATCH 019/125] core-app-api: removed deprecated internal functions Signed-off-by: Patrik Oldsberg --- .changeset/tall-beds-bake.md | 5 + .../src/extensions/componentData.test.tsx | 118 ------------------ .../src/extensions/componentData.tsx | 84 ------------- .../src/extensions/extensions.tsx | 54 -------- packages/core-app-api/src/extensions/index.ts | 22 ---- .../core-app-api/src/plugins/collectors.ts | 3 +- .../src/routing/collectors.test.tsx | 2 +- .../core-app-api/src/routing/collectors.tsx | 3 +- 8 files changed, 8 insertions(+), 283 deletions(-) create mode 100644 .changeset/tall-beds-bake.md delete mode 100644 packages/core-app-api/src/extensions/componentData.test.tsx delete mode 100644 packages/core-app-api/src/extensions/componentData.tsx delete mode 100644 packages/core-app-api/src/extensions/extensions.tsx delete mode 100644 packages/core-app-api/src/extensions/index.ts diff --git a/.changeset/tall-beds-bake.md b/.changeset/tall-beds-bake.md new file mode 100644 index 0000000000..2a0c9f7023 --- /dev/null +++ b/.changeset/tall-beds-bake.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-app-api': patch +--- + +Removed deprecated internal functions. diff --git a/packages/core-app-api/src/extensions/componentData.test.tsx b/packages/core-app-api/src/extensions/componentData.test.tsx deleted file mode 100644 index 808ab08cf1..0000000000 --- a/packages/core-app-api/src/extensions/componentData.test.tsx +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { attachComponentData, getComponentData } from './componentData'; - -describe('elementData', () => { - it('should attach a single piece of data', () => { - const data = { foo: 'bar' }; - const Component = () => null; - attachComponentData(Component, 'my-data', data); - - const element = ; - expect(getComponentData(element, 'my-data')).toBe(data); - }); - - it('should attach several distinct pieces of data', () => { - const data1 = { foo: 'bar' }; - const data2 = { test: 'value' }; - const Component = () => null; - attachComponentData(Component, 'my-data', data1); - attachComponentData(Component, 'second', data2); - - const element = ; - expect(getComponentData(element, 'my-data')).toBe(data1); - expect(getComponentData(element, 'second')).toBe(data2); - }); - - it('returns undefined for missing data', () => { - const data = { foo: 'bar' }; - const Component1 = () => null; - const Component2 = () => null; - attachComponentData(Component2, 'my-data', data); - - const element1 = ; - const element2 = ; - expect(getComponentData(element1, 'missing')).toBeUndefined(); - expect(getComponentData(element2, 'missing')).toBeUndefined(); - }); - - it('should throw when attempting to overwrite data', () => { - const data = { foo: 'bar' }; - const MyComponent = () => null; - attachComponentData(MyComponent, 'my-data', data); - expect(() => attachComponentData(MyComponent, 'my-data', data)).toThrow( - 'Attempted to attach duplicate data "my-data" to component "MyComponent"', - ); - }); - - describe('works across versions', () => { - function getDataSymbol() { - const Component = () => null; - attachComponentData(Component, 'my-data', {}); - const [symbol] = Object.getOwnPropertySymbols(Component); - return symbol; - } - - it('should should be able to get data from older versions', () => { - const symbol = getDataSymbol(); - - const data = { foo: 'bar' }; - const Component = () => null; - attachComponentData(Component, 'my-data', data); - - const element = ; - expect((element as any).type[symbol].map.get('my-data')).toBe(data); - }); - - it('should should be able to attach data for older versions', () => { - const symbol = getDataSymbol(); - - const data = { foo: 'bar' }; - const Component = () => null; - (Component as any)[symbol] = { - map: new Map([['my-data', data]]), - }; - - const element = ; - expect(getComponentData(element, 'my-data')).toBe(data); - }); - - it('should be able to get data from newer versions', () => { - const data = { foo: 'bar' }; - const Component = () => null; - attachComponentData(Component, 'my-data', data); - - const element = ; - const container = (global as any)[ - '__@backstage/component-data-store__' - ].get(element.type); - expect(container.map.get('my-data')).toBe(data); - }); - - it('should should be able to attach data for newer versions', () => { - const data = { foo: 'bar' }; - const Component = () => null; - (global as any)['__@backstage/component-data-store__'].set(Component, { - map: new Map([['my-data', data]]), - }); - - const element = ; - expect(getComponentData(element, 'my-data')).toBe(data); - }); - }); -}); diff --git a/packages/core-app-api/src/extensions/componentData.tsx b/packages/core-app-api/src/extensions/componentData.tsx deleted file mode 100644 index d4975d9eef..0000000000 --- a/packages/core-app-api/src/extensions/componentData.tsx +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ComponentType, ReactNode } from 'react'; -import { getOrCreateGlobalSingleton } from '../lib/globalObject'; - -// TODO(Rugvip): Access via symbol is deprecated, remove once on 0.3.x -const DATA_KEY = Symbol('backstage-component-data'); - -type ComponentWithData

= ComponentType

& { - [DATA_KEY]?: DataContainer; -}; - -type DataContainer = { - map: Map; -}; - -type MaybeComponentNode = ReactNode & { - type?: ComponentType & { [DATA_KEY]?: DataContainer }; -}; - -// The store is bridged across versions using the global object -const store = getOrCreateGlobalSingleton( - 'component-data-store', - () => new WeakMap, DataContainer>(), -); - -export function attachComponentData

( - component: ComponentType

, - type: string, - data: unknown, -) { - const dataComponent = component as ComponentWithData

; - - let container = store.get(component) || dataComponent[DATA_KEY]; - if (!container) { - container = { map: new Map() }; - store.set(component, container); - dataComponent[DATA_KEY] = container; - } - - if (container.map.has(type)) { - const name = component.displayName || component.name; - throw new Error( - `Attempted to attach duplicate data "${type}" to component "${name}"`, - ); - } - - container.map.set(type, data); -} - -export function getComponentData( - node: ReactNode, - type: string, -): T | undefined { - if (!node) { - return undefined; - } - - const component = (node as MaybeComponentNode).type; - if (!component) { - return undefined; - } - - const container = store.get(component) || component[DATA_KEY]; - if (!container) { - return undefined; - } - - return container.map.get(type) as T | undefined; -} diff --git a/packages/core-app-api/src/extensions/extensions.tsx b/packages/core-app-api/src/extensions/extensions.tsx deleted file mode 100644 index 199430c619..0000000000 --- a/packages/core-app-api/src/extensions/extensions.tsx +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Extension, RouteRef } from '@backstage/core-plugin-api'; - -type ComponentLoader = - | { - lazy: () => Promise; - } - | { - sync: T; - }; - -const ERROR_MESSAGE = 'Import this from @backstage/core-plugin-api'; - -/** @deprecated Import from @backstage/core-plugin-api instead */ -export function createRoutableExtension< - T extends (props: any) => JSX.Element | null, ->(_options: { - component: () => Promise; - mountPoint: RouteRef; -}): Extension { - throw new Error(ERROR_MESSAGE); -} - -/** @deprecated Import from @backstage/core-plugin-api instead */ -export function createComponentExtension< - T extends (props: any) => JSX.Element | null, ->(_options: { component: ComponentLoader }): Extension { - throw new Error(ERROR_MESSAGE); -} - -/** @deprecated Import from @backstage/core-plugin-api instead */ -export function createReactExtension< - T extends (props: any) => JSX.Element | null, ->(_options: { - component: ComponentLoader; - data?: Record; -}): Extension { - throw new Error(ERROR_MESSAGE); -} diff --git a/packages/core-app-api/src/extensions/index.ts b/packages/core-app-api/src/extensions/index.ts deleted file mode 100644 index 914d76aebf..0000000000 --- a/packages/core-app-api/src/extensions/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { attachComponentData, getComponentData } from './componentData'; -export { - createReactExtension, - createRoutableExtension, - createComponentExtension, -} from './extensions'; diff --git a/packages/core-app-api/src/plugins/collectors.ts b/packages/core-app-api/src/plugins/collectors.ts index 11e5cd51b3..0f8b65ad62 100644 --- a/packages/core-app-api/src/plugins/collectors.ts +++ b/packages/core-app-api/src/plugins/collectors.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { getComponentData } from '../extensions'; +import { BackstagePlugin, getComponentData } from '@backstage/core-plugin-api'; import { createCollector } from '../extensions/traversal'; export const pluginCollector = createCollector( diff --git a/packages/core-app-api/src/routing/collectors.test.tsx b/packages/core-app-api/src/routing/collectors.test.tsx index d37b5e3016..36d99d2938 100644 --- a/packages/core-app-api/src/routing/collectors.test.tsx +++ b/packages/core-app-api/src/routing/collectors.test.tsx @@ -31,8 +31,8 @@ import { createRouteRef, createPlugin, RouteRef, + attachComponentData, } from '@backstage/core-plugin-api'; -import { attachComponentData } from '../extensions'; import { MemoryRouter, Routes, Route } from 'react-router-dom'; const MockComponent = ({ children }: PropsWithChildren<{ path?: string }>) => ( diff --git a/packages/core-app-api/src/routing/collectors.tsx b/packages/core-app-api/src/routing/collectors.tsx index fcbe3ca923..0ba83e90f8 100644 --- a/packages/core-app-api/src/routing/collectors.tsx +++ b/packages/core-app-api/src/routing/collectors.tsx @@ -15,9 +15,8 @@ */ import { isValidElement, ReactElement, ReactNode } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; +import { RouteRef, getComponentData } from '@backstage/core-plugin-api'; import { BackstageRouteObject } from './types'; -import { getComponentData } from '../extensions'; import { createCollector } from '../extensions/traversal'; import { FeatureFlagged, FeatureFlaggedProps } from './FeatureFlagged'; From dad38c18091c8fb55d22c0a4b16883542b005a16 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 7 Sep 2021 19:55:42 +0200 Subject: [PATCH 020/125] core-components: remove ugly workaround for routing context bug in stories Signed-off-by: Patrik Oldsberg --- .../src/components/Button/Button.stories.tsx | 53 ++++++++----------- .../src/components/Link/Link.stories.tsx | 35 ++++-------- 2 files changed, 31 insertions(+), 57 deletions(-) diff --git a/packages/core-components/src/components/Button/Button.stories.tsx b/packages/core-components/src/components/Button/Button.stories.tsx index 28deb1ad33..3451a77765 100644 --- a/packages/core-components/src/components/Button/Button.stories.tsx +++ b/packages/core-components/src/components/Button/Button.stories.tsx @@ -15,7 +15,7 @@ */ import React, { ComponentType } from 'react'; import { Button } from './Button'; -import { MemoryRouter, useLocation } from 'react-router-dom'; +import { useLocation } from 'react-router-dom'; import { createRouteRef, useRouteRef } from '@backstage/core-plugin-api'; import { Divider, @@ -26,11 +26,7 @@ import { Typography, Button as MaterialButton, } from '@material-ui/core'; -// We don't want to export RoutingProvider from core-app-api, but it's way easier to -// use here. This hack only works in storybook stories. -// TODO: Export a nicer to user routing provider, perhaps from test-utils -// eslint-disable-next-line monorepo/no-internal-import -import { RoutingProvider } from '@backstage/core-app-api/src/routing/RoutingProvider'; +import { wrapInTestApp } from '@backstage/test-utils'; const routeRef = createRouteRef({ id: 'storybook.test-route', @@ -45,36 +41,29 @@ export default { title: 'Inputs/Button', component: Button, decorators: [ - (Story: ComponentType<{}>) => ( - <> - - A collection of buttons that should be used in the Backstage - interface. These leverage the properties inherited from{' '} - - Material-UI Button - - , but include an opinionated set that align to the Backstage design. - + (Story: ComponentType<{}>) => + wrapInTestApp( + <> + + A collection of buttons that should be used in the Backstage + interface. These leverage the properties inherited from{' '} + + Material-UI Button + + , but include an opinionated set that align to the Backstage design. + - + - - +

-
- -
- +
- - - - ), + +
+ , + { mountedRoutes: { '/hello': routeRef } }, + ), ], }; diff --git a/packages/core-components/src/components/Link/Link.stories.tsx b/packages/core-components/src/components/Link/Link.stories.tsx index 516a5adcff..d9944c1c51 100644 --- a/packages/core-components/src/components/Link/Link.stories.tsx +++ b/packages/core-components/src/components/Link/Link.stories.tsx @@ -15,17 +15,9 @@ */ import React, { ComponentType } from 'react'; import { Link } from './Link'; -import { - MemoryRouter, - Route, - useLocation, - NavLink as RouterNavLink, -} from 'react-router-dom'; +import { Route, useLocation, NavLink as RouterNavLink } from 'react-router-dom'; import { createRouteRef, useRouteRef } from '@backstage/core-plugin-api'; -// We don't want to export RoutingProvider from core-app-api, but it's way easier to -// use here. This hack only works in storybook stories. -// eslint-disable-next-line monorepo/no-internal-import -import { RoutingProvider } from '@backstage/core-app-api/src/routing/RoutingProvider'; +import { wrapInTestApp } from '@backstage/test-utils'; const routeRef = createRouteRef({ id: 'storybook.test-route', @@ -40,23 +32,16 @@ export default { title: 'Navigation/Link', component: Link, decorators: [ - (Story: ComponentType<{}>) => ( - - + (Story: ComponentType<{}>) => + wrapInTestApp( +
-
- -
- +
- - - ), + +
, + { mountedRoutes: { '/hello': routeRef } }, + ), ], }; From bcf312fa52834d122aaca94d1e6f33a8d1a0c8e2 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Wed, 1 Sep 2021 07:54:10 -0500 Subject: [PATCH 021/125] Added the HomepageTimer to the new composable Home Page Signed-off-by: Andre Wanlin --- .changeset/late-mangos-allow.md | 5 +++++ .../home/src/components/HomepageCompositionRoot.tsx | 11 +++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 .changeset/late-mangos-allow.md diff --git a/.changeset/late-mangos-allow.md b/.changeset/late-mangos-allow.md new file mode 100644 index 0000000000..82a180c836 --- /dev/null +++ b/.changeset/late-mangos-allow.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-home': patch +--- + +Added the HomepageTimer to the new composable Home Page diff --git a/plugins/home/src/components/HomepageCompositionRoot.tsx b/plugins/home/src/components/HomepageCompositionRoot.tsx index 92232fb387..a6e4f482f8 100644 --- a/plugins/home/src/components/HomepageCompositionRoot.tsx +++ b/plugins/home/src/components/HomepageCompositionRoot.tsx @@ -16,7 +16,12 @@ import React, { ReactNode } from 'react'; import { useOutlet } from 'react-router'; -import { Content, Header, Page } from '@backstage/core-components'; +import { + Content, + Header, + Page, + HomepageTimer, +} from '@backstage/core-components'; export const HomepageCompositionRoot = (props: { title?: string; @@ -26,7 +31,9 @@ export const HomepageCompositionRoot = (props: { const children = props.children ?? outlet; return ( -
+
+ +
{children} ); From f648f9c0b9a59bf82bf7c5edb54d16507873ebc8 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Sat, 4 Sep 2021 14:16:17 -0500 Subject: [PATCH 022/125] Moved Header and Content to HomePage Signed-off-by: Andre Wanlin --- packages/app/src/App.tsx | 4 +- packages/app/src/components/home/HomePage.tsx | 104 ++++++++++-------- 2 files changed, 59 insertions(+), 49 deletions(-) diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 81dbdf4cac..244bc7aa2a 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -114,9 +114,7 @@ const routes = ( {/* TODO(rubenl): Move this to / once its more mature and components exist */} - }> - - + } /> } /> ( - - - - - - - - - - - - - - ( - - ), - }, - { - label: 'Any', - Component: () => ( - - ), - }, - ]} - /> - - + +
+ +
+ + + + + + + + + + + + ( + + ), + }, + { + label: 'Any', + Component: () => ( + + ), + }, + ]} + /> + + + +
); From 643bc5df772b9438a971f0aecdd9d9886d01dfa7 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Mon, 6 Sep 2021 09:08:16 -0500 Subject: [PATCH 023/125] Keep using HomepageCompositionRoot Signed-off-by: Andre Wanlin --- packages/app/src/App.tsx | 4 +++- .../src/components/HomepageCompositionRoot.tsx | 15 +-------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 244bc7aa2a..81dbdf4cac 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -114,7 +114,9 @@ const routes = ( {/* TODO(rubenl): Move this to / once its more mature and components exist */} - } /> + }> + + } /> { const outlet = useOutlet(); const children = props.children ?? outlet; - return ( - -
- -
- {children} -
- ); + return
{children}
; }; From 93917b72c1558680593e320f186063df13c419a4 Mon Sep 17 00:00:00 2001 From: Dominik Henneke Date: Wed, 8 Sep 2021 09:58:57 +0200 Subject: [PATCH 024/125] Forward the error message Signed-off-by: Dominik Henneke --- .../src/ingestion/processors/PlaceholderProcessor.test.ts | 2 +- .../src/ingestion/processors/PlaceholderProcessor.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts index 3abf051e4e..c60b01d53d 100644 --- a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts +++ b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts @@ -345,7 +345,7 @@ describe('PlaceholderProcessor', () => { }, ), ).rejects.toThrow( - 'Placeholder $text could not form a URL out of ./a/b/catalog-info.yaml and ../c/catalog-info.yaml', + 'Placeholder $text could not form a URL out of ./a/b/catalog-info.yaml and ../c/catalog-info.yaml, TypeError: Invalid base URL: ./a/b/catalog-info.yaml', ); expect(read).not.toBeCalled(); diff --git a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts index 4456405857..611e166605 100644 --- a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts +++ b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts @@ -216,13 +216,13 @@ function relativeUrl({ try { return resolveUrl(value, baseUrl); - } catch (_) { + } catch (e) { // The only remaining case that isn't support is a relative file path that should be // resolved using a relative file location. Accessing local file paths can lead to // path traversal attacks and access to any file on the host system. Implementing this // would require additional security measures. throw new Error( - `Placeholder \$${key} could not form a URL out of ${baseUrl} and ${value}`, + `Placeholder \$${key} could not form a URL out of ${baseUrl} and ${value}, ${e}`, ); } } From a316cd838da728b051deafc018dd2f444159114c Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 8 Sep 2021 10:59:40 +0200 Subject: [PATCH 025/125] chore: reverting stripping as we don't need it Signed-off-by: blam --- packages/backend-common/src/reading/AzureUrlReader.ts | 6 +++--- packages/backend-common/src/reading/tree/util.ts | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/backend-common/src/reading/AzureUrlReader.ts b/packages/backend-common/src/reading/AzureUrlReader.ts index 5369306702..2269393cbf 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.ts @@ -94,8 +94,6 @@ export class AzureUrlReader implements UrlReader { url: string, options?: ReadTreeOptions, ): Promise { - // TODO: Support filepath based reading tree feature like other providers - // Get latest commit SHA const commitsAzureResponse = await fetch( @@ -129,11 +127,13 @@ export class AzureUrlReader implements UrlReader { throw new Error(message); } + const { filepath } = parseGitUrl(url); + return await this.deps.treeResponseFactory.fromZipArchive({ stream: archiveAzureResponse.body as unknown as Readable, etag: commitSha, filter: options?.filter, - stripFirstDirectory: true, + subpath: filepath, }); } diff --git a/packages/backend-common/src/reading/tree/util.ts b/packages/backend-common/src/reading/tree/util.ts index cfb986a0b0..5ddc5a3766 100644 --- a/packages/backend-common/src/reading/tree/util.ts +++ b/packages/backend-common/src/reading/tree/util.ts @@ -21,5 +21,6 @@ const directoryNameRegex = /^[^\/]+\//; // Removes the first segment of a forward-slash-separated path export function stripFirstDirectoryFromPath(path: string): string { + console.log('stripFirstDirectoryPath path:', path); return path.replace(directoryNameRegex, ''); } From e7b596fdae5922ca08d1104638bd4f769cd25ce1 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 8 Sep 2021 11:00:59 +0200 Subject: [PATCH 026/125] chore: removing stripFirstDirectory it's not needed Signed-off-by: blam --- .../backend-common/src/reading/tree/ReadTreeResponseFactory.ts | 1 - packages/backend-common/src/reading/types.ts | 3 --- 2 files changed, 4 deletions(-) diff --git a/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts b/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts index 70d8f63af8..5fdd633102 100644 --- a/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts +++ b/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts @@ -55,7 +55,6 @@ export class DefaultReadTreeResponseFactory implements ReadTreeResponseFactory { this.workDir, options.etag, options.filter, - options.stripFirstDirectory, ); } } diff --git a/packages/backend-common/src/reading/types.ts b/packages/backend-common/src/reading/types.ts index 2d9c305b85..b7e1ff823f 100644 --- a/packages/backend-common/src/reading/types.ts +++ b/packages/backend-common/src/reading/types.ts @@ -182,9 +182,6 @@ export type ReadTreeResponseFactoryOptions = { etag: string; // Filter passed on from the ReadTreeOptions filter?: (path: string, info?: { size: number }) => boolean; - - // Strip the first directory in the readTree response - stripFirstDirectory?: boolean; }; /** @public */ From bb7ce1c64c16623f11d047431b915a5538422a3e Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 8 Sep 2021 11:06:24 +0200 Subject: [PATCH 027/125] chore: added test for subpath azure Signed-off-by: blam --- .../src/reading/AzureUrlReader.test.ts | 15 +++++++++++++++ packages/backend-common/src/reading/tree/util.ts | 1 - 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/backend-common/src/reading/AzureUrlReader.test.ts b/packages/backend-common/src/reading/AzureUrlReader.test.ts index c7c8853929..fc1f6a03f3 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.test.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.test.ts @@ -220,6 +220,21 @@ describe('AzureUrlReader', () => { expect(indexMarkdownFile.toString()).toBe('# Test\n'); }); + it('returns the wanted files from an archive when a subpath is passed through', async () => { + const response = await processor.readTree( + 'https://dev.azure.com/organization/project/_git/repository?path=%2Fdocs', + ); + + expect(response.etag).toBe('123abc2'); + + const files = await response.files(); + + expect(files.length).toBe(1); + const indexMarkdownFile = await files[0].content(); + + expect(indexMarkdownFile.toString()).toBe('# Test\n'); + }); + it('creates a directory with the wanted files', async () => { const response = await processor.readTree( 'https://dev.azure.com/organization/project/_git/repository', diff --git a/packages/backend-common/src/reading/tree/util.ts b/packages/backend-common/src/reading/tree/util.ts index 5ddc5a3766..cfb986a0b0 100644 --- a/packages/backend-common/src/reading/tree/util.ts +++ b/packages/backend-common/src/reading/tree/util.ts @@ -21,6 +21,5 @@ const directoryNameRegex = /^[^\/]+\//; // Removes the first segment of a forward-slash-separated path export function stripFirstDirectoryFromPath(path: string): string { - console.log('stripFirstDirectoryPath path:', path); return path.replace(directoryNameRegex, ''); } From db6d2789e7fdc55f6fb2eafaa529b18961383be9 Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Wed, 8 Sep 2021 11:06:29 +0200 Subject: [PATCH 028/125] Make styling of groups tab in the explore page use the Backstage theme Signed-off-by: Oliver Sand --- .changeset/ten-dolls-ring.md | 6 +++ .../GroupsExplorerContent/GroupsDiagram.tsx | 49 +++++++++---------- .../GroupsExplorerContent.tsx | 13 ++++- 3 files changed, 41 insertions(+), 27 deletions(-) create mode 100644 .changeset/ten-dolls-ring.md diff --git a/.changeset/ten-dolls-ring.md b/.changeset/ten-dolls-ring.md new file mode 100644 index 0000000000..8142d1f3c8 --- /dev/null +++ b/.changeset/ten-dolls-ring.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-explore': patch +--- + +Make styling of groups tab in the explore page use the Backstage theme instead +of hard coded colors. Change the layout to be full screen. diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx index c865920e7d..e4fa6e9b57 100644 --- a/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx @@ -26,7 +26,7 @@ import { getEntityRelations, formatEntityRefTitle, } from '@backstage/plugin-catalog-react'; -import { makeStyles, Typography } from '@material-ui/core'; +import { makeStyles, Typography, useTheme } from '@material-ui/core'; import ZoomOutMap from '@material-ui/icons/ZoomOutMap'; import React from 'react'; import { useAsync } from 'react-use'; @@ -42,16 +42,20 @@ import { import { useApi, useRouteRef, configApiRef } from '@backstage/core-plugin-api'; const useStyles = makeStyles((theme: BackstageTheme) => ({ + graph: { + flex: 1, + minHeight: 0, + }, organizationNode: { - fill: 'coral', - stroke: theme.palette.border, + fill: theme.palette.background.paper, + stroke: theme.palette.primary.main, }, groupNode: { - fill: 'yellowgreen', + fill: theme.palette.background.paper, stroke: theme.palette.border, }, centeredContent: { - padding: '10px', + padding: theme.spacing(1), height: '100%', display: 'flex', alignItems: 'center', @@ -59,6 +63,7 @@ const useStyles = makeStyles((theme: BackstageTheme) => ({ color: 'black', }, textWrapper: { + color: theme.palette.textContrast, display: '-webkit-box', WebkitBoxOrient: 'vertical', WebkitLineClamp: 2, @@ -70,14 +75,10 @@ const useStyles = makeStyles((theme: BackstageTheme) => ({ }, })); -const dimensions = { - nodeWidth: 180, - nodeHeight: 90, - nodeCornerRadius: 20, - nodeAligmentShift: 5, -}; - function RenderNode(props: DependencyGraphTypes.RenderNodeProps) { + const nodeWidth = 180; + const nodeHeight = 80; + const theme = useTheme(); const classes = useStyles(); const catalogEntityRoute = useRouteRef(entityRouteRef); @@ -85,16 +86,13 @@ function RenderNode(props: DependencyGraphTypes.RenderNodeProps) { return ( {props.node.name} - +
{props.node.name}
@@ -108,9 +106,9 @@ function RenderNode(props: DependencyGraphTypes.RenderNodeProps) { return ( {props.node.name} @@ -122,10 +120,7 @@ function RenderNode(props: DependencyGraphTypes.RenderNodeProps) { name: ref.name, })} > - +
{props.node.name}
@@ -146,6 +141,7 @@ export function GroupsDiagram() { }>(); const edges = new Array<{ from: string; to: string; label: string }>(); + const classes = useStyles(); const configApi = useApi(configApiRef); const catalogApi = useApi(catalogApiRef); const organizationName = @@ -218,6 +214,7 @@ export function GroupsDiagram() { nodeMargin={10} direction={DependencyGraphTypes.Direction.RIGHT_LEFT} renderNode={RenderNode} + className={classes.graph} /> { + const classes = useStyles(); + return ( - + Explore your groups. From fdaa61a87b2d25f565476db13c7aa2c79779ed7f Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 8 Sep 2021 11:08:01 +0200 Subject: [PATCH 029/125] chore: added changeset Signed-off-by: blam --- .changeset/early-seahorses-stare.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/early-seahorses-stare.md diff --git a/.changeset/early-seahorses-stare.md b/.changeset/early-seahorses-stare.md new file mode 100644 index 0000000000..963058a26f --- /dev/null +++ b/.changeset/early-seahorses-stare.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Fixing issue with `AzureUrlReader` that doesn't do `subpath` directories correctly From 8e6e95fc434fa5b0544774a7f5233e19da71162b Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 8 Sep 2021 11:17:13 +0200 Subject: [PATCH 030/125] chore: remove the `stripFirstDirectory` option to the `ZipArchiveResponse` Signed-off-by: blam --- .../reading/tree/ZipArchiveResponse.test.ts | 30 ------------------- .../src/reading/tree/ZipArchiveResponse.ts | 20 ++----------- 2 files changed, 3 insertions(+), 47 deletions(-) diff --git a/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts b/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts index f6f9a7845a..a54bac0c4a 100644 --- a/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts +++ b/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts @@ -62,36 +62,6 @@ describe('ZipArchiveResponse', () => { ]); }); - it('should read files and strip root dir if requested', async () => { - const stream = fs.createReadStream('/test-archive-with-extra-root-dir.zip'); - - const res = new ZipArchiveResponse( - stream, - '', - '/tmp', - 'etag', - undefined, - true, - ); - const files = await res.files(); - - expect(files).toEqual([ - { - path: 'mkdocs.yml', - content: expect.any(Function), - }, - { - path: 'docs/index.md', - content: expect.any(Function), - }, - ]); - const contents = await Promise.all(files.map(f => f.content())); - expect(contents.map(c => c.toString('utf8').trim())).toEqual([ - 'site_name: Test', - '# Test', - ]); - }); - it('should read files with filter', async () => { const stream = fs.createReadStream('/test-archive.zip'); diff --git a/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts b/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts index fb22f24b94..e07cedde87 100644 --- a/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts +++ b/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts @@ -24,7 +24,6 @@ import { ReadTreeResponseDirOptions, ReadTreeResponseFile, } from '../types'; -import { stripFirstDirectoryFromPath } from './util'; /** * Wraps a zip archive stream into a tree response reader. @@ -38,7 +37,6 @@ export class ZipArchiveResponse implements ReadTreeResponse { private readonly workDir: string, public readonly etag: string, private readonly filter?: (path: string, info: { size: number }) => boolean, - private readonly stripFirstDirectory?: boolean, ) { if (subPath) { if (!subPath.endsWith('/')) { @@ -68,12 +66,8 @@ export class ZipArchiveResponse implements ReadTreeResponse { } private shouldBeIncluded(entry: Entry): boolean { - const strippedPath = this.stripFirstDirectory - ? stripFirstDirectoryFromPath(entry.path) - : entry.path; - if (this.subPath) { - if (!strippedPath.startsWith(this.subPath)) { + if (!entry.path.startsWith(this.subPath)) { return false; } } @@ -102,11 +96,7 @@ export class ZipArchiveResponse implements ReadTreeResponse { if (this.shouldBeIncluded(entry)) { files.push({ - path: this.getInnerPath( - this.stripFirstDirectory - ? stripFirstDirectoryFromPath(entry.path) - : entry.path, - ), + path: this.getInnerPath(entry.path), content: () => entry.buffer(), }); } else { @@ -154,11 +144,7 @@ export class ZipArchiveResponse implements ReadTreeResponse { // Ignore directory entries since we handle that with the file entries // as a zip can have files with directories without directory entries if (entry.type === 'File' && this.shouldBeIncluded(entry)) { - const entryPath = this.getInnerPath( - this.stripFirstDirectory - ? stripFirstDirectoryFromPath(entry.path) - : entry.path, - ); + const entryPath = this.getInnerPath(entry.path); const dirname = platformPath.dirname(entryPath); if (dirname) { await fs.mkdirp(platformPath.join(dir, dirname)); From c299e90a26276eacc90f5120c8826a502a021021 Mon Sep 17 00:00:00 2001 From: hiba-aldalaty Date: Wed, 8 Sep 2021 10:43:09 +0100 Subject: [PATCH 031/125] Disable all buttons in the final step in template when 'Create' button is clicked in template. Signed-off-by: hiba-aldalaty --- .changeset/lovely-windows-return.md | 5 +++++ .../MultistepJsonForm/MultistepJsonForm.tsx | 14 +++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 .changeset/lovely-windows-return.md diff --git a/.changeset/lovely-windows-return.md b/.changeset/lovely-windows-return.md new file mode 100644 index 0000000000..55755af563 --- /dev/null +++ b/.changeset/lovely-windows-return.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Disable all buttons in the final step when 'Create' button is clicked in template. diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx b/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx index ef7e74f2f1..62c2881ab0 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx +++ b/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx @@ -112,7 +112,7 @@ export const MultistepJsonForm = ({ widgets, }: Props) => { const [activeStep, setActiveStep] = useState(0); - const [disableCreateButton, setDisableCreateButton] = useState(false); + const [disableButtons, setDisableButtons] = useState(false); const handleReset = () => { setActiveStep(0); @@ -123,7 +123,7 @@ export const MultistepJsonForm = ({ }; const handleBack = () => setActiveStep(Math.max(activeStep - 1, 0)); const handleCreate = () => { - setDisableCreateButton(true); + setDisableButtons(true); onFinish(); }; @@ -177,13 +177,17 @@ export const MultistepJsonForm = ({ metadata={getReviewData(formData, steps)} /> - - + + From 1797c5ce5dd660db633d22d4b2ad90b0ac431985 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 8 Sep 2021 13:29:35 +0200 Subject: [PATCH 032/125] catalog-backend: Drop support for deprecated location types Signed-off-by: Johan Haals --- .changeset/strange-buckets-design.md | 16 ++++++++++++++++ .../ingestion/processors/UrlReaderProcessor.ts | 18 +----------------- 2 files changed, 17 insertions(+), 17 deletions(-) create mode 100644 .changeset/strange-buckets-design.md diff --git a/.changeset/strange-buckets-design.md b/.changeset/strange-buckets-design.md new file mode 100644 index 0000000000..3cdf858174 --- /dev/null +++ b/.changeset/strange-buckets-design.md @@ -0,0 +1,16 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +This change drops support for deprecated location types which have all been replaced by the `url` type. +There has been a deprecation warning in place since the beginning of this year so most should already be migrated and received information at this point. + +The now removed location types are: + +``` +github +github/api +bitbucket/api +gitlab/api +azure/api +``` diff --git a/plugins/catalog-backend/src/ingestion/processors/UrlReaderProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/UrlReaderProcessor.ts index da7bee12d8..e3ec8c0480 100644 --- a/plugins/catalog-backend/src/ingestion/processors/UrlReaderProcessor.ts +++ b/plugins/catalog-backend/src/ingestion/processors/UrlReaderProcessor.ts @@ -26,16 +26,6 @@ import { CatalogProcessorParser, } from './types'; -// TODO(Rugvip): Added for backwards compatibility when moving to UrlReader, this -// can be removed in a bit -const deprecatedTypes = [ - 'github', - 'github/api', - 'bitbucket/api', - 'gitlab/api', - 'azure/api', -]; - type Options = { reader: UrlReader; logger: Logger; @@ -50,13 +40,7 @@ export class UrlReaderProcessor implements CatalogProcessor { emit: CatalogProcessorEmit, parser: CatalogProcessorParser, ): Promise { - if (deprecatedTypes.includes(location.type)) { - // TODO(Rugvip): Remove this warning a month or two into 2021, and remove support for the deprecated types. - this.options.logger.warn( - `Location '${location.target}' uses deprecated location type '${location.type}', use 'url' instead. ` + - 'Use "scripts/migrate-location-types.js" in the Backstage repo to migrate existing locations.', - ); - } else if (location.type !== 'url') { + if (location.type !== 'url') { return false; } From 5d79be7fb30f839f582ede3177c41fe9d1c07fa8 Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Wed, 8 Sep 2021 13:39:24 +0200 Subject: [PATCH 033/125] Use style similar to material buttons Signed-off-by: Oliver Sand --- .../GroupsExplorerContent/GroupsDiagram.tsx | 62 ++++++++++++------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx index e4fa6e9b57..49a9481b15 100644 --- a/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx @@ -15,31 +15,31 @@ */ import { + GroupEntity, + parseEntityRef, RELATION_CHILD_OF, stringifyEntityRef, - parseEntityRef, - GroupEntity, } from '@backstage/catalog-model'; -import { - catalogApiRef, - entityRouteRef, - getEntityRelations, - formatEntityRefTitle, -} from '@backstage/plugin-catalog-react'; -import { makeStyles, Typography, useTheme } from '@material-ui/core'; -import ZoomOutMap from '@material-ui/icons/ZoomOutMap'; -import React from 'react'; -import { useAsync } from 'react-use'; -import { BackstageTheme } from '@backstage/theme'; - import { DependencyGraph, DependencyGraphTypes, + Link, Progress, ResponseErrorPanel, - Link, } from '@backstage/core-components'; -import { useApi, useRouteRef, configApiRef } from '@backstage/core-plugin-api'; +import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; +import { + catalogApiRef, + entityRouteRef, + formatEntityRefTitle, + getEntityRelations, +} from '@backstage/plugin-catalog-react'; +import { BackstageTheme } from '@backstage/theme'; +import { makeStyles, Typography, useTheme } from '@material-ui/core'; +import ZoomOutMap from '@material-ui/icons/ZoomOutMap'; +import classNames from 'classnames'; +import React from 'react'; +import { useAsync } from 'react-use'; const useStyles = makeStyles((theme: BackstageTheme) => ({ graph: { @@ -47,12 +47,12 @@ const useStyles = makeStyles((theme: BackstageTheme) => ({ minHeight: 0, }, organizationNode: { - fill: theme.palette.background.paper, - stroke: theme.palette.primary.main, + fill: theme.palette.secondary.light, + stroke: theme.palette.secondary.light, }, groupNode: { - fill: theme.palette.background.paper, - stroke: theme.palette.border, + fill: theme.palette.primary.light, + stroke: theme.palette.primary.light, }, centeredContent: { padding: theme.spacing(1), @@ -62,8 +62,13 @@ const useStyles = makeStyles((theme: BackstageTheme) => ({ justifyContent: 'center', color: 'black', }, + textOrganization: { + color: theme.palette.secondary.contrastText, + }, + textGroup: { + color: theme.palette.primary.contrastText, + }, textWrapper: { - color: theme.palette.textContrast, display: '-webkit-box', WebkitBoxOrient: 'vertical', WebkitLineClamp: 2, @@ -77,7 +82,7 @@ const useStyles = makeStyles((theme: BackstageTheme) => ({ function RenderNode(props: DependencyGraphTypes.RenderNodeProps) { const nodeWidth = 180; - const nodeHeight = 80; + const nodeHeight = 60; const theme = useTheme(); const classes = useStyles(); const catalogEntityRoute = useRouteRef(entityRouteRef); @@ -94,7 +99,14 @@ function RenderNode(props: DependencyGraphTypes.RenderNodeProps) { {props.node.name}
-
{props.node.name}
+
+ {props.node.name} +
@@ -122,7 +134,9 @@ function RenderNode(props: DependencyGraphTypes.RenderNodeProps) { >
-
{props.node.name}
+
+ {props.node.name} +
From af05164b67eb33d09cccd5c1a89eeafe72aa6e49 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 8 Sep 2021 13:49:28 +0200 Subject: [PATCH 034/125] chore: fix tests Signed-off-by: Johan Haals --- plugins/catalog-backend/src/service/CatalogBuilder.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-backend/src/service/CatalogBuilder.test.ts b/plugins/catalog-backend/src/service/CatalogBuilder.test.ts index 579772dcce..87a26ed3aa 100644 --- a/plugins/catalog-backend/src/service/CatalogBuilder.test.ts +++ b/plugins/catalog-backend/src/service/CatalogBuilder.test.ts @@ -166,7 +166,7 @@ describe('CatalogBuilder', () => { const { entitiesCatalog, higherOrderOperation } = await builder.build(); await higherOrderOperation.addLocation({ - type: 'github', + type: 'url', target: 'https://github.com/a/b/x.yaml', }); const { entities } = await entitiesCatalog.entities(); From 60c03f69a7553aa5537aec0440b7b079e8cc8612 Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Wed, 8 Sep 2021 14:15:04 +0200 Subject: [PATCH 035/125] Change the styling of the `` to have more contrast in light mode Signed-off-by: Oliver Sand --- .changeset/brave-eggs-rush.md | 6 ++++++ .../src/components/DependencyGraph/DefaultNode.tsx | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 .changeset/brave-eggs-rush.md diff --git a/.changeset/brave-eggs-rush.md b/.changeset/brave-eggs-rush.md new file mode 100644 index 0000000000..8e1a7ca86d --- /dev/null +++ b/.changeset/brave-eggs-rush.md @@ -0,0 +1,6 @@ +--- +'@backstage/core-components': patch +--- + +Change the styling of the `` to have more contrast in light +mode. Nodes now have a design similar to material UI buttons. diff --git a/packages/core-components/src/components/DependencyGraph/DefaultNode.tsx b/packages/core-components/src/components/DependencyGraph/DefaultNode.tsx index 69269d687d..8feca43e9a 100644 --- a/packages/core-components/src/components/DependencyGraph/DefaultNode.tsx +++ b/packages/core-components/src/components/DependencyGraph/DefaultNode.tsx @@ -21,11 +21,11 @@ import { RenderNodeProps } from './types'; const useStyles = makeStyles((theme: BackstageTheme) => ({ node: { - fill: theme.palette.background.paper, - stroke: theme.palette.border, + fill: theme.palette.primary.light, + stroke: theme.palette.primary.light, }, text: { - fill: theme.palette.textContrast, + fill: theme.palette.primary.contrastText, }, })); From 6548b9e23f0244b2624b6b486f1b70e7747f5267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlio=20Zynger?= Date: Wed, 8 Sep 2021 13:20:56 +0200 Subject: [PATCH 036/125] Add code sample for ConfigApi access in frontend Per https://discord.com/channels/687207715902193673/687235481154617364/885085310101377034 Signed-off-by: Julio Zynger --- docs/conf/reading.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/conf/reading.md b/docs/conf/reading.md index 6ac10a8c8b..d492723e3d 100644 --- a/docs/conf/reading.md +++ b/docs/conf/reading.md @@ -112,7 +112,16 @@ example `getString`. These will throw an error if there is no value available. The [ConfigApi](../reference/utility-apis/Config.md) in the frontend is a [UtilityApi](../api/utility-apis.md). It's accessible as usual via the -`configApiRef` exported from `@backstage/core-plugin-api`. +`configApiRef` exported from `@backstage/core-plugin-api`: + +``` +import { useApi, configApiRef } from '@backstage/core-plugin-api'; +... +const MyReactComponent = (...) => { + const config = useApi(configApiRef); + ... +} +``` Depending on the config api in another API is slightly different though, as the `ConfigApi` implementation is supplied via the App itself and not instantiated From d16283a6c330c5c2240ca5b060b3edc41de15c0a Mon Sep 17 00:00:00 2001 From: hiba-aldalaty Date: Wed, 8 Sep 2021 14:21:17 +0100 Subject: [PATCH 037/125] Remove unnecessary extra changeset file Signed-off-by: hiba-aldalaty --- .changeset/sixty-carrots-marry.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .changeset/sixty-carrots-marry.md diff --git a/.changeset/sixty-carrots-marry.md b/.changeset/sixty-carrots-marry.md deleted file mode 100644 index 414c41c645..0000000000 --- a/.changeset/sixty-carrots-marry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Disable 'Create' button in template after initial click to avoid confusion when there is slowness in template execution From b26fc77bfe1542a3a3ebf10672f8670bd0f55293 Mon Sep 17 00:00:00 2001 From: victormorfin97 Date: Wed, 8 Sep 2021 09:53:24 -0600 Subject: [PATCH 038/125] Change the categories list to dropdown Signed-off-by: victormorfin97 --- .../TemplateTypePicker/TemplateTypePicker.tsx | 49 +++++++++---------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.tsx b/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.tsx index 7151446f4f..a38f45c505 100644 --- a/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.tsx +++ b/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.tsx @@ -21,22 +21,20 @@ import { Box, Checkbox, FormControlLabel, - FormGroup, - makeStyles, - Theme, + TextField, Typography, } from '@material-ui/core'; +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 { useEntityTypeFilter } from '@backstage/plugin-catalog-react'; import { alertApiRef, useApi } from '@backstage/core-plugin-api'; -const useStyles = makeStyles(theme => ({ - checkbox: { - padding: theme.spacing(1, 1, 1, 2), - }, -})); +const icon = ; +const checkedIcon = ; export const TemplateTypePicker = () => { - const classes = useStyles(); const alertApi = useApi(alertApiRef); const { error, loading, availableTypes, selectedTypes, setSelectedTypes } = useEntityTypeFilter(); @@ -53,32 +51,31 @@ export const TemplateTypePicker = () => { return null; } - function toggleSelection(type: string) { - setSelectedTypes( - selectedTypes.includes(type) - ? selectedTypes.filter(t => t !== type) - : [...selectedTypes, type], - ); - } - return ( Categories - - {availableTypes.map(type => ( + + multiple + aria-label="Categories" + options={availableTypes} + value={selectedTypes} + onChange={(_: object, value: string[]) => setSelectedTypes(value)} + renderOption={(option, { selected }) => ( toggleSelection(type)} - className={classes.checkbox} + icon={icon} + checkedIcon={checkedIcon} + checked={selected} /> } - label={capitalize(type)} - key={type} + label={option} /> - ))} - + )} + size="small" + popupIcon={} + renderInput={params => } + /> ); }; From 4a6f6ec6dcb3146c8e89320d79cd0a60fa807abe Mon Sep 17 00:00:00 2001 From: victormorfin97 Date: Wed, 8 Sep 2021 09:56:19 -0600 Subject: [PATCH 039/125] capitalize options in dropdown Signed-off-by: victormorfin97 --- .../src/components/TemplateTypePicker/TemplateTypePicker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.tsx b/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.tsx index a38f45c505..a8418cfded 100644 --- a/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.tsx +++ b/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.tsx @@ -69,7 +69,7 @@ export const TemplateTypePicker = () => { checked={selected} /> } - label={option} + label={capitalize(option)} /> )} size="small" From ebed8687c5a70b1ad0b15fed7005d22f87bbd938 Mon Sep 17 00:00:00 2001 From: victormorfin97 Date: Wed, 8 Sep 2021 10:52:02 -0600 Subject: [PATCH 040/125] update the tests Signed-off-by: victormorfin97 --- .../TemplateTypePicker/TemplateTypePicker.test.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.test.tsx b/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.test.tsx index 534b3b6ce9..3d0267ff1f 100644 --- a/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.test.tsx +++ b/plugins/scaffolder/src/components/TemplateTypePicker/TemplateTypePicker.test.tsx @@ -94,6 +94,7 @@ describe('', () => { , ); expect(rendered.getByText('Categories')).toBeInTheDocument(); + fireEvent.click(rendered.getByTestId('categories-picker-expand')); entities.forEach(entity => { expect( @@ -116,22 +117,27 @@ describe('', () => { , ); + fireEvent.click(rendered.getByTestId('categories-picker-expand')); expect(rendered.getByLabelText('Service')).not.toBeChecked(); expect(rendered.getByLabelText('Website')).not.toBeChecked(); fireEvent.click(rendered.getByLabelText('Service')); + fireEvent.click(rendered.getByTestId('categories-picker-expand')); expect(rendered.getByLabelText('Service')).toBeChecked(); expect(rendered.getByLabelText('Website')).not.toBeChecked(); fireEvent.click(rendered.getByLabelText('Website')); + fireEvent.click(rendered.getByTestId('categories-picker-expand')); expect(rendered.getByLabelText('Service')).toBeChecked(); expect(rendered.getByLabelText('Website')).toBeChecked(); fireEvent.click(rendered.getByLabelText('Service')); + fireEvent.click(rendered.getByTestId('categories-picker-expand')); expect(rendered.getByLabelText('Service')).not.toBeChecked(); expect(rendered.getByLabelText('Website')).toBeChecked(); fireEvent.click(rendered.getByLabelText('Website')); + fireEvent.click(rendered.getByTestId('categories-picker-expand')); expect(rendered.getByLabelText('Service')).not.toBeChecked(); expect(rendered.getByLabelText('Website')).not.toBeChecked(); }); From 70fdfbf36af07366ae77fbbc511f05ef88bedd11 Mon Sep 17 00:00:00 2001 From: victormorfin97 Date: Wed, 8 Sep 2021 10:55:41 -0600 Subject: [PATCH 041/125] Add the changeset Signed-off-by: victormorfin97 --- .changeset/poor-weeks-act.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/poor-weeks-act.md diff --git a/.changeset/poor-weeks-act.md b/.changeset/poor-weeks-act.md new file mode 100644 index 0000000000..a9a4e54695 --- /dev/null +++ b/.changeset/poor-weeks-act.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Change the catagories filter to a dropdown component From 24a70ae1eae56462bdeb77e0ff85937775280233 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Sep 2021 04:12:43 +0000 Subject: [PATCH 042/125] chore(deps-dev): bump @types/tar from 4.0.4 to 4.0.5 Bumps [@types/tar](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/tar) from 4.0.4 to 4.0.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/tar) --- updated-dependencies: - dependency-name: "@types/tar" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5db9fd7589..e58e6fe0ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7417,9 +7417,9 @@ integrity sha512-0VBprVqfgFD7Ehb2vd8Lh9TG3jP98gvr8rgehQqzztZNI7o8zS8Ad4jyZneKELphpuE212D8J70LnSNQSyO6bQ== "@types/tar@^4.0.3": - version "4.0.4" - resolved "https://registry.npmjs.org/@types/tar/-/tar-4.0.4.tgz#d680de60855e7778a51c672b755869a3b8d2889f" - integrity sha512-0Xv+xcmkTsOZdIF4yCnd7RkOOyfyqPaqJ7RZFKnwdxfDbkN3eAAE9sHl8zJFqBz4VhxolW9EErbjR1oyH7jK2A== + version "4.0.5" + resolved "https://registry.npmjs.org/@types/tar/-/tar-4.0.5.tgz#5f953f183e36a15c6ce3f336568f6051b7b183f3" + integrity sha512-cgwPhNEabHaZcYIy5xeMtux2EmYBitfqEceBUi2t5+ETy4dW6kswt6WX4+HqLeiiKOo42EXbGiDmVJ2x+vi37Q== dependencies: "@types/minipass" "*" "@types/node" "*" @@ -27589,9 +27589,9 @@ write-pkg@^4.0.0: write-json-file "^3.2.0" ws@7.4.5, ws@^7.4.6: - version "7.5.4" - resolved "https://registry.npmjs.org/ws/-/ws-7.5.4.tgz#56bfa20b167427e138a7795de68d134fe92e21f9" - integrity sha512-zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljohg== + version "7.5.5" + resolved "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" + integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== ws@^5.2.0: version "5.2.3" From 96fef17a18993f08a611f83e988ed2f0dcc9e6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20A=CC=8Ahsberg?= Date: Wed, 8 Sep 2021 16:10:05 +0000 Subject: [PATCH 043/125] chore(deps) bump git-url-parse from 11.4.4 to 11.6.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mathias Åhsberg --- .changeset/strong-geese-hope.md | 13 +++++++++++++ packages/backend-common/package.json | 2 +- packages/integration/package.json | 2 +- packages/techdocs-common/package.json | 2 +- plugins/catalog-backend/package.json | 2 +- plugins/catalog-import/package.json | 2 +- plugins/catalog/package.json | 2 +- plugins/scaffolder-backend/package.json | 2 +- plugins/scaffolder/package.json | 2 +- plugins/techdocs/package.json | 2 +- yarn.lock | 9 ++++++++- 11 files changed, 30 insertions(+), 10 deletions(-) create mode 100644 .changeset/strong-geese-hope.md diff --git a/.changeset/strong-geese-hope.md b/.changeset/strong-geese-hope.md new file mode 100644 index 0000000000..27da35743a --- /dev/null +++ b/.changeset/strong-geese-hope.md @@ -0,0 +1,13 @@ +--- +'@backstage/backend-common': patch +'@backstage/integration': patch +'@backstage/techdocs-common': patch +'@backstage/plugin-catalog': patch +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-catalog-import': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-scaffolder-backend': patch +'@backstage/plugin-techdocs': patch +--- + +Upgrade git-parse-url to v11.6.0 diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 87d1053165..ac7a738ae8 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -49,7 +49,7 @@ "express": "^4.17.1", "express-promise-router": "^4.1.0", "fs-extra": "9.1.0", - "git-url-parse": "~11.4.4", + "git-url-parse": "^11.6.0", "helmet": "^4.0.0", "isomorphic-git": "^1.8.0", "keyv": "^4.0.3", diff --git a/packages/integration/package.json b/packages/integration/package.json index 5ae86ea163..5358912852 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -31,7 +31,7 @@ "dependencies": { "@backstage/config": "^0.1.8", "cross-fetch": "^3.0.6", - "git-url-parse": "~11.4.4", + "git-url-parse": "^11.6.0", "@octokit/rest": "^18.5.3", "@octokit/auth-app": "^3.4.0", "luxon": "^2.0.2" diff --git a/packages/techdocs-common/package.json b/packages/techdocs-common/package.json index a914830fd5..2316d96a55 100644 --- a/packages/techdocs-common/package.json +++ b/packages/techdocs-common/package.json @@ -50,7 +50,7 @@ "aws-sdk": "^2.840.0", "express": "^4.17.1", "fs-extra": "9.1.0", - "git-url-parse": "~11.4.4", + "git-url-parse": "^11.6.0", "js-yaml": "^4.0.0", "json5": "^2.1.3", "mime-types": "^2.1.27", diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 9c4ddef0b8..6abc09d9b3 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -47,7 +47,7 @@ "express-promise-router": "^4.1.0", "fast-json-stable-stringify": "^2.1.0", "fs-extra": "9.1.0", - "git-url-parse": "~11.4.4", + "git-url-parse": "^11.6.0", "glob": "^7.1.6", "knex": "^0.95.1", "lodash": "^4.17.15", diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 570658f712..4e5726c173 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -43,7 +43,7 @@ "@material-ui/lab": "4.0.0-alpha.45", "@octokit/rest": "^18.5.3", "@types/react": "*", - "git-url-parse": "~11.4.4", + "git-url-parse": "^11.6.0", "js-base64": "^3.6.0", "react": "^16.13.1", "react-dom": "^16.13.1", diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 89a0ca20cb..d22dcd7a70 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -44,7 +44,7 @@ "@material-ui/lab": "4.0.0-alpha.45", "@types/react": "*", "classnames": "^2.2.6", - "git-url-parse": "~11.4.4", + "git-url-parse": "^11.6.0", "lodash": "^4.17.21", "react": "^16.13.1", "react-dom": "^16.13.1", diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 902860679d..2ad55e9799 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -49,7 +49,7 @@ "express": "^4.17.1", "express-promise-router": "^4.1.0", "fs-extra": "10.0.0", - "git-url-parse": "~11.4.4", + "git-url-parse": "^11.6.0", "globby": "^11.0.0", "handlebars": "^4.7.6", "helmet": "^4.0.0", diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index c457da8b15..8dd51970a4 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -47,7 +47,7 @@ "@rjsf/material-ui": "^3.0.0", "@types/react": "*", "classnames": "^2.2.6", - "git-url-parse": "~11.4.4", + "git-url-parse": "^11.6.0", "humanize-duration": "^3.25.1", "immer": "^9.0.1", "json-schema": "^0.3.0", diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index a8ca36e2dd..ff81b8bc73 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -49,7 +49,7 @@ "@types/react": "*", "dompurify": "^2.2.9", "event-source-polyfill": "^1.0.25", - "git-url-parse": "~11.4.4", + "git-url-parse": "^11.6.0", "lodash": "^4.17.21", "react": "^16.13.1", "react-dom": "^16.13.1", diff --git a/yarn.lock b/yarn.lock index 5db9fd7589..bdbdbb8573 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14466,13 +14466,20 @@ git-up@^4.0.0: is-ssh "^1.3.0" parse-url "^5.0.0" -git-url-parse@^11.4.4, git-url-parse@~11.4.4: +git-url-parse@^11.4.4: version "11.4.4" resolved "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.4.4.tgz#5d747debc2469c17bc385719f7d0427802d83d77" integrity sha512-Y4o9o7vQngQDIU9IjyCmRJBin5iYjI5u9ZITnddRZpD7dcCFQj2sL2XuMNbLRE4b4B/4ENPsp2Q8P44fjAZ0Pw== dependencies: git-up "^4.0.0" +git-url-parse@^11.6.0: + version "11.6.0" + resolved "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.6.0.tgz#c634b8de7faa66498a2b88932df31702c67df605" + integrity sha512-WWUxvJs5HsyHL6L08wOusa/IXYtMuCAhrMmnTjQPpBU0TTHyDhnOATNH3xNQz7YOQUsqIIPTGr4xiVti1Hsk5g== + dependencies: + git-up "^4.0.0" + gitconfiglocal@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" From f63efec0ece9aaf39d0afd1ef2d08d2beb9a248c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 9 Sep 2021 11:39:33 +0200 Subject: [PATCH 044/125] Revert "fix `subpath` filtering for `AzureDevOps` `readTree`" Signed-off-by: Patrik Oldsberg --- .changeset/early-seahorses-stare.md | 5 ---- .../src/reading/AzureUrlReader.test.ts | 15 ---------- .../src/reading/AzureUrlReader.ts | 5 ++-- .../reading/tree/ZipArchiveResponse.test.ts | 30 +++++++++++++++++++ .../src/reading/tree/ZipArchiveResponse.ts | 20 +++++++++++-- 5 files changed, 49 insertions(+), 26 deletions(-) delete mode 100644 .changeset/early-seahorses-stare.md diff --git a/.changeset/early-seahorses-stare.md b/.changeset/early-seahorses-stare.md deleted file mode 100644 index 963058a26f..0000000000 --- a/.changeset/early-seahorses-stare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Fixing issue with `AzureUrlReader` that doesn't do `subpath` directories correctly diff --git a/packages/backend-common/src/reading/AzureUrlReader.test.ts b/packages/backend-common/src/reading/AzureUrlReader.test.ts index fc1f6a03f3..c7c8853929 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.test.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.test.ts @@ -220,21 +220,6 @@ describe('AzureUrlReader', () => { expect(indexMarkdownFile.toString()).toBe('# Test\n'); }); - it('returns the wanted files from an archive when a subpath is passed through', async () => { - const response = await processor.readTree( - 'https://dev.azure.com/organization/project/_git/repository?path=%2Fdocs', - ); - - expect(response.etag).toBe('123abc2'); - - const files = await response.files(); - - expect(files.length).toBe(1); - const indexMarkdownFile = await files[0].content(); - - expect(indexMarkdownFile.toString()).toBe('# Test\n'); - }); - it('creates a directory with the wanted files', async () => { const response = await processor.readTree( 'https://dev.azure.com/organization/project/_git/repository', diff --git a/packages/backend-common/src/reading/AzureUrlReader.ts b/packages/backend-common/src/reading/AzureUrlReader.ts index 2269393cbf..910e8e04a5 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.ts @@ -94,6 +94,8 @@ export class AzureUrlReader implements UrlReader { url: string, options?: ReadTreeOptions, ): Promise { + // TODO: Support filepath based reading tree feature like other providers + // Get latest commit SHA const commitsAzureResponse = await fetch( @@ -127,13 +129,10 @@ export class AzureUrlReader implements UrlReader { throw new Error(message); } - const { filepath } = parseGitUrl(url); - return await this.deps.treeResponseFactory.fromZipArchive({ stream: archiveAzureResponse.body as unknown as Readable, etag: commitSha, filter: options?.filter, - subpath: filepath, }); } diff --git a/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts b/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts index a54bac0c4a..f6f9a7845a 100644 --- a/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts +++ b/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts @@ -62,6 +62,36 @@ describe('ZipArchiveResponse', () => { ]); }); + it('should read files and strip root dir if requested', async () => { + const stream = fs.createReadStream('/test-archive-with-extra-root-dir.zip'); + + const res = new ZipArchiveResponse( + stream, + '', + '/tmp', + 'etag', + undefined, + true, + ); + const files = await res.files(); + + expect(files).toEqual([ + { + path: 'mkdocs.yml', + content: expect.any(Function), + }, + { + path: 'docs/index.md', + content: expect.any(Function), + }, + ]); + const contents = await Promise.all(files.map(f => f.content())); + expect(contents.map(c => c.toString('utf8').trim())).toEqual([ + 'site_name: Test', + '# Test', + ]); + }); + it('should read files with filter', async () => { const stream = fs.createReadStream('/test-archive.zip'); diff --git a/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts b/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts index e07cedde87..fb22f24b94 100644 --- a/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts +++ b/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts @@ -24,6 +24,7 @@ import { ReadTreeResponseDirOptions, ReadTreeResponseFile, } from '../types'; +import { stripFirstDirectoryFromPath } from './util'; /** * Wraps a zip archive stream into a tree response reader. @@ -37,6 +38,7 @@ export class ZipArchiveResponse implements ReadTreeResponse { private readonly workDir: string, public readonly etag: string, private readonly filter?: (path: string, info: { size: number }) => boolean, + private readonly stripFirstDirectory?: boolean, ) { if (subPath) { if (!subPath.endsWith('/')) { @@ -66,8 +68,12 @@ export class ZipArchiveResponse implements ReadTreeResponse { } private shouldBeIncluded(entry: Entry): boolean { + const strippedPath = this.stripFirstDirectory + ? stripFirstDirectoryFromPath(entry.path) + : entry.path; + if (this.subPath) { - if (!entry.path.startsWith(this.subPath)) { + if (!strippedPath.startsWith(this.subPath)) { return false; } } @@ -96,7 +102,11 @@ export class ZipArchiveResponse implements ReadTreeResponse { if (this.shouldBeIncluded(entry)) { files.push({ - path: this.getInnerPath(entry.path), + path: this.getInnerPath( + this.stripFirstDirectory + ? stripFirstDirectoryFromPath(entry.path) + : entry.path, + ), content: () => entry.buffer(), }); } else { @@ -144,7 +154,11 @@ export class ZipArchiveResponse implements ReadTreeResponse { // Ignore directory entries since we handle that with the file entries // as a zip can have files with directories without directory entries if (entry.type === 'File' && this.shouldBeIncluded(entry)) { - const entryPath = this.getInnerPath(entry.path); + const entryPath = this.getInnerPath( + this.stripFirstDirectory + ? stripFirstDirectoryFromPath(entry.path) + : entry.path, + ); const dirname = platformPath.dirname(entryPath); if (dirname) { await fs.mkdirp(platformPath.join(dir, dirname)); From f2ed25804b37c286872248aa1ce3dab533e08f01 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 9 Sep 2021 11:50:59 +0200 Subject: [PATCH 045/125] backend-common: keep ZipArchiveResponse removal of stripFirstDirectory Signed-off-by: Patrik Oldsberg --- .../reading/tree/ZipArchiveResponse.test.ts | 30 ------------------- .../src/reading/tree/ZipArchiveResponse.ts | 20 ++----------- 2 files changed, 3 insertions(+), 47 deletions(-) diff --git a/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts b/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts index f6f9a7845a..a54bac0c4a 100644 --- a/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts +++ b/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts @@ -62,36 +62,6 @@ describe('ZipArchiveResponse', () => { ]); }); - it('should read files and strip root dir if requested', async () => { - const stream = fs.createReadStream('/test-archive-with-extra-root-dir.zip'); - - const res = new ZipArchiveResponse( - stream, - '', - '/tmp', - 'etag', - undefined, - true, - ); - const files = await res.files(); - - expect(files).toEqual([ - { - path: 'mkdocs.yml', - content: expect.any(Function), - }, - { - path: 'docs/index.md', - content: expect.any(Function), - }, - ]); - const contents = await Promise.all(files.map(f => f.content())); - expect(contents.map(c => c.toString('utf8').trim())).toEqual([ - 'site_name: Test', - '# Test', - ]); - }); - it('should read files with filter', async () => { const stream = fs.createReadStream('/test-archive.zip'); diff --git a/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts b/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts index fb22f24b94..e07cedde87 100644 --- a/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts +++ b/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts @@ -24,7 +24,6 @@ import { ReadTreeResponseDirOptions, ReadTreeResponseFile, } from '../types'; -import { stripFirstDirectoryFromPath } from './util'; /** * Wraps a zip archive stream into a tree response reader. @@ -38,7 +37,6 @@ export class ZipArchiveResponse implements ReadTreeResponse { private readonly workDir: string, public readonly etag: string, private readonly filter?: (path: string, info: { size: number }) => boolean, - private readonly stripFirstDirectory?: boolean, ) { if (subPath) { if (!subPath.endsWith('/')) { @@ -68,12 +66,8 @@ export class ZipArchiveResponse implements ReadTreeResponse { } private shouldBeIncluded(entry: Entry): boolean { - const strippedPath = this.stripFirstDirectory - ? stripFirstDirectoryFromPath(entry.path) - : entry.path; - if (this.subPath) { - if (!strippedPath.startsWith(this.subPath)) { + if (!entry.path.startsWith(this.subPath)) { return false; } } @@ -102,11 +96,7 @@ export class ZipArchiveResponse implements ReadTreeResponse { if (this.shouldBeIncluded(entry)) { files.push({ - path: this.getInnerPath( - this.stripFirstDirectory - ? stripFirstDirectoryFromPath(entry.path) - : entry.path, - ), + path: this.getInnerPath(entry.path), content: () => entry.buffer(), }); } else { @@ -154,11 +144,7 @@ export class ZipArchiveResponse implements ReadTreeResponse { // Ignore directory entries since we handle that with the file entries // as a zip can have files with directories without directory entries if (entry.type === 'File' && this.shouldBeIncluded(entry)) { - const entryPath = this.getInnerPath( - this.stripFirstDirectory - ? stripFirstDirectoryFromPath(entry.path) - : entry.path, - ); + const entryPath = this.getInnerPath(entry.path); const dirname = platformPath.dirname(entryPath); if (dirname) { await fs.mkdirp(platformPath.join(dir, dirname)); From ef09feb9844c2b5fc93c093361d41214bda2b012 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Thu, 9 Sep 2021 08:17:41 -0500 Subject: [PATCH 046/125] Updated to use empty fragments for clarity Signed-off-by: Andre Wanlin --- plugins/home/src/components/HomepageCompositionRoot.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/home/src/components/HomepageCompositionRoot.tsx b/plugins/home/src/components/HomepageCompositionRoot.tsx index 563af75d64..f2c5ad0e8b 100644 --- a/plugins/home/src/components/HomepageCompositionRoot.tsx +++ b/plugins/home/src/components/HomepageCompositionRoot.tsx @@ -23,5 +23,5 @@ export const HomepageCompositionRoot = (props: { }) => { const outlet = useOutlet(); const children = props.children ?? outlet; - return
{children}
; + return <>{children}; }; From 80de2b7965b4ba0431f1d173baeb591ab0d535fb Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Thu, 9 Sep 2021 08:25:17 -0500 Subject: [PATCH 047/125] Updated changeset to minor and added migration instructions Signed-off-by: Andre Wanlin --- .changeset/late-mangos-allow.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/.changeset/late-mangos-allow.md b/.changeset/late-mangos-allow.md index 82a180c836..e1e4fe1d56 100644 --- a/.changeset/late-mangos-allow.md +++ b/.changeset/late-mangos-allow.md @@ -1,5 +1,28 @@ --- -'@backstage/plugin-home': patch +'@backstage/plugin-home': minor --- -Added the HomepageTimer to the new composable Home Page +The homepage `
` is now part of the composable canvas (allowing you to add the , for example). + +You will need to wrap your existing composed `` component in ``, `
`, and `` components, like this: + +```diff +// app/src/components/home/HomePage.tsx + ++ import { Content, Header, Page, HomePageTimer } from '@backstage/core-components'; + +export const HomePage = () => ( ++ ++
++ ++
++ + + + + + // ... ++ ++
+); +``` From 560d6810f0892d1a57c08b4a657a5f9c65a296fe Mon Sep 17 00:00:00 2001 From: Guilherme Vierno Date: Wed, 8 Sep 2021 16:41:53 -0300 Subject: [PATCH 048/125] fix(auth-backend): update gitlab refresh token on refresh Signed-off-by: Guilherme Vierno --- .changeset/afraid-trainers-know.md | 5 + .../src/providers/gitlab/provider.test.ts | 106 +++++++++++++----- .../src/providers/gitlab/provider.ts | 1 + 3 files changed, 86 insertions(+), 26 deletions(-) create mode 100644 .changeset/afraid-trainers-know.md diff --git a/.changeset/afraid-trainers-know.md b/.changeset/afraid-trainers-know.md new file mode 100644 index 0000000000..5df3d3eced --- /dev/null +++ b/.changeset/afraid-trainers-know.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Fix a bug preventing an access token to be refreshed a second time with the GitLab provider. diff --git a/plugins/auth-backend/src/providers/gitlab/provider.test.ts b/plugins/auth-backend/src/providers/gitlab/provider.test.ts index f8795aec34..d1a84b43e8 100644 --- a/plugins/auth-backend/src/providers/gitlab/provider.test.ts +++ b/plugins/auth-backend/src/providers/gitlab/provider.test.ts @@ -16,6 +16,7 @@ import { GitlabAuthProvider, gitlabDefaultSignInResolver } from './provider'; import * as helpers from '../../lib/passport/PassportStrategyHelper'; +import { PassportProfile } from '../../lib/passport/types'; import { OAuthResult } from '../../lib/oauth'; import { getVoidLogger } from '@backstage/backend-common'; import { TokenIssuer } from '../../identity'; @@ -27,6 +28,33 @@ const mockFrameHandler = jest.spyOn( ) as unknown as jest.MockedFunction<() => Promise<{ result: OAuthResult }>>; describe('GitlabAuthProvider', () => { + const tokenIssuer = { + issueToken: jest.fn(), + listPublicKeys: jest.fn(), + }; + const catalogIdentityClient = { + findUser: jest.fn(), + }; + + const provider = new GitlabAuthProvider({ + clientId: 'mock', + clientSecret: 'mock', + callbackUrl: 'mock', + baseUrl: 'mock', + catalogIdentityClient: + catalogIdentityClient as unknown as CatalogIdentityClient, + tokenIssuer: tokenIssuer as unknown as TokenIssuer, + authHandler: async ({ fullProfile }) => ({ + profile: { + email: fullProfile.emails![0]!.value, + displayName: fullProfile.displayName, + picture: 'http://gitlab.com/lols', + }, + }), + signInResolver: gitlabDefaultSignInResolver, + logger: getVoidLogger(), + }); + it('should transform to type OAuthResponse', async () => { const tests = [ { @@ -117,36 +145,62 @@ describe('GitlabAuthProvider', () => { }, ]; - const tokenIssuer = { - issueToken: jest.fn(), - listPublicKeys: jest.fn(), - }; - const catalogIdentityClient = { - findUser: jest.fn(), - }; - - const provider = new GitlabAuthProvider({ - clientId: 'mock', - clientSecret: 'mock', - callbackUrl: 'mock', - baseUrl: 'mock', - catalogIdentityClient: - catalogIdentityClient as unknown as CatalogIdentityClient, - tokenIssuer: tokenIssuer as unknown as TokenIssuer, - authHandler: async ({ fullProfile }) => ({ - profile: { - email: fullProfile.emails![0]!.value, - displayName: fullProfile.displayName, - picture: 'http://gitlab.com/lols', - }, - }), - signInResolver: gitlabDefaultSignInResolver, - logger: getVoidLogger(), - }); for (const test of tests) { mockFrameHandler.mockResolvedValueOnce(test.input); const { response } = await provider.handler({} as any); expect(response).toEqual(test.expect); } }); + + it('should forward a new refresh token on refresh', async () => { + const mockRefreshToken = jest.spyOn( + helpers, + 'executeRefreshTokenStrategy', + ) as unknown as jest.MockedFunction<() => Promise<{}>>; + + mockRefreshToken.mockResolvedValueOnce({ + accessToken: 'a.b.c', + refreshToken: 'dont-forget-to-send-refresh', + params: { + id_token: 'my-id', + scope: 'read_user', + }, + }); + + const mockUserProfile = jest.spyOn( + helpers, + 'executeFetchUserProfileStrategy', + ) as unknown as jest.MockedFunction<() => Promise>; + + mockUserProfile.mockResolvedValueOnce({ + id: 'uid-my-id', + username: 'mockuser', + provider: 'gitlab', + displayName: 'Mocked User', + emails: [ + { + value: 'mockuser@gmail.com', + }, + ], + }); + + const response = await provider.refresh({} as any); + + expect(response).toEqual({ + backstageIdentity: { + id: 'mockuser', + }, + profile: { + displayName: 'Mocked User', + email: 'mockuser@gmail.com', + picture: 'http://gitlab.com/lols', + }, + providerInfo: { + accessToken: 'a.b.c', + idToken: 'my-id', + refreshToken: 'dont-forget-to-send-refresh', + scope: 'read_user', + }, + }); + }); }); diff --git a/plugins/auth-backend/src/providers/gitlab/provider.ts b/plugins/auth-backend/src/providers/gitlab/provider.ts index 419f00a346..6ca405d15f 100644 --- a/plugins/auth-backend/src/providers/gitlab/provider.ts +++ b/plugins/auth-backend/src/providers/gitlab/provider.ts @@ -177,6 +177,7 @@ export class GitlabAuthProvider implements OAuthHandlers { providerInfo: { idToken: result.params.id_token, accessToken: result.accessToken, + refreshToken: result.refreshToken, // GitLab expires the old refresh token when used scope: result.params.scope, expiresInSeconds: result.params.expires_in, }, From 866ec85375567074731a290d42c2fadbd364a5db Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 9 Sep 2021 14:47:05 +0000 Subject: [PATCH 049/125] Version Packages --- .changeset/breezy-camels-bake.md | 5 --- .changeset/breezy-gifts-wave.md | 5 --- .changeset/bright-birds-jog.md | 14 -------- .changeset/dull-trains-shout.md | 11 ------ .changeset/fast-wasps-matter.md | 23 ------------- .changeset/forty-moons-boil.md | 5 --- .changeset/good-singers-flourish.md | 6 ---- .changeset/great-balloons-walk.md | 5 --- .changeset/happy-cups-tap.md | 5 --- .changeset/long-walls-tie.md | 5 --- .changeset/lovely-windows-return.md | 5 --- .changeset/lucky-lies-count.md | 5 --- .changeset/perfect-elephants-do.md | 21 ------------ .changeset/sour-bees-pretend.md | 5 --- .changeset/strange-buckets-design.md | 16 --------- .changeset/strong-pears-wink.md | 5 --- .changeset/tall-beds-bake.md | 5 --- .changeset/twenty-ravens-fetch.md | 5 --- .changeset/wicked-files-brush.md | 5 --- .changeset/wise-monkeys-enjoy.md | 5 --- .changeset/yellow-hats-sniff.md | 6 ---- packages/app/CHANGELOG.md | 16 +++++++++ packages/app/package.json | 22 ++++++------ packages/backend-common/CHANGELOG.md | 11 ++++++ packages/backend-common/package.json | 12 +++---- packages/backend-test-utils/CHANGELOG.md | 10 ++++++ packages/backend-test-utils/package.json | 10 +++--- packages/catalog-client/CHANGELOG.md | 10 ++++++ packages/catalog-client/package.json | 10 +++--- packages/catalog-model/CHANGELOG.md | 9 +++++ packages/catalog-model/package.json | 8 ++--- packages/cli-common/CHANGELOG.md | 6 ++++ packages/cli-common/package.json | 2 +- packages/cli/CHANGELOG.md | 11 ++++++ packages/cli/package.json | 20 +++++------ packages/codemods/CHANGELOG.md | 10 ++++++ packages/codemods/package.json | 4 +-- packages/config-loader/CHANGELOG.md | 9 +++++ packages/config-loader/package.json | 6 ++-- packages/config/CHANGELOG.md | 6 ++++ packages/config/package.json | 2 +- packages/core-app-api/CHANGELOG.md | 10 ++++++ packages/core-app-api/package.json | 10 +++--- packages/core-components/CHANGELOG.md | 20 +++++++++++ packages/core-components/package.json | 12 +++---- packages/core-plugin-api/CHANGELOG.md | 8 +++++ packages/core-plugin-api/package.json | 8 ++--- packages/create-app/CHANGELOG.md | 27 +++++++++++++++ packages/create-app/package.json | 4 +-- packages/dev-utils/CHANGELOG.md | 11 ++++++ packages/dev-utils/package.json | 12 +++---- packages/errors/CHANGELOG.md | 9 +++++ packages/errors/package.json | 6 ++-- plugins/allure/package.json | 10 +++--- plugins/api-docs/package.json | 10 +++--- plugins/badges/package.json | 10 +++--- plugins/bitrise/package.json | 10 +++--- plugins/catalog-backend/CHANGELOG.md | 43 ++++++++++++++++++++++++ plugins/catalog-backend/package.json | 16 ++++----- plugins/catalog-import/package.json | 10 +++--- plugins/catalog/package.json | 10 +++--- plugins/circleci/package.json | 10 +++--- plugins/cloudbuild/package.json | 10 +++--- plugins/code-coverage/package.json | 10 +++--- plugins/config-schema/package.json | 10 +++--- plugins/cost-insights/package.json | 10 +++--- plugins/explore/package.json | 10 +++--- plugins/firehydrant/package.json | 10 +++--- plugins/fossa/package.json | 10 +++--- plugins/gcp-projects/package.json | 10 +++--- plugins/git-release-manager/package.json | 10 +++--- plugins/github-actions/package.json | 10 +++--- plugins/github-deployments/package.json | 10 +++--- plugins/gitops-profiles/package.json | 10 +++--- plugins/graphiql/package.json | 10 +++--- plugins/home/CHANGELOG.md | 13 +++++++ plugins/home/package.json | 12 +++---- plugins/ilert/package.json | 10 +++--- plugins/jenkins/package.json | 10 +++--- plugins/kafka/package.json | 10 +++--- plugins/kubernetes/package.json | 10 +++--- plugins/lighthouse/package.json | 10 +++--- plugins/newrelic/package.json | 10 +++--- plugins/org/CHANGELOG.md | 11 ++++++ plugins/org/package.json | 14 ++++---- plugins/pagerduty/package.json | 10 +++--- plugins/rollbar/package.json | 10 +++--- plugins/scaffolder-backend/CHANGELOG.md | 13 +++++++ plugins/scaffolder-backend/package.json | 14 ++++---- plugins/scaffolder/CHANGELOG.md | 14 ++++++++ plugins/scaffolder/package.json | 20 +++++------ plugins/search/CHANGELOG.md | 12 +++++++ plugins/search/package.json | 18 +++++----- plugins/sentry/package.json | 10 +++--- plugins/shortcuts/package.json | 10 +++--- plugins/sonarqube/package.json | 10 +++--- plugins/splunk-on-call/package.json | 10 +++--- plugins/tech-radar/package.json | 10 +++--- plugins/techdocs/package.json | 12 +++---- plugins/todo/CHANGELOG.md | 12 +++++++ plugins/todo/package.json | 16 ++++----- plugins/user-settings/package.json | 10 +++--- plugins/welcome/package.json | 10 +++--- plugins/xcmetrics/package.json | 10 +++--- 104 files changed, 616 insertions(+), 482 deletions(-) delete mode 100644 .changeset/breezy-camels-bake.md delete mode 100644 .changeset/breezy-gifts-wave.md delete mode 100644 .changeset/bright-birds-jog.md delete mode 100644 .changeset/dull-trains-shout.md delete mode 100644 .changeset/fast-wasps-matter.md delete mode 100644 .changeset/forty-moons-boil.md delete mode 100644 .changeset/good-singers-flourish.md delete mode 100644 .changeset/great-balloons-walk.md delete mode 100644 .changeset/happy-cups-tap.md delete mode 100644 .changeset/long-walls-tie.md delete mode 100644 .changeset/lovely-windows-return.md delete mode 100644 .changeset/lucky-lies-count.md delete mode 100644 .changeset/perfect-elephants-do.md delete mode 100644 .changeset/sour-bees-pretend.md delete mode 100644 .changeset/strange-buckets-design.md delete mode 100644 .changeset/strong-pears-wink.md delete mode 100644 .changeset/tall-beds-bake.md delete mode 100644 .changeset/twenty-ravens-fetch.md delete mode 100644 .changeset/wicked-files-brush.md delete mode 100644 .changeset/wise-monkeys-enjoy.md delete mode 100644 .changeset/yellow-hats-sniff.md diff --git a/.changeset/breezy-camels-bake.md b/.changeset/breezy-camels-bake.md deleted file mode 100644 index 4ec6e7dab1..0000000000 --- a/.changeset/breezy-camels-bake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-todo': patch ---- - -Fix TodoList table column widths diff --git a/.changeset/breezy-gifts-wave.md b/.changeset/breezy-gifts-wave.md deleted file mode 100644 index 2bea8e8cd1..0000000000 --- a/.changeset/breezy-gifts-wave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Fix issue #7021 scaffolder action fetch:template preserves templates file permissions diff --git a/.changeset/bright-birds-jog.md b/.changeset/bright-birds-jog.md deleted file mode 100644 index 20954eca77..0000000000 --- a/.changeset/bright-birds-jog.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Fix warning produced by BottomLink component - -During development, we noticed warnings such as: - -``` -react_devtools_backend.js:2842 Warning: validateDOMNesting(...):
cannot appear as a descendant of

. -``` - -The BottomLink component renders a Box component within a Typography component which leads to a div tag within a p tag. -This change inverts that ordering without changing the visual appearance. diff --git a/.changeset/dull-trains-shout.md b/.changeset/dull-trains-shout.md deleted file mode 100644 index bfd9a461d3..0000000000 --- a/.changeset/dull-trains-shout.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/backend-test-utils': patch -'@backstage/catalog-client': patch -'@backstage/catalog-model': patch -'@backstage/cli-common': patch -'@backstage/config-loader': patch -'@backstage/dev-utils': patch -'@backstage/errors': patch ---- - -Properly export all used types. diff --git a/.changeset/fast-wasps-matter.md b/.changeset/fast-wasps-matter.md deleted file mode 100644 index 6b6a682a37..0000000000 --- a/.changeset/fast-wasps-matter.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Updated the search configuration class to use the static `fromConfig`-based constructor for the `DefaultCatalogCollator`. - -To apply this change to an existing app, replace the following line in `search.ts`: - -```diff --collator: new DefaultCatalogCollator({ discovery }) -+collator: DefaultCatalogCollator.fromConfig(config, { discovery }) -``` - -The `config` parameter was not needed before, so make sure you also add that in the signature of `createPlugin` -in `search.ts`: - -```diff -export default async function createPlugin({ - logger, - discovery, -+ config, -}: PluginEnvironment) { -``` diff --git a/.changeset/forty-moons-boil.md b/.changeset/forty-moons-boil.md deleted file mode 100644 index 0000374546..0000000000 --- a/.changeset/forty-moons-boil.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-todo': patch ---- - -All types are now properly documented and exported. diff --git a/.changeset/good-singers-flourish.md b/.changeset/good-singers-flourish.md deleted file mode 100644 index d8b6e1a140..0000000000 --- a/.changeset/good-singers-flourish.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-home': minor ---- - -Rename RandomJokeHomePageComponent to HomePageRandomJoke to fit convention, and update example app accordingly. -**NOTE**: If you're using the RandomJoke component in your instance, it now has to be renamed to `HomePageRandomJoke` diff --git a/.changeset/great-balloons-walk.md b/.changeset/great-balloons-walk.md deleted file mode 100644 index 7675a2badd..0000000000 --- a/.changeset/great-balloons-walk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/config': patch ---- - -Documented `Config` interface and mark types as public. diff --git a/.changeset/happy-cups-tap.md b/.changeset/happy-cups-tap.md deleted file mode 100644 index 051f9def1c..0000000000 --- a/.changeset/happy-cups-tap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Allow the catalog search collator to filter the entities that it indexes diff --git a/.changeset/long-walls-tie.md b/.changeset/long-walls-tie.md deleted file mode 100644 index c23c34b4ce..0000000000 --- a/.changeset/long-walls-tie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -GitHub Webhook action in Scaffolder Backend has been improved to validate event names against Octokit Webhook event names list. diff --git a/.changeset/lovely-windows-return.md b/.changeset/lovely-windows-return.md deleted file mode 100644 index 55755af563..0000000000 --- a/.changeset/lovely-windows-return.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Disable all buttons in the final step when 'Create' button is clicked in template. diff --git a/.changeset/lucky-lies-count.md b/.changeset/lucky-lies-count.md deleted file mode 100644 index 79e7c09391..0000000000 --- a/.changeset/lucky-lies-count.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-org': patch ---- - -Make ownership card style customizable via custom `theme.getPageTheme()`. diff --git a/.changeset/perfect-elephants-do.md b/.changeset/perfect-elephants-do.md deleted file mode 100644 index d5e4c864d7..0000000000 --- a/.changeset/perfect-elephants-do.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Use `ScmIntegrationRegistry#resolveUrl` in the placeholder processors instead of a custom implementation. - -If you manually instantiate the `PlaceholderProcessor` (you most probably don't), add the new required constructor parameter: - -```diff -+ import { ScmIntegrations } from '@backstage/integration'; - // ... -+ const integrations = ScmIntegrations.fromConfig(config); - // ... - new PlaceholderProcessor({ - resolvers: placeholderResolvers, - reader, -+ integrations, - }); -``` - -All custom `PlaceholderResolver` can use the new `resolveUrl` parameter to resolve relative URLs. diff --git a/.changeset/sour-bees-pretend.md b/.changeset/sour-bees-pretend.md deleted file mode 100644 index 748266132c..0000000000 --- a/.changeset/sour-bees-pretend.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-org': patch ---- - -Use correct `Link` in ownership card to avoid a full reload of the app while navigating. diff --git a/.changeset/strange-buckets-design.md b/.changeset/strange-buckets-design.md deleted file mode 100644 index 3cdf858174..0000000000 --- a/.changeset/strange-buckets-design.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -This change drops support for deprecated location types which have all been replaced by the `url` type. -There has been a deprecation warning in place since the beginning of this year so most should already be migrated and received information at this point. - -The now removed location types are: - -``` -github -github/api -bitbucket/api -gitlab/api -azure/api -``` diff --git a/.changeset/strong-pears-wink.md b/.changeset/strong-pears-wink.md deleted file mode 100644 index 811eb56519..0000000000 --- a/.changeset/strong-pears-wink.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Fix display error when it fails to load a template (/create) page diff --git a/.changeset/tall-beds-bake.md b/.changeset/tall-beds-bake.md deleted file mode 100644 index 2a0c9f7023..0000000000 --- a/.changeset/tall-beds-bake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-app-api': patch ---- - -Removed deprecated internal functions. diff --git a/.changeset/twenty-ravens-fetch.md b/.changeset/twenty-ravens-fetch.md deleted file mode 100644 index 28393b7936..0000000000 --- a/.changeset/twenty-ravens-fetch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search': patch ---- - -Add Home Page Search Bar Component, to be included in composable Home Page. diff --git a/.changeset/wicked-files-brush.md b/.changeset/wicked-files-brush.md deleted file mode 100644 index c4391ba4dd..0000000000 --- a/.changeset/wicked-files-brush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-plugin-api': patch ---- - -Migrated component data attachment method to have better compatibility with component proxies such as `react-hot-loader`. diff --git a/.changeset/wise-monkeys-enjoy.md b/.changeset/wise-monkeys-enjoy.md deleted file mode 100644 index 446d5bbfad..0000000000 --- a/.changeset/wise-monkeys-enjoy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Properly export all used types. diff --git a/.changeset/yellow-hats-sniff.md b/.changeset/yellow-hats-sniff.md deleted file mode 100644 index b360cfef29..0000000000 --- a/.changeset/yellow-hats-sniff.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Support importing font files in tests. -This fixes remaining issues from [#7019](https://github.com/backstage/backstage/pull/7019). diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 7de19802e3..9b6dc1956a 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,21 @@ # example-app +## 0.2.45 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-todo@0.1.9 + - @backstage/core-components@0.4.1 + - @backstage/catalog-model@0.9.2 + - @backstage/plugin-home@0.3.0 + - @backstage/plugin-scaffolder@0.11.3 + - @backstage/plugin-org@0.3.22 + - @backstage/core-app-api@0.1.12 + - @backstage/plugin-search@0.4.10 + - @backstage/core-plugin-api@0.1.7 + - @backstage/cli@0.7.11 + ## 0.2.44 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 011fcb59af..db7a99e632 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,14 +1,14 @@ { "name": "example-app", - "version": "0.2.44", + "version": "0.2.45", "private": true, "bundled": true, "dependencies": { - "@backstage/catalog-model": "^0.9.1", - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/catalog-model": "^0.9.2", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/integration-react": "^0.1.8", "@backstage/plugin-api-docs": "^0.6.7", "@backstage/plugin-badges": "^0.2.8", @@ -23,22 +23,22 @@ "@backstage/plugin-gcp-projects": "^0.3.3", "@backstage/plugin-github-actions": "^0.4.17", "@backstage/plugin-graphiql": "^0.2.15", - "@backstage/plugin-home": "^0.2.1", + "@backstage/plugin-home": "^0.3.0", "@backstage/plugin-jenkins": "^0.5.5", "@backstage/plugin-kafka": "^0.2.14", "@backstage/plugin-kubernetes": "^0.4.12", "@backstage/plugin-lighthouse": "^0.2.24", "@backstage/plugin-newrelic": "^0.3.3", - "@backstage/plugin-org": "^0.3.21", + "@backstage/plugin-org": "^0.3.22", "@backstage/plugin-pagerduty": "0.3.12", "@backstage/plugin-rollbar": "^0.3.13", - "@backstage/plugin-scaffolder": "^0.11.2", - "@backstage/plugin-search": "^0.4.9", + "@backstage/plugin-scaffolder": "^0.11.3", + "@backstage/plugin-search": "^0.4.10", "@backstage/plugin-sentry": "^0.3.20", "@backstage/plugin-shortcuts": "^0.1.7", "@backstage/plugin-tech-radar": "^0.4.6", "@backstage/plugin-techdocs": "^0.11.1", - "@backstage/plugin-todo": "^0.1.8", + "@backstage/plugin-todo": "^0.1.9", "@backstage/plugin-user-settings": "^0.3.4", "@backstage/search-common": "^0.2.0", "@backstage/theme": "^0.2.10", diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index dc83e3aa3c..7ffd6e52dc 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/backend-common +## 0.9.2 + +### Patch Changes + +- 9e5ed27ec: Properly export all used types. +- Updated dependencies + - @backstage/cli-common@0.1.3 + - @backstage/config-loader@0.6.8 + - @backstage/errors@0.1.2 + - @backstage/config@0.1.9 + ## 0.9.1 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 87d1053165..fd0e9a946c 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-common", "description": "Common functionality library for Backstage backends", - "version": "0.9.1", + "version": "0.9.2", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -29,10 +29,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/cli-common": "^0.1.2", - "@backstage/config": "^0.1.8", - "@backstage/config-loader": "^0.6.7", - "@backstage/errors": "^0.1.1", + "@backstage/cli-common": "^0.1.3", + "@backstage/config": "^0.1.9", + "@backstage/config-loader": "^0.6.8", + "@backstage/errors": "^0.1.2", "@backstage/integration": "^0.6.3", "@google-cloud/storage": "^5.8.0", "@octokit/rest": "^18.5.3", @@ -77,7 +77,7 @@ } }, "devDependencies": { - "@backstage/cli": "^0.7.10", + "@backstage/cli": "^0.7.11", "@backstage/test-utils": "^0.1.17", "@types/archiver": "^5.1.0", "@types/compression": "^1.7.0", diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 6d33537e7c..6e10d188df 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/backend-test-utils +## 0.1.7 + +### Patch Changes + +- d1da88a19: Properly export all used types. +- Updated dependencies + - @backstage/config@0.1.9 + - @backstage/backend-common@0.9.2 + - @backstage/cli@0.7.11 + ## 0.1.6 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index cd2855b833..1713f05d25 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-test-utils", "description": "Test helpers library for Backstage backends", - "version": "0.1.6", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -30,9 +30,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.9.0", - "@backstage/cli": "^0.7.8", - "@backstage/config": "^0.1.8", + "@backstage/backend-common": "^0.9.2", + "@backstage/cli": "^0.7.11", + "@backstage/config": "^0.1.9", "knex": "^0.95.1", "mysql2": "^2.2.5", "pg": "^8.3.0", @@ -41,7 +41,7 @@ "uuid": "^8.0.0" }, "devDependencies": { - "@backstage/cli": "^0.7.8", + "@backstage/cli": "^0.7.11", "jest": "^26.0.1" }, "files": [ diff --git a/packages/catalog-client/CHANGELOG.md b/packages/catalog-client/CHANGELOG.md index d04d1dc936..b32007a3e2 100644 --- a/packages/catalog-client/CHANGELOG.md +++ b/packages/catalog-client/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/catalog-client +## 0.3.19 + +### Patch Changes + +- d1da88a19: Properly export all used types. +- Updated dependencies + - @backstage/catalog-model@0.9.2 + - @backstage/errors@0.1.2 + - @backstage/config@0.1.9 + ## 0.3.18 ### Patch Changes diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index cdbee32305..2040090fde 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/catalog-client", - "version": "0.3.18", + "version": "0.3.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,13 +29,13 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.9.0", - "@backstage/config": "^0.1.5", - "@backstage/errors": "^0.1.1", + "@backstage/catalog-model": "^0.9.2", + "@backstage/config": "^0.1.9", + "@backstage/errors": "^0.1.2", "cross-fetch": "^3.0.6" }, "devDependencies": { - "@backstage/cli": "^0.7.6", + "@backstage/cli": "^0.7.11", "@types/jest": "^26.0.7", "msw": "^0.29.0" }, diff --git a/packages/catalog-model/CHANGELOG.md b/packages/catalog-model/CHANGELOG.md index 3559c661ef..6e6a7193c1 100644 --- a/packages/catalog-model/CHANGELOG.md +++ b/packages/catalog-model/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/catalog-model +## 0.9.2 + +### Patch Changes + +- d1da88a19: Properly export all used types. +- Updated dependencies + - @backstage/errors@0.1.2 + - @backstage/config@0.1.9 + ## 0.9.1 ### Patch Changes diff --git a/packages/catalog-model/package.json b/packages/catalog-model/package.json index 5a16a1d310..a20fb235c6 100644 --- a/packages/catalog-model/package.json +++ b/packages/catalog-model/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/catalog-model", - "version": "0.9.1", + "version": "0.9.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,8 +29,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.5", - "@backstage/errors": "^0.1.1", + "@backstage/config": "^0.1.9", + "@backstage/errors": "^0.1.2", "@types/json-schema": "^7.0.5", "@types/yup": "^0.29.8", "ajv": "^7.0.3", @@ -40,7 +40,7 @@ "yup": "^0.29.3" }, "devDependencies": { - "@backstage/cli": "^0.7.10", + "@backstage/cli": "^0.7.11", "@types/express": "^4.17.6", "@types/jest": "^26.0.7", "@types/lodash": "^4.14.151", diff --git a/packages/cli-common/CHANGELOG.md b/packages/cli-common/CHANGELOG.md index 52a247f57a..8a2a903efd 100644 --- a/packages/cli-common/CHANGELOG.md +++ b/packages/cli-common/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/cli-common +## 0.1.3 + +### Patch Changes + +- d1da88a19: Properly export all used types. + ## 0.1.2 ### Patch Changes diff --git a/packages/cli-common/package.json b/packages/cli-common/package.json index 16f10717f9..c643192df3 100644 --- a/packages/cli-common/package.json +++ b/packages/cli-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli-common", "description": "Common functionality used by cli, backend, and create-app", - "version": "0.1.2", + "version": "0.1.3", "private": false, "main": "src/index.ts", "types": "src/index.ts", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 47f4545ea2..f404b49e48 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/cli +## 0.7.11 + +### Patch Changes + +- 13895db37: Support importing font files in tests. + This fixes remaining issues from [#7019](https://github.com/backstage/backstage/pull/7019). +- Updated dependencies + - @backstage/cli-common@0.1.3 + - @backstage/config-loader@0.6.8 + - @backstage/config@0.1.9 + ## 0.7.10 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 831a4af0c3..12cc584e2d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli", "description": "CLI for developing Backstage plugins and apps", - "version": "0.7.10", + "version": "0.7.11", "private": false, "publishConfig": { "access": "public" @@ -30,9 +30,9 @@ "dependencies": { "@babel/core": "^7.4.4", "@babel/plugin-transform-modules-commonjs": "^7.4.4", - "@backstage/cli-common": "^0.1.2", - "@backstage/config": "^0.1.8", - "@backstage/config-loader": "^0.6.7", + "@backstage/cli-common": "^0.1.3", + "@backstage/config": "^0.1.9", + "@backstage/config-loader": "^0.6.8", "@hot-loader/react-dom": "^16.13.0", "@lerna/package-graph": "^4.0.0", "@lerna/project": "^4.0.0", @@ -120,12 +120,12 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/backend-common": "^0.9.1", - "@backstage/config": "^0.1.8", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/backend-common": "^0.9.2", + "@backstage/config": "^0.1.9", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@backstage/theme": "^0.2.10", "@types/diff": "^5.0.0", diff --git a/packages/codemods/CHANGELOG.md b/packages/codemods/CHANGELOG.md index e0b3bfb693..aa21ebc3a1 100644 --- a/packages/codemods/CHANGELOG.md +++ b/packages/codemods/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/codemods +## 0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.4.1 + - @backstage/cli-common@0.1.3 + - @backstage/core-app-api@0.1.12 + - @backstage/core-plugin-api@0.1.7 + ## 0.1.12 ### Patch Changes diff --git a/packages/codemods/package.json b/packages/codemods/package.json index b14d3e880e..0fbafe7fe2 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/codemods", "description": "A collection of codemods for Backstage projects", - "version": "0.1.12", + "version": "0.1.13", "private": false, "publishConfig": { "access": "public", @@ -31,7 +31,7 @@ "backstage-codemods": "bin/backstage-codemods" }, "dependencies": { - "@backstage/cli-common": "0.1.2", + "@backstage/cli-common": "0.1.3", "@backstage/core-app-api": "*", "@backstage/core-components": "*", "@backstage/core-plugin-api": "*", diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md index aee4cf453f..88479bbb18 100644 --- a/packages/config-loader/CHANGELOG.md +++ b/packages/config-loader/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/config-loader +## 0.6.8 + +### Patch Changes + +- d1da88a19: Properly export all used types. +- Updated dependencies + - @backstage/cli-common@0.1.3 + - @backstage/config@0.1.9 + ## 0.6.7 ### Patch Changes diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index f810841d3e..0f5bac2ffc 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config-loader", "description": "Config loading functionality used by Backstage backend, and CLI", - "version": "0.6.7", + "version": "0.6.8", "private": false, "publishConfig": { "access": "public", @@ -30,8 +30,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/cli-common": "^0.1.1", - "@backstage/config": "^0.1.7", + "@backstage/cli-common": "^0.1.3", + "@backstage/config": "^0.1.9", "@types/json-schema": "^7.0.6", "ajv": "^7.0.3", "chokidar": "^3.5.2", diff --git a/packages/config/CHANGELOG.md b/packages/config/CHANGELOG.md index 742ae86a57..7691ed2865 100644 --- a/packages/config/CHANGELOG.md +++ b/packages/config/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/config +## 0.1.9 + +### Patch Changes + +- f88b2c7db: Documented `Config` interface and mark types as public. + ## 0.1.8 ### Patch Changes diff --git a/packages/config/package.json b/packages/config/package.json index 6adee62ca3..969bc44045 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config", "description": "Config API used by Backstage core, backend, and CLI", - "version": "0.1.8", + "version": "0.1.9", "private": false, "publishConfig": { "access": "public", diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index 55b20aac8b..9020661647 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/core-app-api +## 0.1.12 + +### Patch Changes + +- 841666a19: Removed deprecated internal functions. +- Updated dependencies + - @backstage/core-components@0.4.1 + - @backstage/config@0.1.9 + - @backstage/core-plugin-api@0.1.7 + ## 0.1.11 ### Patch Changes diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index e0801b45db..5223d2b27e 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-app-api", "description": "Core app API used by Backstage apps", - "version": "0.1.11", + "version": "0.1.12", "private": false, "publishConfig": { "access": "public", @@ -29,9 +29,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.4.0", - "@backstage/config": "^0.1.8", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/config": "^0.1.9", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -44,7 +44,7 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.7.10", + "@backstage/cli": "^0.7.11", "@backstage/test-utils": "^0.1.17", "@backstage/test-utils-core": "^0.1.2", "@testing-library/jest-dom": "^5.10.1", diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index 0f89c26682..1c195cdd2c 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/core-components +## 0.4.1 + +### Patch Changes + +- 06e275705: Fix warning produced by BottomLink component + + During development, we noticed warnings such as: + + ``` + react_devtools_backend.js:2842 Warning: validateDOMNesting(...):

cannot appear as a descendant of

. + ``` + + The BottomLink component renders a Box component within a Typography component which leads to a div tag within a p tag. + This change inverts that ordering without changing the visual appearance. + +- Updated dependencies + - @backstage/errors@0.1.2 + - @backstage/config@0.1.9 + - @backstage/core-plugin-api@0.1.7 + ## 0.4.0 ### Minor Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index 720482f46b..7ac256ad30 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-components", "description": "Core components used by Backstage plugins and apps", - "version": "0.4.0", + "version": "0.4.1", "private": false, "publishConfig": { "access": "public", @@ -29,9 +29,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.8", - "@backstage/core-plugin-api": "^0.1.6", - "@backstage/errors": "^0.1.1", + "@backstage/config": "^0.1.9", + "@backstage/core-plugin-api": "^0.1.7", + "@backstage/errors": "^0.1.2", "@backstage/theme": "^0.2.10", "@material-table/core": "^3.1.0", "@material-ui/core": "^4.12.2", @@ -70,8 +70,8 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/core-app-api": "^0.1.11", - "@backstage/cli": "^0.7.10", + "@backstage/core-app-api": "^0.1.12", + "@backstage/cli": "^0.7.11", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/packages/core-plugin-api/CHANGELOG.md b/packages/core-plugin-api/CHANGELOG.md index 2a76ab243f..4cd9b4ade7 100644 --- a/packages/core-plugin-api/CHANGELOG.md +++ b/packages/core-plugin-api/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/core-plugin-api +## 0.1.7 + +### Patch Changes + +- 3d238b028: Migrated component data attachment method to have better compatibility with component proxies such as `react-hot-loader`. +- Updated dependencies + - @backstage/config@0.1.9 + ## 0.1.6 ### Patch Changes diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index d482795c90..414ca2afe1 100644 --- a/packages/core-plugin-api/package.json +++ b/packages/core-plugin-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-plugin-api", "description": "Core API used by Backstage plugins", - "version": "0.1.6", + "version": "0.1.7", "private": false, "publishConfig": { "access": "public", @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.6", + "@backstage/config": "^0.1.9", "@backstage/theme": "^0.2.9", "@material-ui/core": "^4.12.2", "@types/react": "*", @@ -41,8 +41,8 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.7.8", - "@backstage/core-app-api": "^0.1.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", "@backstage/test-utils": "^0.1.17", "@backstage/test-utils-core": "^0.1.2", "@testing-library/jest-dom": "^5.10.1", diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 670613dac9..f8d93846ba 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/create-app +## 0.3.40 + +### Patch Changes + +- a5013957e: Updated the search configuration class to use the static `fromConfig`-based constructor for the `DefaultCatalogCollator`. + + To apply this change to an existing app, replace the following line in `search.ts`: + + ```diff + -collator: new DefaultCatalogCollator({ discovery }) + +collator: DefaultCatalogCollator.fromConfig(config, { discovery }) + ``` + + The `config` parameter was not needed before, so make sure you also add that in the signature of `createPlugin` + in `search.ts`: + + ```diff + export default async function createPlugin({ + logger, + discovery, + + config, + }: PluginEnvironment) { + ``` + +- Updated dependencies + - @backstage/cli-common@0.1.3 + ## 0.3.39 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index f0939c213e..aac845093f 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "Create app package for Backstage", - "version": "0.3.39", + "version": "0.3.40", "private": false, "publishConfig": { "access": "public" @@ -27,7 +27,7 @@ "start": "nodemon --" }, "dependencies": { - "@backstage/cli-common": "^0.1.2", + "@backstage/cli-common": "^0.1.3", "chalk": "^4.0.0", "commander": "^6.1.0", "fs-extra": "9.1.0", diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index f0c4c062b4..b15b3437f2 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/dev-utils +## 0.2.9 + +### Patch Changes + +- d1da88a19: Properly export all used types. +- Updated dependencies + - @backstage/core-components@0.4.1 + - @backstage/catalog-model@0.9.2 + - @backstage/core-app-api@0.1.12 + - @backstage/core-plugin-api@0.1.7 + ## 0.2.8 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 9317c0a107..5d6bbba3d7 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/dev-utils", "description": "Utilities for developing Backstage plugins.", - "version": "0.2.8", + "version": "0.2.9", "private": false, "publishConfig": { "access": "public", @@ -29,10 +29,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-app-api": "^0.1.11", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", - "@backstage/catalog-model": "^0.9.1", + "@backstage/core-app-api": "^0.1.12", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", + "@backstage/catalog-model": "^0.9.2", "@backstage/integration-react": "^0.1.8", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/test-utils": "^0.1.17", @@ -50,7 +50,7 @@ "react-router-dom": "6.0.0-beta.0" }, "devDependencies": { - "@backstage/cli": "^0.7.10", + "@backstage/cli": "^0.7.11", "@types/jest": "^26.0.7", "@types/node": "^14.14.32" }, diff --git a/packages/errors/CHANGELOG.md b/packages/errors/CHANGELOG.md index e69de29bb2..7cadaa6e07 100644 --- a/packages/errors/CHANGELOG.md +++ b/packages/errors/CHANGELOG.md @@ -0,0 +1,9 @@ +# @backstage/errors + +## 0.1.2 + +### Patch Changes + +- d1da88a19: Properly export all used types. +- Updated dependencies + - @backstage/config@0.1.9 diff --git a/packages/errors/package.json b/packages/errors/package.json index 8fa76d8bfc..dc31d8827e 100644 --- a/packages/errors/package.json +++ b/packages/errors/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/errors", - "version": "0.1.1", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,12 +29,12 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.2", + "@backstage/config": "^0.1.9", "cross-fetch": "^3.0.6", "serialize-error": "^8.0.1" }, "devDependencies": { - "@backstage/cli": "^0.7.0", + "@backstage/cli": "^0.7.11", "@types/jest": "^26.0.7" }, "files": [ diff --git a/plugins/allure/package.json b/plugins/allure/package.json index bc56349a1c..efa44cb6f8 100644 --- a/plugins/allure/package.json +++ b/plugins/allure/package.json @@ -22,8 +22,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -35,9 +35,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 083464ed9b..63871ce4e1 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -31,8 +31,8 @@ "dependencies": { "@asyncapi/react-component": "^0.23.0", "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog": "^0.6.14", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", @@ -52,9 +52,9 @@ "swagger-ui-react": "^3.37.2" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 7a8bf9079f..8b286599e5 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -21,8 +21,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", @@ -35,9 +35,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index d0b9a012f5..a476d0f4cb 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -21,8 +21,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -38,9 +38,9 @@ "recharts": "^1.8.5" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 67b71f3fe8..ddf62aa655 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,48 @@ # @backstage/plugin-catalog-backend +## 0.13.7 + +### Patch Changes + +- ce17a1693: Allow the catalog search collator to filter the entities that it indexes +- dbb952787: Use `ScmIntegrationRegistry#resolveUrl` in the placeholder processors instead of a custom implementation. + + If you manually instantiate the `PlaceholderProcessor` (you most probably don't), add the new required constructor parameter: + + ```diff + + import { ScmIntegrations } from '@backstage/integration'; + // ... + + const integrations = ScmIntegrations.fromConfig(config); + // ... + new PlaceholderProcessor({ + resolvers: placeholderResolvers, + reader, + + integrations, + }); + ``` + + All custom `PlaceholderResolver` can use the new `resolveUrl` parameter to resolve relative URLs. + +- 1797c5ce5: This change drops support for deprecated location types which have all been replaced by the `url` type. + There has been a deprecation warning in place since the beginning of this year so most should already be migrated and received information at this point. + + The now removed location types are: + + ``` + github + github/api + bitbucket/api + gitlab/api + azure/api + ``` + +- Updated dependencies + - @backstage/catalog-client@0.3.19 + - @backstage/catalog-model@0.9.2 + - @backstage/errors@0.1.2 + - @backstage/config@0.1.9 + - @backstage/backend-common@0.9.2 + ## 0.13.6 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 9c4ddef0b8..2ceaa40241 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend", - "version": "0.13.6", + "version": "0.13.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,11 +29,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.9.1", - "@backstage/catalog-client": "^0.3.18", - "@backstage/catalog-model": "^0.9.1", - "@backstage/config": "^0.1.8", - "@backstage/errors": "^0.1.1", + "@backstage/backend-common": "^0.9.2", + "@backstage/catalog-client": "^0.3.19", + "@backstage/catalog-model": "^0.9.2", + "@backstage/config": "^0.1.9", + "@backstage/errors": "^0.1.2", "@backstage/integration": "^0.6.3", "@backstage/plugin-search-backend-node": "^0.4.2", "@backstage/search-common": "^0.2.0", @@ -63,8 +63,8 @@ "yup": "^0.29.3" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.6", - "@backstage/cli": "^0.7.10", + "@backstage/backend-test-utils": "^0.1.7", + "@backstage/cli": "^0.7.11", "@backstage/test-utils": "^0.1.17", "@types/core-js": "^2.5.4", "@types/git-url-parse": "^9.0.0", diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 570658f712..10a984c908 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -32,8 +32,8 @@ "dependencies": { "@backstage/catalog-client": "^0.3.18", "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/integration": "^0.6.3", "@backstage/integration-react": "^0.1.8", "@backstage/plugin-catalog-react": "^0.4.5", @@ -54,9 +54,9 @@ "yaml": "^1.10.0" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 89a0ca20cb..ac5f3f679c 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -32,8 +32,8 @@ "dependencies": { "@backstage/catalog-client": "^0.3.18", "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.6.3", "@backstage/integration-react": "^0.1.8", @@ -54,9 +54,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index a828a26ba0..466171e6ac 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -32,8 +32,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -50,9 +50,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index f28a42bac6..d45542a082 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -31,8 +31,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -48,9 +48,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index d69ce9c910..061e4108c1 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -22,8 +22,8 @@ "dependencies": { "@backstage/catalog-model": "^0.9.1", "@backstage/config": "^0.1.6", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", @@ -40,9 +40,9 @@ "recharts": "^1.8.5" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 8001f6b055..b6fb078a6a 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -21,8 +21,8 @@ }, "dependencies": { "@backstage/config": "^0.1.6", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/errors": "^0.1.1", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -35,9 +35,9 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index b48888025d..f4cad51d21 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -31,8 +31,8 @@ }, "dependencies": { "@backstage/config": "^0.1.6", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -54,9 +54,9 @@ "yup": "^0.29.3" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 204fa7f1ae..85e9e32669 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -31,8 +31,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/plugin-explore-react": "^0.0.6", "@backstage/theme": "^0.2.10", @@ -48,9 +48,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index be6abb11ff..551c6af021 100644 --- a/plugins/firehydrant/package.json +++ b/plugins/firehydrant/package.json @@ -21,8 +21,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -34,9 +34,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index 1fbcdb1a90..7fb897095b 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -32,8 +32,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", @@ -48,9 +48,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 9c81c58f3c..0e8028d0b8 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -30,8 +30,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -42,9 +42,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json index 0427f4d7fd..8a6cd56e37 100644 --- a/plugins/git-release-manager/package.json +++ b/plugins/git-release-manager/package.json @@ -20,8 +20,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/integration": "^0.6.3", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -38,9 +38,9 @@ "recharts": "^1.8.5" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 0d2aba6af4..97bbee8913 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -33,8 +33,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/integration": "^0.6.3", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", @@ -51,9 +51,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index 420a948ec3..f5439d9bc6 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -21,8 +21,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.6.3", "@backstage/integration-react": "^0.1.8", @@ -38,9 +38,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index 95300a86af..cec185dadc 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -43,9 +43,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index ec74cedd37..302c0361a7 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -44,9 +44,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index c573ebb32b..0092442f02 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-home +## 0.3.0 + +### Minor Changes + +- 7f00902d9: Rename RandomJokeHomePageComponent to HomePageRandomJoke to fit convention, and update example app accordingly. + **NOTE**: If you're using the RandomJoke component in your instance, it now has to be renamed to `HomePageRandomJoke` + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.4.1 + - @backstage/core-plugin-api@0.1.7 + ## 0.2.1 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index 8ae92e8ace..86b9d238a4 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home", - "version": "0.2.1", + "version": "0.3.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,8 +20,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -33,9 +33,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index b3591fb903..689a4ec957 100644 --- a/plugins/ilert/package.json +++ b/plugins/ilert/package.json @@ -21,8 +21,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", @@ -38,9 +38,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index c9e0b5a36d..b25cffef61 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -32,8 +32,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -47,9 +47,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index 3024d88311..06fb56a17e 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -21,8 +21,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -34,9 +34,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 7d64315e0c..fe4391e1f7 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -32,8 +32,8 @@ "dependencies": { "@backstage/catalog-model": "^0.9.1", "@backstage/config": "^0.1.6", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/plugin-kubernetes-common": "^0.1.3", "@backstage/theme": "^0.2.10", @@ -50,9 +50,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 256767ede6..8702dc8f99 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -33,8 +33,8 @@ "dependencies": { "@backstage/catalog-model": "^0.9.1", "@backstage/config": "^0.1.6", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -47,9 +47,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index dfb245b65f..16a03ec473 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -42,9 +42,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index b6b94201ce..ff6ed74c6b 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-org +## 0.3.22 + +### Patch Changes + +- 6ad8fe1a0: Make ownership card style customizable via custom `theme.getPageTheme()`. +- 70718686f: Use correct `Link` in ownership card to avoid a full reload of the app while navigating. +- Updated dependencies + - @backstage/core-components@0.4.1 + - @backstage/catalog-model@0.9.2 + - @backstage/core-plugin-api@0.1.7 + ## 0.3.21 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index 22df2e6606..60abb61e74 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org", - "version": "0.3.21", + "version": "0.3.22", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,9 +20,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/catalog-model": "^0.9.2", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -36,9 +36,9 @@ "qs": "^6.10.1" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index b8066e9080..ddeaecb462 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -31,8 +31,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -47,9 +47,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index 79cfab6f43..e2384b6b1b 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -32,8 +32,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -48,9 +48,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 5827b82466..1024798587 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend +## 0.15.4 + +### Patch Changes + +- 04aad2dab: Fix issue #7021 scaffolder action fetch:template preserves templates file permissions +- 21ccd4997: GitHub Webhook action in Scaffolder Backend has been improved to validate event names against Octokit Webhook event names list. +- Updated dependencies + - @backstage/catalog-client@0.3.19 + - @backstage/catalog-model@0.9.2 + - @backstage/errors@0.1.2 + - @backstage/config@0.1.9 + - @backstage/backend-common@0.9.2 + ## 0.15.3 ### Patch Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 902860679d..ca924fecc6 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend", - "version": "0.15.3", + "version": "0.15.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,11 +29,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.9.1", - "@backstage/catalog-client": "^0.3.17", - "@backstage/catalog-model": "^0.9.1", - "@backstage/config": "^0.1.8", - "@backstage/errors": "^0.1.1", + "@backstage/backend-common": "^0.9.2", + "@backstage/catalog-client": "^0.3.19", + "@backstage/catalog-model": "^0.9.2", + "@backstage/config": "^0.1.9", + "@backstage/errors": "^0.1.2", "@backstage/integration": "^0.6.3", "@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.1.2", "@gitbeaker/core": "^30.2.0", @@ -67,7 +67,7 @@ "yaml": "^1.10.0" }, "devDependencies": { - "@backstage/cli": "^0.7.10", + "@backstage/cli": "^0.7.11", "@backstage/test-utils": "^0.1.17", "@types/command-exists": "^1.2.0", "@types/fs-extra": "^9.0.1", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index f180e67011..922d583a57 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-scaffolder +## 0.11.3 + +### Patch Changes + +- c299e90a2: Disable all buttons in the final step when 'Create' button is clicked in template. +- 3acf5988f: Fix display error when it fails to load a template (/create) page +- Updated dependencies + - @backstage/core-components@0.4.1 + - @backstage/catalog-client@0.3.19 + - @backstage/catalog-model@0.9.2 + - @backstage/errors@0.1.2 + - @backstage/config@0.1.9 + - @backstage/core-plugin-api@0.1.7 + ## 0.11.2 ### Patch Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index c457da8b15..b4a46eb98d 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder", - "version": "0.11.2", + "version": "0.11.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,12 +30,12 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-client": "^0.3.18", - "@backstage/catalog-model": "^0.9.1", - "@backstage/config": "^0.1.7", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", - "@backstage/errors": "^0.1.1", + "@backstage/catalog-client": "^0.3.19", + "@backstage/catalog-model": "^0.9.2", + "@backstage/config": "^0.1.9", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", + "@backstage/errors": "^0.1.2", "@backstage/integration": "^0.6.3", "@backstage/integration-react": "^0.1.8", "@backstage/plugin-catalog-react": "^0.4.5", @@ -63,9 +63,9 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index de2af423dd..cb869810dc 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search +## 0.4.10 + +### Patch Changes + +- 7f00902d9: Add Home Page Search Bar Component, to be included in composable Home Page. +- Updated dependencies + - @backstage/core-components@0.4.1 + - @backstage/catalog-model@0.9.2 + - @backstage/errors@0.1.2 + - @backstage/config@0.1.9 + - @backstage/core-plugin-api@0.1.7 + ## 0.4.9 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index 900ea3c11d..c60ae7c5d8 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search", - "version": "0.4.9", + "version": "0.4.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,11 +29,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.9.1", - "@backstage/config": "^0.1.8", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", - "@backstage/errors": "^0.1.1", + "@backstage/catalog-model": "^0.9.2", + "@backstage/config": "^0.1.9", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", + "@backstage/errors": "^0.1.2", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/search-common": "^0.2.0", "@backstage/theme": "^0.2.10", @@ -49,9 +49,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index 5b7f174583..7241858e78 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -32,8 +32,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -47,9 +47,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index 1df0981b18..a5e03e97e4 100644 --- a/plugins/shortcuts/package.json +++ b/plugins/shortcuts/package.json @@ -20,8 +20,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -36,9 +36,9 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 3fce16b5fe..e821dd0bf5 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -33,8 +33,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -48,9 +48,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index 5d821dd44b..b3704d7551 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -31,8 +31,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -46,9 +46,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index cede08d9f4..46b279c3fd 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -30,8 +30,8 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -44,9 +44,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index a8ca36e2dd..27576a6beb 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -33,14 +33,14 @@ "dependencies": { "@backstage/catalog-model": "^0.9.1", "@backstage/config": "^0.1.8", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/errors": "^0.1.1", - "@backstage/plugin-search": "^0.4.9", "@backstage/integration": "^0.6.3", "@backstage/integration-react": "^0.1.8", "@backstage/plugin-catalog": "^0.6.14", "@backstage/plugin-catalog-react": "^0.4.5", + "@backstage/plugin-search": "^0.4.9", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -60,9 +60,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/todo/CHANGELOG.md b/plugins/todo/CHANGELOG.md index d867c6fe77..bbab997e8f 100644 --- a/plugins/todo/CHANGELOG.md +++ b/plugins/todo/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-todo +## 0.1.9 + +### Patch Changes + +- a3734ba27: Fix TodoList table column widths +- b07378742: All types are now properly documented and exported. +- Updated dependencies + - @backstage/core-components@0.4.1 + - @backstage/catalog-model@0.9.2 + - @backstage/errors@0.1.2 + - @backstage/core-plugin-api@0.1.7 + ## 0.1.8 ### Patch Changes diff --git a/plugins/todo/package.json b/plugins/todo/package.json index eb02b12a20..73b29f14e1 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-todo", - "version": "0.1.8", + "version": "0.1.9", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -26,10 +26,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.9.1", - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", - "@backstage/errors": "^0.1.1", + "@backstage/catalog-model": "^0.9.2", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", + "@backstage/errors": "^0.1.2", "@backstage/plugin-catalog-react": "^0.4.5", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -40,9 +40,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index cef50d1f2b..73208f3ec6 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -30,8 +30,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -42,10 +42,10 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", "@backstage/core-plugin-api": "^0.1.5", - "@backstage/dev-utils": "^0.2.8", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/welcome/package.json b/plugins/welcome/package.json index 9dbf2a3a04..07989801c8 100644 --- a/plugins/welcome/package.json +++ b/plugins/welcome/package.json @@ -30,8 +30,8 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -42,9 +42,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index dc72855765..a5cadb03ac 100644 --- a/plugins/xcmetrics/package.json +++ b/plugins/xcmetrics/package.json @@ -20,8 +20,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.4.0", - "@backstage/core-plugin-api": "^0.1.6", + "@backstage/core-components": "^0.4.1", + "@backstage/core-plugin-api": "^0.1.7", "@backstage/errors": "^0.1.1", "@backstage/theme": "^0.2.10", "@material-ui/core": "^4.12.2", @@ -34,9 +34,9 @@ "recharts": "^1.8.5" }, "devDependencies": { - "@backstage/cli": "^0.7.10", - "@backstage/core-app-api": "^0.1.11", - "@backstage/dev-utils": "^0.2.8", + "@backstage/cli": "^0.7.11", + "@backstage/core-app-api": "^0.1.12", + "@backstage/dev-utils": "^0.2.9", "@backstage/test-utils": "^0.1.17", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", From b14a4846bd9b27fc3f41e57785b302cc2f34ffec Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 9 Sep 2021 17:28:06 +0200 Subject: [PATCH 050/125] codeowners: add @backstage/reviewers ownership to some paths Signed-off-by: Patrik Oldsberg --- .github/CODEOWNERS | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 781feb1f04..0854635a2b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,18 +8,18 @@ /docs/features/techdocs @backstage/techdocs-core /docs/features/search @backstage/techdocs-core /docs/assets/search @backstage/techdocs-core -/plugins/code-coverage @alde @nissayeva -/plugins/code-coverage-backend @alde @nissayeva +/plugins/code-coverage @backstage/reviewers @alde @nissayeva +/plugins/code-coverage-backend @backstage/reviewers @alde @nissayeva /plugins/cost-insights @backstage/silver-lining -/plugins/cloudbuild @trivago/ebarrios +/plugins/cloudbuild @backstage/reviewers @trivago/ebarrios /plugins/search @backstage/techdocs-core /plugins/search-* @backstage/techdocs-core /plugins/techdocs @backstage/techdocs-core /plugins/techdocs-backend @backstage/techdocs-core -/plugins/ilert @yacut +/plugins/ilert @backstage/reviewers @yacut /plugins/home @backstage/techdocs-core /packages/search-common @backstage/techdocs-core /packages/techdocs-common @backstage/techdocs-core -/.changeset/cost-insights-* @backstage/silver-lining +/.changeset/cost-insights-* @backstage/reviewers @backstage/silver-lining /.changeset/search-* @backstage/techdocs-core /.changeset/techdocs-* @backstage/techdocs-core From 33271a7f4aa1c18e86f96dfab95bc99856991321 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 9 Sep 2021 18:26:59 +0200 Subject: [PATCH 051/125] github/workflows: add snyk monitoring workflow Signed-off-by: Patrik Oldsberg --- .github/workflows/snyk-monitor.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/snyk-monitor.yml diff --git a/.github/workflows/snyk-monitor.yml b/.github/workflows/snyk-monitor.yml new file mode 100644 index 0000000000..5c6f5b722d --- /dev/null +++ b/.github/workflows/snyk-monitor.yml @@ -0,0 +1,29 @@ +name: Snyk Monitoring + +on: + workflow_dispatch: + push: + branches: [master] + paths: + - '.snyk' + - '.github/workflows/snyk-monitor.yml' + - '**/package.json' + - 'yarn.lock' + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Monitor and Synchronize Snyk Policies + uses: snyk/actions/node@master + with: + command: monitor + args: > + --yarn-workspaces + --policy-path=.snyk + --org=backstage-dgh + --strict-out-of-sync=false + --remote-repo-url=https://github.com/backstage/backstage + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} From b3ccc97df801d5284cf291f2cbc98dbe66901344 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 9 Sep 2021 19:40:38 +0200 Subject: [PATCH 052/125] snyk: move .snyk into each package dir instead of a single root one Signed-off-by: Patrik Oldsberg --- .github/workflows/snyk-monitor.yml | 1 - .snyk => packages/app/.snyk | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) rename .snyk => packages/app/.snyk (87%) diff --git a/.github/workflows/snyk-monitor.yml b/.github/workflows/snyk-monitor.yml index 5c6f5b722d..a6dc0d6e77 100644 --- a/.github/workflows/snyk-monitor.yml +++ b/.github/workflows/snyk-monitor.yml @@ -21,7 +21,6 @@ jobs: command: monitor args: > --yarn-workspaces - --policy-path=.snyk --org=backstage-dgh --strict-out-of-sync=false --remote-repo-url=https://github.com/backstage/backstage diff --git a/.snyk b/packages/app/.snyk similarity index 87% rename from .snyk rename to packages/app/.snyk index 732671517a..8fbbfa574c 100644 --- a/.snyk +++ b/packages/app/.snyk @@ -3,7 +3,7 @@ version: v1.22.1 # ignores vulnerabilities until expiry date; change duration by modifying expiry date ignore: SNYK-JS-ANSIHTML-1296849: - - '@backstage/cli > webpack-dev-server > ansi-html': + - 'webpack-dev-server > ansi-html': reason: Developer tools are not a valid target for ReDoS attacks expires: 2022-03-06T17:18:55.019Z created: 2021-09-06T17:18:55.027Z From c414c907cb06470fbf8cf70ddc5340c0141f14d0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 9 Sep 2021 20:08:09 +0200 Subject: [PATCH 053/125] SECURITY: add a section describing how we handle snyk policies Signed-off-by: Patrik Oldsberg --- .github/workflows/snyk-monitor.yml | 5 +++++ SECURITY.md | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/.github/workflows/snyk-monitor.yml b/.github/workflows/snyk-monitor.yml index 5c6f5b722d..7435550c68 100644 --- a/.github/workflows/snyk-monitor.yml +++ b/.github/workflows/snyk-monitor.yml @@ -10,6 +10,11 @@ on: - '**/package.json' - 'yarn.lock' +# This workflow synchronizes the packages in this repo along with policies in +# each .snyk file with the remote state in our snyk org. It allows us to define +# ignore policies in the .snyk files and then have them show up in the snyk web +# UI, and also automatically adds any new packages that are created. + jobs: sync: runs-on: ubuntu-latest diff --git a/SECURITY.md b/SECURITY.md index b410404bcf..ba96c694ee 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -26,3 +26,13 @@ In the event of a vulnerability the runbook for the maintainers is as follows: 1. Create one or multiple Pull Requests with fixes towards the fork. Note that these PRs will not have CI checks run on them, so more care should be taken to run local validation. The PRs are also not merged like normal PRs, but are instead merged straight into the main repo all at once when the merge button is hit on the security advisory. 4. Once the fix is ready in a PR or private fork and it is time to release it, there are a couple of options. Either merge into the main branch with a changeset and wait for a regular release, or do a quick release by manually bumping the version in `package.json` of the affected package, along with a manual `CHANGELOG.md` entry. Note that a quick release will only work if the package does not have any other pending changes that depend on pending changes in other packages, so be sure to manually check that first, and fall back to an early regular release if needed. In general it's best to stick with the regular release flow, with the quick release being used only for time sensitive fixes. 5. Finalize and publish the security advisory. Note that once you hit the publish button it's no longer possible to edit the advisory. Just like the CVE number this can take up to 72h, and expect it to be slower than the CVE number request. + +## Vulnerability Policies + +Backstage uses Snyk vulnerability scans in order to make sure we minimize vulnerabilities in our dependencies and get notified of new vulnerabilities. + +There are many situations where a vulnerability does not affect a particular dependency because of how the vulnerable package is used. In that situation the package authors may choose to stay at the current version rather than bumping the dependency, leading to a warning in the vulnerability scans but no actual vulnerability. + +To work around this and other similar issues, Snyk provides a method to ignore vulnerabilities. In order to provide the best visibility and most utility to adopters of Backstage, we store these ignore rules in `.snyk` policy files. This allows adopters to rely on our ignore policies if they wish to do so. + +Adding a new ignore policy is done by creating or modifying an existing `.snyk` file within a package root. See the [Snyk Documentation](https://support.snyk.io/hc/en-us/articles/360007487097-The-snyk-file) for details on the syntax. Always include a description, full path, and time limit of the ignore policy. From 14834a340bad589b98c8a78fd31477061722d40f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 9 Sep 2021 20:19:27 +0200 Subject: [PATCH 054/125] snyk: move .snyk from app to cli where it belongs Signed-off-by: Patrik Oldsberg --- packages/{app => cli}/.snyk | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/{app => cli}/.snyk (100%) diff --git a/packages/app/.snyk b/packages/cli/.snyk similarity index 100% rename from packages/app/.snyk rename to packages/cli/.snyk From cb173f7440e879825ddf484ec3ddb83df87e2053 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 9 Sep 2021 21:17:55 +0200 Subject: [PATCH 055/125] github/workflows: fix .snyk path pattern Signed-off-by: Patrik Oldsberg --- .github/workflows/snyk-monitor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/snyk-monitor.yml b/.github/workflows/snyk-monitor.yml index a6dc0d6e77..16e961ebee 100644 --- a/.github/workflows/snyk-monitor.yml +++ b/.github/workflows/snyk-monitor.yml @@ -5,8 +5,8 @@ on: push: branches: [master] paths: - - '.snyk' - '.github/workflows/snyk-monitor.yml' + - '**/.snyk' - '**/package.json' - 'yarn.lock' From e57ab03a070c6730c11b77a6c9eb8f03dc94d5a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Sep 2021 04:07:23 +0000 Subject: [PATCH 056/125] chore(deps-dev): bump prettier from 2.3.2 to 2.4.0 in /microsite Bumps [prettier](https://github.com/prettier/prettier) from 2.3.2 to 2.4.0. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.3.2...2.4.0) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- microsite/package.json | 2 +- microsite/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/microsite/package.json b/microsite/package.json index 532bb62d15..b3048612a7 100644 --- a/microsite/package.json +++ b/microsite/package.json @@ -19,7 +19,7 @@ "@spotify/prettier-config": "^11.0.0", "docusaurus": "^2.0.0-alpha.70", "js-yaml": "^4.1.0", - "prettier": "^2.3.2", + "prettier": "^2.4.0", "yarn-lock-check": "^1.0.5" }, "prettier": "@spotify/prettier-config" diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 0f7ddb9c60..0938f7e2f7 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -5207,10 +5207,10 @@ prepend-http@^2.0.0: resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= -prettier@^2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" - integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== +prettier@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.0.tgz#85bdfe0f70c3e777cf13a4ffff39713ca6f64cba" + integrity sha512-DsEPLY1dE5HF3BxCRBmD4uYZ+5DCbvatnolqTqcxEgKVZnL2kUfyu7b8pPQ5+hTBkdhU9SLUmK0/pHb07RE4WQ== prismjs@^1.22.0: version "1.23.0" From 4d283f28b246b2f8f0c2a39d80b5b3e8760ab3d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Sep 2021 04:10:52 +0000 Subject: [PATCH 057/125] chore(deps-dev): bump @types/stoppable from 1.1.0 to 1.1.1 Bumps [@types/stoppable](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/stoppable) from 1.1.0 to 1.1.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/stoppable) --- updated-dependencies: - dependency-name: "@types/stoppable" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index e58e6fe0ac..a3d5121dfd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7369,9 +7369,9 @@ integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== "@types/stoppable@^1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@types/stoppable/-/stoppable-1.1.0.tgz#a5fa6a48120b109ca9233eed05c67c50bc4f3b91" - integrity sha512-BRR23Q9CJduH7AM6mk4JRttd8XyFkb4qIPZu4mdLF+VoP+wcjIxIWIKiBbN78NBbEuynrAyMPtzOHnIp2B/JPQ== + version "1.1.1" + resolved "https://registry.npmjs.org/@types/stoppable/-/stoppable-1.1.1.tgz#a6f1f280e29f8f3c743277534425e0a75041d2f9" + integrity sha512-b8N+fCADRIYYrGZOcmOR8ZNBOqhktWTB/bMUl5LvGtT201QKJZOOH5UsFyI3qtteM6ZAJbJqZoBcLqqxKIwjhw== dependencies: "@types/node" "*" @@ -11040,9 +11040,9 @@ core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: integrity sha512-GUbtPllXMYRzIgHNZ4dTYTcUemls2cni83Q4Q/TrFONHfhcg9oEGOtaGHfb0cpzec60P96UKPvMkjX1jET8rUw== core-js@^3.6.0: - version "3.17.2" - resolved "https://registry.npmjs.org/core-js/-/core-js-3.17.2.tgz#f960eae710dc62c29cca93d5332e3660e289db10" - integrity sha512-XkbXqhcXeMHPRk2ItS+zQYliAMilea2euoMsnpRRdDad6b2VY6CQQcwz1K8AnWesfw4p165RzY0bTnr3UrbYiA== + version "3.17.3" + resolved "https://registry.npmjs.org/core-js/-/core-js-3.17.3.tgz#8e8bd20e91df9951e903cabe91f9af4a0895bc1e" + integrity sha512-lyvajs+wd8N1hXfzob1LdOCCHFU4bGMbqqmLn1Q4QlCpDqWPpGf+p0nj+LNrvDDG33j0hZXw2nsvvVpHysxyNw== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" From 608f067ea19445b455c8f1c3e221a59ab9a73d1e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Sep 2021 04:24:04 +0000 Subject: [PATCH 058/125] chore(deps-dev): bump prettier from 2.3.2 to 2.4.0 Bumps [prettier](https://github.com/prettier/prettier) from 2.3.2 to 2.4.0. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.3.2...2.4.0) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e58e6fe0ac..48efadb6c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21844,9 +21844,9 @@ prettier@^1.19.1: integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== prettier@^2.2.1: - version "2.3.2" - resolved "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" - integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== + version "2.4.0" + resolved "https://registry.npmjs.org/prettier/-/prettier-2.4.0.tgz#85bdfe0f70c3e777cf13a4ffff39713ca6f64cba" + integrity sha512-DsEPLY1dE5HF3BxCRBmD4uYZ+5DCbvatnolqTqcxEgKVZnL2kUfyu7b8pPQ5+hTBkdhU9SLUmK0/pHb07RE4WQ== prettier@~2.2.1: version "2.2.1" From cc5c8f4979ceb6488c8cffc0c7a4c05f7c48969a Mon Sep 17 00:00:00 2001 From: kim5566 Date: Fri, 10 Sep 2021 17:06:25 +1000 Subject: [PATCH 059/125] add paginate Signed-off-by: kim5566 --- .changeset/tidy-shoes-occur.md | 5 +++++ packages/integration/src/github/GithubCredentialsProvider.ts | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/tidy-shoes-occur.md diff --git a/.changeset/tidy-shoes-occur.md b/.changeset/tidy-shoes-occur.md new file mode 100644 index 0000000000..67fa36b672 --- /dev/null +++ b/.changeset/tidy-shoes-occur.md @@ -0,0 +1,5 @@ +--- +'@backstage/integration': patch +--- + +Handle pagination on return results when fetch Github API to list selected repos diff --git a/packages/integration/src/github/GithubCredentialsProvider.ts b/packages/integration/src/github/GithubCredentialsProvider.ts index c7ba6408d9..330187b140 100644 --- a/packages/integration/src/github/GithubCredentialsProvider.ts +++ b/packages/integration/src/github/GithubCredentialsProvider.ts @@ -111,8 +111,8 @@ class GithubAppManager { auth: result.data.token, }); const repos = - await installationClient.apps.listReposAccessibleToInstallation(); - const hasRepo = repos.data.repositories.some(repository => { + await installationClient.paginate(installationClient.apps.listReposAccessibleToInstallation); + const hasRepo = repos && repos.repositories.some(repository => { return repository.name === repo; }); if (!hasRepo) { From bce900e0aebceb9d8b7b3cd2b85c0e7840e606d7 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 10 Sep 2021 09:41:19 +0200 Subject: [PATCH 060/125] fix lockfile Signed-off-by: Johan Haals --- microsite/yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 0938f7e2f7..2973f364b0 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -5209,7 +5209,7 @@ prepend-http@^2.0.0: prettier@^2.4.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.0.tgz#85bdfe0f70c3e777cf13a4ffff39713ca6f64cba" + resolved "https://registry.npmjs.org/prettier/-/prettier-2.4.0.tgz#85bdfe0f70c3e777cf13a4ffff39713ca6f64cba" integrity sha512-DsEPLY1dE5HF3BxCRBmD4uYZ+5DCbvatnolqTqcxEgKVZnL2kUfyu7b8pPQ5+hTBkdhU9SLUmK0/pHb07RE4WQ== prismjs@^1.22.0: From 3c78883ba3fc7e9fbba6dde6fda7615367b15cc4 Mon Sep 17 00:00:00 2001 From: kim5566 Date: Fri, 10 Sep 2021 17:55:29 +1000 Subject: [PATCH 061/125] fix formatting and slection of returned results Signed-off-by: kim5566 --- .changeset/clever-months-switch.md | 5 +++++ .../integration/src/github/GithubCredentialsProvider.ts | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 .changeset/clever-months-switch.md diff --git a/.changeset/clever-months-switch.md b/.changeset/clever-months-switch.md new file mode 100644 index 0000000000..9ffac60f56 --- /dev/null +++ b/.changeset/clever-months-switch.md @@ -0,0 +1,5 @@ +--- +'@backstage/integration': patch +--- + +Handle pagination on return results when fetch GitHub API to list selected repos diff --git a/packages/integration/src/github/GithubCredentialsProvider.ts b/packages/integration/src/github/GithubCredentialsProvider.ts index 330187b140..3156488ba7 100644 --- a/packages/integration/src/github/GithubCredentialsProvider.ts +++ b/packages/integration/src/github/GithubCredentialsProvider.ts @@ -110,9 +110,10 @@ class GithubAppManager { const installationClient = new Octokit({ auth: result.data.token, }); - const repos = - await installationClient.paginate(installationClient.apps.listReposAccessibleToInstallation); - const hasRepo = repos && repos.repositories.some(repository => { + const repos = await installationClient.paginate( + installationClient.apps.listReposAccessibleToInstallation, + ); + const hasRepo = repos.some(repository => { return repository.name === repo; }); if (!hasRepo) { From 63399d41478f9799e46b2681cbc284b02152328f Mon Sep 17 00:00:00 2001 From: kim5566 Date: Fri, 10 Sep 2021 17:58:54 +1000 Subject: [PATCH 062/125] remove duplicate changeset Signed-off-by: kim5566 --- .changeset/clever-months-switch.md | 5 ----- .changeset/tidy-shoes-occur.md | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 .changeset/clever-months-switch.md diff --git a/.changeset/clever-months-switch.md b/.changeset/clever-months-switch.md deleted file mode 100644 index 9ffac60f56..0000000000 --- a/.changeset/clever-months-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/integration': patch ---- - -Handle pagination on return results when fetch GitHub API to list selected repos diff --git a/.changeset/tidy-shoes-occur.md b/.changeset/tidy-shoes-occur.md index 67fa36b672..9ffac60f56 100644 --- a/.changeset/tidy-shoes-occur.md +++ b/.changeset/tidy-shoes-occur.md @@ -2,4 +2,4 @@ '@backstage/integration': patch --- -Handle pagination on return results when fetch Github API to list selected repos +Handle pagination on return results when fetch GitHub API to list selected repos From c6c5a92e92769b40df5a617ebbd4e2bc5c9e37d2 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 10 Sep 2021 10:11:27 +0200 Subject: [PATCH 063/125] format Signed-off-by: Johan Haals --- packages/docgen/src/docgen/TypeLocator.ts | 6 +++--- plugins/catalog-graphql/src/graphql/types.ts | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/docgen/src/docgen/TypeLocator.ts b/packages/docgen/src/docgen/TypeLocator.ts index 30d240da3d..adec0c2a42 100644 --- a/packages/docgen/src/docgen/TypeLocator.ts +++ b/packages/docgen/src/docgen/TypeLocator.ts @@ -57,9 +57,9 @@ export default class TypeLocator { * Find exported instances and return values from calls using the types * provided in the lookup table. */ - findExportedInstances( - typeLookupTable: { [key in T]: ts.Type }, - ): { [key in T]: ExportedInstance[] } { + findExportedInstances(typeLookupTable: { + [key in T]: ts.Type; + }): { [key in T]: ExportedInstance[] } { const docMap = new Map(); for (const type of Object.values(typeLookupTable)) { docMap.set(type, []); diff --git a/plugins/catalog-graphql/src/graphql/types.ts b/plugins/catalog-graphql/src/graphql/types.ts index 71e40181d4..5c53a6d1e3 100644 --- a/plugins/catalog-graphql/src/graphql/types.ts +++ b/plugins/catalog-graphql/src/graphql/types.ts @@ -27,8 +27,7 @@ export type Exact = { export type Omit = Pick>; export type RequireFields = { [X in Exclude]?: T[X]; -} & - { [P in K]-?: NonNullable }; +} & { [P in K]-?: NonNullable }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { ID: string; From 3bfd62b55cb1232632ec9418e67b4e54a9df893d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 10 Sep 2021 10:34:55 +0200 Subject: [PATCH 064/125] integration: add empty AureUrl implementation Signed-off-by: Patrik Oldsberg --- packages/integration/src/azure/AzureUrl.ts | 62 ++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 packages/integration/src/azure/AzureUrl.ts diff --git a/packages/integration/src/azure/AzureUrl.ts b/packages/integration/src/azure/AzureUrl.ts new file mode 100644 index 0000000000..09b9df6e1d --- /dev/null +++ b/packages/integration/src/azure/AzureUrl.ts @@ -0,0 +1,62 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export class AzureUrl { + /** + * Parses an azure URL as copied from the browser address bar. + * + * Throws an error if the URL is not a valid azure repo URL. + */ + static fromRepoUrl(_repoUrl: string): AzureUrl { + throw new Error('not implemented'); + } + + /** + * Returns a repo URL that can be used to navigate to the resource in azure. + * + * Throws an error if the URL is not a valid azure repo URL. + */ + toRepoUrl(): string { + throw new Error('not implemented'); + } + + /** + * Returns the file download URL for this azure resource. + * + * Throws an error if the URL does not point to a file. + */ + toFileUrl(): string { + throw new Error('not implemented'); + } + + /** + * Returns the archive download URL for this azure resource. + * + * Throws an error if the URL does not point to a repo. + */ + toArchiveUrl(): string { + throw new Error('not implemented'); + } + + /** + * Returns the API url for fetching commits from a branch for this azure resource. + * + * Throws an error if the URL does not point to a commit. + */ + toCommitsUrl(): string { + throw new Error('not implemented'); + } +} From 0c2b9522875b33414e0475e950c0009e6cbb515e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 10 Sep 2021 10:43:18 +0200 Subject: [PATCH 065/125] integration: extend AzureUrl API with accessors for each part Signed-off-by: Patrik Oldsberg --- packages/integration/src/azure/AzureUrl.ts | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/packages/integration/src/azure/AzureUrl.ts b/packages/integration/src/azure/AzureUrl.ts index 09b9df6e1d..2a0c082831 100644 --- a/packages/integration/src/azure/AzureUrl.ts +++ b/packages/integration/src/azure/AzureUrl.ts @@ -59,4 +59,39 @@ export class AzureUrl { toCommitsUrl(): string { throw new Error('not implemented'); } + + /** + * Returns the name of the owner, a user or an organization. + */ + getOwner(): string { + throw new Error('not implemented'); + } + + /** + * Returns the name of the project. + */ + getProject(): string { + throw new Error('not implemented'); + } + + /** + * Returns the name of the repo. + */ + getRepo(): string { + throw new Error('not implemented'); + } + + /** + * Returns the file path within the repo if the URL contains one. + */ + getPath(): string | undefined { + throw new Error('not implemented'); + } + + /** + * Returns the git ref in the repo if the URL contains one. + */ + getRef(): string | undefined { + throw new Error('not implemented'); + } } From 5a41c16fc72c61903c17c9b573df6b3256bf2c6d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 10 Sep 2021 11:15:20 +0200 Subject: [PATCH 066/125] integration: added failing AzureUrl tests Signed-off-by: Patrik Oldsberg --- .../integration/src/azure/AzureUrl.test.ts | 177 ++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 packages/integration/src/azure/AzureUrl.test.ts diff --git a/packages/integration/src/azure/AzureUrl.test.ts b/packages/integration/src/azure/AzureUrl.test.ts new file mode 100644 index 0000000000..2f22dd13da --- /dev/null +++ b/packages/integration/src/azure/AzureUrl.test.ts @@ -0,0 +1,177 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AzureUrl } from './AzureUrl'; + +describe('AzureUrl', () => { + it('should work with the short URL form', () => { + const url = AzureUrl.fromRepoUrl( + 'https://dev.azure.com/my-org/_git/my-project', + ); + + expect(url.getOwner()).toBe('my-org'); + expect(url.getProject()).toBe('my-project'); + expect(url.getRepo()).toBe('my-project'); + expect(url.getRef()).toBeUndefined(); + expect(url.getPath()).toBeUndefined(); + + expect(url.toRepoUrl()).toBe( + 'https://dev.azure.com/my-org/_git/my-project', + ); + expect(() => url.toFileUrl()).toThrow( + 'Azure URL must point to a specific path to be able to download a file', + ); + expect(url.toArchiveUrl()).toBe( + 'https://dev.azure.com/my-org/my-project/_apis/git/repositories/my-project/items?recursionLevel=full&download=true&api-version=6.0', + ); + expect(url.toCommitsUrl()).toBe( + 'https://dev.azure.com/my-org/my-project/_apis/git/repositories/my-project/commits?api-version=6.0', + ); + }); + + it('should work with the short URL form with a path', () => { + const url = AzureUrl.fromRepoUrl( + 'https://dev.azure.com/my-org/_git/my-project?path=%2Ftest.yaml', + ); + + expect(url.getOwner()).toBe('my-org'); + expect(url.getProject()).toBe('my-project'); + expect(url.getRepo()).toBe('my-project'); + expect(url.getRef()).toBeUndefined(); + expect(url.getPath()).toBe('/test.yaml'); + + expect(url.toRepoUrl()).toBe( + 'https://dev.azure.com/my-org/_git/my-project?path=%2Ftest.yaml', + ); + expect(url.toFileUrl()).toBe( + 'https://dev.azure.com/my-org/my-project/_apis/git/repositories/my-project/items?api-version=6.0&path=%2Ftest.yaml', + ); + expect(url.toArchiveUrl()).toBe( + 'https://dev.azure.com/my-org/my-project/_apis/git/repositories/my-project/items?recursionLevel=full&download=true&api-version=6.0&scopePath=%2Ftest.yaml', + ); + expect(url.toCommitsUrl()).toBe( + 'https://dev.azure.com/my-org/my-project/_apis/git/repositories/my-project/commits?api-version=6.0', + ); + }); + + it('should work with the short URL form with a path and ref', () => { + const url = AzureUrl.fromRepoUrl( + 'https://dev.azure.com/my-org/_git/my-project?path=%2Ftest.yaml&version=GBtest-branch', + ); + + expect(url.getOwner()).toBe('my-org'); + expect(url.getProject()).toBe('my-project'); + expect(url.getRepo()).toBe('my-project'); + expect(url.getRef()).toBe('test-branch'); + expect(url.getPath()).toBe('/test.yaml'); + + expect(url.toRepoUrl()).toBe( + 'https://dev.azure.com/my-org/_git/my-project?path=%2Ftest.yaml&version=GBtest-branch', + ); + expect(url.toFileUrl()).toBe( + 'https://dev.azure.com/my-org/my-project/_apis/git/repositories/my-project/items?api-version=6.0&path=%2Ftest.yaml&version=test-branch', + ); + expect(url.toArchiveUrl()).toBe( + 'https://dev.azure.com/my-org/my-project/_apis/git/repositories/my-project/items?recursionLevel=full&download=true&api-version=6.0&scopePath=%2Ftest.yaml&version=test-branch', + ); + expect(url.toCommitsUrl()).toBe( + 'https://dev.azure.com/my-org/my-project/_apis/git/repositories/my-project/commits?api-version=6.0&searchCriteria.itemVersion.version=test-branch', + ); + }); + + it('should work with the long URL', () => { + const url = AzureUrl.fromRepoUrl( + 'http://my-host/my-org/my-project/_git/my-repo', + ); + + expect(url.getOwner()).toBe('my-org'); + expect(url.getProject()).toBe('my-project'); + expect(url.getRepo()).toBe('my-repo'); + expect(url.getRef()).toBeUndefined(); + expect(url.getPath()).toBeUndefined(); + + expect(url.toRepoUrl()).toBe( + 'http://my-host/my-org/my-project/_git/my-repo', + ); + expect(() => url.toFileUrl()).toThrow( + 'Azure URL must point to a specific path to be able to download a file', + ); + expect(url.toArchiveUrl()).toBe( + 'http://my-host/my-org/my-project/_apis/git/repositories/my-repo/items?recursionLevel=full&download=true&api-version=6.0', + ); + expect(url.toCommitsUrl()).toBe( + 'http://my-host/my-org/my-project/_apis/git/repositories/my-repo/commits?api-version=6.0', + ); + }); + + it('should work with the long URL form with a path and ref', () => { + const url = AzureUrl.fromRepoUrl( + 'http://my-host/my-org/my-project/_git/my-repo?path=%2Ffolder&version=GBtest-branch', + ); + + expect(url.getOwner()).toBe('my-org'); + expect(url.getProject()).toBe('my-project'); + expect(url.getRepo()).toBe('my-repo'); + expect(url.getRef()).toBe('test-branch'); + expect(url.getPath()).toBe('/folder'); + + expect(url.toRepoUrl()).toBe( + 'http://my-host/my-org/my-project/_git/my-repo?path=%2Ffolder&version=GBtest-branch', + ); + expect(url.toFileUrl()).toBe( + 'http://my-host/my-org/my-project/_apis/git/repositories/my-repo/items?api-version=6.0&path=%2Ffolder&version=test-branch', + ); + expect(url.toArchiveUrl()).toBe( + 'http://my-host/my-org/my-project/_apis/git/repositories/my-repo/items?recursionLevel=full&download=true&api-version=6.0&scopePath=%2Ffolder&version=test-branch', + ); + expect(url.toCommitsUrl()).toBe( + 'http://my-host/my-org/my-project/_apis/git/repositories/my-repo/commits?api-version=6.0&searchCriteria.itemVersion.version=test-branch', + ); + }); + + it('should reject non-branch refs', () => { + expect(() => + AzureUrl.fromRepoUrl( + 'https://dev.azure.com/my-org/_git/my-project?version=GC6eead79870d998a3befd4bc7c72cc89e446f2970', + ), + ).toThrow('Azure URL version must point to a git branch'); + }); + + it('should reject non-repo URLs', () => { + expect(() => + AzureUrl.fromRepoUrl('https://dev.azure.com/my-org/_git'), + ).toThrow('Azure URL must point to a git repository'); + expect(() => + AzureUrl.fromRepoUrl('https://dev.azure.com/my-org/_git/'), + ).toThrow('Azure URL must point to a git repository'); + expect(() => + AzureUrl.fromRepoUrl('https://dev.azure.com/my-org/my-project/'), + ).toThrow('Azure URL must point to a git repository'); + expect(() => + AzureUrl.fromRepoUrl('https://dev.azure.com/my-org/my-project/_not-git'), + ).toThrow('Azure URL must point to a git repository'); + expect(() => + AzureUrl.fromRepoUrl( + 'https://dev.azure.com/my-org/my-project/_not-git/my-repo', + ), + ).toThrow('Azure URL must point to a git repository'); + expect(() => + AzureUrl.fromRepoUrl( + 'https://dev.azure.com/my-org/_workitems/recentlyupdated/', + ), + ).toThrow('Azure URL must point to a git repository'); + }); +}); From 63e3745fe34494053e452e3786cc549d5bef67f9 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 10 Sep 2021 11:40:16 +0200 Subject: [PATCH 067/125] integration: implement AzureUrl Signed-off-by: Patrik Oldsberg --- packages/integration/src/azure/AzureUrl.ts | 156 +++++++++++++++++++-- 1 file changed, 145 insertions(+), 11 deletions(-) diff --git a/packages/integration/src/azure/AzureUrl.ts b/packages/integration/src/azure/AzureUrl.ts index 2a0c082831..add03b7876 100644 --- a/packages/integration/src/azure/AzureUrl.ts +++ b/packages/integration/src/azure/AzureUrl.ts @@ -14,14 +14,77 @@ * limitations under the License. */ +const VERSION_PREFIX_GIT_BRANCH = 'GB'; + export class AzureUrl { /** * Parses an azure URL as copied from the browser address bar. * * Throws an error if the URL is not a valid azure repo URL. */ - static fromRepoUrl(_repoUrl: string): AzureUrl { - throw new Error('not implemented'); + static fromRepoUrl(repoUrl: string): AzureUrl { + const url = new URL(repoUrl); + + let owner; + let project; + let repo; + + const parts = url.pathname.split('/').map(part => decodeURIComponent(part)); + if (parts[2] === '_git') { + owner = parts[1]; + project = repo = parts[3]; + } else if (parts[3] === '_git') { + owner = parts[1]; + project = parts[2]; + repo = parts[4]; + } + + if (!owner || !project || !repo) { + throw new Error('Azure URL must point to a git repository'); + } + + const path = url.searchParams.get('path') ?? undefined; + + let ref; + const version = url.searchParams.get('version'); + if (version) { + const prefix = version.slice(0, 2); + if (prefix !== 'GB') { + throw new Error('Azure URL version must point to a git branch'); + } + ref = version.slice(2); + } + + return new AzureUrl(url.origin, owner, project, repo, path, ref); + } + + #origin: string; + #owner: string; + #project: string; + #repo: string; + #path?: string; + #ref?: string; + + private constructor( + origin: string, + owner: string, + project: string, + repo: string, + path?: string, + ref?: string, + ) { + this.#origin = origin; + this.#owner = owner; + this.#project = project; + this.#repo = repo; + this.#path = path; + this.#ref = ref; + } + + #baseUrl(...parts: string[]): URL { + const url = new URL(this.#origin); + url.pathname = parts.map(part => encodeURIComponent(part)).join('/'); + return url; } /** @@ -30,7 +93,21 @@ export class AzureUrl { * Throws an error if the URL is not a valid azure repo URL. */ toRepoUrl(): string { - throw new Error('not implemented'); + let url; + if (this.#project === this.#repo) { + url = this.#baseUrl(this.#owner, '_git', this.#repo); + } else { + url = this.#baseUrl(this.#owner, this.#project, '_git', this.#repo); + } + + if (this.#path) { + url.searchParams.set('path', this.#path); + } + if (this.#ref) { + url.searchParams.set('version', VERSION_PREFIX_GIT_BRANCH + this.#ref); + } + + return url.toString(); } /** @@ -39,7 +116,29 @@ export class AzureUrl { * Throws an error if the URL does not point to a file. */ toFileUrl(): string { - throw new Error('not implemented'); + if (!this.#path) { + throw new Error( + 'Azure URL must point to a specific path to be able to download a file', + ); + } + + const url = this.#baseUrl( + this.#owner, + this.#project, + '_apis', + 'git', + 'repositories', + this.#repo, + 'items', + ); + url.searchParams.set('api-version', '6.0'); + url.searchParams.set('path', this.#path); + + if (this.#ref) { + url.searchParams.set('version', this.#ref); + } + + return url.toString(); } /** @@ -48,7 +147,27 @@ export class AzureUrl { * Throws an error if the URL does not point to a repo. */ toArchiveUrl(): string { - throw new Error('not implemented'); + const url = this.#baseUrl( + this.#owner, + this.#project, + '_apis', + 'git', + 'repositories', + this.#repo, + 'items', + ); + url.searchParams.set('recursionLevel', 'full'); + url.searchParams.set('download', 'true'); + url.searchParams.set('api-version', '6.0'); + + if (this.#path) { + url.searchParams.set('scopePath', this.#path); + } + if (this.#ref) { + url.searchParams.set('version', this.#ref); + } + + return url.toString(); } /** @@ -57,41 +176,56 @@ export class AzureUrl { * Throws an error if the URL does not point to a commit. */ toCommitsUrl(): string { - throw new Error('not implemented'); + const url = this.#baseUrl( + this.#owner, + this.#project, + '_apis', + 'git', + 'repositories', + this.#repo, + 'commits', + ); + url.searchParams.set('api-version', '6.0'); + + if (this.#ref) { + url.searchParams.set('searchCriteria.itemVersion.version', this.#ref); + } + + return url.toString(); } /** * Returns the name of the owner, a user or an organization. */ getOwner(): string { - throw new Error('not implemented'); + return this.#owner; } /** * Returns the name of the project. */ getProject(): string { - throw new Error('not implemented'); + return this.#project; } /** * Returns the name of the repo. */ getRepo(): string { - throw new Error('not implemented'); + return this.#repo; } /** * Returns the file path within the repo if the URL contains one. */ getPath(): string | undefined { - throw new Error('not implemented'); + return this.#path; } /** * Returns the git ref in the repo if the URL contains one. */ getRef(): string | undefined { - throw new Error('not implemented'); + return this.#ref; } } From 0408b0d7ff71f1a18240686e789853f89600634b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 10 Sep 2021 11:46:48 +0200 Subject: [PATCH 068/125] integration: implement azure core with AzureUrl + fix tests Signed-off-by: Patrik Oldsberg --- packages/integration/src/azure/core.test.ts | 16 ++- packages/integration/src/azure/core.ts | 122 +------------------- 2 files changed, 11 insertions(+), 127 deletions(-) diff --git a/packages/integration/src/azure/core.test.ts b/packages/integration/src/azure/core.test.ts index 37fe50f3ea..ad8f2691b5 100644 --- a/packages/integration/src/azure/core.test.ts +++ b/packages/integration/src/azure/core.test.ts @@ -45,22 +45,22 @@ describe('azure core', () => { { url: 'https://dev.azure.com/org-name/project-name/_git/repo-name?path=my-template.yaml&version=GBmaster', result: - 'https://dev.azure.com/org-name/project-name/_apis/git/repositories/repo-name/items?path=my-template.yaml&version=master', + 'https://dev.azure.com/org-name/project-name/_apis/git/repositories/repo-name/items?api-version=6.0&path=my-template.yaml&version=master', }, { url: 'https://dev.azure.com/org-name/project-name/_git/repo-name?path=my-template.yaml', result: - 'https://dev.azure.com/org-name/project-name/_apis/git/repositories/repo-name/items?path=my-template.yaml', + 'https://dev.azure.com/org-name/project-name/_apis/git/repositories/repo-name/items?api-version=6.0&path=my-template.yaml', }, { url: 'https://api.com/org-name/project-name/_git/repo-name?path=my-template.yaml', result: - 'https://api.com/org-name/project-name/_apis/git/repositories/repo-name/items?path=my-template.yaml', + 'https://api.com/org-name/project-name/_apis/git/repositories/repo-name/items?api-version=6.0&path=my-template.yaml', }, { url: 'https://api.com/org-name/project-name/_git/repo-name?path=my-template.yaml&version=GBmaster', result: - 'https://api.com/org-name/project-name/_apis/git/repositories/repo-name/items?path=my-template.yaml&version=master', + 'https://api.com/org-name/project-name/_apis/git/repositories/repo-name/items?api-version=6.0&path=my-template.yaml&version=master', }, ])('should handle happy path %#', async ({ url, result }) => { expect(getAzureFileFetchUrl(url)).toBe(result); @@ -69,13 +69,11 @@ describe('azure core', () => { it.each([ { url: 'https://api.com/a/b/blob/master/path/to/c.yaml', - error: - 'Incorrect URL: https://api.com/a/b/blob/master/path/to/c.yaml, Error: Wrong Azure Devops URL or Invalid file path', + error: 'Azure URL must point to a git repository', }, { url: 'com/a/b/blob/master/path/to/c.yaml', - error: - 'Incorrect URL: com/a/b/blob/master/path/to/c.yaml, TypeError: Invalid URL: com/a/b/blob/master/path/to/c.yaml', + error: 'Invalid URL: com/a/b/blob/master/path/to/c.yaml', }, ])('should handle error path %#', ({ url, error }) => { expect(() => getAzureFileFetchUrl(url)).toThrow(error); @@ -95,7 +93,7 @@ describe('azure core', () => { const result = getAzureDownloadUrl( 'https://dev.azure.com/organization/project/_git/repository?path=%2Fdocs', ); - expect(new URL(result).searchParams.get('scopePath')).toEqual('docs'); + expect(new URL(result).searchParams.get('scopePath')).toEqual('/docs'); }); it.each([ diff --git a/packages/integration/src/azure/core.ts b/packages/integration/src/azure/core.ts index e22764f643..30603b1f09 100644 --- a/packages/integration/src/azure/core.ts +++ b/packages/integration/src/azure/core.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import parseGitUrl from 'git-url-parse'; +import { AzureUrl } from './AzureUrl'; import { AzureIntegrationConfig } from './config'; /** @@ -28,53 +28,7 @@ import { AzureIntegrationConfig } from './config'; * @param url A URL pointing to a file */ export function getAzureFileFetchUrl(url: string): string { - try { - const parsedUrl = new URL(url); - - const [empty, userOrOrg, project, srcKeyword, repoName] = - parsedUrl.pathname.split('/'); - - const path = parsedUrl.searchParams.get('path') || ''; - const ref = parsedUrl.searchParams.get('version')?.substr(2); - - if ( - empty !== '' || - userOrOrg === '' || - project === '' || - srcKeyword !== '_git' || - repoName === '' || - path === '' || - ref === '' - ) { - throw new Error('Wrong Azure Devops URL or Invalid file path'); - } - - // transform to api - parsedUrl.pathname = [ - empty, - userOrOrg, - project, - '_apis', - 'git', - 'repositories', - repoName, - 'items', - ].join('/'); - - const queryParams = [`path=${path}`]; - - if (ref) { - queryParams.push(`version=${ref}`); - } - - parsedUrl.search = queryParams.join('&'); - - parsedUrl.protocol = 'https'; - - return parsedUrl.toString(); - } catch (e) { - throw new Error(`Incorrect URL: ${url}, ${e}`); - } + return AzureUrl.fromRepoUrl(url).toFileUrl(); } /** @@ -84,33 +38,7 @@ export function getAzureFileFetchUrl(url: string): string { * @param url A URL pointing to a path */ export function getAzureDownloadUrl(url: string): string { - const { - name: repoName, - owner: project, - organization, - protocol, - resource, - filepath, - } = parseGitUrl(url); - - // scopePath will limit the downloaded content - // /docs will only download the docs folder and everything below it - // /docs/index.md will only download index.md but put it in the root of the archive - const scopePath = filepath - ? `&scopePath=${encodeURIComponent(filepath)}` - : ''; - - if (resource === 'dev.azure.com') { - return `${protocol}://${resource}/${organization}/${project}/_apis/git/repositories/${repoName}/items?recursionLevel=full&download=true&api-version=6.0${scopePath}`; - } - - // For Azure DevOps Server `parseGitUrl` returns the same values - // for `organization` and `project` like this: `organization/project/_git` - // so we drop `project` and then strip `/_git` from `organization` - return `${protocol}://${resource}/${organization.replace( - '/_git', - '', - )}/_apis/git/repositories/${repoName}/items?recursionLevel=full&download=true&api-version=6.0${scopePath}`; + return AzureUrl.fromRepoUrl(url).toArchiveUrl(); } /** @@ -119,49 +47,7 @@ export function getAzureDownloadUrl(url: string): string { * @param url A URL pointing to a repository or a sub-path */ export function getAzureCommitsUrl(url: string): string { - try { - const parsedUrl = new URL(url); - - const [empty, userOrOrg, project, srcKeyword, repoName] = - parsedUrl.pathname.split('/'); - - // Remove the "GB" from "GBmain" for example. - const ref = parsedUrl.searchParams.get('version')?.substr(2); - - if ( - !!empty || - !userOrOrg || - !project || - srcKeyword !== '_git' || - !repoName - ) { - throw new Error('Wrong Azure Devops URL'); - } - - // transform to commits api - parsedUrl.pathname = [ - empty, - userOrOrg, - project, - '_apis', - 'git', - 'repositories', - repoName, - 'commits', - ].join('/'); - - const queryParams = []; - if (ref) { - queryParams.push(`searchCriteria.itemVersion.version=${ref}`); - } - parsedUrl.search = queryParams.join('&'); - - parsedUrl.protocol = 'https'; - - return parsedUrl.toString(); - } catch (e) { - throw new Error(`Incorrect URL: ${url}, ${e}`); - } + return AzureUrl.fromRepoUrl(url).toCommitsUrl(); } /** From 8cfeb5fe08dd20d0fbeeaa0d2442ba6e8bff74a2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 10 Sep 2021 12:08:08 +0200 Subject: [PATCH 069/125] backend-common: fix azure readTree subpath handling Signed-off-by: Patrik Oldsberg --- .../src/reading/AzureUrlReader.test.ts | 10 ++++----- .../src/reading/AzureUrlReader.ts | 22 +++++++++++++------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/packages/backend-common/src/reading/AzureUrlReader.test.ts b/packages/backend-common/src/reading/AzureUrlReader.test.ts index c7c8853929..e014fa2e75 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.test.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.test.ts @@ -81,14 +81,14 @@ describe('AzureUrlReader', () => { url: 'https://dev.azure.com/org-name/project-name/_git/repo-name?path=my-template.yaml&version=GBmaster', config: createConfig(), response: expect.objectContaining({ - url: 'https://dev.azure.com/org-name/project-name/_apis/git/repositories/repo-name/items?path=my-template.yaml&version=master', + url: 'https://dev.azure.com/org-name/project-name/_apis/git/repositories/repo-name/items?api-version=6.0&path=my-template.yaml&version=master', }), }, { url: 'https://dev.azure.com/org-name/project-name/_git/repo-name?path=my-template.yaml', config: createConfig(), response: expect.objectContaining({ - url: 'https://dev.azure.com/org-name/project-name/_apis/git/repositories/repo-name/items?path=my-template.yaml', + url: 'https://dev.azure.com/org-name/project-name/_apis/git/repositories/repo-name/items?api-version=6.0&path=my-template.yaml', }), }, { @@ -125,14 +125,12 @@ describe('AzureUrlReader', () => { { url: 'https://api.com/a/b/blob/master/path/to/c.yaml', config: createConfig(), - error: - 'Incorrect URL: https://api.com/a/b/blob/master/path/to/c.yaml, Error: Wrong Azure Devops URL or Invalid file path', + error: 'Azure URL must point to a git repository', }, { url: 'com/a/b/blob/master/path/to/c.yaml', config: createConfig(), - error: - 'Incorrect URL: com/a/b/blob/master/path/to/c.yaml, TypeError: Invalid URL: com/a/b/blob/master/path/to/c.yaml', + error: 'Invalid URL: com/a/b/blob/master/path/to/c.yaml', }, { url: '', diff --git a/packages/backend-common/src/reading/AzureUrlReader.ts b/packages/backend-common/src/reading/AzureUrlReader.ts index 910e8e04a5..6015b044bc 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.ts @@ -23,11 +23,9 @@ import { ScmIntegrations, } from '@backstage/integration'; import fetch from 'cross-fetch'; -import parseGitUrl from 'git-url-parse'; import { Minimatch } from 'minimatch'; import { Readable } from 'stream'; import { NotFoundError, NotModifiedError } from '@backstage/errors'; -import { stripFirstDirectoryFromPath } from './tree/util'; import { ReadTreeResponseFactory, ReaderFactory, @@ -129,28 +127,38 @@ export class AzureUrlReader implements UrlReader { throw new Error(message); } + // When downloading a zip archive from azure on a subpath we get an extra directory + // layer added at the top. With for example the file /a/b/c.txt and a download of + // /a/b, we'll see /b/c.txt in the zip archive. This picks out /b so that we can remove it. + let subpath; + const path = new URL(url).searchParams.get('path'); + if (path) { + subpath = path.split('/').filter(Boolean).slice(-1)[0]; + } + return await this.deps.treeResponseFactory.fromZipArchive({ stream: archiveAzureResponse.body as unknown as Readable, etag: commitSha, filter: options?.filter, + subpath, }); } async search(url: string, options?: SearchOptions): Promise { - const { filepath } = parseGitUrl(url); - const matcher = new Minimatch(filepath); + const treeUrl = new URL(url); + + const path = treeUrl.searchParams.get('path'); + const matcher = path && new Minimatch(path.replace(/^\/+/, '')); // TODO(freben): For now, read the entire repo and filter through that. In // a future improvement, we could be smart and try to deduce that non-glob // prefixes (like for filepaths such as some-prefix/**/a.yaml) can be used // to get just that part of the repo. - const treeUrl = new URL(url); treeUrl.searchParams.delete('path'); - treeUrl.pathname = treeUrl.pathname.replace(/\/+$/, ''); const tree = await this.readTree(treeUrl.toString(), { etag: options?.etag, - filter: path => matcher.match(stripFirstDirectoryFromPath(path)), + filter: p => (matcher ? matcher.match(p) : true), }); const files = await tree.files(); From f7ad3a89252913ebefa274a5ac92132fb69c7fe4 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 10 Sep 2021 12:12:38 +0200 Subject: [PATCH 070/125] added changesets for azure URL updates Signed-off-by: Patrik Oldsberg --- .changeset/neat-mugs-add.md | 7 +++++++ .changeset/real-beans-collect.md | 5 +++++ 2 files changed, 12 insertions(+) create mode 100644 .changeset/neat-mugs-add.md create mode 100644 .changeset/real-beans-collect.md diff --git a/.changeset/neat-mugs-add.md b/.changeset/neat-mugs-add.md new file mode 100644 index 0000000000..b90c95440d --- /dev/null +++ b/.changeset/neat-mugs-add.md @@ -0,0 +1,7 @@ +--- +'@backstage/integration': patch +--- + +Fix Azure URL handling to properly support both repo shorthand (`/owner/_git/project`) and full URLs (`/owner/project/_git/repo`). + +Fix Azure DevOps Server URL handling by being able to parse URLs with hosts other than `dev.azure.com`. Note that the `api-version` used for API requests is currently `6.0`, meaning you need to support at least this version in your Azure DevOps Server instance. diff --git a/.changeset/real-beans-collect.md b/.changeset/real-beans-collect.md new file mode 100644 index 0000000000..43dae9cd9a --- /dev/null +++ b/.changeset/real-beans-collect.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Fix Azure `readTree` and `search` handling to properly support paths. From 5400d81f28efd2c282545723ff4166105cea5436 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 10 Sep 2021 13:00:35 +0200 Subject: [PATCH 071/125] integrations: workaround lack of private method support Signed-off-by: Patrik Oldsberg --- packages/integration/src/azure/AzureUrl.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/integration/src/azure/AzureUrl.ts b/packages/integration/src/azure/AzureUrl.ts index add03b7876..76de8550ed 100644 --- a/packages/integration/src/azure/AzureUrl.ts +++ b/packages/integration/src/azure/AzureUrl.ts @@ -81,11 +81,11 @@ export class AzureUrl { this.#ref = ref; } - #baseUrl(...parts: string[]): URL { + #baseUrl = (...parts: string[]): URL => { const url = new URL(this.#origin); url.pathname = parts.map(part => encodeURIComponent(part)).join('/'); return url; - } + }; /** * Returns a repo URL that can be used to navigate to the resource in azure. From 1befb5ad577fdfd556ac8a626cb4b5a9d4427543 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 10 Sep 2021 13:08:22 +0200 Subject: [PATCH 072/125] integrations: update AzureIntegration tests with unexpected failure cases Signed-off-by: Patrik Oldsberg --- .../src/azure/AzureIntegration.test.ts | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/packages/integration/src/azure/AzureIntegration.test.ts b/packages/integration/src/azure/AzureIntegration.test.ts index 80cc68047f..c30283f432 100644 --- a/packages/integration/src/azure/AzureIntegration.test.ts +++ b/packages/integration/src/azure/AzureIntegration.test.ts @@ -60,22 +60,43 @@ describe('AzureIntegration', () => { expect( integration.resolveUrl({ url: '/a.yaml', - base: 'https://dev.azure.com/organization/project/_git/repository?path=%2Ffolder%2Fcatalog-info.yaml', + base: 'https://internal.com/organization/project/_git/repository?path=%2Ffolder%2Fcatalog-info.yaml', lineNumber: 14, }), ).toBe( - 'https://dev.azure.com/organization/project/_git/repository?path=%2Fa.yaml&line=14&lineEnd=15&lineStartColumn=1&lineEndColumn=1', + 'https://internal.com/organization/project/_git/repository?path=%2Fa.yaml&line=14&lineEnd=15&lineStartColumn=1&lineEndColumn=1', ); expect( integration.resolveUrl({ url: './a.yaml', - base: 'https://dev.azure.com/organization/project/_git/repository', + base: 'https://dev.azure.com/organization/_git/project', + }), + ).toBe('https://dev.azure.com/organization/_git/project?path=%2Fa.yaml'); + + expect( + integration.resolveUrl({ + url: 'https://dev.azure.com/organization/_git/project?path=%2Fa.yaml', + base: 'https://dev.azure.com/organization/_git/project', + }), + ).toBe('https://dev.azure.com/organization/_git/project?path=%2Fa.yaml'); + + expect( + integration.resolveUrl({ + url: 'https://dev.azure.com/other-organization/_git/other-project?path=%2Fa.yaml', + base: 'https://dev.azure.com/organization/_git/project', }), ).toBe( - 'https://dev.azure.com/organization/project/_git/repository?path=%2Fa.yaml', + 'https://dev.azure.com/other-organization/_git/other-project?path=%2Fa.yaml', ); + expect( + integration.resolveUrl({ + url: './a.yaml', + base: 'http://not-azure.com/organization/_git/project', + }), + ).toBe('http://not-azure.com/organization/_git/project?path=%2Fa.yaml'); + expect( integration.resolveUrl({ url: 'https://absolute.com/path', From 2e9d71281e218ecd0cbfd018ea305d71dc63e723 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 10 Sep 2021 13:14:22 +0200 Subject: [PATCH 073/125] integration: fix AzureIntegration resolveUrl path handling Signed-off-by: Patrik Oldsberg --- .../integration/src/azure/AzureIntegration.ts | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/packages/integration/src/azure/AzureIntegration.ts b/packages/integration/src/azure/AzureIntegration.ts index c2a8dd8f5e..ab1b2489ae 100644 --- a/packages/integration/src/azure/AzureIntegration.ts +++ b/packages/integration/src/azure/AzureIntegration.ts @@ -14,9 +14,9 @@ * limitations under the License. */ -import parseGitUrl from 'git-url-parse'; import { basicIntegrations, isValidUrl } from '../helpers'; import { ScmIntegration, ScmIntegrationsFactory } from '../types'; +import { AzureUrl } from './AzureUrl'; import { AzureIntegrationConfig, readAzureIntegrationConfigs } from './config'; export class AzureIntegration implements ScmIntegration { @@ -61,29 +61,27 @@ export class AzureIntegration implements ScmIntegration { return url; } - const parsed = parseGitUrl(base); - const { organization, owner, name, filepath } = parsed; + try { + const azureUrl = AzureUrl.fromRepoUrl(base); + const newUrl = new URL(base); - // If not an actual file path within a repo, treat the URL as raw - if (!organization || !owner || !name) { + // We lean on the URL path resolution logic to resolve the path param + const mockBaseUrl = new URL(`https://a.com${azureUrl.getPath() ?? ''}`); + const updatedPath = new URL(url, mockBaseUrl).pathname; + newUrl.searchParams.set('path', updatedPath); + + if (options.lineNumber) { + newUrl.searchParams.set('line', String(options.lineNumber)); + newUrl.searchParams.set('lineEnd', String(options.lineNumber + 1)); + newUrl.searchParams.set('lineStartColumn', '1'); + newUrl.searchParams.set('lineEndColumn', '1'); + } + + return newUrl.toString(); + } catch { + // If not an actual file path within a repo, treat the URL as raw return new URL(url, base).toString(); } - - const path = filepath?.replace(/^\//, '') || ''; - const mockBaseUrl = new URL(`https://a.com/${path}`); - const updatedPath = new URL(url, mockBaseUrl).pathname; - - const newUrl = new URL(base); - newUrl.searchParams.set('path', updatedPath); - - if (options.lineNumber) { - newUrl.searchParams.set('line', String(options.lineNumber)); - newUrl.searchParams.set('lineEnd', String(options.lineNumber + 1)); - newUrl.searchParams.set('lineStartColumn', '1'); - newUrl.searchParams.set('lineEndColumn', '1'); - } - - return newUrl.toString(); } resolveEditUrl(url: string): string { From b5311cfa06588513d8acb9125c0fd355cbd4c986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlio=20Zynger?= Date: Fri, 10 Sep 2021 13:40:25 +0200 Subject: [PATCH 074/125] Fix import for createPlugin in example snippet Signed-off-by: Julio Zynger --- .../user-settings/src/components/FeatureFlags/EmptyFlags.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/user-settings/src/components/FeatureFlags/EmptyFlags.tsx b/plugins/user-settings/src/components/FeatureFlags/EmptyFlags.tsx index 878141f7dc..785f398d6f 100644 --- a/plugins/user-settings/src/components/FeatureFlags/EmptyFlags.tsx +++ b/plugins/user-settings/src/components/FeatureFlags/EmptyFlags.tsx @@ -18,7 +18,7 @@ import React from 'react'; import { Button, Typography } from '@material-ui/core'; import { CodeSnippet, EmptyState } from '@backstage/core-components'; -const EXAMPLE = `import { createPlugin } from '@backstage/core'; +const EXAMPLE = `import { createPlugin } from '@backstage/core-plugin-api'; export default createPlugin({ id: 'plugin-name', From 7bd1a87e1528e0137f2154c61c8b0ce5506e3cd0 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Fri, 10 Sep 2021 15:05:09 +0200 Subject: [PATCH 075/125] fix comments Signed-off-by: Vincenzo Scamporlino --- .../components/SearchType/SearchType.stories.tsx | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/plugins/search/src/components/SearchType/SearchType.stories.tsx b/plugins/search/src/components/SearchType/SearchType.stories.tsx index 24a24fa4cb..da662d8fef 100644 --- a/plugins/search/src/components/SearchType/SearchType.stories.tsx +++ b/plugins/search/src/components/SearchType/SearchType.stories.tsx @@ -14,7 +14,6 @@ * limitations under the License. */ import React, { useState } from 'react'; -import { MemoryRouter } from 'react-router'; import { SearchType } from '../index'; import { SearchContext } from '../SearchContext'; @@ -30,15 +29,8 @@ export const Default = () => { const [types, setTypes] = useState([]); return ( - - {/* @ts-ignore (value requires more than what is used here) */} - - - - + + + ); }; From ace57abe4c4f874481d496a12ced7124a2215c2a Mon Sep 17 00:00:00 2001 From: irma12 Date: Fri, 10 Sep 2021 14:53:12 +0200 Subject: [PATCH 076/125] Improve UX on popup Signed-off-by: irma12 --- .../OAuthRequestDialog/LoginRequestListItem.tsx | 11 +++++------ .../OAuthRequestDialog/OAuthRequestDialog.tsx | 11 ++++++++--- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/core-components/src/components/OAuthRequestDialog/LoginRequestListItem.tsx b/packages/core-components/src/components/OAuthRequestDialog/LoginRequestListItem.tsx index e0102564fd..f9533d9d03 100644 --- a/packages/core-components/src/components/OAuthRequestDialog/LoginRequestListItem.tsx +++ b/packages/core-components/src/components/OAuthRequestDialog/LoginRequestListItem.tsx @@ -21,6 +21,7 @@ import { makeStyles, Typography, Theme, + Button, } from '@material-ui/core'; import React, { useState } from 'react'; import { PendingAuthRequest } from '@backstage/core-plugin-api'; @@ -55,12 +56,7 @@ const LoginRequestListItem = ({ request, busy, setBusy }: RowProps) => { const IconComponent = request.provider.icon; return ( - + @@ -74,6 +70,9 @@ const LoginRequestListItem = ({ request, busy, setBusy }: RowProps) => { ) } /> + ); }; diff --git a/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx b/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx index 687e4211bf..14b0789ff8 100644 --- a/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx +++ b/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx @@ -39,6 +39,9 @@ const useStyles = makeStyles(theme => ({ contentList: { padding: 0, }, + actionButtons: { + padding: theme.spacing(2), + }, })); export const OAuthRequestDialog = () => { @@ -65,7 +68,7 @@ export const OAuthRequestDialog = () => { Login Required - + {requests.map(request => ( { - - + + ); From 61e9fcf4063d22327d3c400b36e930b124b0247f Mon Sep 17 00:00:00 2001 From: irma12 Date: Fri, 10 Sep 2021 14:55:20 +0200 Subject: [PATCH 077/125] Added changeset Signed-off-by: irma12 --- .changeset/short-mugs-drive.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/short-mugs-drive.md diff --git a/.changeset/short-mugs-drive.md b/.changeset/short-mugs-drive.md new file mode 100644 index 0000000000..f2b34fd2c4 --- /dev/null +++ b/.changeset/short-mugs-drive.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Improve UX for Login pop-up From a2e8db8dc0ec192b318ac4a3a8fe66bb7dc43b2c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 10 Sep 2021 15:09:53 +0200 Subject: [PATCH 078/125] docs: add a heads up about dockerignore for multi-stage builds Signed-off-by: Patrik Oldsberg --- docs/deployment/docker.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index e542b02ebf..599c01a0ce 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -113,6 +113,9 @@ browser at `http://localhost:7000` ## Multi-stage Build +> NOTE: The `.dockerignore` is different in this setup, read on for more +> details. + This section describes how to set up a multi-stage Docker build that builds the entire project within Docker. This is typically slower than a host build, but is sometimes desired because Docker in Docker is not available in the build @@ -137,6 +140,7 @@ WORKDIR /app COPY package.json yarn.lock ./ COPY packages packages +# Comment this out if you don't have any internal plugins COPY plugins plugins RUN find packages \! -name "package.json" -mindepth 2 -maxdepth 2 -exec rm -rf {} \+ @@ -182,8 +186,9 @@ end up being properly installed. To speed up the build when not running in a fresh clone of the repo you should set up a `.dockerignore`. This one is different than the host build one, because -we want to have access to the source code of all packages for the build, but can -ignore any existing build output or dependencies: +we want to have access to the source code of all packages for the build. We can +however ignore any existing build output or dependencies on the host. For our +new `.dockerignore`, replace the contents of your existing one with this: ```text node_modules From 6082b9178c5bfbfbe9bee43bc4188588d38fca1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlio=20Zynger?= Date: Fri, 10 Sep 2021 15:39:34 +0200 Subject: [PATCH 079/125] Create grumpy-beds-design.md Signed-off-by: Julio Zynger --- .changeset/grumpy-beds-design.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/grumpy-beds-design.md diff --git a/.changeset/grumpy-beds-design.md b/.changeset/grumpy-beds-design.md new file mode 100644 index 0000000000..3e15e9c5ea --- /dev/null +++ b/.changeset/grumpy-beds-design.md @@ -0,0 +1,5 @@ +--- +"@backstage/plugin-user-settings": patch +--- + +Fix import for createPlugin in example snippet From 06728d627324a7eaf2510d75f60de3811f6a154b Mon Sep 17 00:00:00 2001 From: blam Date: Fri, 10 Sep 2021 15:48:00 +0200 Subject: [PATCH 080/125] docs: add a note about our ideas for environments Signed-off-by: blam --- .../software-catalog/extending-the-model.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/features/software-catalog/extending-the-model.md b/docs/features/software-catalog/extending-the-model.md index aa5aed0540..328e7eaa93 100644 --- a/docs/features/software-catalog/extending-the-model.md +++ b/docs/features/software-catalog/extending-the-model.md @@ -393,3 +393,20 @@ of interest to you, you might consider contacting the maintainers on Discord or my making a GitHub issue describing your use case. [This issue](https://github.com/backstage/backstage/issues/2292) also contains more context. + +## Referencing different environments with the model + +Example intent: + +> "I have multiple versions of my API deployed in different environments so I +> want to have `mytool-dev` and `mytool-prod` as different entities." + +Whilst it's possible to have different versions of different entities deployed +as separate entities, it's something we recommend against. We believe that a +developer should be able to just find one `Component` and be able to see the +different code versions that are deployed throughout your stack, and also +similarly for any other `kind` like `API` too. + +When writing your custom plugins, we encourage the behavior to expect if +possible that you should be showing all the different variations through +environments etc under one canonical reference to your software in the catalog. From de5717872d7244980710ad0ce4a1675364cf7660 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 10 Sep 2021 16:15:26 +0200 Subject: [PATCH 081/125] auth-backend: throw error if OIDC IdP does not have a userinfo endpoint Signed-off-by: Patrik Oldsberg --- .changeset/polite-dragons-allow.md | 5 +++++ plugins/auth-backend/src/providers/oidc/provider.ts | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/polite-dragons-allow.md diff --git a/.changeset/polite-dragons-allow.md b/.changeset/polite-dragons-allow.md new file mode 100644 index 0000000000..05eac53a1f --- /dev/null +++ b/.changeset/polite-dragons-allow.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Use a more informative error message if the configured OIDC identity provider does not provide a `userinfo_endpoint` in its metadata. diff --git a/plugins/auth-backend/src/providers/oidc/provider.ts b/plugins/auth-backend/src/providers/oidc/provider.ts index 306adc70f5..092ffa7099 100644 --- a/plugins/auth-backend/src/providers/oidc/provider.ts +++ b/plugins/auth-backend/src/providers/oidc/provider.ts @@ -157,6 +157,11 @@ export class OidcAuthProvider implements OAuthHandlers { userinfo: UserinfoResponse, done: PassportDoneCallback, ) => { + if (typeof done !== 'function') { + throw new Error( + 'OIDC IdP must provide a userinfo_endpoint in the metadata response', + ); + } done( undefined, { tokenset, userinfo }, From 3afe111b23f171deb41067029fd41cabb8900ce6 Mon Sep 17 00:00:00 2001 From: victormorfin97 Date: Fri, 10 Sep 2021 09:37:38 -0600 Subject: [PATCH 082/125] Fix typo on changeset Signed-off-by: victormorfin97 --- .changeset/poor-weeks-act.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/poor-weeks-act.md b/.changeset/poor-weeks-act.md index a9a4e54695..152ce4bfc6 100644 --- a/.changeset/poor-weeks-act.md +++ b/.changeset/poor-weeks-act.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder': patch --- -Change the catagories filter to a dropdown component +Change the Categories filter to a dropdown component From 0b3dc2d25db1fed9ae61b1e058082e0c5b11b6ec Mon Sep 17 00:00:00 2001 From: Ryan Vazquez Date: Fri, 10 Sep 2021 17:32:56 -0400 Subject: [PATCH 083/125] fix: hremove hardcoded min height in page header Signed-off-by: Ryan Vazquez --- packages/core-components/src/layout/Header/Header.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/core-components/src/layout/Header/Header.tsx b/packages/core-components/src/layout/Header/Header.tsx index 3b2771e299..4090644403 100644 --- a/packages/core-components/src/layout/Header/Header.tsx +++ b/packages/core-components/src/layout/Header/Header.tsx @@ -22,13 +22,10 @@ import { Helmet } from 'react-helmet'; import { Link } from '../../components/Link'; import { Breadcrumbs } from '../Breadcrumbs'; -const minHeaderHeight = 118; - const useStyles = makeStyles(theme => ({ header: { gridArea: 'pageHeader', padding: theme.spacing(3), - minHeight: minHeaderHeight, width: '100%', boxShadow: '0 0 8px 3px rgba(20, 20, 20, 0.3)', position: 'relative', From 005510dabe0f07fda5e16cb232f77d53eeb35f25 Mon Sep 17 00:00:00 2001 From: Ryan Vazquez Date: Fri, 10 Sep 2021 17:47:39 -0400 Subject: [PATCH 084/125] changeset Signed-off-by: Ryan Vazquez --- .changeset/six-crabs-sit.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/six-crabs-sit.md diff --git a/.changeset/six-crabs-sit.md b/.changeset/six-crabs-sit.md new file mode 100644 index 0000000000..9389906ee9 --- /dev/null +++ b/.changeset/six-crabs-sit.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +remove hard coded min height in page header From 1f564b4dc155c728483794a85d8c59b24c6dd255 Mon Sep 17 00:00:00 2001 From: Ben Lambert Date: Sat, 11 Sep 2021 03:09:56 +0200 Subject: [PATCH 085/125] Update docs/features/software-catalog/extending-the-model.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ben Lambert Co-authored-by: Fredrik Adelöw --- .../software-catalog/extending-the-model.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/features/software-catalog/extending-the-model.md b/docs/features/software-catalog/extending-the-model.md index 328e7eaa93..5895cfaa12 100644 --- a/docs/features/software-catalog/extending-the-model.md +++ b/docs/features/software-catalog/extending-the-model.md @@ -401,12 +401,11 @@ Example intent: > "I have multiple versions of my API deployed in different environments so I > want to have `mytool-dev` and `mytool-prod` as different entities." -Whilst it's possible to have different versions of different entities deployed -as separate entities, it's something we recommend against. We believe that a -developer should be able to just find one `Component` and be able to see the -different code versions that are deployed throughout your stack, and also -similarly for any other `kind` like `API` too. +While it's possible to have different versions of the same thing represented +as separate entities, it's something we generally recommend against. We believe that a +developer should be able to just find for example one `Component` representing a service, and to be able to see the +different code versions that are deployed throughout your stack within its view. This reasoning works similarly for other kinds as well, such as `API`. -When writing your custom plugins, we encourage the behavior to expect if -possible that you should be showing all the different variations through -environments etc under one canonical reference to your software in the catalog. +That being said - sometimes the differences between versions are so large, that they represent what is for all intents and purposes an entirely new entity as seen from the consumer's point of view. This can happen for example for different _significant_ major versions of an API, and in particular if the two major versions coexist in the ecosystem for some time. In those cases, it can be motivated to have one `my-api-v2` and one `my-api-v3` named entity. This matches the end user's expectations when searching for the API, and matches the desire to maybe have separate documentation for the two and similar. But use this sparingly - only do it if the extra modelling burden is outweighed by any potential better clarity for users. + +When writing your custom plugins, we encourage designing them such that they can show all the different variations through environments etc under one canonical reference to your software in the catalog. For example for a continuous deployment plugin, a user is likely to be greatly helped by being able to see the entity's versions deployed in all different environments next to each other in one view. That is also where they might be offered the ability to promote from one environment to the other, do rollbacks, see their relative performance metrics, and similar. This coherency and collection of tooling in one place is where something like Backstage can offer the most value and effectiveness of use. Splitting your entities apart into small islands makes this harder. From f8b3635f908289d9280d420f981d7474c3d811dd Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 11 Sep 2021 19:08:55 +0200 Subject: [PATCH 086/125] api-extractor: working docs mvp Signed-off-by: Patrik Oldsberg --- scripts/api-extractor.ts | 120 +++++++++++++++++++++++++++++++++++++++ tsdoc.json | 10 ++++ 2 files changed, 130 insertions(+) create mode 100644 tsdoc.json diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index ab5f063fb4..413d8e888e 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -31,8 +31,12 @@ import { CompilerState, ExtractorLogLevel, } from '@microsoft/api-extractor'; +import { DocNode, IDocNodeContainerParameters } from '@microsoft/tsdoc'; +import { TSDocConfigFile } from '@microsoft/tsdoc-config'; import { ApiPackage, ApiModel } from '@microsoft/api-extractor-model'; import { MarkdownDocumenter } from '@microsoft/api-documenter/lib/documenters/MarkdownDocumenter'; +import { CustomMarkdownEmitter } from '@microsoft/api-documenter/lib/markdown/CustomMarkdownEmitter'; +import { IMarkdownEmitterContext } from '@microsoft/api-documenter/lib/markdown/MarkdownEmitter'; const tmpDir = resolvePath(__dirname, '../node_modules/.cache/api-extractor'); @@ -150,6 +154,11 @@ async function runApiExtraction({ const projectFolder = resolvePath(__dirname, '..', packageDir); const packageFolder = resolvePath(__dirname, '../dist-types', packageDir); + const tsdocConf = TSDocConfigFile.loadFile( + resolvePath(__dirname, '../tsdoc.json'), + ); + tsdocConf.setSupportForTag('@component', true); + const extractorConfig = ExtractorConfig.prepare({ configObject: { mainEntryPointFilePath: resolvePath(packageFolder, 'src/index.d.ts'), @@ -211,6 +220,7 @@ async function runApiExtraction({ }, configObjectFullPath: projectFolder, packageJsonFullPath: resolvePath(projectFolder, 'package.json'), + tsdocConfigFile: tsdocConf, }); // The `packageFolder` needs to point to the location within `dist-types` in order for relative @@ -350,6 +360,116 @@ async function buildDocs({ outputFolder: outputDir, }); + class DocFrontMatter extends DocNode { + static kind = 'DocFrontMatter'; + + public readonly id: string; + public readonly title: string; + public readonly description: string; + + public constructor( + parameters: IDocNodeContainerParameters & { + id: string; + title: string; + description: string; + }, + ) { + super(parameters); + this.id = parameters.id; + this.title = parameters.title; + this.description = parameters.description; + } + + /** @override */ + public get kind(): string { + return DocFrontMatter.kind; + } + } + + const anyDocumenter = documenter as any; + + anyDocumenter._tsdocConfiguration.docNodeManager.registerDocNodes( + '@backstage/docs', + [{ docNodeKind: DocFrontMatter.kind, constructor: DocFrontMatter }], + ); + anyDocumenter._tsdocConfiguration.docNodeManager.registerAllowableChildren( + 'Paragraph', + [DocFrontMatter.kind], + ); + + class CustomCustomMarkdownEmitter extends CustomMarkdownEmitter { + /** @override */ + protected writeNode( + docNode: DocNode, + context: IMarkdownEmitterContext, + docNodeSiblings: boolean, + ): void { + switch (docNode.kind) { + case DocFrontMatter.kind: { + const node = docNode as DocFrontMatter; + context.writer.writeLine('---'); + context.writer.writeLine(`id: ${node.id}`); + context.writer.writeLine(`title: ${node.title}`); + context.writer.writeLine(`description: ${node.description}`); + context.writer.writeLine('---'); + context.writer.writeLine(); + break; + } + default: + super.writeNode(docNode, context, docNodeSiblings); + } + } + + /** @override */ + emit(stringBuilder, docNode, options) { + // Hack to get rid of the leading comment + stringBuilder._chunks.length = 0; + return super.emit(stringBuilder, docNode, options); + } + } + + const emitter = new CustomCustomMarkdownEmitter(newModel); + anyDocumenter._markdownEmitter = emitter; + + const oldWrite = anyDocumenter._writeBreadcrumb; + + anyDocumenter._writeBreadcrumb = function patchedWriteBreadcrumb( + output, + apiItem, + ) { + let title; + let description; + + const name = apiItem.getScopedNameWithinPackage(); + if (name) { + title = name; + description = `API reference for ${apiItem.getScopedNameWithinPackage()}`; + } else if (apiItem.kind === 'Model') { + title = 'Package Index'; + description = 'Index of all Backstage Packages'; + } else { + title = apiItem.name; + description = `API Reference for ${apiItem.name}`; + } + + output.appendNodeInParagraph( + new DocFrontMatter({ + configuration: this._tsdocConfiguration, + id: this._getFilenameForApiItem(apiItem).slice(0, -3), + title, + description, + }), + ); + + oldWrite.call(this, output, apiItem); + + // We wanna ignore the header that always gets written after the breadcrumb + const oldAppendNode = output.appendNode; + output.appendNode = () => { + output.appendNode = oldAppendNode; + }; + }; + documenter.generateFiles(); } diff --git a/tsdoc.json b/tsdoc.json new file mode 100644 index 0000000000..c19ba9f22b --- /dev/null +++ b/tsdoc.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "extends": ["@microsoft/api-extractor/extends/tsdoc-base.json"], + "tagDefinitions": [ + { + "tagName": "@component", + "syntaxKind": "modifier" + } + ] +} From e79b23d38bbf9a051873f137bca9d9e3e7b3c8fc Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 11 Sep 2021 19:10:16 +0200 Subject: [PATCH 087/125] api-extractor: drop special handling of @component Signed-off-by: Patrik Oldsberg --- scripts/api-extractor.ts | 16 +--------------- tsdoc.json | 10 ---------- 2 files changed, 1 insertion(+), 25 deletions(-) delete mode 100644 tsdoc.json diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index 413d8e888e..93e68a460a 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -32,7 +32,6 @@ import { ExtractorLogLevel, } from '@microsoft/api-extractor'; import { DocNode, IDocNodeContainerParameters } from '@microsoft/tsdoc'; -import { TSDocConfigFile } from '@microsoft/tsdoc-config'; import { ApiPackage, ApiModel } from '@microsoft/api-extractor-model'; import { MarkdownDocumenter } from '@microsoft/api-documenter/lib/documenters/MarkdownDocumenter'; import { CustomMarkdownEmitter } from '@microsoft/api-documenter/lib/markdown/CustomMarkdownEmitter'; @@ -154,11 +153,6 @@ async function runApiExtraction({ const projectFolder = resolvePath(__dirname, '..', packageDir); const packageFolder = resolvePath(__dirname, '../dist-types', packageDir); - const tsdocConf = TSDocConfigFile.loadFile( - resolvePath(__dirname, '../tsdoc.json'), - ); - tsdocConf.setSupportForTag('@component', true); - const extractorConfig = ExtractorConfig.prepare({ configObject: { mainEntryPointFilePath: resolvePath(packageFolder, 'src/index.d.ts'), @@ -220,7 +214,6 @@ async function runApiExtraction({ }, configObjectFullPath: projectFolder, packageJsonFullPath: resolvePath(projectFolder, 'package.json'), - tsdocConfigFile: tsdocConf, }); // The `packageFolder` needs to point to the location within `dist-types` in order for relative @@ -308,11 +301,6 @@ async function runApiExtraction({ } } -function isComponentMember(member: any) { - // React components are annotated with @component, and we want to skip those - return Boolean(member.docComment.match(/\n\s*\**\s*@component/m)); -} - async function buildDocs({ inputDir, outputDir, @@ -334,9 +322,7 @@ async function buildDocs({ const newModel = new ApiModel(); for (const serialized of serializedPackages) { - serialized.members[0].members = serialized.members[0].members.filter( - member => !isComponentMember(member), - ); + // Add any docs filtering logic here const pkg = ApiPackage.deserialize( serialized, diff --git a/tsdoc.json b/tsdoc.json deleted file mode 100644 index c19ba9f22b..0000000000 --- a/tsdoc.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", - "extends": ["@microsoft/api-extractor/extends/tsdoc-base.json"], - "tagDefinitions": [ - { - "tagName": "@component", - "syntaxKind": "modifier" - } - ] -} From 7da91310b0c0d454e4bec22cfd73dfab9625dc79 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 11 Sep 2021 19:21:50 +0200 Subject: [PATCH 088/125] api-extractor: document doc generation a bit Signed-off-by: Patrik Oldsberg --- scripts/api-extractor.ts | 44 ++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index 93e68a460a..f53c46ddf2 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -301,6 +301,14 @@ async function runApiExtraction({ } } +/* +WARNING: Bring a blanket if you're gonna read the code below + +There's some weird shit going on here, and it's because we cba +forking rushstash to modify the api-documenter markdown generation, +which otherwise is the recommended way to do customizations. +*/ + async function buildDocs({ inputDir, outputDir, @@ -308,6 +316,8 @@ async function buildDocs({ inputDir: string; outputDir: string; }) { + // We start by constructing our own model from the files so that + // we get a change to modify them, as the model is otherwise read-only. const parseFile = async (filename: string): Promise => { console.log(`Reading ${filename}`); return fs.readJson(resolvePath(inputDir, filename)); @@ -331,9 +341,9 @@ async function buildDocs({ newModel.addMember(pkg); } - await fs.remove(outputDir); - await fs.ensureDir(outputDir); - + // This is root of the documentation generation, but it's not directly + // responsible for generating markdown, it just constructs an AST that + // is the consumed by an emitter to actually write the files. const documenter = new MarkdownDocumenter({ apiModel: newModel, documenterConfig: { @@ -346,6 +356,12 @@ async function buildDocs({ outputFolder: outputDir, }); + // We're accessing a lot of internal things... + const anyDocumenter = documenter as any; + + // The doc AST need to be extended with custom nodes if we want to + // add any extra content. + // This one is for the YAML front matter that we need for the microsite. class DocFrontMatter extends DocNode { static kind = 'DocFrontMatter'; @@ -372,8 +388,7 @@ async function buildDocs({ } } - const anyDocumenter = documenter as any; - + // It's a strict model, we gotta register the allowed usage of our new node anyDocumenter._tsdocConfiguration.docNodeManager.registerDocNodes( '@backstage/docs', [{ docNodeKind: DocFrontMatter.kind, constructor: DocFrontMatter }], @@ -383,6 +398,8 @@ async function buildDocs({ [DocFrontMatter.kind], ); + // This is where we actually write the markdown and where we can hook + // in the rendering of our own nodes. class CustomCustomMarkdownEmitter extends CustomMarkdownEmitter { /** @override */ protected writeNode( @@ -408,17 +425,22 @@ async function buildDocs({ /** @override */ emit(stringBuilder, docNode, options) { - // Hack to get rid of the leading comment + // Hack to get rid of the leading comment of each file, since + // we want the front matter to come first stringBuilder._chunks.length = 0; return super.emit(stringBuilder, docNode, options); } } - const emitter = new CustomCustomMarkdownEmitter(newModel); - anyDocumenter._markdownEmitter = emitter; + // The emitter is an internal thing, but it's fine to rewrite + anyDocumenter._markdownEmitter = new CustomCustomMarkdownEmitter(newModel); + // Gotta keep this around so we can call the real implementation const oldWrite = anyDocumenter._writeBreadcrumb; + // We don't really get many chances to modify the generated AST + // so we hook in wherever we can. In this case we add the front matter + // just before writing the breadcrumbs at the top. anyDocumenter._writeBreadcrumb = function patchedWriteBreadcrumb( output, apiItem, @@ -438,6 +460,7 @@ async function buildDocs({ description = `API Reference for ${apiItem.name}`; } + // Add our front matter output.appendNodeInParagraph( new DocFrontMatter({ configuration: this._tsdocConfiguration, @@ -447,15 +470,20 @@ async function buildDocs({ }), ); + // Now write the actual breadcrumbs oldWrite.call(this, output, apiItem); // We wanna ignore the header that always gets written after the breadcrumb + // This otherwise becomes more or less a duplicate of the title in the front matter const oldAppendNode = output.appendNode; output.appendNode = () => { output.appendNode = oldAppendNode; }; }; + // Clean up existing stuff and write ALL the docs! + await fs.remove(outputDir); + await fs.ensureDir(outputDir); documenter.generateFiles(); } From 87e63d8181fcfe986e29544f21016eef5f00e24c Mon Sep 17 00:00:00 2001 From: Ryan Vazquez Date: Sat, 11 Sep 2021 14:57:07 -0400 Subject: [PATCH 089/125] fix: remove title and wrapper margins; add subtitle margins Signed-off-by: Ryan Vazquez --- packages/core-components/src/layout/Header/Header.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/core-components/src/layout/Header/Header.tsx b/packages/core-components/src/layout/Header/Header.tsx index 4090644403..6cd3b588c2 100644 --- a/packages/core-components/src/layout/Header/Header.tsx +++ b/packages/core-components/src/layout/Header/Header.tsx @@ -41,7 +41,6 @@ const useStyles = makeStyles(theme => ({ leftItemsBox: { maxWidth: '100%', flexGrow: 1, - marginBottom: theme.spacing(1), }, rightItemsBox: { width: 'auto', @@ -50,11 +49,13 @@ const useStyles = makeStyles(theme => ({ color: theme.palette.bursts.fontColor, wordBreak: 'break-all', fontSize: 'calc(24px + 6 * ((100vw - 320px) / 680))', - marginBottom: theme.spacing(1), + marginBottom: 0, }, subtitle: { color: 'rgba(255, 255, 255, 0.8)', lineHeight: '1.0em', + display: 'inline-block', // prevents margin collapse of adjacent siblings + marginTop: theme.spacing(1), }, type: { textTransform: 'uppercase', From 6caa4df79b535b187edd2b312e1bc839ec2f0b63 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 11:42:17 +0200 Subject: [PATCH 090/125] api-extractor: switch to subclassing instead of monkey patching Signed-off-by: Patrik Oldsberg --- scripts/api-extractor.ts | 142 +++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index f53c46ddf2..5e8393fc78 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -33,7 +33,10 @@ import { } from '@microsoft/api-extractor'; import { DocNode, IDocNodeContainerParameters } from '@microsoft/tsdoc'; import { ApiPackage, ApiModel } from '@microsoft/api-extractor-model'; -import { MarkdownDocumenter } from '@microsoft/api-documenter/lib/documenters/MarkdownDocumenter'; +import { + IMarkdownDocumenterOptions, + MarkdownDocumenter, +} from '@microsoft/api-documenter/lib/documenters/MarkdownDocumenter'; import { CustomMarkdownEmitter } from '@microsoft/api-documenter/lib/markdown/CustomMarkdownEmitter'; import { IMarkdownEmitterContext } from '@microsoft/api-documenter/lib/markdown/MarkdownEmitter'; @@ -341,24 +344,6 @@ async function buildDocs({ newModel.addMember(pkg); } - // This is root of the documentation generation, but it's not directly - // responsible for generating markdown, it just constructs an AST that - // is the consumed by an emitter to actually write the files. - const documenter = new MarkdownDocumenter({ - apiModel: newModel, - documenterConfig: { - outputTarget: 'markdown', - newlineKind: '\n', - // De ba dålig kod - configFilePath: '', - configFile: {}, - } as any, - outputFolder: outputDir, - }); - - // We're accessing a lot of internal things... - const anyDocumenter = documenter as any; - // The doc AST need to be extended with custom nodes if we want to // add any extra content. // This one is for the YAML front matter that we need for the microsite. @@ -388,16 +373,6 @@ async function buildDocs({ } } - // It's a strict model, we gotta register the allowed usage of our new node - anyDocumenter._tsdocConfiguration.docNodeManager.registerDocNodes( - '@backstage/docs', - [{ docNodeKind: DocFrontMatter.kind, constructor: DocFrontMatter }], - ); - anyDocumenter._tsdocConfiguration.docNodeManager.registerAllowableChildren( - 'Paragraph', - [DocFrontMatter.kind], - ); - // This is where we actually write the markdown and where we can hook // in the rendering of our own nodes. class CustomCustomMarkdownEmitter extends CustomMarkdownEmitter { @@ -432,54 +407,79 @@ async function buildDocs({ } } - // The emitter is an internal thing, but it's fine to rewrite - anyDocumenter._markdownEmitter = new CustomCustomMarkdownEmitter(newModel); + class CustomMarkdownDocumenter extends (MarkdownDocumenter as any) { + constructor(options: IMarkdownDocumenterOptions) { + super(options); - // Gotta keep this around so we can call the real implementation - const oldWrite = anyDocumenter._writeBreadcrumb; + // It's a strict model, we gotta register the allowed usage of our new node + this._tsdocConfiguration.docNodeManager.registerDocNodes( + '@backstage/docs', + [{ docNodeKind: DocFrontMatter.kind, constructor: DocFrontMatter }], + ); + this._tsdocConfiguration.docNodeManager.registerAllowableChildren( + 'Paragraph', + [DocFrontMatter.kind], + ); - // We don't really get many chances to modify the generated AST - // so we hook in wherever we can. In this case we add the front matter - // just before writing the breadcrumbs at the top. - anyDocumenter._writeBreadcrumb = function patchedWriteBreadcrumb( - output, - apiItem, - ) { - let title; - let description; - - const name = apiItem.getScopedNameWithinPackage(); - if (name) { - title = name; - description = `API reference for ${apiItem.getScopedNameWithinPackage()}`; - } else if (apiItem.kind === 'Model') { - title = 'Package Index'; - description = 'Index of all Backstage Packages'; - } else { - title = apiItem.name; - description = `API Reference for ${apiItem.name}`; + this._markdownEmitter = new CustomCustomMarkdownEmitter(newModel); } - // Add our front matter - output.appendNodeInParagraph( - new DocFrontMatter({ - configuration: this._tsdocConfiguration, - id: this._getFilenameForApiItem(apiItem).slice(0, -3), - title, - description, - }), - ); + // We don't really get many chances to modify the generated AST + // so we hook in wherever we can. In this case we add the front matter + // just before writing the breadcrumbs at the top. + /** @override */ + _writeBreadcrumb(output, apiItem) { + let title; + let description; - // Now write the actual breadcrumbs - oldWrite.call(this, output, apiItem); + const name = apiItem.getScopedNameWithinPackage(); + if (name) { + title = name; + description = `API reference for ${apiItem.getScopedNameWithinPackage()}`; + } else if (apiItem.kind === 'Model') { + title = 'Package Index'; + description = 'Index of all Backstage Packages'; + } else { + title = apiItem.name; + description = `API Reference for ${apiItem.name}`; + } - // We wanna ignore the header that always gets written after the breadcrumb - // This otherwise becomes more or less a duplicate of the title in the front matter - const oldAppendNode = output.appendNode; - output.appendNode = () => { - output.appendNode = oldAppendNode; - }; - }; + // Add our front matter + output.appendNodeInParagraph( + new DocFrontMatter({ + configuration: this._tsdocConfiguration, + id: this._getFilenameForApiItem(apiItem).slice(0, -3), + title, + description, + }), + ); + + // Now write the actual breadcrumbs + super._writeBreadcrumb(output, apiItem); + + // We wanna ignore the header that always gets written after the breadcrumb + // This otherwise becomes more or less a duplicate of the title in the front matter + const oldAppendNode = output.appendNode; + output.appendNode = () => { + output.appendNode = oldAppendNode; + }; + } + } + + // This is root of the documentation generation, but it's not directly + // responsible for generating markdown, it just constructs an AST that + // is the consumed by an emitter to actually write the files. + const documenter = new CustomMarkdownDocumenter({ + apiModel: newModel, + documenterConfig: { + outputTarget: 'markdown', + newlineKind: '\n', + // De ba dålig kod + configFilePath: '', + configFile: {}, + } as any, + outputFolder: outputDir, + }); // Clean up existing stuff and write ALL the docs! await fs.remove(outputDir); From 1a7340e1aef631b9ddd0c7af88f887c0e630947a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 11:45:46 +0200 Subject: [PATCH 091/125] docs: clear out the reference folder Signed-off-by: Patrik Oldsberg --- docs/reference/.generated | 2 + docs/reference/createPlugin-feature-flags.md | 44 --- docs/reference/createPlugin.md | 41 --- docs/reference/utility-apis/AlertApi.md | 114 -------- docs/reference/utility-apis/AppThemeApi.md | 271 ------------------ .../utility-apis/BackstageIdentityApi.md | 100 ------- docs/reference/utility-apis/Config.md | 187 ------------ docs/reference/utility-apis/DiscoveryApi.md | 24 -- docs/reference/utility-apis/ErrorApi.md | 134 --------- .../reference/utility-apis/FeatureFlagsApi.md | 113 -------- docs/reference/utility-apis/IdentityApi.md | 81 ------ docs/reference/utility-apis/OAuthApi.md | 117 -------- .../reference/utility-apis/OAuthRequestApi.md | 233 --------------- .../utility-apis/OpenIdConnectApi.md | 75 ----- docs/reference/utility-apis/ProfileInfoApi.md | 104 ------- docs/reference/utility-apis/README.md | 202 ------------- docs/reference/utility-apis/SessionApi.md | 144 ---------- .../reference/utility-apis/SessionStateApi.md | 119 -------- docs/reference/utility-apis/StorageApi.md | 186 ------------ microsite/sidebars.json | 16 +- 20 files changed, 5 insertions(+), 2302 deletions(-) create mode 100644 docs/reference/.generated delete mode 100644 docs/reference/createPlugin-feature-flags.md delete mode 100644 docs/reference/createPlugin.md delete mode 100644 docs/reference/utility-apis/AlertApi.md delete mode 100644 docs/reference/utility-apis/AppThemeApi.md delete mode 100644 docs/reference/utility-apis/BackstageIdentityApi.md delete mode 100644 docs/reference/utility-apis/Config.md delete mode 100644 docs/reference/utility-apis/DiscoveryApi.md delete mode 100644 docs/reference/utility-apis/ErrorApi.md delete mode 100644 docs/reference/utility-apis/FeatureFlagsApi.md delete mode 100644 docs/reference/utility-apis/IdentityApi.md delete mode 100644 docs/reference/utility-apis/OAuthApi.md delete mode 100644 docs/reference/utility-apis/OAuthRequestApi.md delete mode 100644 docs/reference/utility-apis/OpenIdConnectApi.md delete mode 100644 docs/reference/utility-apis/ProfileInfoApi.md delete mode 100644 docs/reference/utility-apis/README.md delete mode 100644 docs/reference/utility-apis/SessionApi.md delete mode 100644 docs/reference/utility-apis/SessionStateApi.md delete mode 100644 docs/reference/utility-apis/StorageApi.md diff --git a/docs/reference/.generated b/docs/reference/.generated new file mode 100644 index 0000000000..e08947a827 --- /dev/null +++ b/docs/reference/.generated @@ -0,0 +1,2 @@ +The contents of this folder is generated by the root `yarn build:api-docs` command. +Don't put any additional content here as it will be overwritten during the microsite build. diff --git a/docs/reference/createPlugin-feature-flags.md b/docs/reference/createPlugin-feature-flags.md deleted file mode 100644 index d550ba10a9..0000000000 --- a/docs/reference/createPlugin-feature-flags.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -id: createPlugin-feature-flags -title: createPlugin - feature flags -description: Documentation on createPlugin - feature flags ---- - -The `featureFlags` object passed to the `register` function makes it possible -for plugins to register Feature Flags in Backstage for users to opt into. You -can use this to split out logic in your code for manual A/B testing, etc. - -Here's a code sample: - -```typescript -import { createPlugin } from '@backstage/core-plugin-api'; - -export default createPlugin({ - id: 'plugin-name', - register({ featureFlags }) { - featureFlags.register('enable-example-feature'); - }, -}); -``` - -## Using with useApi - -To inspect the state of a feature flag inside your plugin, you can use the -`FeatureFlagsApi`, accessed via the `featureFlagsApiRef`. For example: - -```tsx -import React from 'react'; -import { Button } from '@material-ui/core'; -import { featureFlagsApiRef, useApi } from '@backstage/core-plugin-api'; - -const ExamplePage = () => { - const featureFlags = useApi(featureFlagsApiRef); - - return ( -

- - { featureFlags.isActive('enable-example-feature') && } -
- ); -}; -``` diff --git a/docs/reference/createPlugin.md b/docs/reference/createPlugin.md deleted file mode 100644 index 6602b0b2cc..0000000000 --- a/docs/reference/createPlugin.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -id: createPlugin -title: createPlugin -description: Documentation on createPlugin ---- - -Takes a plugin config as an argument and returns a new plugin. - -## Plugin Config - -```typescript -function createPlugin(config: PluginConfig): BackstagePlugin; - -type PluginConfig = { - id: string; - register?(hooks: PluginHooks): void; -}; - -type PluginHooks = { - featureFlags: FeatureFlagsHooks; -}; -``` - -- [Read more about feature flags here](createPlugin-feature-flags.md) - -## Example Uses - -### Creating a basic plugin - -Showcasing adding a feature flag. - -```jsx -import { createPlugin } from '@backstage/core-plugin-api'; - -export default createPlugin({ - id: 'new-plugin', - register({ router, featureFlags }) { - featureFlags.register('enable-example-component'); - }, -}); -``` diff --git a/docs/reference/utility-apis/AlertApi.md b/docs/reference/utility-apis/AlertApi.md deleted file mode 100644 index 8d1851cc44..0000000000 --- a/docs/reference/utility-apis/AlertApi.md +++ /dev/null @@ -1,114 +0,0 @@ -# AlertApi - -The AlertApi type is defined at -[packages/core-api/src/apis/definitions/AlertApi.ts:29](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/AlertApi.ts#L29). - -The following Utility API implements this type: [alertApiRef](./README.md#alert) - -## Members - -### post() - -Post an alert for handling by the application. - -
-post(alert: AlertMessage): void
-
- -### alert\$() - -Observe alerts posted by other parts of the application. - -
-alert$(): Observable<AlertMessage>
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### AlertMessage - -
-export type AlertMessage = {
-  message: string;
-  // Severity will default to success since that is what material ui defaults the value to.
-  severity?: 'success' | 'info' | 'warning' | 'error';
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/AlertApi.ts:19](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/AlertApi.ts#L19). - -Referenced by: [post](#post), [alert\$](#alert). - -### Observable - -Observable sequence of values and errors, see TC39. - -https://github.com/tc39/proposal-observable - -This is used as a common return type for observable values and can be created -using many different observable implementations, such as zen-observable or -RxJS 5. - -
-export type Observable<T> = {
-  /**
-   * Subscribes to this observable to start receiving new values.
-   */
-  subscribe(observer: Observer<T>): Subscription;
-  subscribe(
-    onNext: (value: T) => void,
-    onError?: (error: Error) => void,
-    onComplete?: () => void,
-  ): Subscription;
-}
-
- -Defined at -[packages/core-api/src/types.ts:53](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L53). - -Referenced by: [alert\$](#alert). - -### Observer - -This file contains non-react related core types used throughout Backstage. - -Observer interface for consuming an Observer, see TC39. - -
-export type Observer<T> = {
-  next?(value: T): void;
-  error?(error: Error): void;
-  complete?(): void;
-}
-
- -Defined at -[packages/core-api/src/types.ts:24](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L24). - -Referenced by: [Observable](#observable). - -### Subscription - -Subscription returned when subscribing to an Observable, see TC39. - -
-export type Subscription = {
-  /**
-   * Cancels the subscription
-   */
-  unsubscribe(): void;
-
-  /**
-   * Value indicating whether the subscription is closed.
-   */
-  readonly closed: Boolean;
-}
-
- -Defined at -[packages/core-api/src/types.ts:33](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L33). - -Referenced by: [Observable](#observable). diff --git a/docs/reference/utility-apis/AppThemeApi.md b/docs/reference/utility-apis/AppThemeApi.md deleted file mode 100644 index a662b4cb70..0000000000 --- a/docs/reference/utility-apis/AppThemeApi.md +++ /dev/null @@ -1,271 +0,0 @@ -# AppThemeApi - -The AppThemeApi type is defined at -[packages/core-api/src/apis/definitions/AppThemeApi.ts:56](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/AppThemeApi.ts#L56). - -The following Utility API implements this type: -[appThemeApiRef](./README.md#apptheme) - -## Members - -### getInstalledThemes() - -Get a list of available themes. - -
-getInstalledThemes(): AppTheme[]
-
- -### activeThemeId\$() - -Observe the currently selected theme. A value of undefined means no specific -theme has been selected. - -
-activeThemeId$(): Observable<string | undefined>
-
- -### getActiveThemeId() - -Get the current theme ID. Returns undefined if no specific theme is selected. - -
-getActiveThemeId(): string | undefined
-
- -### setActiveThemeId() - -Set a specific theme to use in the app, overriding the default theme selection. - -Clear the selection by passing in undefined. - -
-setActiveThemeId(themeId?: string): void
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### AppTheme - -Describes a theme provided by the app. - -
-export type AppTheme = {
-  /**
-   * ID used to remember theme selections.
-   */
-  id: string;
-
-  /**
-   * Title of the theme
-   */
-  title: string;
-
-  /**
-   * Theme variant
-   */
-  variant: 'light' | 'dark';
-
-  /**
-   * The specialized MaterialUI theme instance.
-   */
-  theme: BackstageTheme;
-
-  /**
-   * An Icon for the theme mode setting.
-   */
-  icon?: React.ReactElement<SvgIconProps>;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/AppThemeApi.ts:25](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/AppThemeApi.ts#L25). - -Referenced by: [getInstalledThemes](#getinstalledthemes). - -### BackstagePalette - -
-export type BackstagePalette = Palette & PaletteAdditions
-
- -Defined at -[packages/theme/src/types.ts:74](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/theme/src/types.ts#L74). - -Referenced by: [BackstageTheme](#backstagetheme). - -### BackstageTheme - -
-export interface BackstageTheme extends Theme {
-  palette: BackstagePalette;
-  page: PageTheme;
-  getPageTheme: ({ themeId }: PageThemeSelector) => PageTheme;
-}
-
- -Defined at -[packages/theme/src/types.ts:81](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/theme/src/types.ts#L81). - -Referenced by: [AppTheme](#apptheme). - -### Observable - -Observable sequence of values and errors, see TC39. - -https://github.com/tc39/proposal-observable - -This is used as a common return type for observable values and can be created -using many different observable implementations, such as zen-observable or -RxJS 5. - -
-export type Observable<T> = {
-  /**
-   * Subscribes to this observable to start receiving new values.
-   */
-  subscribe(observer: Observer<T>): Subscription;
-  subscribe(
-    onNext: (value: T) => void,
-    onError?: (error: Error) => void,
-    onComplete?: () => void,
-  ): Subscription;
-}
-
- -Defined at -[packages/core-api/src/types.ts:53](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L53). - -Referenced by: [activeThemeId\$](#activethemeid). - -### Observer - -This file contains non-react related core types used throughout Backstage. - -Observer interface for consuming an Observer, see TC39. - -
-export type Observer<T> = {
-  next?(value: T): void;
-  error?(error: Error): void;
-  complete?(): void;
-}
-
- -Defined at -[packages/core-api/src/types.ts:24](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L24). - -Referenced by: [Observable](#observable). - -### PageTheme - -
-export type PageTheme = {
-  colors: string[];
-  shape: string;
-  backgroundImage: string;
-}
-
- -Defined at -[packages/theme/src/types.ts:103](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/theme/src/types.ts#L103). - -Referenced by: [BackstageTheme](#backstagetheme). - -### PageThemeSelector - -
-export type PageThemeSelector = {
-  themeId: string;
-}
-
- -Defined at -[packages/theme/src/types.ts:77](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/theme/src/types.ts#L77). - -Referenced by: [BackstageTheme](#backstagetheme). - -### PaletteAdditions - -
-type PaletteAdditions = {
-  status: {
-    ok: string;
-    warning: string;
-    error: string;
-    pending: string;
-    running: string;
-    aborted: string;
-  };
-  border: string;
-  textContrast: string;
-  textVerySubtle: string;
-  textSubtle: string;
-  highlight: string;
-  errorBackground: string;
-  warningBackground: string;
-  infoBackground: string;
-  errorText: string;
-  infoText: string;
-  warningText: string;
-  linkHover: string;
-  link: string;
-  gold: string;
-  navigation: {
-    background: string;
-    indicator: string;
-    color: string;
-    selectedColor: string;
-  };
-  tabbar: {
-    indicator: string;
-  };
-  bursts: {
-    fontColor: string;
-    slackChannelText: string;
-    backgroundColor: {
-      default: string;
-    };
-  };
-  pinSidebarButton: {
-    icon: string;
-    background: string;
-  };
-  banner: {
-    info: string;
-    error: string;
-    text: string;
-    link: string;
-  };
-}
-
- -Defined at -[packages/theme/src/types.ts:23](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/theme/src/types.ts#L23). - -Referenced by: [BackstagePalette](#backstagepalette). - -### Subscription - -Subscription returned when subscribing to an Observable, see TC39. - -
-export type Subscription = {
-  /**
-   * Cancels the subscription
-   */
-  unsubscribe(): void;
-
-  /**
-   * Value indicating whether the subscription is closed.
-   */
-  readonly closed: Boolean;
-}
-
- -Defined at -[packages/core-api/src/types.ts:33](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L33). - -Referenced by: [Observable](#observable). diff --git a/docs/reference/utility-apis/BackstageIdentityApi.md b/docs/reference/utility-apis/BackstageIdentityApi.md deleted file mode 100644 index 80a40d427e..0000000000 --- a/docs/reference/utility-apis/BackstageIdentityApi.md +++ /dev/null @@ -1,100 +0,0 @@ -# BackstageIdentityApi - -The BackstageIdentityApi type is defined at -[packages/core-api/src/apis/definitions/auth.ts:134](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L134). - -The following Utility APIs implement this type: - -- [auth0AuthApiRef](./README.md#auth0auth) - -- [githubAuthApiRef](./README.md#githubauth) - -- [gitlabAuthApiRef](./README.md#gitlabauth) - -- [googleAuthApiRef](./README.md#googleauth) - -- [microsoftAuthApiRef](./README.md#microsoftauth) - -- [oauth2ApiRef](./README.md#oauth2) - -- [oidcAuthApiRef](./README.md#oidcauth) - -- [oktaAuthApiRef](./README.md#oktaauth) - -- [oneloginAuthApiRef](./README.md#oneloginauth) - -- [samlAuthApiRef](./README.md#samlauth) - -## Members - -### getBackstageIdentity() - -Get the user's identity within Backstage. This should normally not be called -directly, use the @IdentityApi instead. - -If the optional flag is not set, a session is guaranteed to be returned, while -if the optional flag is set, the session may be undefined. See -@AuthRequestOptions for more details. - -
-getBackstageIdentity(
-    options?: AuthRequestOptions,
-  ): Promise<BackstageIdentity | undefined>
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### AuthRequestOptions - -
-export type AuthRequestOptions = {
-  /**
-   * If this is set to true, the user will not be prompted to log in,
-   * and an empty response will be returned if there is no existing session.
-   *
-   * This can be used to perform a check whether the user is logged in, or if you don't
-   * want to force a user to be logged in, but provide functionality if they already are.
-   *
-   * @default false
-   */
-  optional?: boolean;
-
-  /**
-   * If this is set to true, the request will bypass the regular oauth login modal
-   * and open the login popup directly.
-   *
-   * The method must be called synchronously from a user action for this to work in all browsers.
-   *
-   * @default false
-   */
-  instantPopup?: boolean;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/auth.ts:40](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L40). - -Referenced by: [getBackstageIdentity](#getbackstageidentity). - -### BackstageIdentity - -
-export type BackstageIdentity = {
-  /**
-   * The backstage user ID.
-   */
-  id: string;
-
-  /**
-   * An ID token that can be used to authenticate the user within Backstage.
-   */
-  idToken: string;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/auth.ts:147](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L147). - -Referenced by: [getBackstageIdentity](#getbackstageidentity). diff --git a/docs/reference/utility-apis/Config.md b/docs/reference/utility-apis/Config.md deleted file mode 100644 index c5b20610e7..0000000000 --- a/docs/reference/utility-apis/Config.md +++ /dev/null @@ -1,187 +0,0 @@ -# Config - -The Config type is defined at -[packages/config/src/types.ts:32](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/config/src/types.ts#L32). - -The following Utility API implements this type: -[configApiRef](./README.md#config) - -## Members - -### has() - -
-has(key: string): boolean
-
- -### keys() - -
-keys(): string[]
-
- -### get() - -
-get(key?: string): JsonValue
-
- -### getOptional() - -
-getOptional(key?: string): JsonValue | undefined
-
- -### getConfig() - -
-getConfig(key: string): Config
-
- -### getOptionalConfig() - -
-getOptionalConfig(key: string): Config | undefined
-
- -### getConfigArray() - -
-getConfigArray(key: string): Config[]
-
- -### getOptionalConfigArray() - -
-getOptionalConfigArray(key: string): Config[] | undefined
-
- -### getNumber() - -
-getNumber(key: string): number
-
- -### getOptionalNumber() - -
-getOptionalNumber(key: string): number | undefined
-
- -### getBoolean() - -
-getBoolean(key: string): boolean
-
- -### getOptionalBoolean() - -
-getOptionalBoolean(key: string): boolean | undefined
-
- -### getString() - -
-getString(key: string): string
-
- -### getOptionalString() - -
-getOptionalString(key: string): string | undefined
-
- -### getStringArray() - -
-getStringArray(key: string): string[]
-
- -### getOptionalStringArray() - -
-getOptionalStringArray(key: string): string[] | undefined
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### Config - -
-export type Config = {
-  has(key: string): boolean;
-
-  keys(): string[];
-
-  get(key?: string): JsonValue;
-  getOptional(key?: string): JsonValue | undefined;
-
-  getConfig(key: string): Config;
-  getOptionalConfig(key: string): Config | undefined;
-
-  getConfigArray(key: string): Config[];
-  getOptionalConfigArray(key: string): Config[] | undefined;
-
-  getNumber(key: string): number;
-  getOptionalNumber(key: string): number | undefined;
-
-  getBoolean(key: string): boolean;
-  getOptionalBoolean(key: string): boolean | undefined;
-
-  getString(key: string): string;
-  getOptionalString(key: string): string | undefined;
-
-  getStringArray(key: string): string[];
-  getOptionalStringArray(key: string): string[] | undefined;
-}
-
- -Defined at -[packages/config/src/types.ts:32](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/config/src/types.ts#L32). - -Referenced by: [getConfig](#getconfig), [getOptionalConfig](#getoptionalconfig), -[getConfigArray](#getconfigarray), -[getOptionalConfigArray](#getoptionalconfigarray), [Config](#config). - -### JsonArray - -
-export type JsonArray = JsonValue[]
-
- -Defined at -[packages/config/src/types.ts:18](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/config/src/types.ts#L18). - -Referenced by: [JsonValue](#jsonvalue). - -### JsonObject - -
-export type JsonObject = { [key in string]?: JsonValue }
-
- -Defined at -[packages/config/src/types.ts:17](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/config/src/types.ts#L17). - -Referenced by: [JsonValue](#jsonvalue). - -### JsonValue - -
-export type JsonValue =
-  | JsonObject
-  | JsonArray
-  | number
-  | string
-  | boolean
-  | null
-
- -Defined at -[packages/config/src/types.ts:19](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/config/src/types.ts#L19). - -Referenced by: [get](#get), [getOptional](#getoptional), -[JsonObject](#jsonobject), [JsonArray](#jsonarray), [Config](#config). diff --git a/docs/reference/utility-apis/DiscoveryApi.md b/docs/reference/utility-apis/DiscoveryApi.md deleted file mode 100644 index 0d888c1daa..0000000000 --- a/docs/reference/utility-apis/DiscoveryApi.md +++ /dev/null @@ -1,24 +0,0 @@ -# DiscoveryApi - -The DiscoveryApi type is defined at -[packages/core-api/src/apis/definitions/DiscoveryApi.ts:30](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/DiscoveryApi.ts#L30). - -The following Utility API implements this type: -[discoveryApiRef](./README.md#discovery) - -## Members - -### getBaseUrl() - -Returns the HTTP base backend URL for a given plugin, without a trailing slash. - -This method must always be called just before making a request, as opposed to -fetching the URL when constructing an API client. That is to ensure that more -flexible routing patterns can be supported. - -For example, asking for the URL for `auth` may return something like -`https://backstage.example.com/api/auth` - -
-getBaseUrl(pluginId: string): Promise<string>
-
diff --git a/docs/reference/utility-apis/ErrorApi.md b/docs/reference/utility-apis/ErrorApi.md deleted file mode 100644 index 1aaecdb47e..0000000000 --- a/docs/reference/utility-apis/ErrorApi.md +++ /dev/null @@ -1,134 +0,0 @@ -# ErrorApi - -The ErrorApi type is defined at -[packages/core-api/src/apis/definitions/ErrorApi.ts:53](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/ErrorApi.ts#L53). - -The following Utility API implements this type: [errorApiRef](./README.md#error) - -## Members - -### post() - -Post an error for handling by the application. - -
-post(error: Error, context?: ErrorContext): void
-
- -### error\$() - -Observe errors posted by other parts of the application. - -
-error$(): Observable<{ error: Error; context?: ErrorContext }>
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### Error - -Mirrors the JavaScript Error class, for the purpose of providing documentation -and optional fields. - -
-type Error = {
-  name: string;
-  message: string;
-  stack?: string;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/ErrorApi.ts:24](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/ErrorApi.ts#L24). - -Referenced by: [post](#post), [error\$](#error). - -### ErrorContext - -Provides additional information about an error that was posted to the -application. - -
-export type ErrorContext = {
-  // If set to true, this error should not be displayed to the user. Defaults to false.
-  hidden?: boolean;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/ErrorApi.ts:33](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/ErrorApi.ts#L33). - -Referenced by: [post](#post), [error\$](#error). - -### Observable - -Observable sequence of values and errors, see TC39. - -https://github.com/tc39/proposal-observable - -This is used as a common return type for observable values and can be created -using many different observable implementations, such as zen-observable or -RxJS 5. - -
-export type Observable<T> = {
-  /**
-   * Subscribes to this observable to start receiving new values.
-   */
-  subscribe(observer: Observer<T>): Subscription;
-  subscribe(
-    onNext: (value: T) => void,
-    onError?: (error: Error) => void,
-    onComplete?: () => void,
-  ): Subscription;
-}
-
- -Defined at -[packages/core-api/src/types.ts:53](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L53). - -Referenced by: [error\$](#error). - -### Observer - -This file contains non-react related core types used throughout Backstage. - -Observer interface for consuming an Observer, see TC39. - -
-export type Observer<T> = {
-  next?(value: T): void;
-  error?(error: Error): void;
-  complete?(): void;
-}
-
- -Defined at -[packages/core-api/src/types.ts:24](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L24). - -Referenced by: [Observable](#observable). - -### Subscription - -Subscription returned when subscribing to an Observable, see TC39. - -
-export type Subscription = {
-  /**
-   * Cancels the subscription
-   */
-  unsubscribe(): void;
-
-  /**
-   * Value indicating whether the subscription is closed.
-   */
-  readonly closed: Boolean;
-}
-
- -Defined at -[packages/core-api/src/types.ts:33](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L33). - -Referenced by: [Observable](#observable). diff --git a/docs/reference/utility-apis/FeatureFlagsApi.md b/docs/reference/utility-apis/FeatureFlagsApi.md deleted file mode 100644 index 1e8979c02e..0000000000 --- a/docs/reference/utility-apis/FeatureFlagsApi.md +++ /dev/null @@ -1,113 +0,0 @@ -# FeatureFlagsApi - -The FeatureFlagsApi type is defined at -[packages/core-api/src/apis/definitions/FeatureFlagsApi.ts:60](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/FeatureFlagsApi.ts#L60). - -The following Utility API implements this type: -[featureFlagsApiRef](./README.md#featureflags) - -## Members - -### registerFlag() - -Registers a new feature flag. Once a feature flag has been registered it can be -toggled by users, and read back to enable or disable features. - -
-registerFlag(flag: FeatureFlag): void
-
- -### getRegisteredFlags() - -Get a list of all registered flags. - -
-getRegisteredFlags(): FeatureFlag[]
-
- -### isActive() - -Whether the feature flag with the given name is currently activated for the -user. - -
-isActive(name: string): boolean
-
- -### save() - -Save the user's choice of feature flag states. - -
-save(options: FeatureFlagsSaveOptions): void
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### FeatureFlag - -The feature flags API is used to toggle functionality to users across plugins -and Backstage. - -Plugins can use this API to register feature flags that they have available for -users to enable/disable, and this API will centralize the current user's state -of which feature flags they would like to enable. - -This is ideal for Backstage plugins, as well as your own App, to trial -incomplete or unstable upcoming features. Although there will be a common -interface for users to enable and disable feature flags, this API acts as -another way to enable/disable. - -
-export type FeatureFlag = {
-  name: string;
-  pluginId: string;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/FeatureFlagsApi.ts:31](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/FeatureFlagsApi.ts#L31). - -Referenced by: [registerFlag](#registerflag), -[getRegisteredFlags](#getregisteredflags). - -### FeatureFlagState - -
-export enum FeatureFlagState {
-  None = 0,
-  Active = 1,
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/FeatureFlagsApi.ts:36](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/FeatureFlagsApi.ts#L36). - -Referenced by: [FeatureFlagsSaveOptions](#featureflagssaveoptions). - -### FeatureFlagsSaveOptions - -Options to use when saving feature flags. - -
-export type FeatureFlagsSaveOptions = {
-  /**
-   * The new feature flag states to save.
-   */
-  states: Record<string, FeatureFlagState>;
-
-  /**
-   * Whether the saves states should be merged into the existing ones, or replace them.
-   *
-   * Defaults to false.
-   */
-  merge?: boolean;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/FeatureFlagsApi.ts:44](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/FeatureFlagsApi.ts#L44). - -Referenced by: [save](#save). diff --git a/docs/reference/utility-apis/IdentityApi.md b/docs/reference/utility-apis/IdentityApi.md deleted file mode 100644 index aa2a4dd9a0..0000000000 --- a/docs/reference/utility-apis/IdentityApi.md +++ /dev/null @@ -1,81 +0,0 @@ -# IdentityApi - -The IdentityApi type is defined at -[packages/core-api/src/apis/definitions/IdentityApi.ts:22](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/IdentityApi.ts#L22). - -The following Utility API implements this type: -[identityApiRef](./README.md#identity) - -## Members - -### getUserId() - -The ID of the signed in user. This ID is not meant to be presented to the user, -but used as an opaque string to pass on to backends or use in frontend logic. - -TODO: The intention of the user ID is to be able to tie the user to an identity -that is known by the catalog and/or identity backend. It should for example be -possible to fetch all owned components using this ID. - -
-getUserId(): string
-
- -### getProfile() - -The profile of the signed in user. - -
-getProfile(): ProfileInfo
-
- -### getIdToken() - -An OpenID Connect ID Token which proves the identity of the signed in user. - -The ID token will be undefined if the signed in user does not have a verified -identity, such as a demo user or mocked user for e2e tests. - -
-getIdToken(): Promise<string | undefined>
-
- -### signOut() - -Sign out the current user - -
-signOut(): Promise<void>
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### ProfileInfo - -Profile information of the user. - -
-export type ProfileInfo = {
-  /**
-   * Email ID.
-   */
-  email?: string;
-
-  /**
-   * Display name that can be presented to the user.
-   */
-  displayName?: string;
-
-  /**
-   * URL to an avatar image of the user.
-   */
-  picture?: string;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/auth.ts:162](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L162). - -Referenced by: [getProfile](#getprofile). diff --git a/docs/reference/utility-apis/OAuthApi.md b/docs/reference/utility-apis/OAuthApi.md deleted file mode 100644 index 9af6b3bb53..0000000000 --- a/docs/reference/utility-apis/OAuthApi.md +++ /dev/null @@ -1,117 +0,0 @@ -# OAuthApi - -The OAuthApi type is defined at -[packages/core-api/src/apis/definitions/auth.ts:67](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L67). - -The following Utility APIs implement this type: - -- [githubAuthApiRef](./README.md#githubauth) - -- [gitlabAuthApiRef](./README.md#gitlabauth) - -- [googleAuthApiRef](./README.md#googleauth) - -- [microsoftAuthApiRef](./README.md#microsoftauth) - -- [oauth2ApiRef](./README.md#oauth2) - -- [oidcAuthApiRef](./README.md#oidcauth) - -- [oktaAuthApiRef](./README.md#oktaauth) - -- [oneloginAuthApiRef](./README.md#oneloginauth) - -## Members - -### getAccessToken() - -Requests an OAuth 2 Access Token, optionally with a set of scopes. The access -token allows you to make requests on behalf of the user, and the copes may grant -you broader access, depending on the auth provider. - -Each auth provider has separate handling of scope, so you need to look at the -documentation for each one to know what scope you need to request. - -This method is cheap and should be called each time an access token is used. Do -not for example store the access token in React component state, as that could -cause the token to expire. Instead fetch a new access token for each request. - -Be sure to include all required scopes when requesting an access token. When -testing your implementation it is best to log out the Backstage session and then -visit your plugin page directly, as you might already have some required scopes -in your existing session. Not requesting the correct scopes can lead to 403 or -other authorization errors, which can be tricky to debug. - -If the user has not yet granted access to the provider and the set of requested -scopes, the user will be prompted to log in. The returned promise will not -resolve until the user has successfully logged in. The returned promise can be -rejected, but only if the user rejects the login request. - -
-getAccessToken(
-    scope?: OAuthScope,
-    options?: AuthRequestOptions,
-  ): Promise<string>
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### AuthRequestOptions - -
-export type AuthRequestOptions = {
-  /**
-   * If this is set to true, the user will not be prompted to log in,
-   * and an empty response will be returned if there is no existing session.
-   *
-   * This can be used to perform a check whether the user is logged in, or if you don't
-   * want to force a user to be logged in, but provide functionality if they already are.
-   *
-   * @default false
-   */
-  optional?: boolean;
-
-  /**
-   * If this is set to true, the request will bypass the regular oauth login modal
-   * and open the login popup directly.
-   *
-   * The method must be called synchronously from a user action for this to work in all browsers.
-   *
-   * @default false
-   */
-  instantPopup?: boolean;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/auth.ts:40](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L40). - -Referenced by: [getAccessToken](#getaccesstoken). - -### OAuthScope - -This file contains declarations for common interfaces of auth-related APIs. The -declarations should be used to signal which type of authentication and -authorization methods each separate auth provider supports. - -For example, a Google OAuth provider that supports OAuth 2 and OpenID Connect, -would be declared as follows: - -const googleAuthApiRef = createApiRef({ ... }) - -An array of scopes, or a scope string formatted according to the auth provider, -which is typically a space separated list. - -See the documentation for each auth provider for the list of scopes supported by -each provider. - -
-export type OAuthScope = string | string[]
-
- -Defined at -[packages/core-api/src/apis/definitions/auth.ts:38](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L38). - -Referenced by: [getAccessToken](#getaccesstoken). diff --git a/docs/reference/utility-apis/OAuthRequestApi.md b/docs/reference/utility-apis/OAuthRequestApi.md deleted file mode 100644 index 5f521cf288..0000000000 --- a/docs/reference/utility-apis/OAuthRequestApi.md +++ /dev/null @@ -1,233 +0,0 @@ -# OAuthRequestApi - -The OAuthRequestApi type is defined at -[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:99](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L99). - -The following Utility API implements this type: -[oauthRequestApiRef](./README.md#oauthrequest) - -## Members - -### createAuthRequester() - -A utility for showing login popups or similar things, and merging together -multiple requests for different scopes into one request that includes all -scopes. - -The passed in options provide information about the login provider, and how to -handle auth requests. - -The returned AuthRequester function is used to request login with new scopes. -These requests are merged together and forwarded to the auth handler, as soon as -a consumer of auth requests triggers an auth flow. - -See AuthRequesterOptions, AuthRequester, and handleAuthRequests for more info. - -
-createAuthRequester<AuthResponse>(
-    options: AuthRequesterOptions<AuthResponse>,
-  ): AuthRequester<AuthResponse>
-
- -### authRequest\$() - -Observers pending auth requests. The returned observable will emit all current -active auth request, at most one for each created auth requester. - -Each request has its own info about the login provider, forwarded from the auth -requester options. - -Depending on user interaction, the request should either be rejected, or used to -trigger the auth handler. If the request is rejected, all pending AuthRequester -calls will fail with a "RejectedError". If a auth is triggered, and the auth -handler resolves successfully, then all currently pending AuthRequester calls -will resolve to the value returned by the onAuthRequest call. - -
-authRequest$(): Observable<PendingAuthRequest[]>
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### AuthProvider - -Information about the auth provider that we're requesting a login towards. - -This should be shown to the user so that they can be informed about what login -is being requested before a popup is shown. - -
-export type AuthProvider = {
-  /**
-   * Title for the auth provider, for example "GitHub"
-   */
-  title: string;
-
-  /**
-   * Icon for the auth provider.
-   */
-  icon: IconComponent;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:27](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L27). - -Referenced by: [AuthRequesterOptions](#authrequesteroptions), -[PendingAuthRequest](#pendingauthrequest). - -### AuthRequester - -Function used to trigger new auth requests for a set of scopes. - -The returned promise will resolve to the same value returned by the -onAuthRequest in the AuthRequesterOptions. Or rejected, if the request is -rejected. - -This function can be called multiple times before the promise resolves. All -calls will be merged into one request, and the scopes forwarded to the -onAuthRequest will be the union of all requested scopes. - -
-export type AuthRequester<AuthResponse> = (
-  scopes: Set<string>,
-) => Promise<AuthResponse>
-
- -Defined at -[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:66](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L66). - -Referenced by: [createAuthRequester](#createauthrequester). - -### AuthRequesterOptions - -Describes how to handle auth requests. Both how to show them to the user, and -what to do when the user accesses the auth request. - -
-export type AuthRequesterOptions<AuthResponse> = {
-  /**
-   * Information about the auth provider, which will be forwarded to auth requests.
-   */
-  provider: AuthProvider;
-
-  /**
-   * Implementation of the auth flow, which will be called synchronously when
-   * trigger() is called on an auth requests.
-   */
-  onAuthRequest(scopes: Set<string>): Promise<AuthResponse>;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:43](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L43). - -Referenced by: [createAuthRequester](#createauthrequester). - -### Observable - -Observable sequence of values and errors, see TC39. - -https://github.com/tc39/proposal-observable - -This is used as a common return type for observable values and can be created -using many different observable implementations, such as zen-observable or -RxJS 5. - -
-export type Observable<T> = {
-  /**
-   * Subscribes to this observable to start receiving new values.
-   */
-  subscribe(observer: Observer<T>): Subscription;
-  subscribe(
-    onNext: (value: T) => void,
-    onError?: (error: Error) => void,
-    onComplete?: () => void,
-  ): Subscription;
-}
-
- -Defined at -[packages/core-api/src/types.ts:53](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L53). - -Referenced by: [authRequest\$](#authrequest). - -### Observer - -This file contains non-react related core types used throughout Backstage. - -Observer interface for consuming an Observer, see TC39. - -
-export type Observer<T> = {
-  next?(value: T): void;
-  error?(error: Error): void;
-  complete?(): void;
-}
-
- -Defined at -[packages/core-api/src/types.ts:24](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L24). - -Referenced by: [Observable](#observable). - -### PendingAuthRequest - -An pending auth request for a single auth provider. The request will remain in -this pending state until either reject() or trigger() is called. - -Any new requests for the same provider are merged into the existing pending -request, meaning there will only ever be a single pending request for a given -provider. - -
-export type PendingAuthRequest = {
-  /**
-   * Information about the auth provider, as given in the AuthRequesterOptions
-   */
-  provider: AuthProvider;
-
-  /**
-   * Rejects the request, causing all pending AuthRequester calls to fail with "RejectedError".
-   */
-  reject: () => void;
-
-  /**
-   * Trigger the auth request to continue the auth flow, by for example showing a popup.
-   *
-   * Synchronously calls onAuthRequest with all scope currently in the request.
-   */
-  trigger(): Promise<void>;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/OAuthRequestApi.ts:77](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L77). - -Referenced by: [authRequest\$](#authrequest). - -### Subscription - -Subscription returned when subscribing to an Observable, see TC39. - -
-export type Subscription = {
-  /**
-   * Cancels the subscription
-   */
-  unsubscribe(): void;
-
-  /**
-   * Value indicating whether the subscription is closed.
-   */
-  readonly closed: Boolean;
-}
-
- -Defined at -[packages/core-api/src/types.ts:33](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L33). - -Referenced by: [Observable](#observable). diff --git a/docs/reference/utility-apis/OpenIdConnectApi.md b/docs/reference/utility-apis/OpenIdConnectApi.md deleted file mode 100644 index 6d05af6189..0000000000 --- a/docs/reference/utility-apis/OpenIdConnectApi.md +++ /dev/null @@ -1,75 +0,0 @@ -# OpenIdConnectApi - -The OpenIdConnectApi type is defined at -[packages/core-api/src/apis/definitions/auth.ts:99](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L99). - -The following Utility APIs implement this type: - -- [auth0AuthApiRef](./README.md#auth0auth) - -- [googleAuthApiRef](./README.md#googleauth) - -- [microsoftAuthApiRef](./README.md#microsoftauth) - -- [oauth2ApiRef](./README.md#oauth2) - -- [oidcAuthApiRef](./README.md#oidcauth) - -- [oktaAuthApiRef](./README.md#oktaauth) - -- [oneloginAuthApiRef](./README.md#oneloginauth) - -## Members - -### getIdToken() - -Requests an OpenID Connect ID Token. - -This method is cheap and should be called each time an ID token is used. Do not -for example store the id token in React component state, as that could cause the -token to expire. Instead fetch a new id token for each request. - -If the user has not yet logged in to Google inside Backstage, the user will be -prompted to log in. The returned promise will not resolve until the user has -successfully logged in. The returned promise can be rejected, but only if the -user rejects the login request. - -
-getIdToken(options?: AuthRequestOptions): Promise<string>
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### AuthRequestOptions - -
-export type AuthRequestOptions = {
-  /**
-   * If this is set to true, the user will not be prompted to log in,
-   * and an empty response will be returned if there is no existing session.
-   *
-   * This can be used to perform a check whether the user is logged in, or if you don't
-   * want to force a user to be logged in, but provide functionality if they already are.
-   *
-   * @default false
-   */
-  optional?: boolean;
-
-  /**
-   * If this is set to true, the request will bypass the regular oauth login modal
-   * and open the login popup directly.
-   *
-   * The method must be called synchronously from a user action for this to work in all browsers.
-   *
-   * @default false
-   */
-  instantPopup?: boolean;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/auth.ts:40](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L40). - -Referenced by: [getIdToken](#getidtoken). diff --git a/docs/reference/utility-apis/ProfileInfoApi.md b/docs/reference/utility-apis/ProfileInfoApi.md deleted file mode 100644 index 1a2f94d031..0000000000 --- a/docs/reference/utility-apis/ProfileInfoApi.md +++ /dev/null @@ -1,104 +0,0 @@ -# ProfileInfoApi - -The ProfileInfoApi type is defined at -[packages/core-api/src/apis/definitions/auth.ts:117](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L117). - -The following Utility APIs implement this type: - -- [auth0AuthApiRef](./README.md#auth0auth) - -- [githubAuthApiRef](./README.md#githubauth) - -- [gitlabAuthApiRef](./README.md#gitlabauth) - -- [googleAuthApiRef](./README.md#googleauth) - -- [microsoftAuthApiRef](./README.md#microsoftauth) - -- [oauth2ApiRef](./README.md#oauth2) - -- [oidcAuthApiRef](./README.md#oidcauth) - -- [oktaAuthApiRef](./README.md#oktaauth) - -- [oneloginAuthApiRef](./README.md#oneloginauth) - -- [samlAuthApiRef](./README.md#samlauth) - -## Members - -### getProfile() - -Get profile information for the user as supplied by this auth provider. - -If the optional flag is not set, a session is guaranteed to be returned, while -if the optional flag is set, the session may be undefined. See -@AuthRequestOptions for more details. - -
-getProfile(options?: AuthRequestOptions): Promise<ProfileInfo | undefined>
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### AuthRequestOptions - -
-export type AuthRequestOptions = {
-  /**
-   * If this is set to true, the user will not be prompted to log in,
-   * and an empty response will be returned if there is no existing session.
-   *
-   * This can be used to perform a check whether the user is logged in, or if you don't
-   * want to force a user to be logged in, but provide functionality if they already are.
-   *
-   * @default false
-   */
-  optional?: boolean;
-
-  /**
-   * If this is set to true, the request will bypass the regular oauth login modal
-   * and open the login popup directly.
-   *
-   * The method must be called synchronously from a user action for this to work in all browsers.
-   *
-   * @default false
-   */
-  instantPopup?: boolean;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/auth.ts:40](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L40). - -Referenced by: [getProfile](#getprofile). - -### ProfileInfo - -Profile information of the user. - -
-export type ProfileInfo = {
-  /**
-   * Email ID.
-   */
-  email?: string;
-
-  /**
-   * Display name that can be presented to the user.
-   */
-  displayName?: string;
-
-  /**
-   * URL to an avatar image of the user.
-   */
-  picture?: string;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/auth.ts:162](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L162). - -Referenced by: [getProfile](#getprofile). diff --git a/docs/reference/utility-apis/README.md b/docs/reference/utility-apis/README.md deleted file mode 100644 index aefbb4b925..0000000000 --- a/docs/reference/utility-apis/README.md +++ /dev/null @@ -1,202 +0,0 @@ -# Backstage Core Utility APIs - -The following is a list of all Utility APIs defined by `@backstage/core`. They -are available to use by plugins and components, and can be accessed using the -`useApi` hook, also provided by `@backstage/core`. For more information, see -https://github.com/backstage/backstage/blob/master/docs/api/utility-apis.md. - -### alert - -Used to report alerts and forward them to the app - -Implemented type: [AlertApi](./AlertApi.md) - -ApiRef: -[alertApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/AlertApi.ts#L41) - -### appTheme - -API Used to configure the app theme, and enumerate options - -Implemented type: [AppThemeApi](./AppThemeApi.md) - -ApiRef: -[appThemeApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/AppThemeApi.ts#L80) - -### auth0Auth - -Provides authentication towards Auth0 APIs - -Implemented types: [OpenIdConnectApi](./OpenIdConnectApi.md), -[ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) - -ApiRef: -[auth0AuthApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L275) - -### config - -Used to access runtime configuration - -Implemented type: [Config](./Config.md) - -ApiRef: -[configApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/ConfigApi.ts#L25) - -### discovery - -Provides service discovery of backend plugins - -Implemented type: [DiscoveryApi](./DiscoveryApi.md) - -ApiRef: -[discoveryApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/DiscoveryApi.ts#L44) - -### error - -Used to report errors and forward them to the app - -Implemented type: [ErrorApi](./ErrorApi.md) - -ApiRef: -[errorApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/ErrorApi.ts#L65) - -### featureFlags - -Used to toggle functionality in features across Backstage - -Implemented type: [FeatureFlagsApi](./FeatureFlagsApi.md) - -ApiRef: -[featureFlagsApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/FeatureFlagsApi.ts#L83) - -### githubAuth - -Provides authentication towards GitHub APIs - -Implemented types: [OAuthApi](./OAuthApi.md), -[ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) - -ApiRef: -[githubAuthApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L232) - -### gitlabAuth - -Provides authentication towards GitLab APIs - -Implemented types: [OAuthApi](./OAuthApi.md), -[ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) - -ApiRef: -[gitlabAuthApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L262) - -### googleAuth - -Provides authentication towards Google APIs and identities - -Implemented types: [OAuthApi](./OAuthApi.md), -[OpenIdConnectApi](./OpenIdConnectApi.md), -[ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) - -ApiRef: -[googleAuthApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L215) - -### identity - -Provides access to the identity of the signed in user - -Implemented type: [IdentityApi](./IdentityApi.md) - -ApiRef: -[identityApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/IdentityApi.ts#L53) - -### microsoftAuth - -Provides authentication towards Microsoft APIs and identities - -Implemented types: [OAuthApi](./OAuthApi.md), -[OpenIdConnectApi](./OpenIdConnectApi.md), -[ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) - -ApiRef: -[microsoftAuthApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L289) - -### oauth2 - -Example of how to use oauth2 custom provider - -Implemented types: [OAuthApi](./OAuthApi.md), -[OpenIdConnectApi](./OpenIdConnectApi.md), -[ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) - -ApiRef: -[oauth2ApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L303) - -### oauthRequest - -An API for implementing unified OAuth flows in Backstage - -Implemented type: [OAuthRequestApi](./OAuthRequestApi.md) - -ApiRef: -[oauthRequestApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/OAuthRequestApi.ts#L130) - -### oidcAuth - -Example of how to use oidc custom provider - -Implemented types: [OAuthApi](./OAuthApi.md), -[OpenIdConnectApi](./OpenIdConnectApi.md), -[ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) - -ApiRef: -[oidcAuthApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L317) - -### oktaAuth - -Provides authentication towards Okta APIs - -Implemented types: [OAuthApi](./OAuthApi.md), -[OpenIdConnectApi](./OpenIdConnectApi.md), -[ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) - -ApiRef: -[oktaAuthApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L245) - -### oneloginAuth - -Provides authentication towards OneLogin APIs and identities - -Implemented types: [OAuthApi](./OAuthApi.md), -[OpenIdConnectApi](./OpenIdConnectApi.md), -[ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) - -ApiRef: -[oneloginAuthApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L338) - -### samlAuth - -Example of how to use SAML custom provider - -Implemented types: [ProfileInfoApi](./ProfileInfoApi.md), -[BackstageIdentityApi](./BackstageIdentityApi.md), [SessionApi](./SessionApi.md) - -ApiRef: -[samlAuthApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L331) - -### storage - -Provides the ability to store data which is unique to the user - -Implemented type: [StorageApi](./StorageApi.md) - -ApiRef: -[storageApiRef](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/StorageApi.ts#L68) diff --git a/docs/reference/utility-apis/SessionApi.md b/docs/reference/utility-apis/SessionApi.md deleted file mode 100644 index 4b584d92c8..0000000000 --- a/docs/reference/utility-apis/SessionApi.md +++ /dev/null @@ -1,144 +0,0 @@ -# SessionApi - -The SessionApi type is defined at -[packages/core-api/src/apis/definitions/auth.ts:190](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L190). - -The following Utility APIs implement this type: - -- [auth0AuthApiRef](./README.md#auth0auth) - -- [githubAuthApiRef](./README.md#githubauth) - -- [gitlabAuthApiRef](./README.md#gitlabauth) - -- [googleAuthApiRef](./README.md#googleauth) - -- [microsoftAuthApiRef](./README.md#microsoftauth) - -- [oauth2ApiRef](./README.md#oauth2) - -- [oidcAuthApiRef](./README.md#oidcauth) - -- [oktaAuthApiRef](./README.md#oktaauth) - -- [oneloginAuthApiRef](./README.md#oneloginauth) - -- [samlAuthApiRef](./README.md#samlauth) - -## Members - -### signIn() - -Sign in with a minimum set of permissions. - -
-signIn(): Promise<void>
-
- -### signOut() - -Sign out from the current session. This will reload the page. - -
-signOut(): Promise<void>
-
- -### sessionState\$() - -Observe the current state of the auth session. Emits the current state on -subscription. - -
-sessionState$(): Observable<SessionState>
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### Observable - -Observable sequence of values and errors, see TC39. - -https://github.com/tc39/proposal-observable - -This is used as a common return type for observable values and can be created -using many different observable implementations, such as zen-observable or -RxJS 5. - -
-export type Observable<T> = {
-  /**
-   * Subscribes to this observable to start receiving new values.
-   */
-  subscribe(observer: Observer<T>): Subscription;
-  subscribe(
-    onNext: (value: T) => void,
-    onError?: (error: Error) => void,
-    onComplete?: () => void,
-  ): Subscription;
-}
-
- -Defined at -[packages/core-api/src/types.ts:53](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L53). - -Referenced by: [sessionState\$](#sessionstate). - -### Observer - -This file contains non-react related core types used throughout Backstage. - -Observer interface for consuming an Observer, see TC39. - -
-export type Observer<T> = {
-  next?(value: T): void;
-  error?(error: Error): void;
-  complete?(): void;
-}
-
- -Defined at -[packages/core-api/src/types.ts:24](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L24). - -Referenced by: [Observable](#observable). - -### SessionState - -Session state values passed to subscribers of the SessionApi. - -
-export enum SessionState {
-  SignedIn = 'SignedIn',
-  SignedOut = 'SignedOut',
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/auth.ts:182](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/auth.ts#L182). - -Referenced by: [sessionState\$](#sessionstate). - -### Subscription - -Subscription returned when subscribing to an Observable, see TC39. - -
-export type Subscription = {
-  /**
-   * Cancels the subscription
-   */
-  unsubscribe(): void;
-
-  /**
-   * Value indicating whether the subscription is closed.
-   */
-  readonly closed: Boolean;
-}
-
- -Defined at -[packages/core-api/src/types.ts:33](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L33). - -Referenced by: [Observable](#observable). diff --git a/docs/reference/utility-apis/SessionStateApi.md b/docs/reference/utility-apis/SessionStateApi.md deleted file mode 100644 index a8a4c3bc3d..0000000000 --- a/docs/reference/utility-apis/SessionStateApi.md +++ /dev/null @@ -1,119 +0,0 @@ -# SessionStateApi - -The SessionStateApi type is defined at -[packages/core-api/src/apis/definitions/auth.ts:201](https://github.com/backstage/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L201). - -The following Utility APIs implement this type: - -- [auth0AuthApiRef](./README.md#auth0auth) - -- [githubAuthApiRef](./README.md#githubauth) - -- [gitlabAuthApiRef](./README.md#gitlabauth) - -- [googleAuthApiRef](./README.md#googleauth) - -- [microsoftAuthApiRef](./README.md#microsoftauth) - -- [oauth2ApiRef](./README.md#oauth2) - -- [oktaAuthApiRef](./README.md#oktaauth) - -## Members - -### sessionState\$() - -
-sessionState$(): Observable<SessionState>
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### Observable - -Observable sequence of values and errors, see TC39. - -https://github.com/tc39/proposal-observable - -This is used as a common return type for observable values and can be created -using many different observable implementations, such as zen-observable or -RxJS 5. - -
-export type Observable<T> = {
-  /**
-   * Subscribes to this observable to start receiving new values.
-   */
-  subscribe(observer: Observer<T>): Subscription;
-  subscribe(
-    onNext: (value: T) => void,
-    onError?: (error: Error) => void,
-    onComplete?: () => void,
-  ): Subscription;
-}
-
- -Defined at -[packages/core-api/src/types.ts:53](https://github.com/backstage/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L53). - -Referenced by: [sessionState\$](#sessionstate). - -### Observer - -This file contains non-react related core types used through Backstage. - -Observer interface for consuming an Observer, see TC39. - -
-export type Observer<T> = {
-  next?(value: T): void;
-  error?(error: Error): void;
-  complete?(): void;
-}
-
- -Defined at -[packages/core-api/src/types.ts:24](https://github.com/backstage/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L24). - -Referenced by: [Observable](#observable). - -### SessionState - -Session state values passed to subscribers of the SessionStateApi. - -
-export enum SessionState {
-  SignedIn = 'SignedIn',
-  SignedOut = 'SignedOut',
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/auth.ts:192](https://github.com/backstage/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/apis/definitions/auth.ts#L192). - -Referenced by: [sessionState\$](#sessionstate). - -### Subscription - -Subscription returned when subscribing to an Observable, see TC39. - -
-export type Subscription = {
-  /**
-   * Cancels the subscription
-   */
-  unsubscribe(): void;
-
-  /**
-   * Value indicating whether the subscription is closed.
-   */
-  readonly closed: Boolean;
-}
-
- -Defined at -[packages/core-api/src/types.ts:33](https://github.com/backstage/backstage/blob/82d329555c16af46db9b4e5cd2f44a3cc006a52e/packages/core-api/src/types.ts#L33). - -Referenced by: [Observable](#observable). diff --git a/docs/reference/utility-apis/StorageApi.md b/docs/reference/utility-apis/StorageApi.md deleted file mode 100644 index 3247d28f60..0000000000 --- a/docs/reference/utility-apis/StorageApi.md +++ /dev/null @@ -1,186 +0,0 @@ -# StorageApi - -The StorageApi type is defined at -[packages/core-api/src/apis/definitions/StorageApi.ts:31](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/StorageApi.ts#L31). - -The following Utility API implements this type: -[storageApiRef](./README.md#storage) - -## Members - -### forBucket() - -Create a bucket to store data in. - -
-forBucket(name: string): StorageApi
-
- -### get() - -Get the current value for persistent data, use observe\$ to be notified of -updates. - -
-get<T>(key: string): T | undefined
-
- -### remove() - -Remove persistent data. - -
-remove(key: string): Promise<void>
-
- -### set() - -Save persistent data, and emit messages to anyone that is using observe\$ for -this key - -
-set(key: string, data: any): Promise<void>
-
- -### observe\$() - -Observe changes on a particular key in the bucket - -
-observe$<T>(key: string): Observable<StorageValueChange<T>>
-
- -## Supporting types - -These types are part of the API declaration, but may not be unique to this API. - -### Observable - -Observable sequence of values and errors, see TC39. - -https://github.com/tc39/proposal-observable - -This is used as a common return type for observable values and can be created -using many different observable implementations, such as zen-observable or -RxJS 5. - -
-export type Observable<T> = {
-  /**
-   * Subscribes to this observable to start receiving new values.
-   */
-  subscribe(observer: Observer<T>): Subscription;
-  subscribe(
-    onNext: (value: T) => void,
-    onError?: (error: Error) => void,
-    onComplete?: () => void,
-  ): Subscription;
-}
-
- -Defined at -[packages/core-api/src/types.ts:53](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L53). - -Referenced by: [observe\$](#observe), [StorageApi](#storageapi). - -### Observer - -This file contains non-react related core types used throughout Backstage. - -Observer interface for consuming an Observer, see TC39. - -
-export type Observer<T> = {
-  next?(value: T): void;
-  error?(error: Error): void;
-  complete?(): void;
-}
-
- -Defined at -[packages/core-api/src/types.ts:24](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L24). - -Referenced by: [Observable](#observable). - -### StorageApi - -
-export interface StorageApi {
-  /**
-   * Create a bucket to store data in.
-   * @param {String} name Namespace for the storage to be stored under,
-   *                      will inherit previous namespaces too
-   */
-  forBucket(name: string): StorageApi;
-
-  /**
-   * Get the current value for persistent data, use observe$ to be notified of updates.
-   *
-   * @param {String} key Unique key associated with the data.
-   * @return {Object} data The data that should is stored.
-   */
-  get<T>(key: string): T | undefined;
-
-  /**
-   * Remove persistent data.
-   *
-   * @param {String} key Unique key associated with the data.
-   */
-  remove(key: string): Promise<void>;
-
-  /**
-   * Save persistent data, and emit messages to anyone that is using observe$ for this key
-   *
-   * @param {String} key Unique key associated with the data.
-   */
-  set(key: string, data: any): Promise<void>;
-
-  /**
-   * Observe changes on a particular key in the bucket
-   * @param {String} key Unique key associated with the data
-   */
-  observe$<T>(key: string): Observable<StorageValueChange<T>>;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/StorageApi.ts:31](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/StorageApi.ts#L31). - -Referenced by: [forBucket](#forbucket). - -### StorageValueChange - -
-export type StorageValueChange<T = any> = {
-  key: string;
-  newValue?: T;
-}
-
- -Defined at -[packages/core-api/src/apis/definitions/StorageApi.ts:21](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/apis/definitions/StorageApi.ts#L21). - -Referenced by: [observe\$](#observe), [StorageApi](#storageapi). - -### Subscription - -Subscription returned when subscribing to an Observable, see TC39. - -
-export type Subscription = {
-  /**
-   * Cancels the subscription
-   */
-  unsubscribe(): void;
-
-  /**
-   * Value indicating whether the subscription is closed.
-   */
-  readonly closed: Boolean;
-}
-
- -Defined at -[packages/core-api/src/types.ts:33](https://github.com/backstage/backstage/blob/a4dbd8353cfa4d4d4334473e2c33afcda64e130d/packages/core-api/src/types.ts#L33). - -Referenced by: [Observable](#observable). diff --git a/microsite/sidebars.json b/microsite/sidebars.json index d200b615f1..dc8aa516cf 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -234,21 +234,11 @@ "dls/contributing-to-storybook", "dls/figma" ], - "API references": [ + "API Reference": [ { "type": "subcategory", - "label": "TypeScript API", - "ids": [ - "api/utility-apis", - "reference/utility-apis/README", - "reference/createPlugin", - "reference/createPlugin-feature-flags" - ] - }, - { - "type": "subcategory", - "label": "Backend APIs", - "ids": ["api/backend"] + "label": "Guides", + "ids": [ "api/utility-apis" ] } ], "Tutorials": [ From 5e0c8cdaaa0f3d55e6228daf12fad2d856e3a263 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 11:47:58 +0200 Subject: [PATCH 092/125] root: bump api-extractor deps and add missing explicit tsdoc dep Signed-off-by: Patrik Oldsberg --- package.json | 7 +++--- yarn.lock | 70 ++++++++++++++++++++++++++-------------------------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/package.json b/package.json index c9a33f78e6..ea930b060f 100644 --- a/package.json +++ b/package.json @@ -54,9 +54,10 @@ }, "version": "1.0.0", "dependencies": { - "@microsoft/api-documenter": "^7.13.30", - "@microsoft/api-extractor": "^7.18.1", - "@microsoft/api-extractor-model": "^7.13.3" + "@microsoft/api-documenter": "^7.13.47", + "@microsoft/api-extractor": "^7.18.7", + "@microsoft/api-extractor-model": "^7.13.5", + "@microsoft/tsdoc": "^0.13.2" }, "devDependencies": { "@types/webpack": "^5.28.0", diff --git a/yarn.lock b/yarn.lock index 1d408ff5ae..5c7c1b0235 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4540,45 +4540,45 @@ resolved "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== -"@microsoft/api-documenter@^7.13.30": - version "7.13.30" - resolved "https://registry.npmjs.org/@microsoft/api-documenter/-/api-documenter-7.13.30.tgz#f4832b8747ad9f61b3a0d87eb61b6b1aca2aeb60" - integrity sha512-n91XihJptwcHp1g5FUIcrjDXhg/g2q6+Rj+nuPBkvsCAKQP/OwCLNVO3tYNpz+qa+lWrHPWL3Urc8G3th5cn7w== +"@microsoft/api-documenter@^7.13.47": + version "7.13.47" + resolved "https://registry.npmjs.org/@microsoft/api-documenter/-/api-documenter-7.13.47.tgz#0b7726634232b37f76c0e5e8353cdbb5b52d4ece" + integrity sha512-jk78Pf8cKL2WZf6CkKUUtwegdsTA1Jf0MfIzD50qpG7T257HLrqCi1t70ZA85VpRLR8oSeNHMayqNTWkdku9iA== dependencies: - "@microsoft/api-extractor-model" "7.13.3" + "@microsoft/api-extractor-model" "7.13.5" "@microsoft/tsdoc" "0.13.2" - "@rushstack/node-core-library" "3.39.0" - "@rushstack/ts-command-line" "4.8.0" + "@rushstack/node-core-library" "3.40.0" + "@rushstack/ts-command-line" "4.9.0" colors "~1.2.1" js-yaml "~3.13.1" resolve "~1.17.0" -"@microsoft/api-extractor-model@7.13.3", "@microsoft/api-extractor-model@^7.13.3": - version "7.13.3" - resolved "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.13.3.tgz#ac01c064c5af520d3661c85d7e5ef95e1ca8ab92" - integrity sha512-uXilAhu2GcvyY/0NwVRk3AN7TFYjkPnjHLV2UywTTz9uglS+Af0YjNrCy+aaK8qXtfbFWdBzkH9N2XU8/YBeRQ== +"@microsoft/api-extractor-model@7.13.5", "@microsoft/api-extractor-model@^7.13.5": + version "7.13.5" + resolved "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.13.5.tgz#7836a81ba47b9a654062ed0361e4eee69afae51e" + integrity sha512-il6AebNltYo5hEtqXZw4DMvrwBPn6+F58TxwqmsLY+U+sSJNxaYn2jYksArrjErXVPR3gUgRMqD6zsdIkg+WEQ== dependencies: "@microsoft/tsdoc" "0.13.2" "@microsoft/tsdoc-config" "~0.15.2" - "@rushstack/node-core-library" "3.39.0" + "@rushstack/node-core-library" "3.40.0" -"@microsoft/api-extractor@^7.18.1": - version "7.18.1" - resolved "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.18.1.tgz#61b39f972b646261dd49f2de9f5d448aa6497e7a" - integrity sha512-qljUF2Q0zAx1vJrjKkJVGN7OVbsXki+Pji99jywyl6L/FK3YZ7PpstUJYE6uBcLPy6rhNPWPAsHNTMpG/kHIsg== +"@microsoft/api-extractor@^7.18.7": + version "7.18.7" + resolved "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.18.7.tgz#851d2413a3c5d696f7cc914eb59de7a7882b2e8b" + integrity sha512-JhtV8LoyLuIecbgCPyZQg08G1kngIRWpai2UzwNil9mGVGYiDZVeeKx8c2phmlPcogmMDm4oQROxyuiYt5sJiw== dependencies: - "@microsoft/api-extractor-model" "7.13.3" + "@microsoft/api-extractor-model" "7.13.5" "@microsoft/tsdoc" "0.13.2" "@microsoft/tsdoc-config" "~0.15.2" - "@rushstack/node-core-library" "3.39.0" - "@rushstack/rig-package" "0.2.12" - "@rushstack/ts-command-line" "4.8.0" + "@rushstack/node-core-library" "3.40.0" + "@rushstack/rig-package" "0.3.0" + "@rushstack/ts-command-line" "4.9.0" colors "~1.2.1" lodash "~4.17.15" resolve "~1.17.0" semver "~7.3.0" source-map "~0.6.1" - typescript "~4.3.2" + typescript "~4.3.5" "@microsoft/fetch-event-source@2.0.1": version "2.0.1" @@ -4600,7 +4600,7 @@ jju "~1.4.0" resolve "~1.19.0" -"@microsoft/tsdoc@0.13.2": +"@microsoft/tsdoc@0.13.2", "@microsoft/tsdoc@^0.13.2": version "0.13.2" resolved "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.13.2.tgz#3b0efb6d3903bd49edb073696f60e90df08efb26" integrity sha512-WrHvO8PDL8wd8T2+zBGKrMwVL5IyzR3ryWUsl0PXgEV0QHup4mTLi0QcATefGI6Gx9Anu7vthPyyyLpY0EpiQg== @@ -5217,10 +5217,10 @@ estree-walker "^2.0.1" picomatch "^2.2.2" -"@rushstack/node-core-library@3.39.0": - version "3.39.0" - resolved "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.39.0.tgz#38928946d15ae89b773386cf97433d0d1ec83b93" - integrity sha512-kgu3+7/zOBkZU0+NdJb1rcHcpk3/oTjn5c8cg5nUTn+JDjEw58yG83SoeJEcRNNdl11dGX0lKG2PxPsjCokZOQ== +"@rushstack/node-core-library@3.40.0": + version "3.40.0" + resolved "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.40.0.tgz#2551915ea34e34ec2abb7172b9d7f4546144d9d4" + integrity sha512-P6uMPI7cqTdawLSPAG5BQrBu1MHlGRPqecp7ruIRgyukIEzkmh0QAnje4jAL/l1r3hw0qe4e+Dz5ZSnukT/Egg== dependencies: "@types/node" "10.17.13" colors "~1.2.1" @@ -5232,18 +5232,18 @@ timsort "~0.3.0" z-schema "~3.18.3" -"@rushstack/rig-package@0.2.12": - version "0.2.12" - resolved "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.2.12.tgz#c434d62b28e0418a040938226f8913971d0424c7" - integrity sha512-nbePcvF8hQwv0ql9aeQxcaMPK/h1OLAC00W7fWCRWIvD2MchZOE8jumIIr66HGrfG2X1sw++m/ZYI4D+BM5ovQ== +"@rushstack/rig-package@0.3.0": + version "0.3.0" + resolved "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.3.0.tgz#334ad2846797861361b3445d4cc9ae9164b1885c" + integrity sha512-Lj6noF7Q4BBm1hKiBDw94e6uZvq1xlBwM/d2cBFaPqXeGdV+G6r3qaCWfRiSXK0pcHpGGpV5Tb2MdfhVcO6G/g== dependencies: resolve "~1.17.0" strip-json-comments "~3.1.1" -"@rushstack/ts-command-line@4.8.0": - version "4.8.0" - resolved "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.8.0.tgz#611accb931b9ac62ff4d078f68f95c47f6606724" - integrity sha512-nZ8cbzVF1VmFPfSJfy8vEohdiFAH/59Y/Y+B4nsJbn4SkifLJ8LqNZ5+LxCC2UR242EXFumxlsY1d6fPBxck5Q== +"@rushstack/ts-command-line@4.9.0": + version "4.9.0" + resolved "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.9.0.tgz#781ba42cff73cae097b6d5241b6441e7cc2fe6e0" + integrity sha512-kmT8t+JfnvphISF1C5WwY56RefjwgajhSjs9J4ckvAFXZDXR6F5cvF5/RTh7fGCzIomg8esy2PHO/b52zFoZvA== dependencies: "@types/argparse" "1.0.38" argparse "~1.0.9" @@ -26334,7 +26334,7 @@ typescript@^4.0.3, typescript@~4.2.3: resolved "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== -typescript@~4.3.2: +typescript@~4.3.5: version "4.3.5" resolved "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== From 575d8bd9f25ed8ea5a8d3d8c9b002e18a6f57f13 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 12:00:12 +0200 Subject: [PATCH 093/125] build api reference as part of the microsite Signed-off-by: Patrik Oldsberg --- .github/workflows/microsite-with-storybook-deploy.yml | 9 +++------ docs/.gitignore | 1 + microsite/sidebars.json | 7 ++++++- 3 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 docs/.gitignore diff --git a/.github/workflows/microsite-with-storybook-deploy.yml b/.github/workflows/microsite-with-storybook-deploy.yml index e8886b7d6b..47e18340eb 100644 --- a/.github/workflows/microsite-with-storybook-deploy.yml +++ b/.github/workflows/microsite-with-storybook-deploy.yml @@ -4,12 +4,6 @@ on: push: branches: - master - paths: - - '.github/workflows/microsite-with-storybook-deploy.yml' - - 'packages/storybook/**' - - 'packages/core-components/src/**' - - 'microsite/**' - - 'docs/**' jobs: deploy-microsite-and-storybook: @@ -41,6 +35,9 @@ jobs: run: yarn install --frozen-lockfile working-directory: microsite + - name: build API reference + run: yarn build:api-docs + - name: build microsite run: yarn build working-directory: microsite diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000000..c757205e4c --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +reference/*.md diff --git a/microsite/sidebars.json b/microsite/sidebars.json index dc8aa516cf..d0d77e9b59 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -238,7 +238,12 @@ { "type": "subcategory", "label": "Guides", - "ids": [ "api/utility-apis" ] + "ids": ["api/utility-apis"] + }, + { + "type": "subcategory", + "label": "API Reference", + "ids": ["reference/index"] } ], "Tutorials": [ From cf06e3881b94854384648fd41d6e1c25cc04ab2a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 12:19:24 +0200 Subject: [PATCH 094/125] docs/api/utility-apis: links out to api reference Signed-off-by: Patrik Oldsberg --- docs/api/utility-apis.md | 177 +++++++++++++++++++++++---------------- 1 file changed, 106 insertions(+), 71 deletions(-) diff --git a/docs/api/utility-apis.md b/docs/api/utility-apis.md index f04202b79b..1a1e29c19c 100644 --- a/docs/api/utility-apis.md +++ b/docs/api/utility-apis.md @@ -12,25 +12,32 @@ however always be a need for plugins to communicate outside of its boundaries, both with other plugins and the app itself. Backstage provides two primary methods for plugins to communicate across their -boundaries in client-side code. The first one being the `createPlugin` API and -the registration hooks passed to the `register` method, and the second one being -Utility APIs. While the `createPlugin` API is focused on the initialization -plugins and the app, the Utility APIs provide ways for plugins to communicate -during their entire life cycle. +boundaries in client-side code. The first one being the +[createPlugin](../reference/core-plugin-api.createPlugin.md) API along with the +extensions that it can provide, and the second one being Utility APIs. While the +[createPlugin](../reference/core-plugin-api.createPlugin.md) API is focused on +the initialization plugins and the app, the Utility APIs provide ways for +plugins to communicate during their entire life cycle. ## Consuming APIs -Each Utility API is tied to an `ApiRef` instance, which is a global singleton -object without any additional state or functionality, its only purpose is to -reference Utility APIs. `ApiRef`s are created using `createApiRef`, which is -exported by `@backstage/core-plugin-api`. There are many -[predefined Utility APIs](../reference/utility-apis/README.md) defined in -`@backstage/core-plugin-api`, and they're all exported with a name of the -pattern `*ApiRef`, for example `errorApiRef`. +Each Utility API is tied to an [ApiRef](../reference/core-plugin-api.ApiRef.md) +instance, which is a global singleton object without any additional state or +functionality, its only purpose is to reference Utility APIs. +[ApiRef](../reference/core-plugin-api.ApiRef.md)s are created using +[createApiRef](../reference/core-plugin-api.createApiRef.md), which is exported +by [@backstage/core-plugin-api](../reference/core-plugin-api.md). There are also +many predefined Utility APIs in +[@backstage/core-plugin-api](../reference/core-plugin-api.md), and they're all +exported with a name of the pattern `*ApiRef`, for example +[errorApiRef](../reference/core-plugin-api.errorApiRef.md). -To access one of the Utility APIs inside a React component, use the `useApi` -hook exported by `@backstage/core-plugin-api`, or the `withApis` HOC if you -prefer class components. For example, the `ErrorApi` can be accessed like this: +To access one of the Utility APIs inside a React component, use the +[useApi](../reference/core-plugin-api.useApi.md) hook exported by +[@backstage/core-plugin-api](../reference/core-plugin-api.md), or the +[withApis](../reference/core-plugin-api.withApis.md) HOC if you prefer class +components. For example, the +[ErrorApi](../reference/core-plugin-api.ErrorApi.md) can be accessed like this: ```tsx import React from 'react'; @@ -48,24 +55,31 @@ export const MyComponent = () => { }; ``` -Note that there is no explicit type given for `ErrorApi`. This is because the -`errorApiRef` has the type embedded, and `useApi` is able to infer the type. +Note that there is no explicit type given for +[ErrorApi](../reference/core-plugin-api.ErrorApi.md). This is because the +[errorApiRef](../reference/core-plugin-api.errorApiRef.md) has the type +embedded, and [useApi](../reference/core-plugin-api.useApi.md) is able to infer +the type. Also note that consuming Utility APIs is not limited to plugins, it can be done from any component inside Backstage, including the ones in -`@backstage/core-plugin-api`. The only requirement is that they are beneath the -`AppProvider` in the react tree. +[@backstage/core-plugin-api](../reference/core-plugin-api.md). The only +requirement is that they are beneath the `AppProvider` in the react tree. ## Supplying APIs ### API Factories -APIs are registered in the form of `ApiFactories`, which encapsulate the process -of instantiating an API. It is a collection of three things: the `ApiRef` of the -API to instantiate, a list of all required dependencies, and a factory function -that returns a new API instance. +APIs are registered in the form of +[ApiFactories](../reference/core-plugin-api.ApiFactory.md), which encapsulate +the process of instantiating an API. It is a collection of three things: the +[ApiRef](../reference/core-plugin-api.ApiRef.md) of the API to instantiate, a +list of all required dependencies, and a factory function that returns a new API +instance. -For example, this is the default `ApiFactory` for the `ErrorApi`: +For example, this is the default +[ApiFactory](../reference/core-plugin-api.ApiFactory.md) for the +[ErrorApi](../reference/core-plugin-api.ErrorApi.md): ```ts createApiFactory({ @@ -79,18 +93,25 @@ createApiFactory({ }); ``` -In this example the `errorApiRef` is our API, which encapsulates the `ErrorApi` -type. The `alertApiRef` is our single dependency, which we give the name -`alertApi`, and is then passed on to the factory function, which returns an -implementation of the `ErrorApi`. +In this example the [errorApiRef](../reference/core-plugin-api.errorApiRef.md) +is our API, which encapsulates the +[ErrorApi](../reference/core-plugin-api.ErrorApi.md) type. The +[alertApiRef](../reference/core-plugin-api.alertApiRef.md) is our single +dependency, which we give the name `alertApi`, and is then passed on to the +factory function, which returns an implementation of the +[ErrorApi](../reference/core-plugin-api.ErrorApi.md). -The `createApiFactory` function is a thin wrapper that enables TypeScript type -inference. You may notice that there are no type annotations in the above -example, and that is because we're able to infer all types from the `ApiRef`s. -TypeScript will make sure that the return value of the `factory` function -matches the type embedded in `api`'s `ApiRef`, in this case the `ErrorApi`. It -will also match the types between the `deps` and the parameters of the `factory` -function, again using the type embedded within the `ApiRef`s. +The [createApiFactory](../reference/core-plugin-api.createApiFactory.md) +function is a thin wrapper that enables TypeScript type inference. You may +notice that there are no type annotations in the above example, and that is +because we're able to infer all types from the +[ApiRef](../reference/core-plugin-api.ApiRef.md)s. TypeScript will make sure +that the return value of the `factory` function matches the type embedded in +`api`'s [ApiRef](../reference/core-plugin-api.ApiRef.md), in this case the +[ErrorApi](../reference/core-plugin-api.ErrorApi.md). It will also match the +types between the `deps` and the parameters of the `factory` function, again +using the type embedded within the +[ApiRef](../reference/core-plugin-api.ApiRef.md)s. ## Registering API Factories @@ -102,24 +123,27 @@ app, and the app itself. Starting with the Backstage core library, it provides implementations for all of the core APIs. The core APIs are the ones exported by -`@backstage/core-plugin-api`, such as the `errorApiRef` and `configApiRef`. You -can find a full list of them [here](../reference/utility-apis/README.md). +[@backstage/core-plugin-api](../reference/core-plugin-api.md), such as the +[errorApiRef](../reference/core-plugin-api.errorApiRef.md) and +[configApiRef](../reference/core-plugin-api.configApiRef.md). -The core APIs are loaded for any app created with `createApp` from -`@backstage/core-plugin-api`, which means that there is no step that needs to be -taken to include these APIs in an app. +The core APIs are loaded for any app created with +[createApp](../reference/core-app-api.createApp.md) from +[@backstage/core-plugin-api](../reference/core-plugin-api.md), which means that +there is no step that needs to be taken to include these APIs in an app. ### Plugin APIs In addition to the core APIs, plugins can define and export their own APIs. While doing so they should usually also provide default implementations of their own APIs, for example, the `catalog` plugin exports `catalogApiRef`, and also -supplies a default `ApiFactory` of that API using the `CatalogClient`. There is -one restriction to plugin-provided API Factories: plugins may not supply -factories for core APIs, trying to do so will cause the app to refuse to start. +supplies a default [ApiFactory](../reference/core-plugin-api.ApiFactory.md) of +that API using the `CatalogClient`. There is one restriction to plugin-provided +API Factories: plugins may not supply factories for core APIs, trying to do so +will cause the app to refuse to start. -Plugins supply their APIs through the `apis` option of `createPlugin`, for -example: +Plugins supply their APIs through the `apis` option of +[createPlugin](../reference/core-plugin-api.createPlugin.md), for example: ```ts export const techdocsPlugin = createPlugin({ @@ -144,7 +168,8 @@ Lastly, the app itself is the final point where APIs can be added, and what has the final say in what APIs will be loaded at runtime. The app may override the factories for any of the core or plugin APIs, with the exception of the config, app theme, and identity APIs. These are static APIs that are tied into the -`createApp` implementation, and therefore not possible to override. +[createApp](../reference/core-app-api.createApp.md) implementation, and +therefore not possible to override. Overriding APIs is useful for apps that want to switch out behavior to tailor it to their environment. In some cases plugins may also export multiple @@ -206,16 +231,19 @@ const app = createApp({ ``` Note that the above line will cause an error if `IgnoreErrorApi` does not fully -implement the `ErrorApi`, as it is checked by the type embedded in the -`errorApiRef` at compile time. +implement the [ErrorApi](../reference/core-plugin-api.ErrorApi.md), as it is +checked by the type embedded in the +[errorApiRef](../reference/core-plugin-api.errorApiRef.md) at compile time. ## Defining custom Utility APIs Plugins are free to define their own Utility APIs. Simply define the TypeScript -interface for the API, and create an `ApiRef` using `createApiRef` exported from -`@backstage/core-plugin-api`. Also be sure to provide at least one -implementation of the API, and to declare a default factory for the API in -`createPlugin`. +interface for the API, and create an +[ApiRef](../reference/core-plugin-api.ApiRef.md) using +[createApiRef](../reference/core-plugin-api.createApiRef.md) exported from +[@backstage/core-plugin-api](../reference/core-plugin-api.md). Also be sure to +provide at least one implementation of the API, and to declare a default factory +for the API in [createPlugin](../reference/core-plugin-api.createPlugin.md). Custom Utility APIs can be either public or private, which is up to the plugin to choose. Private APIs do not expose an external API surface, and it's @@ -226,15 +254,18 @@ plugin to override the API in the app. It is however important to maintain backwards compatibility of public APIs, as you may otherwise break apps that are using your plugin. -To make an API public, simply export the `ApiRef` of the API, and any associated -types. To make an API private, just avoid exporting the `ApiRef`, but still be -sure to supply a default factory to `createPlugin`. +To make an API public, simply export the +[ApiRef](../reference/core-plugin-api.ApiRef.md) of the API, and any associated +types. To make an API private, just avoid exporting the +[ApiRef](../reference/core-plugin-api.ApiRef.md), but still be sure to supply a +default factory to [createPlugin](../reference/core-plugin-api.createPlugin.md). Private APIs are useful for plugins that want to depend on other APIs outside of React components, but not have to expose an entire API surface to maintain. When using private APIs, it is fine to use the `typeof` of an implementing class as -the type parameter passed to `createApiRef`, while public APIs should always -define a separate TypeScript interface type. +the type parameter passed to +[createApiRef](../reference/core-plugin-api.createApiRef.md), while public APIs +should always define a separate TypeScript interface type. Plugins may depend on APIs from other plugins, both in React components and as dependencies to API factories. Do however be sure to not cause circular @@ -242,13 +273,14 @@ dependencies between plugins. ## Architecture -The `ApiRef` instances mentioned above provide a point of indirection between -consumers and producers of Utility APIs. It allows for plugins and components to -depend on APIs in a type-safe way, without having a direct reference to a -concrete implementation of the APIs. The Apps are also given a lot of -flexibility in what implementations to provide. As long as they adhere to the -contract established by an `ApiRef`, they are free to choose any implementation -they want. +The [ApiRef](../reference/core-plugin-api.ApiRef.md) instances mentioned above +provide a point of indirection between consumers and producers of Utility APIs. +It allows for plugins and components to depend on APIs in a type-safe way, +without having a direct reference to a concrete implementation of the APIs. The +Apps are also given a lot of flexibility in what implementations to provide. As +long as they adhere to the contract established by an +[ApiRef](../reference/core-plugin-api.ApiRef.md), they are free to choose any +implementation they want. The figure below shows the relationship between different Apps, that provide @@ -271,14 +303,17 @@ directly tied to React. The indirection provided by Utility APIs also makes it straightforward to test components that depend on APIs, and to provide a standard common development environment for plugins. A proper test wrapper with mocked API implementations -is not yet ready, but it will be provided as a part of `@backstage/test-utils`. -It will provide mocked variants of APIs, with additional methods for asserting a -component's interaction with the API. +is not yet ready, but it will be provided as a part of +[@backstage/test-utils](../reference/test-utils.md). It will provide mocked +variants of APIs, with additional methods for asserting a component's +interaction with the API. The common development environment for plugins is included in -`@backstage/dev-utils`, where the exported `createDevApp` function creates an +[@backstage/dev-utils](../reference/dev-utils.md), where the exported +[createDevApp](../reference/dev-utils.createDevApp.md) function creates an application with implementations for all core APIs already present. Contrary to the method for wiring up Utility API implementations in an app created with -`createApp`, `createDevApp` uses automatic dependency injection. This is to make -it possible to replace any API implementation, and having that be reflected in -dependents of that API. +[createApp](../reference/core-app-api.createApp.md), +[createDevApp](../reference/dev-utils.createDevApp.md) uses automatic dependency +injection. This is to make it possible to replace any API implementation, and +having that be reflected in dependents of that API. From 8d30e0ec048180fe07d30dfcdb2c1d54dc48690b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 12:24:05 +0200 Subject: [PATCH 095/125] docs: remove references to removed utility API docs Signed-off-by: Patrik Oldsberg --- docs/auth/index.md | 5 ++--- docs/auth/using-auth.md | 3 ++- docs/conf/reading.md | 4 ++-- mkdocs.yml | 9 ++------- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/docs/auth/index.md b/docs/auth/index.md index 76cd79b0fd..0c03e33900 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -60,9 +60,8 @@ small update to show this provider as a login option. The `SignInPage` component handles this, and takes either a `provider` or `providers` (array) prop of `SignInProviderConfig` definitions. -These reference the [ApiRef](../reference/utility-apis/README.md) exported by -the provider. Again, an example using GitHub that can be adapted to any of the -built-in providers: +These reference the `ApiRef` exported by the provider. Again, an example using +GitHub that can be adapted to any of the built-in providers: ```diff # packages/app/src/App.tsx diff --git a/docs/auth/using-auth.md b/docs/auth/using-auth.md index e4f87a12f9..067c43e8a0 100644 --- a/docs/auth/using-auth.md +++ b/docs/auth/using-auth.md @@ -28,7 +28,8 @@ OAuth helps in that regard. The method with which frontend plugins request access to third party services is through [Utility APIs](../api/utility-apis.md) for each service provider. For a full list of providers, see the -[Utility API References](../reference/utility-apis/README.md). +[@backstage/core-plugin-api](../reference/core-plugin-api.md#variables) +reference. ### Identity - WIP diff --git a/docs/conf/reading.md b/docs/conf/reading.md index d492723e3d..4568f4c378 100644 --- a/docs/conf/reading.md +++ b/docs/conf/reading.md @@ -7,7 +7,7 @@ description: Documentation on Reading Backstage Configuration ## Config API There's a common configuration API for by both frontend and backend plugins. An -API reference can be found [here](../reference/utility-apis/Config.md). +API reference can be found [here](../reference/config.Config.md). The configuration API is tailored towards failing fast in case of missing or bad config. That's because configuration errors can always be considered programming @@ -110,7 +110,7 @@ example `getString`. These will throw an error if there is no value available. ## Accessing ConfigApi in Frontend Plugins -The [ConfigApi](../reference/utility-apis/Config.md) in the frontend is a +The [ConfigApi](../reference/core-plugin-api.ConfigApi.md) in the frontend is a [UtilityApi](../api/utility-apis.md). It's accessible as usual via the `configApiRef` exported from `@backstage/core-plugin-api`: diff --git a/mkdocs.yml b/mkdocs.yml index bddce144d3..3ffd4aa97d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -156,14 +156,9 @@ nav: - Design: 'dls/design.md' - Contributing to Storybook: 'dls/contributing-to-storybook.md' - Figma: 'dls/figma.md' - - API references: - - TypeScript API: + - API Reference: + - Guides: - Utility APIs: 'api/utility-apis.md' - - reference/utility-apis/README: 'reference/utility-apis/README.md' - - createPlugin: 'reference/createPlugin.md' - - createPlugin -feature flags: 'reference/createPlugin-feature-flags.md' - - Backend APIs: - - Backend: 'api/backend.md' - Tutorials: - Future developer journey: 'tutorials/journey.md' - Migrating away from @backstage/core: 'tutorials/migrating-away-from-core.md' From 2485ea499db2c3cebc2ad078f2c917673140931f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 12:25:09 +0200 Subject: [PATCH 096/125] workflows: generate API reference as part of CI to check links Signed-off-by: Patrik Oldsberg --- .github/workflows/ci.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8361654038..d203fafa2c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,9 +105,6 @@ jobs: run: git diff --quiet origin/master HEAD -- yarn.lock continue-on-error: true - - name: verify doc links - run: node scripts/verify-links.js - - name: prettier run: yarn prettier:check '!ADOPTERS.md' @@ -123,8 +120,12 @@ jobs: - name: type checking and declarations run: yarn tsc:full - - name: check api reports - run: yarn build:api-reports:only --ci + # We need to generate the API references as well, so that we can verify the doc links + - name: check api reports and generate API reference + run: yarn build:api-reports:only --ci --docs + + - name: verify doc links + run: node scripts/verify-links.js - name: build changed packages if: ${{ steps.yarn-lock.outcome == 'success' }} From eb4fecca82a4b40ea9257970052ceb61e213d796 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 13:40:50 +0200 Subject: [PATCH 097/125] core-components: rewrite component components to use functions Signed-off-by: Patrik Oldsberg --- packages/core-components/api-report.md | 836 ++---------------- .../components/AlertDisplay/AlertDisplay.tsx | 4 +- .../src/components/Avatar/Avatar.tsx | 5 +- .../src/components/Button/Button.tsx | 13 +- .../components/CheckboxTree/CheckboxTree.tsx | 11 +- .../components/CodeSnippet/CodeSnippet.tsx | 17 +- .../CopyTextButton/CopyTextButton.tsx | 4 +- .../components/CreateButton/CreateButton.tsx | 5 +- .../DependencyGraph/DependencyGraph.tsx | 43 +- .../DismissableBanner/DismissableBanner.tsx | 8 +- .../src/components/EmptyState/EmptyState.tsx | 5 +- .../MissingAnnotationEmptyState.tsx | 5 +- .../src/components/ErrorPanel/ErrorPanel.tsx | 10 +- .../FeatureCalloutCircular.tsx | 10 +- .../HeaderIconLinkRow/HeaderIconLinkRow.tsx | 5 +- .../HorizontalScrollGrid.tsx | 4 +- .../src/components/Lifecycle/Lifecycle.tsx | 4 +- .../src/components/Link/Link.tsx | 11 +- .../MarkdownContent/MarkdownContent.tsx | 5 +- .../OAuthRequestDialog/OAuthRequestDialog.tsx | 4 +- .../OverflowTooltip/OverflowTooltip.tsx | 4 +- .../src/components/Progress/Progress.tsx | 4 +- .../src/components/ProgressBars/Gauge.tsx | 4 +- .../src/components/ProgressBars/GaugeCard.tsx | 4 +- .../components/ProgressBars/LinearGauge.tsx | 5 +- .../ResponseErrorPanel/ResponseErrorPanel.tsx | 9 +- .../src/components/Select/Select.tsx | 21 +- .../SimpleStepper/SimpleStepper.tsx | 10 +- .../SimpleStepper/SimpleStepperStep.tsx | 11 +- .../src/components/Status/Status.tsx | 24 +- .../StructuredMetadataTable.tsx | 9 +- .../SupportButton/SupportButton.tsx | 5 +- .../components/TabbedLayout/RoutedTabs.tsx | 5 +- .../components/TabbedLayout/TabbedLayout.tsx | 6 +- .../src/components/Table/SubvalueCell.tsx | 5 +- .../src/components/Table/Table.tsx | 28 +- .../src/components/Tabs/Tabs.tsx | 5 +- .../src/components/TrendLine/TrendLine.tsx | 6 +- .../components/WarningPanel/WarningPanel.tsx | 17 +- 39 files changed, 256 insertions(+), 935 deletions(-) diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index f73eee1f13..0f8ea308c6 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -9,10 +9,8 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { BackstageIdentityApi } from '@backstage/core-plugin-api'; import { Breadcrumbs as Breadcrumbs_2 } from '@material-ui/core'; import { ButtonProps } from '@material-ui/core'; -import { ButtonTypeMap } from '@material-ui/core'; import { CardHeaderProps } from '@material-ui/core'; import { Column } from '@material-table/core'; -import { CommonProps } from '@material-ui/core/OverridableComponent'; import { ComponentClass } from 'react'; import { ComponentProps } from 'react'; import { Context } from 'react'; @@ -50,7 +48,7 @@ import { WithStyles } from '@material-ui/core'; // Warning: (ae-missing-release-tag) "AlertDisplay" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const AlertDisplay: () => JSX.Element | null; +export function AlertDisplay(_props: {}): JSX.Element | null; // Warning: (ae-missing-release-tag) "Alignment" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -70,11 +68,7 @@ enum Alignment { // Warning: (ae-missing-release-tag) "Avatar" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const Avatar: ({ - displayName, - picture, - customStyles, -}: AvatarProps) => JSX.Element; +export function Avatar(props: AvatarProps): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "Breadcrumbs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -88,316 +82,10 @@ export const Breadcrumbs: ({ children, ...props }: Props_24) => JSX.Element; export const BrokenImageIcon: IconComponent; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "Button" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ButtonType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public -export const Button: React_2.ForwardRefExoticComponent< - Pick< - Props, - | 'replace' - | 'media' - | 'hidden' - | 'dir' - | 'form' - | 'slot' - | 'title' - | 'disabled' - | 'color' - | 'size' - | 'underline' - | 'display' - | 'translate' - | 'prefix' - | 'children' - | 'key' - | 'value' - | 'id' - | 'name' - | 'action' - | 'defaultChecked' - | 'defaultValue' - | 'suppressContentEditableWarning' - | 'suppressHydrationWarning' - | 'accessKey' - | 'contentEditable' - | 'contextMenu' - | 'draggable' - | 'lang' - | 'placeholder' - | 'spellCheck' - | 'tabIndex' - | 'radioGroup' - | 'role' - | 'about' - | 'datatype' - | 'inlist' - | 'property' - | 'resource' - | 'typeof' - | 'vocab' - | 'autoCapitalize' - | 'autoCorrect' - | 'autoSave' - | 'itemProp' - | 'itemScope' - | 'itemType' - | 'itemID' - | 'itemRef' - | 'results' - | 'security' - | 'unselectable' - | 'inputMode' - | 'is' - | 'aria-activedescendant' - | 'aria-atomic' - | 'aria-autocomplete' - | 'aria-busy' - | 'aria-checked' - | 'aria-colcount' - | 'aria-colindex' - | 'aria-colspan' - | 'aria-controls' - | 'aria-current' - | 'aria-describedby' - | 'aria-details' - | 'aria-disabled' - | 'aria-dropeffect' - | 'aria-errormessage' - | 'aria-expanded' - | 'aria-flowto' - | 'aria-grabbed' - | 'aria-haspopup' - | 'aria-hidden' - | 'aria-invalid' - | 'aria-keyshortcuts' - | 'aria-label' - | 'aria-labelledby' - | 'aria-level' - | 'aria-live' - | 'aria-modal' - | 'aria-multiline' - | 'aria-multiselectable' - | 'aria-orientation' - | 'aria-owns' - | 'aria-placeholder' - | 'aria-posinset' - | 'aria-pressed' - | 'aria-readonly' - | 'aria-relevant' - | 'aria-required' - | 'aria-roledescription' - | 'aria-rowcount' - | 'aria-rowindex' - | 'aria-rowspan' - | 'aria-selected' - | 'aria-setsize' - | 'aria-sort' - | 'aria-valuemax' - | 'aria-valuemin' - | 'aria-valuenow' - | 'aria-valuetext' - | 'dangerouslySetInnerHTML' - | 'onCopy' - | 'onCopyCapture' - | 'onCut' - | 'onCutCapture' - | 'onPaste' - | 'onPasteCapture' - | 'onCompositionEnd' - | 'onCompositionEndCapture' - | 'onCompositionStart' - | 'onCompositionStartCapture' - | 'onCompositionUpdate' - | 'onCompositionUpdateCapture' - | 'onFocus' - | 'onFocusCapture' - | 'onBlur' - | 'onBlurCapture' - | 'onChange' - | 'onChangeCapture' - | 'onBeforeInput' - | 'onBeforeInputCapture' - | 'onInput' - | 'onInputCapture' - | 'onReset' - | 'onResetCapture' - | 'onSubmit' - | 'onSubmitCapture' - | 'onInvalid' - | 'onInvalidCapture' - | 'onLoad' - | 'onLoadCapture' - | 'onError' - | 'onErrorCapture' - | 'onKeyDown' - | 'onKeyDownCapture' - | 'onKeyPress' - | 'onKeyPressCapture' - | 'onKeyUp' - | 'onKeyUpCapture' - | 'onAbort' - | 'onAbortCapture' - | 'onCanPlay' - | 'onCanPlayCapture' - | 'onCanPlayThrough' - | 'onCanPlayThroughCapture' - | 'onDurationChange' - | 'onDurationChangeCapture' - | 'onEmptied' - | 'onEmptiedCapture' - | 'onEncrypted' - | 'onEncryptedCapture' - | 'onEnded' - | 'onEndedCapture' - | 'onLoadedData' - | 'onLoadedDataCapture' - | 'onLoadedMetadata' - | 'onLoadedMetadataCapture' - | 'onLoadStart' - | 'onLoadStartCapture' - | 'onPause' - | 'onPauseCapture' - | 'onPlay' - | 'onPlayCapture' - | 'onPlaying' - | 'onPlayingCapture' - | 'onProgress' - | 'onProgressCapture' - | 'onRateChange' - | 'onRateChangeCapture' - | 'onSeeked' - | 'onSeekedCapture' - | 'onSeeking' - | 'onSeekingCapture' - | 'onStalled' - | 'onStalledCapture' - | 'onSuspend' - | 'onSuspendCapture' - | 'onTimeUpdate' - | 'onTimeUpdateCapture' - | 'onVolumeChange' - | 'onVolumeChangeCapture' - | 'onWaiting' - | 'onWaitingCapture' - | 'onAuxClick' - | 'onAuxClickCapture' - | 'onClick' - | 'onClickCapture' - | 'onContextMenu' - | 'onContextMenuCapture' - | 'onDoubleClick' - | 'onDoubleClickCapture' - | 'onDrag' - | 'onDragCapture' - | 'onDragEnd' - | 'onDragEndCapture' - | 'onDragEnter' - | 'onDragEnterCapture' - | 'onDragExit' - | 'onDragExitCapture' - | 'onDragLeave' - | 'onDragLeaveCapture' - | 'onDragOver' - | 'onDragOverCapture' - | 'onDragStart' - | 'onDragStartCapture' - | 'onDrop' - | 'onDropCapture' - | 'onMouseDown' - | 'onMouseDownCapture' - | 'onMouseEnter' - | 'onMouseLeave' - | 'onMouseMove' - | 'onMouseMoveCapture' - | 'onMouseOut' - | 'onMouseOutCapture' - | 'onMouseOver' - | 'onMouseOverCapture' - | 'onMouseUp' - | 'onMouseUpCapture' - | 'onSelect' - | 'onSelectCapture' - | 'onTouchCancel' - | 'onTouchCancelCapture' - | 'onTouchEnd' - | 'onTouchEndCapture' - | 'onTouchMove' - | 'onTouchMoveCapture' - | 'onTouchStart' - | 'onTouchStartCapture' - | 'onPointerDown' - | 'onPointerDownCapture' - | 'onPointerMove' - | 'onPointerMoveCapture' - | 'onPointerUp' - | 'onPointerUpCapture' - | 'onPointerCancel' - | 'onPointerCancelCapture' - | 'onPointerEnter' - | 'onPointerEnterCapture' - | 'onPointerLeave' - | 'onPointerLeaveCapture' - | 'onPointerOver' - | 'onPointerOverCapture' - | 'onPointerOut' - | 'onPointerOutCapture' - | 'onGotPointerCapture' - | 'onGotPointerCaptureCapture' - | 'onLostPointerCapture' - | 'onLostPointerCaptureCapture' - | 'onScroll' - | 'onScrollCapture' - | 'onWheel' - | 'onWheelCapture' - | 'onAnimationStart' - | 'onAnimationStartCapture' - | 'onAnimationEnd' - | 'onAnimationEndCapture' - | 'onAnimationIteration' - | 'onAnimationIterationCapture' - | 'onTransitionEnd' - | 'onTransitionEndCapture' - | 'component' - | 'variant' - | 'download' - | 'href' - | 'hrefLang' - | 'ping' - | 'rel' - | 'target' - | 'type' - | 'referrerPolicy' - | 'disableElevation' - | 'fullWidth' - | 'startIcon' - | 'endIcon' - | 'noWrap' - | 'gutterBottom' - | 'paragraph' - | 'autoFocus' - | 'formAction' - | 'formEncType' - | 'formMethod' - | 'formNoValidate' - | 'formTarget' - | 'disableFocusRipple' - | 'buttonRef' - | 'centerRipple' - | 'disableRipple' - | 'disableTouchRipple' - | 'focusRipple' - | 'focusVisibleClassName' - | 'onFocusVisible' - | 'TouchRippleProps' - | 'align' - | 'variantMapping' - | 'to' - | 'state' - | 'TypographyClasses' - | keyof CommonProps> - > & - React_2.RefAttributes ->; +// @public (undocumented) +export function Button(props: Props): JSX.Element; // Warning: (ae-forgotten-export) The symbol "CardTabProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "CardTab" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -422,14 +110,7 @@ export const ChatIcon: IconComponent; // Warning: (ae-missing-release-tag) "CodeSnippet" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const CodeSnippet: ({ - text, - language, - showLineNumbers, - showCopyCodeButton, - highlightedNumbers, - customStyle, -}: Props_2) => JSX.Element; +export const CodeSnippet: (props: Props_2) => JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "Content" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -455,26 +136,28 @@ export const ContentHeader: ({ textAlign, }: PropsWithChildren) => JSX.Element; +// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "CopyTextButton" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-missing-release-tag) "CopyTextButton" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const CopyTextButton: { - (props: Props_3): JSX.Element; - propTypes: { - text: PropTypes.Validator; - tooltipDelay: PropTypes.Requireable; - tooltipText: PropTypes.Requireable; - }; -}; +export function CopyTextButton(props: Props_3): JSX.Element; + +// @public (undocumented) +export namespace CopyTextButton { + var // (undocumented) + propTypes: { + text: PropTypes.Validator; + tooltipDelay: PropTypes.Requireable; + tooltipText: PropTypes.Requireable; + }; +} // Warning: (ae-forgotten-export) The symbol "CreateButtonProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "CreateButton" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const CreateButton: ({ - title, - to, -}: CreateButtonProps) => JSX.Element | null; +export function CreateButton(props: CreateButtonProps): JSX.Element | null; // Warning: (ae-missing-release-tag) "DashboardIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -495,27 +178,7 @@ type DependencyEdge = T & { // Warning: (ae-missing-release-tag) "DependencyGraph" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export function DependencyGraph({ - edges, - nodes, - renderNode, - direction, - align, - nodeMargin, - edgeMargin, - rankMargin, - paddingX, - paddingY, - acyclicer, - ranker, - labelPosition, - labelOffset, - edgeRanks, - edgeWeight, - renderLabel, - defs, - ...svgProps -}: DependencyGraphProps): JSX.Element; +export function DependencyGraph(props: DependencyGraphProps): JSX.Element; declare namespace DependencyGraphTypes { export { @@ -561,12 +224,7 @@ enum Direction { // Warning: (ae-missing-release-tag) "DismissableBanner" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const DismissableBanner: ({ - variant, - message, - id, - fixed, -}: Props_4) => JSX.Element; +export const DismissableBanner: (props: Props_4) => JSX.Element; // Warning: (ae-missing-release-tag) "DocsIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -596,12 +254,7 @@ export const EmailIcon: IconComponent; // Warning: (ae-missing-release-tag) "EmptyState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const EmptyState: ({ - title, - description, - missing, - action, -}: Props_5) => JSX.Element; +export function EmptyState(props: Props_5): JSX.Element; // Warning: (ae-forgotten-export) The symbol "State" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "ErrorBoundary" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -630,12 +283,9 @@ export const ErrorPage: ({ // Warning: (ae-missing-release-tag) "ErrorPanel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export const ErrorPanel: ({ - title, - error, - defaultExpanded, - children, -}: PropsWithChildren) => JSX.Element; +export function ErrorPanel( + props: PropsWithChildren, +): JSX.Element; // Warning: (ae-missing-release-tag) "ErrorPanelProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -650,24 +300,21 @@ export type ErrorPanelProps = { // Warning: (ae-missing-release-tag) "FeatureCalloutCircular" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const FeatureCalloutCircular: ({ - featureId, - title, - description, - children, -}: PropsWithChildren) => JSX.Element; +export function FeatureCalloutCircular( + props: PropsWithChildren, +): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "Gauge" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const Gauge: (props: Props_14) => JSX.Element; +export function Gauge(props: Props_14): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "GaugeCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const GaugeCard: (props: Props_13) => JSX.Element; +export function GaugeCard(props: Props_13): JSX.Element; // Warning: (ae-missing-release-tag) "GitHubIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -710,7 +357,7 @@ export const Header: ({ // Warning: (ae-missing-release-tag) "HeaderIconLinkRow" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const HeaderIconLinkRow: ({ links }: Props_8) => JSX.Element; +export function HeaderIconLinkRow(props: Props_8): JSX.Element; // Warning: (ae-forgotten-export) The symbol "HeaderLabelProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "HeaderLabel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -746,9 +393,9 @@ export const HomepageTimer: () => JSX.Element | null; // Warning: (ae-missing-release-tag) "HorizontalScrollGrid" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const HorizontalScrollGrid: ( +export function HorizontalScrollGrid( props: PropsWithChildren, -) => JSX.Element; +): JSX.Element; // Warning: (ae-missing-release-tag) "IconLinkVerticalProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -872,302 +519,18 @@ enum LabelPosition { // Warning: (ae-missing-release-tag) "Lifecycle" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const Lifecycle: (props: Props_10) => JSX.Element; +export function Lifecycle(props: Props_10): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "LinearGauge" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const LinearGauge: ({ value }: Props_15) => JSX.Element | null; +export function LinearGauge(props: Props_15): JSX.Element | null; -// Warning: (ae-missing-release-tag) "Link" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "LinkType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public -export const Link: React_2.ForwardRefExoticComponent< - Pick< - LinkProps, - | 'replace' - | 'media' - | 'hidden' - | 'dir' - | 'slot' - | 'style' - | 'title' - | 'color' - | 'underline' - | 'display' - | 'translate' - | 'prefix' - | 'children' - | 'key' - | 'id' - | 'classes' - | 'defaultChecked' - | 'defaultValue' - | 'suppressContentEditableWarning' - | 'suppressHydrationWarning' - | 'accessKey' - | 'className' - | 'contentEditable' - | 'contextMenu' - | 'draggable' - | 'lang' - | 'placeholder' - | 'spellCheck' - | 'tabIndex' - | 'radioGroup' - | 'role' - | 'about' - | 'datatype' - | 'inlist' - | 'property' - | 'resource' - | 'typeof' - | 'vocab' - | 'autoCapitalize' - | 'autoCorrect' - | 'autoSave' - | 'itemProp' - | 'itemScope' - | 'itemType' - | 'itemID' - | 'itemRef' - | 'results' - | 'security' - | 'unselectable' - | 'inputMode' - | 'is' - | 'aria-activedescendant' - | 'aria-atomic' - | 'aria-autocomplete' - | 'aria-busy' - | 'aria-checked' - | 'aria-colcount' - | 'aria-colindex' - | 'aria-colspan' - | 'aria-controls' - | 'aria-current' - | 'aria-describedby' - | 'aria-details' - | 'aria-disabled' - | 'aria-dropeffect' - | 'aria-errormessage' - | 'aria-expanded' - | 'aria-flowto' - | 'aria-grabbed' - | 'aria-haspopup' - | 'aria-hidden' - | 'aria-invalid' - | 'aria-keyshortcuts' - | 'aria-label' - | 'aria-labelledby' - | 'aria-level' - | 'aria-live' - | 'aria-modal' - | 'aria-multiline' - | 'aria-multiselectable' - | 'aria-orientation' - | 'aria-owns' - | 'aria-placeholder' - | 'aria-posinset' - | 'aria-pressed' - | 'aria-readonly' - | 'aria-relevant' - | 'aria-required' - | 'aria-roledescription' - | 'aria-rowcount' - | 'aria-rowindex' - | 'aria-rowspan' - | 'aria-selected' - | 'aria-setsize' - | 'aria-sort' - | 'aria-valuemax' - | 'aria-valuemin' - | 'aria-valuenow' - | 'aria-valuetext' - | 'dangerouslySetInnerHTML' - | 'onCopy' - | 'onCopyCapture' - | 'onCut' - | 'onCutCapture' - | 'onPaste' - | 'onPasteCapture' - | 'onCompositionEnd' - | 'onCompositionEndCapture' - | 'onCompositionStart' - | 'onCompositionStartCapture' - | 'onCompositionUpdate' - | 'onCompositionUpdateCapture' - | 'onFocus' - | 'onFocusCapture' - | 'onBlur' - | 'onBlurCapture' - | 'onChange' - | 'onChangeCapture' - | 'onBeforeInput' - | 'onBeforeInputCapture' - | 'onInput' - | 'onInputCapture' - | 'onReset' - | 'onResetCapture' - | 'onSubmit' - | 'onSubmitCapture' - | 'onInvalid' - | 'onInvalidCapture' - | 'onLoad' - | 'onLoadCapture' - | 'onError' - | 'onErrorCapture' - | 'onKeyDown' - | 'onKeyDownCapture' - | 'onKeyPress' - | 'onKeyPressCapture' - | 'onKeyUp' - | 'onKeyUpCapture' - | 'onAbort' - | 'onAbortCapture' - | 'onCanPlay' - | 'onCanPlayCapture' - | 'onCanPlayThrough' - | 'onCanPlayThroughCapture' - | 'onDurationChange' - | 'onDurationChangeCapture' - | 'onEmptied' - | 'onEmptiedCapture' - | 'onEncrypted' - | 'onEncryptedCapture' - | 'onEnded' - | 'onEndedCapture' - | 'onLoadedData' - | 'onLoadedDataCapture' - | 'onLoadedMetadata' - | 'onLoadedMetadataCapture' - | 'onLoadStart' - | 'onLoadStartCapture' - | 'onPause' - | 'onPauseCapture' - | 'onPlay' - | 'onPlayCapture' - | 'onPlaying' - | 'onPlayingCapture' - | 'onProgress' - | 'onProgressCapture' - | 'onRateChange' - | 'onRateChangeCapture' - | 'onSeeked' - | 'onSeekedCapture' - | 'onSeeking' - | 'onSeekingCapture' - | 'onStalled' - | 'onStalledCapture' - | 'onSuspend' - | 'onSuspendCapture' - | 'onTimeUpdate' - | 'onTimeUpdateCapture' - | 'onVolumeChange' - | 'onVolumeChangeCapture' - | 'onWaiting' - | 'onWaitingCapture' - | 'onAuxClick' - | 'onAuxClickCapture' - | 'onClick' - | 'onClickCapture' - | 'onContextMenu' - | 'onContextMenuCapture' - | 'onDoubleClick' - | 'onDoubleClickCapture' - | 'onDrag' - | 'onDragCapture' - | 'onDragEnd' - | 'onDragEndCapture' - | 'onDragEnter' - | 'onDragEnterCapture' - | 'onDragExit' - | 'onDragExitCapture' - | 'onDragLeave' - | 'onDragLeaveCapture' - | 'onDragOver' - | 'onDragOverCapture' - | 'onDragStart' - | 'onDragStartCapture' - | 'onDrop' - | 'onDropCapture' - | 'onMouseDown' - | 'onMouseDownCapture' - | 'onMouseEnter' - | 'onMouseLeave' - | 'onMouseMove' - | 'onMouseMoveCapture' - | 'onMouseOut' - | 'onMouseOutCapture' - | 'onMouseOver' - | 'onMouseOverCapture' - | 'onMouseUp' - | 'onMouseUpCapture' - | 'onSelect' - | 'onSelectCapture' - | 'onTouchCancel' - | 'onTouchCancelCapture' - | 'onTouchEnd' - | 'onTouchEndCapture' - | 'onTouchMove' - | 'onTouchMoveCapture' - | 'onTouchStart' - | 'onTouchStartCapture' - | 'onPointerDown' - | 'onPointerDownCapture' - | 'onPointerMove' - | 'onPointerMoveCapture' - | 'onPointerUp' - | 'onPointerUpCapture' - | 'onPointerCancel' - | 'onPointerCancelCapture' - | 'onPointerEnter' - | 'onPointerEnterCapture' - | 'onPointerLeave' - | 'onPointerLeaveCapture' - | 'onPointerOver' - | 'onPointerOverCapture' - | 'onPointerOut' - | 'onPointerOutCapture' - | 'onGotPointerCapture' - | 'onGotPointerCaptureCapture' - | 'onLostPointerCapture' - | 'onLostPointerCaptureCapture' - | 'onScroll' - | 'onScrollCapture' - | 'onWheel' - | 'onWheelCapture' - | 'onAnimationStart' - | 'onAnimationStartCapture' - | 'onAnimationEnd' - | 'onAnimationEndCapture' - | 'onAnimationIteration' - | 'onAnimationIterationCapture' - | 'onTransitionEnd' - | 'onTransitionEndCapture' - | 'component' - | 'variant' - | 'innerRef' - | 'download' - | 'href' - | 'hrefLang' - | 'ping' - | 'rel' - | 'target' - | 'type' - | 'referrerPolicy' - | 'noWrap' - | 'gutterBottom' - | 'paragraph' - | 'align' - | 'variantMapping' - | 'to' - | 'state' - | 'TypographyClasses' - > & - React_2.RefAttributes ->; +// @public (undocumented) +export function Link(props: LinkProps): JSX.Element; // Warning: (ae-missing-release-tag) "LinkProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1181,26 +544,24 @@ export type LinkProps = LinkProps_2 & // Warning: (ae-missing-release-tag) "MarkdownContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export const MarkdownContent: ({ content, dialect }: Props_11) => JSX.Element; +export function MarkdownContent(props: Props_11): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "MissingAnnotationEmptyState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const MissingAnnotationEmptyState: ({ - annotation, -}: Props_6) => JSX.Element; +export function MissingAnnotationEmptyState(props: Props_6): JSX.Element; // Warning: (ae-missing-release-tag) "OAuthRequestDialog" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const OAuthRequestDialog: () => JSX.Element; +export function OAuthRequestDialog(_props: {}): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "OverflowTooltip" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const OverflowTooltip: (props: Props_12) => JSX.Element; +export function OverflowTooltip(props: Props_12): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "Page" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -1224,9 +585,9 @@ export const PageWithHeader: ({ // Warning: (ae-missing-release-tag) "Progress" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const Progress: ( +export function Progress( props: PropsWithChildren, -) => JSX.Element; +): JSX.Element; // Warning: (ae-missing-release-tag) "Ranker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1267,30 +628,18 @@ type RenderNodeProps = { // Warning: (ae-missing-release-tag) "ResponseErrorPanel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export const ResponseErrorPanel: ({ - title, - error, - defaultExpanded, -}: ErrorPanelProps) => JSX.Element; +export function ResponseErrorPanel(props: ErrorPanelProps): JSX.Element; // Warning: (ae-missing-release-tag) "RoutedTabs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const RoutedTabs: ({ routes }: { routes: SubRoute_2[] }) => JSX.Element; +export function RoutedTabs(props: { routes: SubRoute_2[] }): JSX.Element; // Warning: (ae-forgotten-export) The symbol "SelectProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "SelectComponent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const Select: ({ - multiple, - items, - label, - placeholder, - selected, - onChange, - triggerReset, -}: SelectProps) => JSX.Element; +export function Select(props: SelectProps): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "Sidebar" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -2473,82 +1822,65 @@ export type SignInProviderConfig = { // Warning: (ae-missing-release-tag) "SimpleStepper" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const SimpleStepper: ({ - children, - elevated, - onStepChange, - activeStep, -}: PropsWithChildren) => JSX.Element; +export function SimpleStepper( + props: PropsWithChildren, +): JSX.Element; // Warning: (ae-forgotten-export) The symbol "StepProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "SimpleStepperStep" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const SimpleStepperStep: ({ - title, - children, - end, - actions, - ...muiProps -}: PropsWithChildren) => JSX.Element; +export function SimpleStepperStep( + props: PropsWithChildren, +): JSX.Element; // Warning: (ae-missing-release-tag) "StatusAborted" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const StatusAborted: (props: PropsWithChildren<{}>) => JSX.Element; +export function StatusAborted(props: PropsWithChildren<{}>): JSX.Element; // Warning: (ae-missing-release-tag) "StatusError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const StatusError: (props: PropsWithChildren<{}>) => JSX.Element; +export function StatusError(props: PropsWithChildren<{}>): JSX.Element; // Warning: (ae-missing-release-tag) "StatusOK" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const StatusOK: (props: PropsWithChildren<{}>) => JSX.Element; +export function StatusOK(props: PropsWithChildren<{}>): JSX.Element; // Warning: (ae-missing-release-tag) "StatusPending" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const StatusPending: (props: PropsWithChildren<{}>) => JSX.Element; +export function StatusPending(props: PropsWithChildren<{}>): JSX.Element; // Warning: (ae-missing-release-tag) "StatusRunning" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const StatusRunning: (props: PropsWithChildren<{}>) => JSX.Element; +export function StatusRunning(props: PropsWithChildren<{}>): JSX.Element; // Warning: (ae-missing-release-tag) "StatusWarning" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const StatusWarning: (props: PropsWithChildren<{}>) => JSX.Element; +export function StatusWarning(props: PropsWithChildren<{}>): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "StructuredMetadataTable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const StructuredMetadataTable: ({ - metadata, - dense, - options, -}: Props_16) => JSX.Element; +export function StructuredMetadataTable(props: Props_16): JSX.Element; // Warning: (ae-forgotten-export) The symbol "SubvalueCellProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "SubvalueCell" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const SubvalueCell: ({ - value, - subvalue, -}: SubvalueCellProps) => JSX.Element; +export function SubvalueCell(props: SubvalueCellProps): JSX.Element; // Warning: (ae-forgotten-export) The symbol "SupportButtonProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "SupportButton" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const SupportButton: ({ - title, - children, -}: SupportButtonProps) => JSX.Element; +export function SupportButton(props: SupportButtonProps): JSX.Element; // Warning: (ae-missing-release-tag) "SupportConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -2603,28 +1935,24 @@ export const TabbedCard: ({ onChange, }: PropsWithChildren) => JSX.Element; +// Warning: (ae-missing-release-tag) "TabbedLayout" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-missing-release-tag) "TabbedLayout" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export const TabbedLayout: { - ({ children }: PropsWithChildren<{}>): JSX.Element; - Route: (props: SubRoute) => null; -}; +export function TabbedLayout(props: PropsWithChildren<{}>): JSX.Element; + +// @public (undocumented) +export namespace TabbedLayout { + var // Warning: (ae-forgotten-export) The symbol "SubRoute" needs to be exported by the entry point index.d.ts + // + // (undocumented) + Route: (props: SubRoute) => null; +} // Warning: (ae-missing-release-tag) "Table" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export function Table({ - columns, - options, - title, - subtitle, - filters, - initialState, - emptyContent, - onStateChange, - ...props -}: TableProps): JSX.Element; +export function Table(props: TableProps): JSX.Element; // Warning: (ae-missing-release-tag) "TableColumn" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -2676,17 +2004,17 @@ export type TableState = { // Warning: (ae-missing-release-tag) "Tabs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const Tabs: ({ tabs }: TabsProps) => JSX.Element; +export function Tabs(props: TabsProps): JSX.Element; // Warning: (ae-missing-release-tag) "TrendLine" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const TrendLine: ( +export function TrendLine( props: SparklinesProps & Pick & { title?: string; }, -) => JSX.Element | null; +): JSX.Element | null; // Warning: (ae-forgotten-export) The symbol "SetQueryParams" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "useQueryParamState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -2728,19 +2056,11 @@ export const WarningIcon: IconComponent; // Warning: (ae-missing-release-tag) "WarningPanel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export const WarningPanel: ({ - severity, - title, - message, - children, - defaultExpanded, -}: WarningProps) => JSX.Element; +export function WarningPanel(props: WarningProps): JSX.Element; // Warnings were encountered during analysis: // -// src/components/CopyTextButton/CopyTextButton.d.ts:24:5 - (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // src/components/TabbedLayout/RoutedTabs.d.ts:9:5 - (ae-forgotten-export) The symbol "SubRoute" needs to be exported by the entry point index.d.ts -// src/components/TabbedLayout/TabbedLayout.d.ts:29:5 - (ae-forgotten-export) The symbol "SubRoute" needs to be exported by the entry point index.d.ts // src/components/Table/Table.d.ts:15:5 - (ae-forgotten-export) The symbol "SelectedFilters" needs to be exported by the entry point index.d.ts // src/layout/ErrorBoundary/ErrorBoundary.d.ts:7:5 - (ae-forgotten-export) The symbol "SlackChannel" needs to be exported by the entry point index.d.ts diff --git a/packages/core-components/src/components/AlertDisplay/AlertDisplay.tsx b/packages/core-components/src/components/AlertDisplay/AlertDisplay.tsx index 495e2ea14c..f3e102d9a0 100644 --- a/packages/core-components/src/components/AlertDisplay/AlertDisplay.tsx +++ b/packages/core-components/src/components/AlertDisplay/AlertDisplay.tsx @@ -22,7 +22,7 @@ import { AlertMessage, useApi, alertApiRef } from '@backstage/core-plugin-api'; import pluralize from 'pluralize'; // TODO: improve on this and promote to a shared component for use by all apps. -export const AlertDisplay = () => { +export function AlertDisplay(_props: {}) { const [messages, setMessages] = useState>([]); const alertApi = useApi(alertApiRef); @@ -73,4 +73,4 @@ export const AlertDisplay = () => { ); -}; +} diff --git a/packages/core-components/src/components/Avatar/Avatar.tsx b/packages/core-components/src/components/Avatar/Avatar.tsx index df3c46fba7..f694365233 100644 --- a/packages/core-components/src/components/Avatar/Avatar.tsx +++ b/packages/core-components/src/components/Avatar/Avatar.tsx @@ -41,7 +41,8 @@ export type AvatarProps = { customStyles?: CSSProperties; }; -export const Avatar = ({ displayName, picture, customStyles }: AvatarProps) => { +export function Avatar(props: AvatarProps) { + const { displayName, picture, customStyles } = props; const classes = useStyles(); return ( { {displayName && extractInitials(displayName)} ); -}; +} diff --git a/packages/core-components/src/components/Button/Button.tsx b/packages/core-components/src/components/Button/Button.tsx index 6dd593d776..e52285312b 100644 --- a/packages/core-components/src/components/Button/Button.tsx +++ b/packages/core-components/src/components/Button/Button.tsx @@ -23,10 +23,19 @@ import { Link, LinkProps } from '../Link'; type Props = MaterialButtonProps & Omit; +declare function ButtonType(props: Props): JSX.Element; + /** * Thin wrapper on top of material-ui's Button component * Makes the Button to utilise react-router */ -export const Button = React.forwardRef((props, ref) => ( +const ActualButton = React.forwardRef((props, ref) => ( -)); +)) as { (props: Props): JSX.Element }; + +// TODO(Rugvip): We use this as a workaround to make the exported type be a +// function, which makes our API reference docs much nicer. +// The first type to be exported gets priority, but it will +// be thrown away when compiling to JS. +// @ts-ignore +export { ButtonType as Button, ActualButton as Button }; diff --git a/packages/core-components/src/components/CheckboxTree/CheckboxTree.tsx b/packages/core-components/src/components/CheckboxTree/CheckboxTree.tsx index 7e7155143b..695da88192 100644 --- a/packages/core-components/src/components/CheckboxTree/CheckboxTree.tsx +++ b/packages/core-components/src/components/CheckboxTree/CheckboxTree.tsx @@ -225,13 +225,8 @@ const indexer = ( }; }, {}); -export const CheckboxTree = ({ - subCategories, - label, - selected, - onChange, - triggerReset, -}: CheckboxTreeProps) => { +export function CheckboxTree(props: CheckboxTreeProps) { + const { subCategories, label, selected, onChange, triggerReset } = props; const classes = useStyles(); const [state, dispatch] = useReducer(reducer, indexer(subCategories)); @@ -355,4 +350,4 @@ export const CheckboxTree = ({
); -}; +} diff --git a/packages/core-components/src/components/CodeSnippet/CodeSnippet.tsx b/packages/core-components/src/components/CodeSnippet/CodeSnippet.tsx index a3badaad07..6417151ff4 100644 --- a/packages/core-components/src/components/CodeSnippet/CodeSnippet.tsx +++ b/packages/core-components/src/components/CodeSnippet/CodeSnippet.tsx @@ -30,14 +30,15 @@ type Props = { customStyle?: any; }; -export const CodeSnippet = ({ - text, - language, - showLineNumbers = false, - showCopyCodeButton = false, - highlightedNumbers, - customStyle, -}: Props) => { +export const CodeSnippet = (props: Props) => { + const { + text, + language, + showLineNumbers = false, + showCopyCodeButton = false, + highlightedNumbers, + customStyle, + } = props; const theme = useTheme(); const mode = theme.palette.type === 'dark' ? dark : docco; const highlightColor = theme.palette.type === 'dark' ? '#256bf3' : '#e6ffed'; diff --git a/packages/core-components/src/components/CopyTextButton/CopyTextButton.tsx b/packages/core-components/src/components/CopyTextButton/CopyTextButton.tsx index cc0ecaf76f..2d3afff1dc 100644 --- a/packages/core-components/src/components/CopyTextButton/CopyTextButton.tsx +++ b/packages/core-components/src/components/CopyTextButton/CopyTextButton.tsx @@ -47,7 +47,7 @@ const defaultProps = { tooltipText: 'Text copied to clipboard', }; -export const CopyTextButton = (props: Props) => { +export function CopyTextButton(props: Props) { const { text, tooltipDelay, tooltipText } = { ...defaultProps, ...props, @@ -84,7 +84,7 @@ export const CopyTextButton = (props: Props) => { ); -}; +} // Type check for the JS files using this core component CopyTextButton.propTypes = { diff --git a/packages/core-components/src/components/CreateButton/CreateButton.tsx b/packages/core-components/src/components/CreateButton/CreateButton.tsx index 021e1b002d..1ca4fdaa97 100644 --- a/packages/core-components/src/components/CreateButton/CreateButton.tsx +++ b/packages/core-components/src/components/CreateButton/CreateButton.tsx @@ -24,7 +24,8 @@ type CreateButtonProps = { title: string; } & Partial>; -export const CreateButton = ({ title, to }: CreateButtonProps) => { +export function CreateButton(props: CreateButtonProps) { + const { title, to } = props; const isXSScreen = useMediaQuery(theme => theme.breakpoints.down('xs'), ); @@ -48,4 +49,4 @@ export const CreateButton = ({ title, to }: CreateButtonProps) => { {title} ); -}; +} diff --git a/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx b/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx index 436eda614c..0d74965e7e 100644 --- a/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx +++ b/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx @@ -60,27 +60,28 @@ export type DependencyGraphProps = React.SVGProps & { const WORKSPACE_ID = 'workspace'; -export function DependencyGraph({ - edges, - nodes, - renderNode, - direction = Direction.TOP_BOTTOM, - align, - nodeMargin = 50, - edgeMargin = 10, - rankMargin = 50, - paddingX = 0, - paddingY = 0, - acyclicer, - ranker = Ranker.NETWORK_SIMPLEX, - labelPosition = LabelPosition.RIGHT, - labelOffset = 10, - edgeRanks = 1, - edgeWeight = 1, - renderLabel, - defs, - ...svgProps -}: DependencyGraphProps) { +export function DependencyGraph(props: DependencyGraphProps) { + const { + edges, + nodes, + renderNode, + direction = Direction.TOP_BOTTOM, + align, + nodeMargin = 50, + edgeMargin = 10, + rankMargin = 50, + paddingX = 0, + paddingY = 0, + acyclicer, + ranker = Ranker.NETWORK_SIMPLEX, + labelPosition = LabelPosition.RIGHT, + labelOffset = 10, + edgeRanks = 1, + edgeWeight = 1, + renderLabel, + defs, + ...svgProps + } = props; const theme: BackstageTheme = useTheme(); const [containerWidth, setContainerWidth] = React.useState(100); const [containerHeight, setContainerHeight] = React.useState(100); diff --git a/packages/core-components/src/components/DismissableBanner/DismissableBanner.tsx b/packages/core-components/src/components/DismissableBanner/DismissableBanner.tsx index 6c4e43811d..cc20a49ad6 100644 --- a/packages/core-components/src/components/DismissableBanner/DismissableBanner.tsx +++ b/packages/core-components/src/components/DismissableBanner/DismissableBanner.tsx @@ -70,12 +70,8 @@ type Props = { fixed?: boolean; }; -export const DismissableBanner = ({ - variant, - message, - id, - fixed = false, -}: Props) => { +export const DismissableBanner = (props: Props) => { + const { variant, message, id, fixed = false } = props; const classes = useStyles(); const storageApi = useApi(storageApiRef); const notificationsStore = storageApi.forBucket('notifications'); diff --git a/packages/core-components/src/components/EmptyState/EmptyState.tsx b/packages/core-components/src/components/EmptyState/EmptyState.tsx index d916ad9a61..b2f5eca65e 100644 --- a/packages/core-components/src/components/EmptyState/EmptyState.tsx +++ b/packages/core-components/src/components/EmptyState/EmptyState.tsx @@ -38,7 +38,8 @@ type Props = { action?: JSX.Element; }; -export const EmptyState = ({ title, description, missing, action }: Props) => { +export function EmptyState(props: Props) { + const { title, description, missing, action } = props; const classes = useStyles(); return ( { ); -}; +} diff --git a/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx b/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx index d477494964..17061fa237 100644 --- a/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx +++ b/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx @@ -45,7 +45,8 @@ const useStyles = makeStyles(theme => ({ }, })); -export const MissingAnnotationEmptyState = ({ annotation }: Props) => { +export function MissingAnnotationEmptyState(props: Props) { + const { annotation } = props; const classes = useStyles(); const description = ( <> @@ -84,4 +85,4 @@ export const MissingAnnotationEmptyState = ({ annotation }: Props) => { } /> ); -}; +} diff --git a/packages/core-components/src/components/ErrorPanel/ErrorPanel.tsx b/packages/core-components/src/components/ErrorPanel/ErrorPanel.tsx index f9996b9b1f..309f2b447a 100644 --- a/packages/core-components/src/components/ErrorPanel/ErrorPanel.tsx +++ b/packages/core-components/src/components/ErrorPanel/ErrorPanel.tsx @@ -92,12 +92,8 @@ export type ErrorPanelProps = { /** * Renders a warning panel as the effect of an error. */ -export const ErrorPanel = ({ - title, - error, - defaultExpanded, - children, -}: PropsWithChildren) => { +export function ErrorPanel(props: PropsWithChildren) { + const { title, error, defaultExpanded, children } = props; return ( ); -}; +} diff --git a/packages/core-components/src/components/FeatureDiscovery/FeatureCalloutCircular.tsx b/packages/core-components/src/components/FeatureDiscovery/FeatureCalloutCircular.tsx index 9af6c30c3b..9459c3cbe0 100644 --- a/packages/core-components/src/components/FeatureDiscovery/FeatureCalloutCircular.tsx +++ b/packages/core-components/src/components/FeatureDiscovery/FeatureCalloutCircular.tsx @@ -93,12 +93,8 @@ type Placement = { textWidth: number; }; -export const FeatureCalloutCircular = ({ - featureId, - title, - description, - children, -}: PropsWithChildren) => { +export function FeatureCalloutCircular(props: PropsWithChildren) { + const { featureId, title, description, children } = props; const { show, hide } = useShowCallout(featureId); const portalElement = usePortal('core.callout'); const wrapperRef = useRef(null); @@ -196,4 +192,4 @@ export const FeatureCalloutCircular = ({ )} ); -}; +} diff --git a/packages/core-components/src/components/HeaderIconLinkRow/HeaderIconLinkRow.tsx b/packages/core-components/src/components/HeaderIconLinkRow/HeaderIconLinkRow.tsx index afceda165e..7e49537492 100644 --- a/packages/core-components/src/components/HeaderIconLinkRow/HeaderIconLinkRow.tsx +++ b/packages/core-components/src/components/HeaderIconLinkRow/HeaderIconLinkRow.tsx @@ -31,7 +31,8 @@ type Props = { links: IconLinkVerticalProps[]; }; -export const HeaderIconLinkRow = ({ links }: Props) => { +export function HeaderIconLinkRow(props: Props) { + const { links } = props; const classes = useStyles(); return ( ); -}; +} diff --git a/packages/core-components/src/components/HorizontalScrollGrid/HorizontalScrollGrid.tsx b/packages/core-components/src/components/HorizontalScrollGrid/HorizontalScrollGrid.tsx index f5c45d3eb0..a3d16bc4ec 100644 --- a/packages/core-components/src/components/HorizontalScrollGrid/HorizontalScrollGrid.tsx +++ b/packages/core-components/src/components/HorizontalScrollGrid/HorizontalScrollGrid.tsx @@ -181,7 +181,7 @@ function useSmoothScroll( return setScrollTarget; } -export const HorizontalScrollGrid = (props: PropsWithChildren) => { +export function HorizontalScrollGrid(props: PropsWithChildren) { const { scrollStep = 100, scrollSpeed = 50, @@ -244,4 +244,4 @@ export const HorizontalScrollGrid = (props: PropsWithChildren) => { )}
); -}; +} diff --git a/packages/core-components/src/components/Lifecycle/Lifecycle.tsx b/packages/core-components/src/components/Lifecycle/Lifecycle.tsx index c72ea46f1b..ef451ac1b0 100644 --- a/packages/core-components/src/components/Lifecycle/Lifecycle.tsx +++ b/packages/core-components/src/components/Lifecycle/Lifecycle.tsx @@ -38,7 +38,7 @@ const useStyles = makeStyles({ }, }); -export const Lifecycle = (props: Props) => { +export function Lifecycle(props: Props) { const classes = useStyles(props); const { shorthand, alpha } = props; return shorthand ? ( @@ -53,4 +53,4 @@ export const Lifecycle = (props: Props) => { {alpha ? 'Alpha' : 'Beta'} ); -}; +} diff --git a/packages/core-components/src/components/Link/Link.tsx b/packages/core-components/src/components/Link/Link.tsx index 7853c4f52f..0d301dccf9 100644 --- a/packages/core-components/src/components/Link/Link.tsx +++ b/packages/core-components/src/components/Link/Link.tsx @@ -31,11 +31,13 @@ export type LinkProps = MaterialLinkProps & component?: ElementType; }; +declare function LinkType(props: LinkProps): JSX.Element; + /** * Thin wrapper on top of material-ui's Link component * Makes the Link to utilise react-router */ -export const Link = React.forwardRef((props, ref) => { +const ActualLink = React.forwardRef((props, ref) => { const to = String(props.to); const external = isExternalUri(to); const newWindow = external && !!/^https?:/.exec(to); @@ -52,3 +54,10 @@ export const Link = React.forwardRef((props, ref) => { ); }); + +// TODO(Rugvip): We use this as a workaround to make the exported type be a +// function, which makes our API reference docs much nicer. +// The first type to be exported gets priority, but it will +// be thrown away when compiling to JS. +// @ts-ignore +export { LinkType as Link, ActualLink as Link }; diff --git a/packages/core-components/src/components/MarkdownContent/MarkdownContent.tsx b/packages/core-components/src/components/MarkdownContent/MarkdownContent.tsx index 296df22ecd..d2930cbf5d 100644 --- a/packages/core-components/src/components/MarkdownContent/MarkdownContent.tsx +++ b/packages/core-components/src/components/MarkdownContent/MarkdownContent.tsx @@ -76,7 +76,8 @@ const renderers = { * Renders markdown with the default dialect [gfm - GitHub flavored Markdown](https://github.github.com/gfm/) to backstage theme styled HTML. * If you just want to render to plain [CommonMark](https://commonmark.org/), set the dialect to `'common-mark'` */ -export const MarkdownContent = ({ content, dialect = 'gfm' }: Props) => { +export function MarkdownContent(props: Props) { + const { content, dialect = 'gfm' } = props; const classes = useStyles(); return ( { renderers={renderers} /> ); -}; +} diff --git a/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx b/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx index 687e4211bf..669b9a02f5 100644 --- a/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx +++ b/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx @@ -41,7 +41,7 @@ const useStyles = makeStyles(theme => ({ }, })); -export const OAuthRequestDialog = () => { +export function OAuthRequestDialog(_props: {}) { const classes = useStyles(); const [busy, setBusy] = useState(false); const oauthRequestApi = useApi(oauthRequestApiRef); @@ -83,4 +83,4 @@ export const OAuthRequestDialog = () => { ); -}; +} diff --git a/packages/core-components/src/components/OverflowTooltip/OverflowTooltip.tsx b/packages/core-components/src/components/OverflowTooltip/OverflowTooltip.tsx index 1be7ebc7ed..fbb1537847 100644 --- a/packages/core-components/src/components/OverflowTooltip/OverflowTooltip.tsx +++ b/packages/core-components/src/components/OverflowTooltip/OverflowTooltip.tsx @@ -32,7 +32,7 @@ const useStyles = makeStyles({ }, }); -export const OverflowTooltip = (props: Props) => { +export function OverflowTooltip(props: Props) { const [hover, setHover] = useState(false); const classes = useStyles(); @@ -54,4 +54,4 @@ export const OverflowTooltip = (props: Props) => { /> ); -}; +} diff --git a/packages/core-components/src/components/Progress/Progress.tsx b/packages/core-components/src/components/Progress/Progress.tsx index 68dcb91785..00ad532b5e 100644 --- a/packages/core-components/src/components/Progress/Progress.tsx +++ b/packages/core-components/src/components/Progress/Progress.tsx @@ -17,7 +17,7 @@ import React, { useState, useEffect, PropsWithChildren } from 'react'; import { LinearProgress, LinearProgressProps } from '@material-ui/core'; -export const Progress = (props: PropsWithChildren) => { +export function Progress(props: PropsWithChildren) { const [isVisible, setIsVisible] = useState(false); useEffect(() => { @@ -30,4 +30,4 @@ export const Progress = (props: PropsWithChildren) => { ) : (
); -}; +} diff --git a/packages/core-components/src/components/ProgressBars/Gauge.tsx b/packages/core-components/src/components/ProgressBars/Gauge.tsx index 46948d4af6..3b31f64fe7 100644 --- a/packages/core-components/src/components/ProgressBars/Gauge.tsx +++ b/packages/core-components/src/components/ProgressBars/Gauge.tsx @@ -77,7 +77,7 @@ export function getProgressColor( return palette.status.ok; } -export const Gauge = (props: Props) => { +export function Gauge(props: Props) { const classes = useStyles(props); const theme = useTheme(); const { value, fractional, inverse, unit, max } = { @@ -103,4 +103,4 @@ export const Gauge = (props: Props) => {
); -}; +} diff --git a/packages/core-components/src/components/ProgressBars/GaugeCard.tsx b/packages/core-components/src/components/ProgressBars/GaugeCard.tsx index 39248b1786..0a603ea991 100644 --- a/packages/core-components/src/components/ProgressBars/GaugeCard.tsx +++ b/packages/core-components/src/components/ProgressBars/GaugeCard.tsx @@ -37,7 +37,7 @@ const useStyles = makeStyles({ }, }); -export const GaugeCard = (props: Props) => { +export function GaugeCard(props: Props) { const classes = useStyles(props); const { title, subheader, progress, inverse, deepLink, variant } = props; @@ -53,4 +53,4 @@ export const GaugeCard = (props: Props) => { ); -}; +} diff --git a/packages/core-components/src/components/ProgressBars/LinearGauge.tsx b/packages/core-components/src/components/ProgressBars/LinearGauge.tsx index d733cb2eae..cf8c022852 100644 --- a/packages/core-components/src/components/ProgressBars/LinearGauge.tsx +++ b/packages/core-components/src/components/ProgressBars/LinearGauge.tsx @@ -28,7 +28,8 @@ type Props = { value: number; }; -export const LinearGauge = ({ value }: Props) => { +export function LinearGauge(props: Props) { + const { value } = props; const theme = useTheme(); if (isNaN(value)) { return null; @@ -50,4 +51,4 @@ export const LinearGauge = ({ value }: Props) => { ); -}; +} diff --git a/packages/core-components/src/components/ResponseErrorPanel/ResponseErrorPanel.tsx b/packages/core-components/src/components/ResponseErrorPanel/ResponseErrorPanel.tsx index ccfb706bf9..9f25e8290f 100644 --- a/packages/core-components/src/components/ResponseErrorPanel/ResponseErrorPanel.tsx +++ b/packages/core-components/src/components/ResponseErrorPanel/ResponseErrorPanel.tsx @@ -39,11 +39,8 @@ const useStyles = makeStyles(theme => ({ * Has special treatment for ResponseError errors, to display rich * server-provided information about what happened. */ -export const ResponseErrorPanel = ({ - title, - error, - defaultExpanded, -}: ErrorPanelProps) => { +export function ResponseErrorPanel(props: ErrorPanelProps) { + const { title, error, defaultExpanded } = props; const classes = useStyles(); if (error.name !== 'ResponseError') { @@ -93,4 +90,4 @@ export const ResponseErrorPanel = ({ ); -}; +} diff --git a/packages/core-components/src/components/Select/Select.tsx b/packages/core-components/src/components/Select/Select.tsx index b4512b3562..ae14545b29 100644 --- a/packages/core-components/src/components/Select/Select.tsx +++ b/packages/core-components/src/components/Select/Select.tsx @@ -106,15 +106,16 @@ export type SelectProps = { triggerReset?: boolean; }; -export const SelectComponent = ({ - multiple, - items, - label, - placeholder, - selected, - onChange, - triggerReset, -}: SelectProps) => { +export function SelectComponent(props: SelectProps) { + const { + multiple, + items, + label, + placeholder, + selected, + onChange, + triggerReset, + } = props; const classes = useStyles(); const [value, setValue] = useState( selected || (multiple ? [] : ''), @@ -228,4 +229,4 @@ export const SelectComponent = ({ ); -}; +} diff --git a/packages/core-components/src/components/SimpleStepper/SimpleStepper.tsx b/packages/core-components/src/components/SimpleStepper/SimpleStepper.tsx index 46b2ce551a..9ffb63c085 100644 --- a/packages/core-components/src/components/SimpleStepper/SimpleStepper.tsx +++ b/packages/core-components/src/components/SimpleStepper/SimpleStepper.tsx @@ -47,12 +47,8 @@ export interface StepperProps { activeStep?: number; } -export const SimpleStepper = ({ - children, - elevated, - onStepChange, - activeStep = 0, -}: PropsWithChildren) => { +export function SimpleStepper(props: PropsWithChildren) { + const { children, elevated, onStepChange, activeStep = 0 } = props; const [stepIndex, setStepIndex] = useState(activeStep); const [stepHistory, setStepHistory] = useState([0]); @@ -95,4 +91,4 @@ export const SimpleStepper = ({ {stepIndex >= Children.count(children) - 1 && endStep} ); -}; +} diff --git a/packages/core-components/src/components/SimpleStepper/SimpleStepperStep.tsx b/packages/core-components/src/components/SimpleStepper/SimpleStepperStep.tsx index 51fcee1f71..39383b934b 100644 --- a/packages/core-components/src/components/SimpleStepper/SimpleStepperStep.tsx +++ b/packages/core-components/src/components/SimpleStepper/SimpleStepperStep.tsx @@ -30,13 +30,8 @@ const useStyles = makeStyles(theme => ({ }, })); -export const SimpleStepperStep = ({ - title, - children, - end, - actions, - ...muiProps -}: PropsWithChildren) => { +export function SimpleStepperStep(props: PropsWithChildren) { + const { title, children, end, actions, ...muiProps } = props; const classes = useStyles(); // The end step is not a part of the stepper @@ -58,4 +53,4 @@ export const SimpleStepperStep = ({ ); -}; +} diff --git a/packages/core-components/src/components/Status/Status.tsx b/packages/core-components/src/components/Status/Status.tsx index 0b370a1397..2b2d40dee3 100644 --- a/packages/core-components/src/components/Status/Status.tsx +++ b/packages/core-components/src/components/Status/Status.tsx @@ -63,7 +63,7 @@ const useStyles = makeStyles(theme => ({ }, })); -export const StatusOK = (props: PropsWithChildren<{}>) => { +export function StatusOK(props: PropsWithChildren<{}>) { const classes = useStyles(props); return ( ) => { {...props} /> ); -}; +} -export const StatusWarning = (props: PropsWithChildren<{}>) => { +export function StatusWarning(props: PropsWithChildren<{}>) { const classes = useStyles(props); return ( ) => { {...props} /> ); -}; +} -export const StatusError = (props: PropsWithChildren<{}>) => { +export function StatusError(props: PropsWithChildren<{}>) { const classes = useStyles(props); return ( ) => { {...props} /> ); -}; +} -export const StatusPending = (props: PropsWithChildren<{}>) => { +export function StatusPending(props: PropsWithChildren<{}>) { const classes = useStyles(props); return ( ) => { {...props} /> ); -}; +} -export const StatusRunning = (props: PropsWithChildren<{}>) => { +export function StatusRunning(props: PropsWithChildren<{}>) { const classes = useStyles(props); return ( ) => { {...props} /> ); -}; +} -export const StatusAborted = (props: PropsWithChildren<{}>) => { +export function StatusAborted(props: PropsWithChildren<{}>) { const classes = useStyles(props); return ( ) => { {...props} /> ); -}; +} diff --git a/packages/core-components/src/components/StructuredMetadataTable/StructuredMetadataTable.tsx b/packages/core-components/src/components/StructuredMetadataTable/StructuredMetadataTable.tsx index 9b08123d1b..22a1a43b69 100644 --- a/packages/core-components/src/components/StructuredMetadataTable/StructuredMetadataTable.tsx +++ b/packages/core-components/src/components/StructuredMetadataTable/StructuredMetadataTable.tsx @@ -153,11 +153,8 @@ type Props = { options?: any; }; -export const StructuredMetadataTable = ({ - metadata, - dense = true, - options, -}: Props) => { +export function StructuredMetadataTable(props: Props) { + const { metadata, dense = true, options } = props; const metadataItems = mapToItems(metadata, options || {}); return {metadataItems}; -}; +} diff --git a/packages/core-components/src/components/SupportButton/SupportButton.tsx b/packages/core-components/src/components/SupportButton/SupportButton.tsx index 22ec5cf47e..8076636654 100644 --- a/packages/core-components/src/components/SupportButton/SupportButton.tsx +++ b/packages/core-components/src/components/SupportButton/SupportButton.tsx @@ -80,7 +80,8 @@ const SupportListItem = ({ item }: { item: SupportItem }) => { ); }; -export const SupportButton = ({ title, children }: SupportButtonProps) => { +export function SupportButton(props: SupportButtonProps) { + const { title, children } = props; const { items } = useSupportConfig(); const [popoverOpen, setPopoverOpen] = useState(false); @@ -160,4 +161,4 @@ export const SupportButton = ({ title, children }: SupportButtonProps) => { ); -}; +} diff --git a/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx b/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx index 52a2c29e2d..2a65c8ffc8 100644 --- a/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx +++ b/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx @@ -47,7 +47,8 @@ export function useSelectedSubRoute(subRoutes: SubRoute[]): { }; } -export const RoutedTabs = ({ routes }: { routes: SubRoute[] }) => { +export function RoutedTabs(props: { routes: SubRoute[] }) { + const { routes } = props; const navigate = useNavigate(); const { index, route, element } = useSelectedSubRoute(routes); const headerTabs = useMemo( @@ -80,4 +81,4 @@ export const RoutedTabs = ({ routes }: { routes: SubRoute[] }) => {
); -}; +} diff --git a/packages/core-components/src/components/TabbedLayout/TabbedLayout.tsx b/packages/core-components/src/components/TabbedLayout/TabbedLayout.tsx index f7671928f2..03f012b78f 100644 --- a/packages/core-components/src/components/TabbedLayout/TabbedLayout.tsx +++ b/packages/core-components/src/components/TabbedLayout/TabbedLayout.tsx @@ -82,10 +82,10 @@ export function createSubRoutesFromChildren( * * ``` */ -export const TabbedLayout = ({ children }: PropsWithChildren<{}>) => { - const routes = createSubRoutesFromChildren(children); +export function TabbedLayout(props: PropsWithChildren<{}>) { + const routes = createSubRoutesFromChildren(props.children); return ; -}; +} TabbedLayout.Route = Route; diff --git a/packages/core-components/src/components/Table/SubvalueCell.tsx b/packages/core-components/src/components/Table/SubvalueCell.tsx index 1dab2e1f49..fd7d3fd9fa 100644 --- a/packages/core-components/src/components/Table/SubvalueCell.tsx +++ b/packages/core-components/src/components/Table/SubvalueCell.tsx @@ -33,7 +33,8 @@ type SubvalueCellProps = { subvalue: React.ReactNode; }; -export const SubvalueCell = ({ value, subvalue }: SubvalueCellProps) => { +export function SubvalueCell(props: SubvalueCellProps) { + const { value, subvalue } = props; const classes = useSubvalueCellStyles(); return ( @@ -42,4 +43,4 @@ export const SubvalueCell = ({ value, subvalue }: SubvalueCellProps) => {
{subvalue}
); -}; +} diff --git a/packages/core-components/src/components/Table/Table.tsx b/packages/core-components/src/components/Table/Table.tsx index 22d8bff014..edc5fd33ce 100644 --- a/packages/core-components/src/components/Table/Table.tsx +++ b/packages/core-components/src/components/Table/Table.tsx @@ -263,21 +263,21 @@ export function TableToolbar(toolbarProps: { ); } -export function Table({ - columns, - options, - title, - subtitle, - filters, - initialState, - emptyContent, - onStateChange, - ...props -}: TableProps) { +export function Table(props: TableProps) { + const { + data, + columns, + options, + title, + subtitle, + filters, + initialState, + emptyContent, + onStateChange, + ...restProps + } = props; const tableClasses = useTableStyles(); - const { data, ...propsWithoutData } = props; - const theme = useTheme(); const calculatedInitialState = { ...defaultInitialState, ...initialState }; @@ -495,7 +495,7 @@ export function Table({ } data={typeof data === 'function' ? data : tableData} style={{ width: '100%' }} - {...propsWithoutData} + {...restProps} /> ); diff --git a/packages/core-components/src/components/Tabs/Tabs.tsx b/packages/core-components/src/components/Tabs/Tabs.tsx index ec9fecaca4..844f54a543 100644 --- a/packages/core-components/src/components/Tabs/Tabs.tsx +++ b/packages/core-components/src/components/Tabs/Tabs.tsx @@ -58,7 +58,8 @@ const useStyles = makeStyles(theme => ({ }, })); -export const Tabs = ({ tabs }: TabsProps) => { +export function Tabs(props: TabsProps) { + const { tabs } = props; const classes = useStyles(); const [value, setValue] = useState([0, 0]); // [selectedChunkedNavIndex, selectedIndex] const [navIndex, setNavIndex] = useState(0); @@ -160,4 +161,4 @@ export const Tabs = ({ tabs }: TabsProps) => { )} ); -}; +} diff --git a/packages/core-components/src/components/TrendLine/TrendLine.tsx b/packages/core-components/src/components/TrendLine/TrendLine.tsx index 0cbc2ca9d7..cb44d2b36b 100644 --- a/packages/core-components/src/components/TrendLine/TrendLine.tsx +++ b/packages/core-components/src/components/TrendLine/TrendLine.tsx @@ -32,10 +32,10 @@ function color(data: number[], theme: BackstageTheme): string | undefined { return theme.palette.status.error; } -export const TrendLine = ( +export function TrendLine( props: SparklinesProps & Pick & { title?: string }, -) => { +) { const theme = useTheme(); if (!props.data) return null; @@ -45,4 +45,4 @@ export const TrendLine = ( ); -}; +} diff --git a/packages/core-components/src/components/WarningPanel/WarningPanel.tsx b/packages/core-components/src/components/WarningPanel/WarningPanel.tsx index e6188172b7..536ab066b3 100644 --- a/packages/core-components/src/components/WarningPanel/WarningPanel.tsx +++ b/packages/core-components/src/components/WarningPanel/WarningPanel.tsx @@ -137,13 +137,14 @@ const capitalize = (s: string) => { * @param {Object} [children] Objects to provide context, such as a stack trace or detailed error reporting. * Will be available inside an unfolded accordion. */ -export const WarningPanel = ({ - severity = 'warning', - title, - message, - children, - defaultExpanded, -}: WarningProps) => { +export function WarningPanel(props: WarningProps) { + const { + severity = 'warning', + title, + message, + children, + defaultExpanded, + } = props; const classes = useStyles({ severity }); // If no severity or title provided, the heading will read simply "Warning" @@ -184,4 +185,4 @@ export const WarningPanel = ({ )} ); -}; +} From 653abaaada5ae5963fef805a2f338d29f98efe88 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 14:04:38 +0200 Subject: [PATCH 098/125] core-components: rewrite layout and icon components to use functions Signed-off-by: Patrik Oldsberg --- packages/core-components/api-report.md | 156 +++++------------- packages/core-components/src/icons/icons.tsx | 61 ++++--- .../src/layout/BottomLink/BottomLink.tsx | 5 +- .../src/layout/Breadcrumbs/Breadcrumbs.tsx | 7 +- .../src/layout/Content/Content.tsx | 13 +- .../layout/ContentHeader/ContentHeader.tsx | 17 +- .../src/layout/ErrorPage/ErrorPage.tsx | 9 +- .../src/layout/Header/Header.tsx | 23 +-- .../HeaderActionMenu/HeaderActionMenu.tsx | 5 +- .../src/layout/HeaderLabel/HeaderLabel.tsx | 5 +- .../src/layout/HeaderTabs/HeaderTabs.tsx | 9 +- .../layout/HomepageTimer/HomepageTimer.tsx | 4 +- .../src/layout/InfoCard/InfoCard.tsx | 43 ++--- .../src/layout/ItemCard/ItemCard.tsx | 15 +- .../src/layout/ItemCard/ItemCardGrid.tsx | 4 +- .../src/layout/ItemCard/ItemCardHeader.tsx | 4 +- .../core-components/src/layout/Page/Page.tsx | 5 +- .../src/layout/Page/PageWithHeader.tsx | 19 +-- .../src/layout/Sidebar/Bar.tsx | 13 +- .../src/layout/Sidebar/Intro.tsx | 8 +- .../src/layout/Sidebar/Items.tsx | 4 +- .../src/layout/Sidebar/Page.tsx | 4 +- .../src/layout/SignInPage/SignInPage.tsx | 4 +- .../src/layout/TabbedCard/TabbedCard.tsx | 30 ++-- 24 files changed, 199 insertions(+), 268 deletions(-) diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index 0f8ea308c6..f3652d98cf 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -74,12 +74,13 @@ export function Avatar(props: AvatarProps): JSX.Element; // Warning: (ae-missing-release-tag) "Breadcrumbs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const Breadcrumbs: ({ children, ...props }: Props_24) => JSX.Element; +export function Breadcrumbs(props: Props_24): JSX.Element; +// Warning: (ae-forgotten-export) The symbol "IconComponentProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "BrokenImageIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const BrokenImageIcon: IconComponent; +export function BrokenImageIcon(props: IconComponentProps): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "ButtonType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -91,20 +92,17 @@ export function Button(props: Props): JSX.Element; // Warning: (ae-missing-release-tag) "CardTab" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const CardTab: ({ - children, - ...props -}: PropsWithChildren) => JSX.Element; +export function CardTab(props: PropsWithChildren): JSX.Element; // Warning: (ae-missing-release-tag) "CatalogIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const CatalogIcon: IconComponent; +export function CatalogIcon(props: IconComponentProps): JSX.Element; // Warning: (ae-missing-release-tag) "ChatIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const ChatIcon: IconComponent; +export function ChatIcon(props: IconComponentProps): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "CodeSnippet" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -116,25 +114,15 @@ export const CodeSnippet: (props: Props_2) => JSX.Element; // Warning: (ae-missing-release-tag) "Content" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const Content: ({ - className, - stretch, - noPadding, - children, - ...props -}: PropsWithChildren) => JSX.Element; +export function Content(props: PropsWithChildren): JSX.Element; // Warning: (ae-forgotten-export) The symbol "ContentHeaderProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "ContentHeader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const ContentHeader: ({ - description, - title, - titleComponent: TitleComponent, - children, - textAlign, -}: PropsWithChildren) => JSX.Element; +export function ContentHeader( + props: PropsWithChildren, +): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "CopyTextButton" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -162,7 +150,7 @@ export function CreateButton(props: CreateButtonProps): JSX.Element | null; // Warning: (ae-missing-release-tag) "DashboardIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const DashboardIcon: IconComponent; +export function DashboardIcon(props: IconComponentProps): JSX.Element; // Warning: (ae-forgotten-export) The symbol "CustomType" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "DependencyEdge" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -229,7 +217,7 @@ export const DismissableBanner: (props: Props_4) => JSX.Element; // Warning: (ae-missing-release-tag) "DocsIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const DocsIcon: IconComponent; +export function DocsIcon(props: IconComponentProps): JSX.Element; // Warning: (ae-missing-release-tag) "EdgeProperties" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -248,7 +236,7 @@ type EdgeProperties = { // Warning: (ae-missing-release-tag) "EmailIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const EmailIcon: IconComponent; +export function EmailIcon(props: IconComponentProps): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "EmptyState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -274,11 +262,7 @@ export type ErrorBoundaryProps = { // Warning: (ae-missing-release-tag) "ErrorPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const ErrorPage: ({ - status, - statusMessage, - additionalInfo, -}: IErrorPageProps) => JSX.Element; +export function ErrorPage(props: IErrorPageProps): JSX.Element; // Warning: (ae-missing-release-tag) "ErrorPanel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -319,7 +303,7 @@ export function GaugeCard(props: Props_13): JSX.Element; // Warning: (ae-missing-release-tag) "GitHubIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const GitHubIcon: IconComponent; +export function GitHubIcon(props: IconComponentProps): JSX.Element; // Warning: (ae-missing-release-tag) "GraphEdge" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -336,22 +320,13 @@ type GraphNode = dagre_2.Node>; // Warning: (ae-missing-release-tag) "GroupIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const GroupIcon: IconComponent; +export function GroupIcon(props: IconComponentProps): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "Header" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const Header: ({ - children, - pageTitleOverride, - style, - subtitle, - title, - tooltip, - type, - typeLink, -}: PropsWithChildren) => JSX.Element; +export function Header(props: PropsWithChildren): JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "HeaderIconLinkRow" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -363,31 +338,23 @@ export function HeaderIconLinkRow(props: Props_8): JSX.Element; // Warning: (ae-missing-release-tag) "HeaderLabel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const HeaderLabel: ({ - label, - value, - url, -}: HeaderLabelProps) => JSX.Element; +export function HeaderLabel(props: HeaderLabelProps): JSX.Element; // Warning: (ae-forgotten-export) The symbol "HeaderTabsProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "HeaderTabs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const HeaderTabs: ({ - tabs, - onChange, - selectedIndex, -}: HeaderTabsProps) => JSX.Element; +export function HeaderTabs(props: HeaderTabsProps): JSX.Element; // Warning: (ae-missing-release-tag) "HelpIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const HelpIcon: IconComponent; +export function HelpIcon(props: IconComponentProps): JSX.Element; // Warning: (ae-missing-release-tag) "HomepageTimer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const HomepageTimer: () => JSX.Element | null; +export function HomepageTimer(_props: {}): JSX.Element | null; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "HorizontalScrollGrid" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -414,26 +381,7 @@ export type IconLinkVerticalProps = { // Warning: (ae-missing-release-tag) "InfoCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const InfoCard: ({ - title, - subheader, - divider, - deepLink, - slackChannel, - errorBoundaryProps, - variant, - children, - headerStyle, - headerProps, - action, - actionsClassName, - actions, - cardClassName, - actionsTopRight, - className, - noPadding, - titleTypographyProps, -}: Props_19) => JSX.Element; +export function InfoCard(props: Props_19): JSX.Element; // Warning: (ae-missing-release-tag) "InfoCardVariants" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -444,7 +392,7 @@ export type InfoCardVariants = 'flex' | 'fullHeight' | 'gridItem'; // Warning: (ae-missing-release-tag) "IntroCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const IntroCard: (props: IntroCardProps) => JSX.Element; +export function IntroCard(props: IntroCardProps): JSX.Element; // Warning: (tsdoc-malformed-html-name) Invalid HTML element: Expecting an HTML name // Warning: (tsdoc-escape-greater-than) The ">" character should be escaped using a backslash to avoid confusion with an HTML tag @@ -452,16 +400,7 @@ export const IntroCard: (props: IntroCardProps) => JSX.Element; // Warning: (ae-missing-release-tag) "ItemCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated -export const ItemCard: ({ - description, - tags, - title, - type, - subtitle, - label, - onClick, - href, -}: ItemCardProps) => JSX.Element; +export function ItemCard(props: ItemCardProps): JSX.Element; // Warning: (tsdoc-escape-greater-than) The ">" character should be escaped using a backslash to avoid confusion with an HTML tag // Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag @@ -472,7 +411,7 @@ export const ItemCard: ({ // Warning: (ae-missing-release-tag) "ItemCardGrid" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export const ItemCardGrid: (props: ItemCardGridProps) => JSX.Element; +export function ItemCardGrid(props: ItemCardGridProps): JSX.Element; // Warning: (ae-forgotten-export) The symbol "styles" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "ItemCardGridProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -491,7 +430,7 @@ export type ItemCardGridProps = Partial> & { // Warning: (ae-missing-release-tag) "ItemCardHeader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export const ItemCardHeader: (props: ItemCardHeaderProps) => JSX.Element; +export function ItemCardHeader(props: ItemCardHeaderProps): JSX.Element; // Warning: (ae-forgotten-export) The symbol "styles" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "ItemCardHeaderProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -567,20 +506,15 @@ export function OverflowTooltip(props: Props_12): JSX.Element; // Warning: (ae-missing-release-tag) "Page" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const Page: ({ - themeId, - children, -}: PropsWithChildren) => JSX.Element; +export function Page(props: PropsWithChildren): JSX.Element; // Warning: (ae-forgotten-export) The symbol "PageWithHeaderProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "PageWithHeader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const PageWithHeader: ({ - themeId, - children, - ...props -}: PropsWithChildren) => JSX.Element; +export function PageWithHeader( + props: PropsWithChildren, +): JSX.Element; // Warning: (ae-missing-release-tag) "Progress" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -645,11 +579,7 @@ export function Select(props: SelectProps): JSX.Element; // Warning: (ae-missing-release-tag) "Sidebar" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const Sidebar: ({ - openDelayMs, - closeDelayMs, - children, -}: PropsWithChildren) => JSX.Element; +export function Sidebar(props: PropsWithChildren): JSX.Element; // Warning: (ae-missing-release-tag) "SIDEBAR_INTRO_LOCAL_STORAGE" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -959,7 +889,7 @@ export const SidebarDivider: React_2.ComponentType< // Warning: (ae-missing-release-tag) "SidebarIntro" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const SidebarIntro: () => JSX.Element | null; +export function SidebarIntro(_props: {}): JSX.Element | null; // Warning: (ae-forgotten-export) The symbol "SidebarItemProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "SidebarItem" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -972,7 +902,7 @@ export const SidebarItem: React_2.ForwardRefExoticComponent< // Warning: (ae-missing-release-tag) "SidebarPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const SidebarPage: (props: PropsWithChildren<{}>) => JSX.Element; +export function SidebarPage(props: PropsWithChildren<{}>): JSX.Element; // Warning: (ae-missing-release-tag) "SidebarPinStateContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1260,9 +1190,7 @@ export const SidebarScrollWrapper: React_2.ComponentType< // Warning: (ae-missing-release-tag) "SidebarSearchField" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const SidebarSearchField: ( - props: SidebarSearchFieldProps, -) => JSX.Element; +export function SidebarSearchField(props: SidebarSearchFieldProps): JSX.Element; // Warning: (ae-missing-release-tag) "SidebarSpace" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1806,7 +1734,7 @@ export const SidebarSpacer: React_2.ComponentType< // Warning: (ae-missing-release-tag) "SignInPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const SignInPage: (props: Props_22) => JSX.Element; +export function SignInPage(props: Props_22): JSX.Element; // Warning: (ae-missing-release-tag) "SignInProviderConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1925,15 +1853,7 @@ export type Tab = { // Warning: (ae-missing-release-tag) "TabbedCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const TabbedCard: ({ - slackChannel, - errorBoundaryProps, - children, - title, - deepLink, - value, - onChange, -}: PropsWithChildren) => JSX.Element; +export function TabbedCard(props: PropsWithChildren): JSX.Element; // Warning: (ae-missing-release-tag) "TabbedLayout" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-missing-release-tag) "TabbedLayout" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -2028,7 +1948,7 @@ export function useQueryParamState( // Warning: (ae-missing-release-tag) "UserIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const UserIcon: IconComponent; +export function UserIcon(props: IconComponentProps): JSX.Element; // Warning: (ae-missing-release-tag) "useSupportConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -2038,7 +1958,7 @@ export function useSupportConfig(): SupportConfig; // Warning: (ae-missing-release-tag) "WarningIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const WarningIcon: IconComponent; +export function WarningIcon(props: IconComponentProps): JSX.Element; // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // Warning: (tsdoc-param-tag-with-invalid-optional-name) The @param should not include a JSDoc-style optional name; it must not be enclosed in '[ ]' brackets. diff --git a/packages/core-components/src/icons/icons.tsx b/packages/core-components/src/icons/icons.tsx index 258bc9f8e1..7a9f7f9832 100644 --- a/packages/core-components/src/icons/icons.tsx +++ b/packages/core-components/src/icons/icons.tsx @@ -15,27 +15,48 @@ */ import MuiBrokenImageIcon from '@material-ui/icons/BrokenImage'; -import React from 'react'; +import React, { ComponentProps } from 'react'; import { useApp, IconComponent } from '@backstage/core-plugin-api'; -const overridableSystemIcon = (key: string): IconComponent => { - const Component: IconComponent = props => { - const app = useApp(); - const Icon = app.getSystemIcon(key); - return Icon ? : ; - }; - return Component; -}; +type IconComponentProps = ComponentProps; + +function useSystemIcon(key: string, props: IconComponentProps) { + const app = useApp(); + const Icon = app.getSystemIcon(key); + return Icon ? : ; +} // Should match the list of overridable system icon keys in @backstage/core-app-api -export const BrokenImageIcon = overridableSystemIcon('brokenImage'); -export const CatalogIcon = overridableSystemIcon('catalog'); -export const ChatIcon = overridableSystemIcon('chat'); -export const DashboardIcon = overridableSystemIcon('dashboard'); -export const DocsIcon = overridableSystemIcon('docs'); -export const EmailIcon = overridableSystemIcon('email'); -export const GitHubIcon = overridableSystemIcon('github'); -export const GroupIcon = overridableSystemIcon('group'); -export const HelpIcon = overridableSystemIcon('help'); -export const UserIcon = overridableSystemIcon('user'); -export const WarningIcon = overridableSystemIcon('warning'); +export function BrokenImageIcon(props: IconComponentProps) { + return useSystemIcon('brokenImage', props); +} +export function CatalogIcon(props: IconComponentProps) { + return useSystemIcon('catalog', props); +} +export function ChatIcon(props: IconComponentProps) { + return useSystemIcon('chat', props); +} +export function DashboardIcon(props: IconComponentProps) { + return useSystemIcon('dashboard', props); +} +export function DocsIcon(props: IconComponentProps) { + return useSystemIcon('docs', props); +} +export function EmailIcon(props: IconComponentProps) { + return useSystemIcon('email', props); +} +export function GitHubIcon(props: IconComponentProps) { + return useSystemIcon('github', props); +} +export function GroupIcon(props: IconComponentProps) { + return useSystemIcon('group', props); +} +export function HelpIcon(props: IconComponentProps) { + return useSystemIcon('help', props); +} +export function UserIcon(props: IconComponentProps) { + return useSystemIcon('user', props); +} +export function WarningIcon(props: IconComponentProps) { + return useSystemIcon('warning', props); +} diff --git a/packages/core-components/src/layout/BottomLink/BottomLink.tsx b/packages/core-components/src/layout/BottomLink/BottomLink.tsx index 74912acf4c..6d6811cc09 100644 --- a/packages/core-components/src/layout/BottomLink/BottomLink.tsx +++ b/packages/core-components/src/layout/BottomLink/BottomLink.tsx @@ -41,7 +41,8 @@ export type BottomLinkProps = { onClick?: (event: React.MouseEvent) => void; }; -export const BottomLink = ({ link, title, onClick }: BottomLinkProps) => { +export function BottomLink(props: BottomLinkProps) { + const { link, title, onClick } = props; const classes = useStyles(); return ( @@ -59,4 +60,4 @@ export const BottomLink = ({ link, title, onClick }: BottomLinkProps) => { ); -}; +} diff --git a/packages/core-components/src/layout/Breadcrumbs/Breadcrumbs.tsx b/packages/core-components/src/layout/Breadcrumbs/Breadcrumbs.tsx index 418217f3b5..28c86d32f0 100644 --- a/packages/core-components/src/layout/Breadcrumbs/Breadcrumbs.tsx +++ b/packages/core-components/src/layout/Breadcrumbs/Breadcrumbs.tsx @@ -41,7 +41,8 @@ const StyledBox = withStyles({ }, })(Box); -export const Breadcrumbs = ({ children, ...props }: Props) => { +export function Breadcrumbs(props: Props) { + const { children, ...restProps } = props; const [anchorEl, setAnchorEl] = React.useState( null, ); @@ -65,7 +66,7 @@ export const Breadcrumbs = ({ children, ...props }: Props) => { const open = Boolean(anchorEl); return ( - + {childrenArray.length > 1 && {firstPage}} {childrenArray.length > 2 && {secondPage}} {hasHiddenBreadcrumbs && ( @@ -96,4 +97,4 @@ export const Breadcrumbs = ({ children, ...props }: Props) => { ); -}; +} diff --git a/packages/core-components/src/layout/Content/Content.tsx b/packages/core-components/src/layout/Content/Content.tsx index 323565159a..a3771dff3f 100644 --- a/packages/core-components/src/layout/Content/Content.tsx +++ b/packages/core-components/src/layout/Content/Content.tsx @@ -47,17 +47,12 @@ type Props = { className?: string; }; -export const Content = ({ - className, - stretch, - noPadding, - children, - ...props -}: PropsWithChildren) => { +export function Content(props: PropsWithChildren) { + const { className, stretch, noPadding, children, ...restProps } = props; const classes = useStyles(); return (
); -}; +} diff --git a/packages/core-components/src/layout/ContentHeader/ContentHeader.tsx b/packages/core-components/src/layout/ContentHeader/ContentHeader.tsx index 2259731148..76fec703a9 100644 --- a/packages/core-components/src/layout/ContentHeader/ContentHeader.tsx +++ b/packages/core-components/src/layout/ContentHeader/ContentHeader.tsx @@ -82,13 +82,14 @@ type ContentHeaderProps = { textAlign?: 'left' | 'right' | 'center'; }; -export const ContentHeader = ({ - description, - title, - titleComponent: TitleComponent = undefined, - children, - textAlign = 'left', -}: PropsWithChildren) => { +export function ContentHeader(props: PropsWithChildren) { + const { + description, + title, + titleComponent: TitleComponent = undefined, + children, + textAlign = 'left', + } = props; const classes = useStyles({ textAlign })(); const renderedTitle = TitleComponent ? ( @@ -112,4 +113,4 @@ export const ContentHeader = ({ ); -}; +} diff --git a/packages/core-components/src/layout/ErrorPage/ErrorPage.tsx b/packages/core-components/src/layout/ErrorPage/ErrorPage.tsx index cca88147c4..f4b2960f96 100644 --- a/packages/core-components/src/layout/ErrorPage/ErrorPage.tsx +++ b/packages/core-components/src/layout/ErrorPage/ErrorPage.tsx @@ -47,11 +47,8 @@ const useStyles = makeStyles(theme => ({ }, })); -export const ErrorPage = ({ - status, - statusMessage, - additionalInfo, -}: IErrorPageProps) => { +export function ErrorPage(props: IErrorPageProps) { + const { status, statusMessage, additionalInfo } = props; const classes = useStyles(); const navigate = useNavigate(); const support = useSupportConfig(); @@ -82,4 +79,4 @@ export const ErrorPage = ({ ); -}; +} diff --git a/packages/core-components/src/layout/Header/Header.tsx b/packages/core-components/src/layout/Header/Header.tsx index 3b2771e299..dd56505720 100644 --- a/packages/core-components/src/layout/Header/Header.tsx +++ b/packages/core-components/src/layout/Header/Header.tsx @@ -174,16 +174,17 @@ const SubtitleFragment = ({ classes, subtitle }: SubtitleFragmentProps) => { ); }; -export const Header = ({ - children, - pageTitleOverride, - style, - subtitle, - title, - tooltip, - type, - typeLink, -}: PropsWithChildren) => { +export function Header(props: PropsWithChildren) { + const { + children, + pageTitleOverride, + style, + subtitle, + title, + tooltip, + type, + typeLink, + } = props; const classes = useStyles(); const configApi = useApi(configApiRef); const appTitle = configApi.getOptionalString('app.title') || 'Backstage'; @@ -216,4 +217,4 @@ export const Header = ({
); -}; +} diff --git a/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.tsx b/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.tsx index 06a9b2b701..5243a65498 100644 --- a/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.tsx +++ b/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.tsx @@ -66,7 +66,8 @@ export type HeaderActionMenuProps = { actionItems: ActionItemProps[]; }; -export const HeaderActionMenu = ({ actionItems }: HeaderActionMenuProps) => { +export function HeaderActionMenu(props: HeaderActionMenuProps) { + const { actionItems } = props; const [open, setOpen] = React.useState(false); const anchorElRef = React.useRef(null); @@ -103,4 +104,4 @@ export const HeaderActionMenu = ({ actionItems }: HeaderActionMenuProps) => { ); -}; +} diff --git a/packages/core-components/src/layout/HeaderLabel/HeaderLabel.tsx b/packages/core-components/src/layout/HeaderLabel/HeaderLabel.tsx index 8557ceddf7..88f6e26bf5 100644 --- a/packages/core-components/src/layout/HeaderLabel/HeaderLabel.tsx +++ b/packages/core-components/src/layout/HeaderLabel/HeaderLabel.tsx @@ -51,7 +51,8 @@ type HeaderLabelProps = { url?: string; }; -export const HeaderLabel = ({ label, value, url }: HeaderLabelProps) => { +export function HeaderLabel(props: HeaderLabelProps) { + const { label, value, url } = props; const classes = useStyles(); const content = ( { ); -}; +} diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index 20742114c9..0fe3cd967e 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -55,11 +55,8 @@ type HeaderTabsProps = { onChange?: (index: number) => void; selectedIndex?: number; }; -export const HeaderTabs = ({ - tabs, - onChange, - selectedIndex, -}: HeaderTabsProps) => { +export function HeaderTabs(props: HeaderTabsProps) { + const { tabs, onChange, selectedIndex } = props; const [selectedTab, setSelectedTab] = useState(selectedIndex ?? 0); const styles = useStyles(); @@ -101,4 +98,4 @@ export const HeaderTabs = ({ ); -}; +} diff --git a/packages/core-components/src/layout/HomepageTimer/HomepageTimer.tsx b/packages/core-components/src/layout/HomepageTimer/HomepageTimer.tsx index 04073cca48..a78f4af8ca 100644 --- a/packages/core-components/src/layout/HomepageTimer/HomepageTimer.tsx +++ b/packages/core-components/src/layout/HomepageTimer/HomepageTimer.tsx @@ -67,7 +67,7 @@ function getTimes(configApi: ConfigApi) { return clocks; } -export const HomepageTimer = () => { +export function HomepageTimer(_props: {}) { const configApi = useApi(configApiRef); const defaultTimes: TimeObj[] = []; @@ -99,4 +99,4 @@ export const HomepageTimer = () => { ); } return null; -}; +} diff --git a/packages/core-components/src/layout/InfoCard/InfoCard.tsx b/packages/core-components/src/layout/InfoCard/InfoCard.tsx index 650bf78bbd..36205b0dc0 100644 --- a/packages/core-components/src/layout/InfoCard/InfoCard.tsx +++ b/packages/core-components/src/layout/InfoCard/InfoCard.tsx @@ -128,26 +128,27 @@ type Props = { titleTypographyProps?: object; }; -export const InfoCard = ({ - title, - subheader, - divider = true, - deepLink, - slackChannel, - errorBoundaryProps, - variant, - children, - headerStyle, - headerProps, - action, - actionsClassName, - actions, - cardClassName, - actionsTopRight, - className, - noPadding, - titleTypographyProps, -}: Props): JSX.Element => { +export function InfoCard(props: Props): JSX.Element { + const { + title, + subheader, + divider = true, + deepLink, + slackChannel, + errorBoundaryProps, + variant, + children, + headerStyle, + headerProps, + action, + actionsClassName, + actions, + cardClassName, + actionsTopRight, + className, + noPadding, + titleTypographyProps, + } = props; const classes = useStyles(); /** * If variant is specified, we build up styles for that particular variant for both @@ -214,4 +215,4 @@ export const InfoCard = ({ ); -}; +} diff --git a/packages/core-components/src/layout/ItemCard/ItemCard.tsx b/packages/core-components/src/layout/ItemCard/ItemCard.tsx index b4273ee837..81a88d2c09 100644 --- a/packages/core-components/src/layout/ItemCard/ItemCard.tsx +++ b/packages/core-components/src/layout/ItemCard/ItemCard.tsx @@ -62,16 +62,9 @@ type ItemCardProps = { * @deprecated Use plain MUI and composable helpers instead. * @see https://material-ui.com/components/cards/ */ -export const ItemCard = ({ - description, - tags, - title, - type, - subtitle, - label, - onClick, - href, -}: ItemCardProps) => { +export function ItemCard(props: ItemCardProps) { + const { description, tags, title, type, subtitle, label, onClick, href } = + props; return ( @@ -101,4 +94,4 @@ export const ItemCard = ({ ); -}; +} diff --git a/packages/core-components/src/layout/ItemCard/ItemCardGrid.tsx b/packages/core-components/src/layout/ItemCard/ItemCardGrid.tsx index a5c57ba246..137c48d272 100644 --- a/packages/core-components/src/layout/ItemCard/ItemCardGrid.tsx +++ b/packages/core-components/src/layout/ItemCard/ItemCardGrid.tsx @@ -51,7 +51,7 @@ export type ItemCardGridProps = Partial> & { * This can be useful for e.g. overriding gridTemplateColumns to adapt the * minimum size of the cells to fit the content better. */ -export const ItemCardGrid = (props: ItemCardGridProps) => { +export function ItemCardGrid(props: ItemCardGridProps) { const { children, ...otherProps } = props; const classes = useStyles(otherProps); return ( @@ -59,4 +59,4 @@ export const ItemCardGrid = (props: ItemCardGridProps) => { {children} ); -}; +} diff --git a/packages/core-components/src/layout/ItemCard/ItemCardHeader.tsx b/packages/core-components/src/layout/ItemCard/ItemCardHeader.tsx index 58c7c1501d..15a1a7d78b 100644 --- a/packages/core-components/src/layout/ItemCard/ItemCardHeader.tsx +++ b/packages/core-components/src/layout/ItemCard/ItemCardHeader.tsx @@ -72,7 +72,7 @@ export type ItemCardHeaderProps = Partial> & { * * */ -export const ItemCardHeader = (props: ItemCardHeaderProps) => { +export function ItemCardHeader(props: ItemCardHeaderProps) { const { title, subtitle, children } = props; const classes = useStyles(props); return ( @@ -90,4 +90,4 @@ export const ItemCardHeader = (props: ItemCardHeaderProps) => { {children} ); -}; +} diff --git a/packages/core-components/src/layout/Page/Page.tsx b/packages/core-components/src/layout/Page/Page.tsx index f78dc038f2..b838693a3c 100644 --- a/packages/core-components/src/layout/Page/Page.tsx +++ b/packages/core-components/src/layout/Page/Page.tsx @@ -34,7 +34,8 @@ type Props = { themeId: string; }; -export const Page = ({ themeId, children }: PropsWithChildren) => { +export function Page(props: PropsWithChildren) { + const { themeId, children } = props; const classes = useStyles(); return ( ) => {
{children}
); -}; +} diff --git a/packages/core-components/src/layout/Page/PageWithHeader.tsx b/packages/core-components/src/layout/Page/PageWithHeader.tsx index 70a6c1f693..541b655dff 100644 --- a/packages/core-components/src/layout/Page/PageWithHeader.tsx +++ b/packages/core-components/src/layout/Page/PageWithHeader.tsx @@ -23,13 +23,12 @@ type PageWithHeaderProps = ComponentProps & { themeId: string; }; -export const PageWithHeader = ({ - themeId, - children, - ...props -}: PropsWithChildren) => ( - -
- {children} - -); +export function PageWithHeader(props: PropsWithChildren) { + const { themeId, children, ...restProps } = props; + return ( + +
+ {children} + + ); +} diff --git a/packages/core-components/src/layout/Sidebar/Bar.tsx b/packages/core-components/src/layout/Sidebar/Bar.tsx index f928c4b7c4..8855f01104 100644 --- a/packages/core-components/src/layout/Sidebar/Bar.tsx +++ b/packages/core-components/src/layout/Sidebar/Bar.tsx @@ -74,11 +74,12 @@ type Props = { closeDelayMs?: number; }; -export const Sidebar = ({ - openDelayMs = sidebarConfig.defaultOpenDelayMs, - closeDelayMs = sidebarConfig.defaultCloseDelayMs, - children, -}: PropsWithChildren) => { +export function Sidebar(props: PropsWithChildren) { + const { + openDelayMs = sidebarConfig.defaultOpenDelayMs, + closeDelayMs = sidebarConfig.defaultCloseDelayMs, + children, + } = props; const classes = useStyles(); const isSmallScreen = useMediaQuery(theme => theme.breakpoints.down('md'), @@ -149,4 +150,4 @@ export const Sidebar = ({ ); -}; +} diff --git a/packages/core-components/src/layout/Sidebar/Intro.tsx b/packages/core-components/src/layout/Sidebar/Intro.tsx index 14c5d9e25a..45098b49e1 100644 --- a/packages/core-components/src/layout/Sidebar/Intro.tsx +++ b/packages/core-components/src/layout/Sidebar/Intro.tsx @@ -74,7 +74,7 @@ type IntroCardProps = { onClose: () => void; }; -export const IntroCard = (props: IntroCardProps) => { +export function IntroCard(props: IntroCardProps) { const classes = useStyles(); const { text, onClose } = props; const handleClose = () => onClose(); @@ -97,7 +97,7 @@ export const IntroCard = (props: IntroCardProps) => { ); -}; +} type SidebarIntroLocalStorage = { starredItemsDismissed: boolean; @@ -127,7 +127,7 @@ Keep an eye out for the little star icon (⭐) next to the plugin name and give const recentlyViewedIntroText = 'And your recently viewed plugins will pop up here!'; -export const SidebarIntro = () => { +export function SidebarIntro(_props: {}) { const { isOpen } = useContext(SidebarContext); const defaultValue = { starredItemsDismissed: false, @@ -177,4 +177,4 @@ export const SidebarIntro = () => { )} ); -}; +} diff --git a/packages/core-components/src/layout/Sidebar/Items.tsx b/packages/core-components/src/layout/Sidebar/Items.tsx index 1068a877bd..b3acc36f98 100644 --- a/packages/core-components/src/layout/Sidebar/Items.tsx +++ b/packages/core-components/src/layout/Sidebar/Items.tsx @@ -282,7 +282,7 @@ type SidebarSearchFieldProps = { to?: string; }; -export const SidebarSearchField = (props: SidebarSearchFieldProps) => { +export function SidebarSearchField(props: SidebarSearchFieldProps) { const [input, setInput] = useState(''); const classes = useStyles(); @@ -334,7 +334,7 @@ export const SidebarSearchField = (props: SidebarSearchFieldProps) => { ); -}; +} export const SidebarSpace = styled('div')({ flex: 1, diff --git a/packages/core-components/src/layout/Sidebar/Page.tsx b/packages/core-components/src/layout/Sidebar/Page.tsx index 0ace7468ef..47c5878cde 100644 --- a/packages/core-components/src/layout/Sidebar/Page.tsx +++ b/packages/core-components/src/layout/Sidebar/Page.tsx @@ -49,7 +49,7 @@ export const SidebarPinStateContext = createContext( }, ); -export const SidebarPage = (props: PropsWithChildren<{}>) => { +export function SidebarPage(props: PropsWithChildren<{}>) { const [isPinned, setIsPinned] = useState(() => LocalStorage.getSidebarPinState(), ); @@ -71,4 +71,4 @@ export const SidebarPage = (props: PropsWithChildren<{}>) => {
{props.children}
); -}; +} diff --git a/packages/core-components/src/layout/SignInPage/SignInPage.tsx b/packages/core-components/src/layout/SignInPage/SignInPage.tsx index dcaad83c72..e0d4f6ed0d 100644 --- a/packages/core-components/src/layout/SignInPage/SignInPage.tsx +++ b/packages/core-components/src/layout/SignInPage/SignInPage.tsx @@ -192,10 +192,10 @@ export const SingleSignInPage = ({ ); }; -export const SignInPage = (props: Props) => { +export function SignInPage(props: Props) { if ('provider' in props) { return ; } return ; -}; +} diff --git a/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx b/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx index c9f2a477ef..f350b24f1d 100644 --- a/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx +++ b/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx @@ -62,15 +62,16 @@ type Props = { deepLink?: BottomLinkProps; }; -const TabbedCard = ({ - slackChannel, - errorBoundaryProps, - children, - title, - deepLink, - value, - onChange, -}: PropsWithChildren) => { +export function TabbedCard(props: PropsWithChildren) { + const { + slackChannel, + errorBoundaryProps, + children, + title, + deepLink, + value, + onChange, + } = props; const tabsClasses = useTabsStyles(); const [selectedIndex, selectIndex] = useState(0); @@ -111,7 +112,7 @@ const TabbedCard = ({ ); -}; +} const useCardTabStyles = makeStyles(theme => ({ root: { @@ -135,10 +136,9 @@ type CardTabProps = TabProps & { children: ReactNode; }; -const CardTab = ({ children, ...props }: PropsWithChildren) => { +export function CardTab(props: PropsWithChildren) { + const { children, ...restProps } = props; const classes = useCardTabStyles(); - return ; -}; - -export { TabbedCard, CardTab }; + return ; +} From 90ee6678159e474a69378975620f9eead67436ab Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 14:38:49 +0200 Subject: [PATCH 099/125] workflows: skip doc link verification in microsite CI Signed-off-by: Patrik Oldsberg --- .github/workflows/microsite-build-check.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/microsite-build-check.yml b/.github/workflows/microsite-build-check.yml index 68a6c08cd9..73f63ed63a 100644 --- a/.github/workflows/microsite-build-check.yml +++ b/.github/workflows/microsite-build-check.yml @@ -27,9 +27,6 @@ jobs: with: node-version: ${{ matrix.node-version }} - - name: verify doc links - run: node scripts/verify-links.js - # Skip caching of microsite dependencies, it keeps the global cache size # smaller, which make Windows builds a lot faster for the rest of the project. - name: yarn install From 6db4de79a17cbcf0f4c6f4d05e4e287fa6307343 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 14:39:22 +0200 Subject: [PATCH 100/125] explore: format API report Signed-off-by: Patrik Oldsberg --- plugins/explore/api-report.md | 67 +++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/plugins/explore/api-report.md b/plugins/explore/api-report.md index 6ed2be6cde..2d04574f88 100644 --- a/plugins/explore/api-report.md +++ b/plugins/explore/api-report.md @@ -3,11 +3,10 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts - /// import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { default } from 'react'; +import { default as default_2 } from 'react'; import { ExternalRouteRef } from '@backstage/core-plugin-api'; import { RouteRef } from '@backstage/core-plugin-api'; import { TabProps } from '@material-ui/core'; @@ -15,25 +14,30 @@ import { TabProps } from '@material-ui/core'; // Warning: (ae-missing-release-tag) "catalogEntityRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const catalogEntityRouteRef: ExternalRouteRef< { -name: string; -kind: string; -namespace: string; -}, false>; +export const catalogEntityRouteRef: ExternalRouteRef< + { + name: string; + kind: string; + namespace: string; + }, + false +>; // Warning: (ae-missing-release-tag) "DomainExplorerContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const DomainExplorerContent: ({ title, }: { - title?: string | undefined; +export const DomainExplorerContent: ({ + title, +}: { + title?: string | undefined; }) => JSX.Element; // Warning: (ae-missing-release-tag) "ExploreLayout" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public export const ExploreLayout: { - ({ title, subtitle, children, }: ExploreLayoutProps): JSX.Element; - Route: (props: SubRoute) => null; + ({ title, subtitle, children }: ExploreLayoutProps): JSX.Element; + Route: (props: SubRoute) => null; }; // Warning: (ae-missing-release-tag) "ExplorePage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -44,17 +48,23 @@ export const ExplorePage: () => JSX.Element; // Warning: (ae-missing-release-tag) "explorePlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -const explorePlugin: BackstagePlugin< { -explore: RouteRef; -}, { -catalogEntity: ExternalRouteRef< { -name: string; -kind: string; -namespace: string; -}, false>; -}>; -export { explorePlugin } -export { explorePlugin as plugin } +const explorePlugin: BackstagePlugin< + { + explore: RouteRef; + }, + { + catalogEntity: ExternalRouteRef< + { + name: string; + kind: string; + namespace: string; + }, + false + >; + } +>; +export { explorePlugin }; +export { explorePlugin as plugin }; // Warning: (ae-missing-release-tag) "exploreRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -64,15 +74,19 @@ export const exploreRouteRef: RouteRef; // Warning: (ae-missing-release-tag) "GroupsExplorerContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const GroupsExplorerContent: ({ title, }: { - title?: string | undefined; +export const GroupsExplorerContent: ({ + title, +}: { + title?: string | undefined; }) => JSX.Element; // Warning: (ae-missing-release-tag) "ToolExplorerContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const ToolExplorerContent: ({ title }: { - title?: string | undefined; +export const ToolExplorerContent: ({ + title, +}: { + title?: string | undefined; }) => JSX.Element; // Warnings were encountered during analysis: @@ -81,5 +95,4 @@ export const ToolExplorerContent: ({ title }: { // src/components/ExploreLayout/ExploreLayout.d.ts:30:5 - (ae-forgotten-export) The symbol "SubRoute" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) - ``` From 7e32ac97cb9a87d683ca92fcb3f4e3e75a3396b4 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 15:31:00 +0200 Subject: [PATCH 101/125] microsite: add hardcoded reference/index to sidebar verification Signed-off-by: Patrik Oldsberg --- microsite/scripts/verify-sidebars.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/microsite/scripts/verify-sidebars.js b/microsite/scripts/verify-sidebars.js index 8d643b15a2..301a1cb4c0 100755 --- a/microsite/scripts/verify-sidebars.js +++ b/microsite/scripts/verify-sidebars.js @@ -28,15 +28,18 @@ try { } const errors = []; -const ids = Object.keys(metadata); -for (let id of ids) { + +// reference/index is generated, so make sure this goes through even if it's not there +const knownIds = new Set([...Object.keys(metadata), 'reference/index']); + +for (const id in metadata) { const { next, previous } = metadata[id]; - if (next && !ids.includes(next)) { + if (next && !knownIds.has(next)) { errors.push(`Next ${next} does not exist in ${id}.`); } - if (previous && !ids.includes(previous)) { + if (previous && !knownIds.has(previous)) { errors.push(`Previous ${previous} does not exist in ${id}.`); } } From e65c42aa77b128884def1711e1e701d949aa52e4 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 15:36:48 +0200 Subject: [PATCH 102/125] docs: fix reference links Signed-off-by: Patrik Oldsberg --- docs/api/utility-apis.md | 90 +++++++++++++-------------- docs/conf/reading.md | 4 +- docs/plugins/structure-of-a-plugin.md | 4 +- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/docs/api/utility-apis.md b/docs/api/utility-apis.md index 1a1e29c19c..1b364bcdae 100644 --- a/docs/api/utility-apis.md +++ b/docs/api/utility-apis.md @@ -13,31 +13,31 @@ both with other plugins and the app itself. Backstage provides two primary methods for plugins to communicate across their boundaries in client-side code. The first one being the -[createPlugin](../reference/core-plugin-api.createPlugin.md) API along with the +[createPlugin](../reference/core-plugin-api.createplugin.md) API along with the extensions that it can provide, and the second one being Utility APIs. While the -[createPlugin](../reference/core-plugin-api.createPlugin.md) API is focused on +[createPlugin](../reference/core-plugin-api.createplugin.md) API is focused on the initialization plugins and the app, the Utility APIs provide ways for plugins to communicate during their entire life cycle. ## Consuming APIs -Each Utility API is tied to an [ApiRef](../reference/core-plugin-api.ApiRef.md) +Each Utility API is tied to an [ApiRef](../reference/core-plugin-api.apiref.md) instance, which is a global singleton object without any additional state or functionality, its only purpose is to reference Utility APIs. -[ApiRef](../reference/core-plugin-api.ApiRef.md)s are created using -[createApiRef](../reference/core-plugin-api.createApiRef.md), which is exported +[ApiRef](../reference/core-plugin-api.apiref.md)s are created using +[createApiRef](../reference/core-plugin-api.createapiref.md), which is exported by [@backstage/core-plugin-api](../reference/core-plugin-api.md). There are also many predefined Utility APIs in [@backstage/core-plugin-api](../reference/core-plugin-api.md), and they're all exported with a name of the pattern `*ApiRef`, for example -[errorApiRef](../reference/core-plugin-api.errorApiRef.md). +[errorApiRef](../reference/core-plugin-api.errorapiref.md). To access one of the Utility APIs inside a React component, use the -[useApi](../reference/core-plugin-api.useApi.md) hook exported by +[useApi](../reference/core-plugin-api.useapi.md) hook exported by [@backstage/core-plugin-api](../reference/core-plugin-api.md), or the -[withApis](../reference/core-plugin-api.withApis.md) HOC if you prefer class +[withApis](../reference/core-plugin-api.withapis.md) HOC if you prefer class components. For example, the -[ErrorApi](../reference/core-plugin-api.ErrorApi.md) can be accessed like this: +[ErrorApi](../reference/core-plugin-api.errorapi.md) can be accessed like this: ```tsx import React from 'react'; @@ -56,9 +56,9 @@ export const MyComponent = () => { ``` Note that there is no explicit type given for -[ErrorApi](../reference/core-plugin-api.ErrorApi.md). This is because the -[errorApiRef](../reference/core-plugin-api.errorApiRef.md) has the type -embedded, and [useApi](../reference/core-plugin-api.useApi.md) is able to infer +[ErrorApi](../reference/core-plugin-api.errorapi.md). This is because the +[errorApiRef](../reference/core-plugin-api.errorapiref.md) has the type +embedded, and [useApi](../reference/core-plugin-api.useapi.md) is able to infer the type. Also note that consuming Utility APIs is not limited to plugins, it can be done @@ -71,15 +71,15 @@ requirement is that they are beneath the `AppProvider` in the react tree. ### API Factories APIs are registered in the form of -[ApiFactories](../reference/core-plugin-api.ApiFactory.md), which encapsulate +[ApiFactories](../reference/core-plugin-api.apifactory.md), which encapsulate the process of instantiating an API. It is a collection of three things: the -[ApiRef](../reference/core-plugin-api.ApiRef.md) of the API to instantiate, a +[ApiRef](../reference/core-plugin-api.apiref.md) of the API to instantiate, a list of all required dependencies, and a factory function that returns a new API instance. For example, this is the default -[ApiFactory](../reference/core-plugin-api.ApiFactory.md) for the -[ErrorApi](../reference/core-plugin-api.ErrorApi.md): +[ApiFactory](../reference/core-plugin-api.apifactory.md) for the +[ErrorApi](../reference/core-plugin-api.errorapi.md): ```ts createApiFactory({ @@ -93,25 +93,25 @@ createApiFactory({ }); ``` -In this example the [errorApiRef](../reference/core-plugin-api.errorApiRef.md) +In this example the [errorApiRef](../reference/core-plugin-api.errorapiref.md) is our API, which encapsulates the -[ErrorApi](../reference/core-plugin-api.ErrorApi.md) type. The -[alertApiRef](../reference/core-plugin-api.alertApiRef.md) is our single +[ErrorApi](../reference/core-plugin-api.errorapi.md) type. The +[alertApiRef](../reference/core-plugin-api.alertapiref.md) is our single dependency, which we give the name `alertApi`, and is then passed on to the factory function, which returns an implementation of the -[ErrorApi](../reference/core-plugin-api.ErrorApi.md). +[ErrorApi](../reference/core-plugin-api.errorapi.md). -The [createApiFactory](../reference/core-plugin-api.createApiFactory.md) +The [createApiFactory](../reference/core-plugin-api.createapifactory.md) function is a thin wrapper that enables TypeScript type inference. You may notice that there are no type annotations in the above example, and that is because we're able to infer all types from the -[ApiRef](../reference/core-plugin-api.ApiRef.md)s. TypeScript will make sure +[ApiRef](../reference/core-plugin-api.apiref.md)s. TypeScript will make sure that the return value of the `factory` function matches the type embedded in -`api`'s [ApiRef](../reference/core-plugin-api.ApiRef.md), in this case the -[ErrorApi](../reference/core-plugin-api.ErrorApi.md). It will also match the +`api`'s [ApiRef](../reference/core-plugin-api.apiref.md), in this case the +[ErrorApi](../reference/core-plugin-api.errorapi.md). It will also match the types between the `deps` and the parameters of the `factory` function, again using the type embedded within the -[ApiRef](../reference/core-plugin-api.ApiRef.md)s. +[ApiRef](../reference/core-plugin-api.apiref.md)s. ## Registering API Factories @@ -124,11 +124,11 @@ app, and the app itself. Starting with the Backstage core library, it provides implementations for all of the core APIs. The core APIs are the ones exported by [@backstage/core-plugin-api](../reference/core-plugin-api.md), such as the -[errorApiRef](../reference/core-plugin-api.errorApiRef.md) and -[configApiRef](../reference/core-plugin-api.configApiRef.md). +[errorApiRef](../reference/core-plugin-api.errorapiref.md) and +[configApiRef](../reference/core-plugin-api.configapiref.md). The core APIs are loaded for any app created with -[createApp](../reference/core-app-api.createApp.md) from +[createApp](../reference/core-app-api.createapp.md) from [@backstage/core-plugin-api](../reference/core-plugin-api.md), which means that there is no step that needs to be taken to include these APIs in an app. @@ -137,13 +137,13 @@ there is no step that needs to be taken to include these APIs in an app. In addition to the core APIs, plugins can define and export their own APIs. While doing so they should usually also provide default implementations of their own APIs, for example, the `catalog` plugin exports `catalogApiRef`, and also -supplies a default [ApiFactory](../reference/core-plugin-api.ApiFactory.md) of +supplies a default [ApiFactory](../reference/core-plugin-api.apifactory.md) of that API using the `CatalogClient`. There is one restriction to plugin-provided API Factories: plugins may not supply factories for core APIs, trying to do so will cause the app to refuse to start. Plugins supply their APIs through the `apis` option of -[createPlugin](../reference/core-plugin-api.createPlugin.md), for example: +[createPlugin](../reference/core-plugin-api.createplugin.md), for example: ```ts export const techdocsPlugin = createPlugin({ @@ -168,7 +168,7 @@ Lastly, the app itself is the final point where APIs can be added, and what has the final say in what APIs will be loaded at runtime. The app may override the factories for any of the core or plugin APIs, with the exception of the config, app theme, and identity APIs. These are static APIs that are tied into the -[createApp](../reference/core-app-api.createApp.md) implementation, and +[createApp](../reference/core-app-api.createapp.md) implementation, and therefore not possible to override. Overriding APIs is useful for apps that want to switch out behavior to tailor it @@ -231,19 +231,19 @@ const app = createApp({ ``` Note that the above line will cause an error if `IgnoreErrorApi` does not fully -implement the [ErrorApi](../reference/core-plugin-api.ErrorApi.md), as it is +implement the [ErrorApi](../reference/core-plugin-api.errorapi.md), as it is checked by the type embedded in the -[errorApiRef](../reference/core-plugin-api.errorApiRef.md) at compile time. +[errorApiRef](../reference/core-plugin-api.errorapiref.md) at compile time. ## Defining custom Utility APIs Plugins are free to define their own Utility APIs. Simply define the TypeScript interface for the API, and create an -[ApiRef](../reference/core-plugin-api.ApiRef.md) using -[createApiRef](../reference/core-plugin-api.createApiRef.md) exported from +[ApiRef](../reference/core-plugin-api.apiref.md) using +[createApiRef](../reference/core-plugin-api.createapiref.md) exported from [@backstage/core-plugin-api](../reference/core-plugin-api.md). Also be sure to provide at least one implementation of the API, and to declare a default factory -for the API in [createPlugin](../reference/core-plugin-api.createPlugin.md). +for the API in [createPlugin](../reference/core-plugin-api.createplugin.md). Custom Utility APIs can be either public or private, which is up to the plugin to choose. Private APIs do not expose an external API surface, and it's @@ -255,16 +255,16 @@ backwards compatibility of public APIs, as you may otherwise break apps that are using your plugin. To make an API public, simply export the -[ApiRef](../reference/core-plugin-api.ApiRef.md) of the API, and any associated +[ApiRef](../reference/core-plugin-api.apiref.md) of the API, and any associated types. To make an API private, just avoid exporting the -[ApiRef](../reference/core-plugin-api.ApiRef.md), but still be sure to supply a -default factory to [createPlugin](../reference/core-plugin-api.createPlugin.md). +[ApiRef](../reference/core-plugin-api.apiref.md), but still be sure to supply a +default factory to [createPlugin](../reference/core-plugin-api.createplugin.md). Private APIs are useful for plugins that want to depend on other APIs outside of React components, but not have to expose an entire API surface to maintain. When using private APIs, it is fine to use the `typeof` of an implementing class as the type parameter passed to -[createApiRef](../reference/core-plugin-api.createApiRef.md), while public APIs +[createApiRef](../reference/core-plugin-api.createapiref.md), while public APIs should always define a separate TypeScript interface type. Plugins may depend on APIs from other plugins, both in React components and as @@ -273,13 +273,13 @@ dependencies between plugins. ## Architecture -The [ApiRef](../reference/core-plugin-api.ApiRef.md) instances mentioned above +The [ApiRef](../reference/core-plugin-api.apiref.md) instances mentioned above provide a point of indirection between consumers and producers of Utility APIs. It allows for plugins and components to depend on APIs in a type-safe way, without having a direct reference to a concrete implementation of the APIs. The Apps are also given a lot of flexibility in what implementations to provide. As long as they adhere to the contract established by an -[ApiRef](../reference/core-plugin-api.ApiRef.md), they are free to choose any +[ApiRef](../reference/core-plugin-api.apiref.md), they are free to choose any implementation they want. The figure below shows the relationship between @@ -310,10 +310,10 @@ interaction with the API. The common development environment for plugins is included in [@backstage/dev-utils](../reference/dev-utils.md), where the exported -[createDevApp](../reference/dev-utils.createDevApp.md) function creates an +[createDevApp](../reference/dev-utils.createdevapp.md) function creates an application with implementations for all core APIs already present. Contrary to the method for wiring up Utility API implementations in an app created with -[createApp](../reference/core-app-api.createApp.md), -[createDevApp](../reference/dev-utils.createDevApp.md) uses automatic dependency +[createApp](../reference/core-app-api.createapp.md), +[createDevApp](../reference/dev-utils.createdevapp.md) uses automatic dependency injection. This is to make it possible to replace any API implementation, and having that be reflected in dependents of that API. diff --git a/docs/conf/reading.md b/docs/conf/reading.md index 4568f4c378..fd1ce4c7a6 100644 --- a/docs/conf/reading.md +++ b/docs/conf/reading.md @@ -7,7 +7,7 @@ description: Documentation on Reading Backstage Configuration ## Config API There's a common configuration API for by both frontend and backend plugins. An -API reference can be found [here](../reference/config.Config.md). +API reference can be found [here](../reference/config.config.md). The configuration API is tailored towards failing fast in case of missing or bad config. That's because configuration errors can always be considered programming @@ -110,7 +110,7 @@ example `getString`. These will throw an error if there is no value available. ## Accessing ConfigApi in Frontend Plugins -The [ConfigApi](../reference/core-plugin-api.ConfigApi.md) in the frontend is a +The [ConfigApi](../reference/core-plugin-api.configapi.md) in the frontend is a [UtilityApi](../api/utility-apis.md). It's accessible as usual via the `configApiRef` exported from `@backstage/core-plugin-api`: diff --git a/docs/plugins/structure-of-a-plugin.md b/docs/plugins/structure-of-a-plugin.md index 99a55745c5..83fcfbddba 100644 --- a/docs/plugins/structure-of-a-plugin.md +++ b/docs/plugins/structure-of-a-plugin.md @@ -82,8 +82,8 @@ export const ExamplePage = examplePlugin.provide( This is where the plugin is created and where it creates and exports extensions that can be imported and used the app. See reference docs for -[createPlugin](../reference/createPlugin.md) or introduction to the new -[Composability System](./composability.md). +[createPlugin](../reference/core-plugin-api.createplugin.md) or introduction to +the new [Composability System](./composability.md). ## Components From 2aad5ab2269fd3569f16bbd5c49e07c3decf7138 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 16:39:53 +0200 Subject: [PATCH 103/125] docs: get rid of the reference dir Signed-off-by: Patrik Oldsberg --- docs/.gitignore | 3 ++- docs/reference/.generated | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 docs/reference/.generated diff --git a/docs/.gitignore b/docs/.gitignore index c757205e4c..90b1e2c7ef 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1 +1,2 @@ -reference/*.md +# This is generated by build:api-docs in the root +reference diff --git a/docs/reference/.generated b/docs/reference/.generated deleted file mode 100644 index e08947a827..0000000000 --- a/docs/reference/.generated +++ /dev/null @@ -1,2 +0,0 @@ -The contents of this folder is generated by the root `yarn build:api-docs` command. -Don't put any additional content here as it will be overwritten during the microsite build. From d4e614bb1da12410e1fff28f8746220d730ad21c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 12 Sep 2021 23:16:11 +0200 Subject: [PATCH 104/125] remove docgen package Signed-off-by: Patrik Oldsberg --- .github/styles/vocab.txt | 1 - docs/getting-started/project-structure.md | 5 - docs/overview/stability-index.md | 6 - package.json | 1 - packages/docgen/.eslintrc.js | 6 - packages/docgen/README.md | 21 -- packages/docgen/bin/backstage-docgen | 36 -- packages/docgen/package.json | 51 --- .../docgen/src/docgen/ApiDocGenerator.test.ts | 266 -------------- packages/docgen/src/docgen/ApiDocGenerator.ts | 343 ------------------ packages/docgen/src/docgen/ApiDocsPrinter.ts | 163 --------- .../src/docgen/GitHubMarkdownPrinter.ts | 145 -------- .../src/docgen/TechdocsMarkdownPrinter.ts | 161 -------- .../docgen/src/docgen/TypeLocator.test.ts | 68 ---- packages/docgen/src/docgen/TypeLocator.ts | 143 -------- .../src/docgen/TypescriptHighlighter.ts | 88 ----- .../docgen/src/docgen/sortSelector.test.ts | 49 --- packages/docgen/src/docgen/sortSelector.ts | 33 -- packages/docgen/src/docgen/testUtils.ts | 67 ---- packages/docgen/src/docgen/types.ts | 119 ------ packages/docgen/src/generate.ts | 127 ------- packages/docgen/src/index.ts | 60 --- scripts/api-extractor.ts | 1 - 23 files changed, 1960 deletions(-) delete mode 100644 packages/docgen/.eslintrc.js delete mode 100644 packages/docgen/README.md delete mode 100755 packages/docgen/bin/backstage-docgen delete mode 100644 packages/docgen/package.json delete mode 100644 packages/docgen/src/docgen/ApiDocGenerator.test.ts delete mode 100644 packages/docgen/src/docgen/ApiDocGenerator.ts delete mode 100644 packages/docgen/src/docgen/ApiDocsPrinter.ts delete mode 100644 packages/docgen/src/docgen/GitHubMarkdownPrinter.ts delete mode 100644 packages/docgen/src/docgen/TechdocsMarkdownPrinter.ts delete mode 100644 packages/docgen/src/docgen/TypeLocator.test.ts delete mode 100644 packages/docgen/src/docgen/TypeLocator.ts delete mode 100644 packages/docgen/src/docgen/TypescriptHighlighter.ts delete mode 100644 packages/docgen/src/docgen/sortSelector.test.ts delete mode 100644 packages/docgen/src/docgen/sortSelector.ts delete mode 100644 packages/docgen/src/docgen/testUtils.ts delete mode 100644 packages/docgen/src/docgen/types.ts delete mode 100644 packages/docgen/src/generate.ts delete mode 100644 packages/docgen/src/index.ts diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt index dd9224fc84..5c9d46ea8a 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -68,7 +68,6 @@ devs discoverability Discoverability dls -docgen Dockerfile dockerfiles Dockerize diff --git a/docs/getting-started/project-structure.md b/docs/getting-started/project-structure.md index 1d5d58c2c9..bf2cc93ea5 100644 --- a/docs/getting-started/project-structure.md +++ b/docs/getting-started/project-structure.md @@ -147,11 +147,6 @@ are separated out into their own folder, see further down. Helps you setup a plugin for isolated development so that it can be served separately. -- [`docgen/`](https://github.com/backstage/backstage/tree/master/packages/docgen) - - Uses the - [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) - to read out definitions and generate documentation for it. - - [`e2e-test/`](https://github.com/backstage/backstage/tree/master/packages/e2e-test) - Another CLI that can be run to try out what would happen if you build all the packages, publish them, create a new app, and then run them. CI uses this for diff --git a/docs/overview/stability-index.md b/docs/overview/stability-index.md index ee2628a893..8e710d4e7c 100644 --- a/docs/overview/stability-index.md +++ b/docs/overview/stability-index.md @@ -145,12 +145,6 @@ Provides utilities for developing plugins in isolation. Stability: `0`. This package is largely broken and needs updates. -### `docgen` [GitHub](https://github.com/backstage/backstage/tree/master/packages/docgen/) - -Internal CLI utility for generating API Documentation. - -Stability: `N/A` - ### `e2e-test` [GitHub](https://github.com/backstage/backstage/tree/master/packages/e2e-test/) Internal CLI utility for running e2e tests. diff --git a/package.json b/package.json index ea930b060f..d362338370 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "lint:docs": "node ./scripts/check-docs-quality", "lint:all": "lerna run lint --", "lint:type-deps": "node scripts/check-type-dependencies.js", - "docgen": "lerna run docgen", "docker-build": "yarn tsc && yarn workspace example-backend build --build-dependencies && yarn workspace example-backend build-image", "create-plugin": "backstage-cli create-plugin --scope backstage --no-private", "remove-plugin": "backstage-cli remove-plugin", diff --git a/packages/docgen/.eslintrc.js b/packages/docgen/.eslintrc.js deleted file mode 100644 index 503c048748..0000000000 --- a/packages/docgen/.eslintrc.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - extends: [require.resolve('@backstage/cli/config/eslint.backend')], - rules: { - 'no-console': 0, - }, -}; diff --git a/packages/docgen/README.md b/packages/docgen/README.md deleted file mode 100644 index be1d7cd521..0000000000 --- a/packages/docgen/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# DocGen - API Reference Documentation Generator - -The docgen package provides a CLI to generate markdown documentation for all exported ApiRefs in `@backstage/core`. The documentation is generated based on exported `ApiRef` instances and their type parameters. - -The CLI supports generating both TechDocs and GitHub Markdown, where the TechDocs one provides some better linking and syntax highlighting. - -## Usage - -To generate markdown documentation in the top-level `docs/` directory, run the following: - -```bash -yarn docgen -``` - -## TODO - -This package was lifted out from the Spotify internal Backstage project and could use some further work: - -- Use a higher-level TypeScript compiler library, e.g. `ts-morph`. -- Support for generating docs for any package or multiple packages. -- Better handling of self-referencing types in APIs, e.g. ConfigApi. diff --git a/packages/docgen/bin/backstage-docgen b/packages/docgen/bin/backstage-docgen deleted file mode 100755 index 71674eedd4..0000000000 --- a/packages/docgen/bin/backstage-docgen +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env node -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* eslint-disable no-restricted-syntax */ -const path = require('path'); - -// Figure out whether we're running inside the backstage repo or as an installed dependency -const isLocal = require('fs').existsSync(path.resolve(__dirname, '../src')); - -if (!isLocal || process.env.BACKSTAGE_E2E_CLI_TEST) { - require('..'); -} else { - require('ts-node').register({ - transpileOnly: true, - project: path.resolve(__dirname, '../../../tsconfig.json'), - compilerOptions: { - module: 'CommonJS', - }, - }); - - require('../src'); -} diff --git a/packages/docgen/package.json b/packages/docgen/package.json deleted file mode 100644 index ad47991159..0000000000 --- a/packages/docgen/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "docgen", - "description": "Tool for generating API Documentation for itself", - "version": "0.1.1", - "private": true, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "packages/docgen" - }, - "keywords": [ - "backstage" - ], - "license": "Apache-2.0", - "main": "src/index.ts", - "scripts": { - "build": "backstage-cli build --outputs cjs", - "lint": "backstage-cli lint", - "test": "backstage-cli test", - "docgen": "backstage-docgen generate --output ../../docs/reference/utility-apis --format github && prettier --write ../../docs/reference/utility-apis", - "clean": "backstage-cli clean", - "start": "nodemon --" - }, - "bin": { - "backstage-docgen": "bin/backstage-docgen" - }, - "dependencies": { - "chalk": "^4.0.0", - "commander": "^6.1.0", - "fs-extra": "9.1.0", - "github-slugger": "^1.3.0", - "ts-node": "^10.0.0", - "typescript": "^4.0.3" - }, - "devDependencies": { - "@types/fs-extra": "^9.0.1", - "@types/github-slugger": "^1.3.0", - "@types/node": "^14.14.32", - "nodemon": "^2.0.2" - }, - "files": [ - "bin", - "dist" - ], - "nodemonConfig": { - "watch": "./src", - "exec": "bin/backstage-docgen", - "ext": "ts" - } -} diff --git a/packages/docgen/src/docgen/ApiDocGenerator.test.ts b/packages/docgen/src/docgen/ApiDocGenerator.test.ts deleted file mode 100644 index ea053b1ef4..0000000000 --- a/packages/docgen/src/docgen/ApiDocGenerator.test.ts +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import ts from 'typescript'; -import TypeLocator from './TypeLocator'; -import { createMemProgram } from './testUtils'; -import ApiDocGenerator from './ApiDocGenerator'; - -describe('ApiDocGenerator', () => { - it('should generate empty API doc', () => { - const program = createMemProgram( - ` - import MyApi from './type'; - - type MyApiType = {}; - - export const myApi = new MyApi({ - id: 'my-id', - description: 'my-description', - }); - `, - { - '/mem/type.ts': `export default class MyApi { - constructor(private readonly info: { id: string, description: string }) {} - }`, - }, - ); - - const typeLocator = TypeLocator.fromProgram(program, '/'); - - const { apiInstances } = typeLocator.findExportedInstances({ - apiInstances: typeLocator.getExportedType('/mem/type.ts'), - }); - - expect(apiInstances.length).toBe(1); - const [apiInstance] = apiInstances; - - const docGenerator = ApiDocGenerator.fromProgram(program, '/'); - const doc = docGenerator.toDoc(apiInstance); - - expect(doc.id).toBe('my-id'); - expect(doc.description).toBe('my-description'); - expect(doc.name).toBe('myApi'); - expect(doc.file).toBe('mem/index.ts'); - expect(doc.lineInFile).toBe(6); - expect(doc.interfaceInfos).toEqual([ - { - dependentTypes: [], - docs: [], - file: 'mem/index.ts', - lineInFile: 4, - members: [], - name: 'MyApiType', - }, - ]); - }); - - it('should generate API docs', () => { - const program = createMemProgram( - ` - import MyApi from './type'; - - /** MySubSubType Docs */ - type MySubSubType = { n: number; }; - - /** MySubType Docs */ - type MySubType = { - /** Field a docs */ - a: boolean; - // Field b docs - b: MySubSubType; - } - - /** MySecondSubType Docs */ - - /** With multiple comments */ - export type MySecondSubType = { s: string }; - - // MyThirdSubType Docs that shouldn't show up - type MyThirdSubType = { b: boolean }; - - /** MyApiType Docs */ - type MyApiType = { - /** Docs for x */ - x: string; - // Line comments shouldn't show up - y: MySubType; - /** Multiple */ - /** JsDoc */ - /** Comments */ - z(a: Promise): Array; - }; - - /** Should not show up */ - export const myApi = new MyApi({ - id: 'my-id', - description: 'my-description', - }); - `, - { - '/mem/type.ts': `export default class MyApi { - constructor(private readonly info: { id: string, description: string }) {} - }`, - }, - ); - - const source = program.getSourceFile('/mem/index.ts'); - - // Figure out type IDs so we can make sure they match later - const checker = program.getTypeChecker(); - const symbols = checker.getSymbolsInScope( - source!.getChildren().slice(-1)[0], - ts.SymbolFlags.TypeAlias, - ); - const Ids = [ - 'MySubType', - 'MySubSubType', - 'MySecondSubType', - 'MyThirdSubType', - ].reduce((ids, name) => { - const symbol = symbols.find(s => s.escapedName === name)!; - const type = checker.getTypeAtLocation(symbol.declarations[0]); - ids[name] = (type.aliasSymbol as any).id; - return ids; - }, {} as { [key in string]: number }); - - const typeLocator = TypeLocator.fromProgram(program, '/mem'); - - const { apiInstances } = typeLocator.findExportedInstances({ - apiInstances: typeLocator.getExportedType('/mem/type.ts'), - }); - - expect(apiInstances.length).toBe(1); - const [apiInstance] = apiInstances; - - const docGenerator = ApiDocGenerator.fromProgram(program, '/mem'); - const doc = docGenerator.toDoc(apiInstance); - - expect(doc.id).toBe('my-id'); - expect(doc.description).toBe('my-description'); - expect(doc.name).toBe('myApi'); - expect(doc.file).toBe('index.ts'); - expect(doc.interfaceInfos.length).toBe(1); - expect(doc.interfaceInfos[0].docs).toEqual(['MyApiType Docs']); - expect(doc.interfaceInfos[0].file).toBe('index.ts'); - expect(doc.interfaceInfos[0].lineInFile).toBe(24); - expect(doc.interfaceInfos[0].name).toBe('MyApiType'); - expect(doc.interfaceInfos[0].members).toEqual([ - { - type: 'prop', - name: 'x', - path: 'MyApiType.x', - text: 'x: string', - docs: ['Docs for x'], - links: [], - }, - { - type: 'prop', - name: 'y', - path: 'MyApiType.y', - text: 'y: MySubType', - docs: [], - links: [ - { - id: Ids.MySubType, - name: 'MySubType', - path: 'index.ts/MySubType', - location: [3, 12], - }, - ], - }, - { - type: 'method', - name: 'z', - path: 'MyApiType.z', - text: 'z(a: Promise): Array', - docs: ['Multiple', 'JsDoc', 'Comments'], - links: [ - { - id: Ids.MySecondSubType, - name: 'MySecondSubType', - path: 'index.ts/MySecondSubType', - location: [27, 42], - }, - { - id: Ids.MyThirdSubType, - name: 'MyThirdSubType', - path: 'index.ts/MyThirdSubType', - location: [56, 70], - }, - ], - }, - ]); - expect(doc.interfaceInfos[0].dependentTypes).toEqual([ - { - id: Ids.MySubType, - name: 'MySubType', - path: 'index.ts/MySubType', - file: 'index.ts', - lineInFile: 8, - text: `type MySubType = { - /** Field a docs */ - a: boolean; - // Field b docs - b: MySubSubType; - }`, - docs: ['MySubType Docs'], - links: [ - { - id: Ids.MySubSubType, - name: 'MySubSubType', - path: 'index.ts/MySubSubType', - location: [102, 114], - }, - ], - children: [], - }, - { - id: Ids.MySubSubType, - name: 'MySubSubType', - path: 'index.ts/MySubSubType', - file: 'index.ts', - lineInFile: 5, - text: 'type MySubSubType = { n: number; }', - docs: ['MySubSubType Docs'], - links: [], - children: [], - }, - { - id: Ids.MySecondSubType, - name: 'MySecondSubType', - path: 'index.ts/MySecondSubType', - file: 'index.ts', - lineInFile: 18, - text: 'export type MySecondSubType = { s: string }', - docs: ['MySecondSubType Docs', 'With multiple comments'], - links: [], - children: [], - }, - { - id: Ids.MyThirdSubType, - name: 'MyThirdSubType', - path: 'index.ts/MyThirdSubType', - file: 'index.ts', - lineInFile: 21, - text: 'type MyThirdSubType = { b: boolean }', - docs: [], - links: [], - children: [], - }, - ]); - }); -}); diff --git a/packages/docgen/src/docgen/ApiDocGenerator.ts b/packages/docgen/src/docgen/ApiDocGenerator.ts deleted file mode 100644 index 32216745a2..0000000000 --- a/packages/docgen/src/docgen/ApiDocGenerator.ts +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import ts from 'typescript'; -import { - relative as relativePath, - sep as pathSep, - posix as posixPath, -} from 'path'; -import { - ExportedInstance, - ApiDoc, - InterfaceInfo, - FieldInfo, - TypeInfo, - TypeLink, -} from './types'; - -// Always use unix path separators for the relative file -// paths, since we'll be using those for HTTP URLs. -function relativeLink(basePath: string, filePath: string) { - return relativePath(basePath, filePath).split(pathSep).join(posixPath.sep); -} - -/** - * The ApiDocGenerator uses the typescript compiler API to build the data structure that - * describes a Backstage API and all of it's related types. - * - * It receives an exported instance that of the form - * `export name = createApiRef({id: ..., description: ...})`. - * It will then traverse all fields and methods on the interface type, and also - * types and declaration of all types that are used by those, both directly and indirectly. - * While traversing, it collects information such as names, location in source, docs, etc. - */ -export default class ApiDocGenerator { - static fromProgram(program: ts.Program, sourcePath: string) { - return new ApiDocGenerator(program.getTypeChecker(), sourcePath); - } - - constructor( - private readonly checker: ts.TypeChecker, - private readonly basePath: string, - ) {} - - /** - * Generate documentation information for a given exported symbol. - */ - toDoc(apiInstance: ExportedInstance): ApiDoc { - const { name, source, args, typeArgs } = apiInstance; - - const [info] = args; - if (!ts.isObjectLiteralExpression(info)) { - throw new Error('api info is not an object literal'); - } - - const id = this.getObjectPropertyLiteral(info, 'id'); - const description = this.getObjectPropertyLiteral(info, 'description'); - const file = relativeLink(this.basePath, source.fileName); - const { line } = source.getLineAndCharacterOfPosition( - apiInstance.node.getStart(), - ); - - const rootTypeNode = typeArgs[0]; - const typeNodes = ts.isIntersectionTypeNode(rootTypeNode) - ? rootTypeNode.types.slice() - : [rootTypeNode]; - const interfaceInfos = typeNodes.map(typeNode => - this.getInterfaceInfo(typeNode), - ); - - return { - id, - name, - file, - lineInFile: line + 1, - description, - interfaceInfos, - }; - } - - /** - * Grab jsDoc and regular comments for a node - */ - private getNodeDocs(node: ts.Node): string[] { - const docNodes = ((node && (node as any).jsDoc) || []) as ts.JSDoc[]; - const docs = docNodes.map(docNode => docNode.comment || '').filter(Boolean); - return docs; - } - - /** - * Collect information about a top-level type. - */ - private getInterfaceInfo(typeNode: ts.TypeNode): InterfaceInfo { - if (ts.isTypeQueryNode(typeNode)) { - throw new Error( - 'APIs must have a proper type parameter, TypeQueries are now allowed', - ); - } - if (!ts.isTypeReferenceNode(typeNode)) { - throw new Error('Interface is not a type node'); - } - - const type = this.checker.getTypeFromTypeNode(typeNode); - const interfaceMembers = type.symbol.members as Map; - if (!interfaceMembers) { - throw new Error('Interface does not have any members'); - } - const name = (type.aliasSymbol || type.symbol).name; - const [declaration] = (type.aliasSymbol || type.symbol).declarations; - const sourceFile = declaration.getSourceFile(); - const file = relativeLink(this.basePath, sourceFile.fileName); - const { line } = sourceFile.getLineAndCharacterOfPosition( - declaration.getStart(), - ); - const docs = this.getNodeDocs(declaration); - - const membersAndTypes = Array.from(interfaceMembers.values()).flatMap( - fieldSymbol => this.getMemberInfo(name, fieldSymbol), - ); - - const members = membersAndTypes.map(t => t.member); - const dependentTypes = this.flattenTypes( - membersAndTypes.flatMap(t => t.dependentTypes), - ); - - return { name, docs, file, lineInFile: line + 1, members, dependentTypes }; - } - - /** - * Grab primitive values from an object literal expression. - */ - private getObjectPropertyLiteral( - objectLiteral: ts.ObjectLiteralExpression, - propertyName: string, - ): string { - const matchingProp = objectLiteral.properties.filter( - prop => - ts.isPropertyAssignment(prop) && - ts.isIdentifier(prop.name) && - prop.name.text === propertyName, - )[0] as ts.PropertyAssignment; - - if (!matchingProp) { - throw new Error(`no identifier found for property ${propertyName}`); - } - - const { initializer } = matchingProp; - if (!ts.isStringLiteral(initializer)) { - throw new Error(`no string literal for ${propertyName}`); - } - - return initializer.text; - } - - /** - * Get field definitions for a given symbol. - */ - private getMemberInfo( - parentName: string, - symbol: ts.Symbol, - ): { member: FieldInfo; dependentTypes: TypeInfo[] } { - const declaration = symbol.valueDeclaration; - - const { links, infos: dependentTypes } = - this.findAllTypeReferences(declaration); - - let type: FieldInfo['type'] = 'prop'; - if ( - ts.isPropertySignature(declaration) && - declaration.type && - ts.isFunctionTypeNode(declaration.type) - ) { - type = 'method'; - } else if (ts.isMethodSignature(declaration)) { - type = 'method'; - } - - return { - member: { - type, - name: symbol.name, - path: `${parentName}.${symbol.name}`, - text: declaration.getText().replace(/;$/, ''), - docs: this.getNodeDocs(declaration), - links: this.recalculateLinkOffsets(declaration, links), - }, - dependentTypes, - }; - } - - /** - * Recursively search for references to types that we care about and want to include in the documentation. - */ - private findAllTypeReferences = ( - node: ts.Node | undefined, - visited: Set = new Set(), - ): { links: TypeLink[]; infos: TypeInfo[] } => { - if (!node || visited.has(node)) { - return { links: [], infos: [] }; - } - // This makes sure we don't end up in a loop. - // It doesn't exclude repeated types, e.g. Array>, since we're exiting on duplicate nodes, not types. - visited.add(node); - - const children = node - .getChildren() - .flatMap(child => this.findAllTypeReferences(child, visited)); - - if (!ts.isTypeReferenceNode(node)) { - return { - links: children.flatMap(child => child.links), - infos: children.flatMap(child => child.infos), - }; - } - - const type = this.checker.getTypeFromTypeNode(node); - - const info = this.validateTypeDeclaration(type); - if (!info) { - return { - links: children.flatMap(child => child.links), - infos: children.flatMap(child => child.infos), - }; - } - const { symbol, declaration } = info; - - const typeRefs = this.findAllTypeReferences(declaration, visited); - - const sourceFile = declaration.getSourceFile(); - const { line } = sourceFile.getLineAndCharacterOfPosition( - declaration.getStart(), - ); - const file = relativeLink(this.basePath, sourceFile.fileName); - const typeInfo = { - id: (symbol as any).id, - name: symbol.name, - text: declaration.getText().replace(/;$/, ''), - docs: this.getNodeDocs(declaration), - path: `${file}/${symbol.name}`, - file, - lineInFile: line + 1, // TS line is 0-based - links: this.recalculateLinkOffsets(declaration, typeRefs.links), - children: typeRefs.infos, - }; - - const link = { - id: typeInfo.id, - path: typeInfo.path, - name: typeInfo.name, - location: [node.typeName.getStart(), node.typeName.getEnd()] as const, - }; - - return { - links: [link, ...children.flatMap(child => child.links)], - infos: [typeInfo, ...children.flatMap(child => child.infos)], - }; - }; - - /** - * Check if a given type declaration is one that we care about. - */ - private validateTypeDeclaration( - type: ts.Type | undefined, - ): undefined | { symbol: ts.Symbol; declaration: ts.Declaration } { - if (!type) { - return undefined; - } - const symbol = type.aliasSymbol || type.symbol; - if (!symbol) { - return undefined; - } - - const [declaration] = symbol.declarations; - - // Don't generate standalone infos for type paramters - if (ts.isTypeParameterDeclaration(declaration)) { - return undefined; - } - - if (declaration.getSourceFile().fileName.includes('node_modules')) { - return undefined; - } - - return { symbol, declaration }; - } - - /** - * Flatten a tree of TypeInfos with children into a flat - * list of TypeInfos with duplicates removed. - */ - private flattenTypes(descs: TypeInfo[]): TypeInfo[] { - function getChildren(parent: TypeInfo): TypeInfo[] { - return [ - { - ...parent, - children: [], - }, - ...parent.children.flatMap(getChildren), - ]; - } - - const flatDescs = descs.flatMap(getChildren); - const seenTypes = new Set(); - return flatDescs.filter(desc => { - if (seenTypes.has(desc.id)) { - return false; - } - seenTypes.add(desc.id); - return true; - }); - } - - /** - * Calculate link positions within a block of code, with 0 being - * the first character in the block. - */ - private recalculateLinkOffsets( - parent: ts.Node, - links: TypeLink[], - ): TypeLink[] { - const parentStart = parent.getStart(); - return links.map(link => { - const [start, end] = link.location; - return { - ...link, - location: [start - parentStart, end - parentStart], - }; - }); - } -} diff --git a/packages/docgen/src/docgen/ApiDocsPrinter.ts b/packages/docgen/src/docgen/ApiDocsPrinter.ts deleted file mode 100644 index 1fd62c29cd..0000000000 --- a/packages/docgen/src/docgen/ApiDocsPrinter.ts +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import sortSelector from './sortSelector'; -import { ApiDoc, InterfaceInfo, MarkdownPrinter } from './types'; - -/** - * The ApiDocPrinter takes a ApiDoc data structure, typically generated by an ApiDocGenerator, - * and prints it out as a markdown doc with custom code highlighting and links. - */ -export default class ApiDocPrinter { - printerFactory: () => MarkdownPrinter; - - constructor(printerFactory: () => MarkdownPrinter) { - this.printerFactory = printerFactory; - } - - /** - * Print an index file with all ApiRefs and what types they implement. - */ - printApiIndex(apiDocs: ApiDoc[]): Buffer { - const printer = this.printerFactory(); - - printer.header(1, 'Backstage Core Utility APIs'); - - printer.paragraph( - 'The following is a list of all Utility APIs defined by `@backstage/core`.', - 'They are available to use by plugins and components, and can be accessed ', - 'using the `useApi` hook, also provided by `@backstage/core`.', - 'For more information, see https://github.com/backstage/backstage/blob/master/docs/api/utility-apis.md.', - ); - - for (const api of apiDocs) { - printer.header(3, `${this.apiDisplayName(api)}`, api.id); - - printer.paragraph(api.description); - - const typeLinks = api.interfaceInfos.map( - i => `[${i.name}](${printer.pageLink(i.name)})`, - ); - printer.paragraph( - `Implemented type${typeLinks.length > 1 ? 's' : ''}: ${typeLinks.join( - ', ', - )}`, - ); - - printer.paragraph(`ApiRef: ${printer.srcLink(api, api.name)}`); - } - - return printer.toBuffer(); - } - - /** - * Print documentation page for a type implemented by an ApiRef and - */ - printInterface(apiType: InterfaceInfo, apiDocs: ApiDoc[]): Buffer { - const printer = this.printerFactory(); - - printer.header(1, apiType.name); - - printer.paragraph( - `The ${apiType.name} type is defined at ${printer.srcLink(apiType)}.`, - ); - - const apiLinks = apiDocs - .filter(ad => ad.interfaceInfos.some(i => i.name === apiType.name)) - .map(ad => { - const link = - printer.indexLink() + - printer.headerLink(this.apiDisplayName(ad), ad.id); - return `[${ad.name}](${link})`; - }); - - if (apiLinks.length === 1) { - printer.paragraph( - `The following Utility API implements this type: ${apiLinks}`, - ); - } else { - printer.paragraph(`The following Utility APIs implement this type:`); - for (const link of apiLinks) { - printer.text(` - ${link}`); - } - } - - printer.header(2, 'Members'); - - this.addInterfaceMembers(printer, apiType); - - if (apiType.dependentTypes.length) { - printer.header(2, 'Supporting types'); - printer.paragraph( - 'These types are part of the API declaration, but may not be unique to this API.', - ); - - this.addInterfaceTypes(printer, apiType); - } - - return printer.toBuffer(); - } - - private addInterfaceMembers( - printer: MarkdownPrinter, - apiType: InterfaceInfo, - ) { - for (const member of apiType.members) { - printer.header( - 3, - `${member.name}${member.type === 'method' ? '()' : ''}`, - member.path, - ); - - for (const doc of member.docs) { - printer.text(doc); - } - - printer.code(member); - } - } - - private addInterfaceTypes(printer: MarkdownPrinter, apiType: InterfaceInfo) { - for (const type of apiType.dependentTypes - .slice() - .sort(sortSelector(x => x.name))) { - printer.header(3, `${type.name}`, type.path); - - for (const doc of type.docs) { - printer.text(doc); - } - printer.code(type); - - printer.paragraph(`Defined at ${printer.srcLink(type)}.`); - - const usageLinks = [...apiType.members, ...apiType.dependentTypes] - .filter(member => { - return member.links.some(link => link.id === type.id); - }) - .map( - ({ name, path }) => `[${name}](${printer.headerLink(name, path)})`, - ); - - if (usageLinks.length) { - printer.paragraph(`Referenced by: ${usageLinks.join(', ')}.`); - } - } - } - - private apiDisplayName(api: ApiDoc): string { - return api.name.replace(/ApiRef$/, ''); - } -} diff --git a/packages/docgen/src/docgen/GitHubMarkdownPrinter.ts b/packages/docgen/src/docgen/GitHubMarkdownPrinter.ts deleted file mode 100644 index b36895597e..0000000000 --- a/packages/docgen/src/docgen/GitHubMarkdownPrinter.ts +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import GithubSlugger from 'github-slugger'; -import sortSelector from './sortSelector'; -import { MarkdownPrinter, TypeLink } from './types'; -import { execSync } from 'child_process'; - -// TODO(Rugvip): provide through options? -const GH_BASE_URL = 'https://github.com/backstage/backstage'; - -const COMMIT_SHA = - process.env.COMMIT_SHA || - execSync('git rev-parse HEAD').toString('utf8').trim(); - -/** - * The GithubMarkdownPrinter is a MarkdownPrinter for printing GitHub Flavored Markdown documents. - */ -export default class GithubMarkdownPrinter implements MarkdownPrinter { - private str: string = ''; - - private line(line: string = '') { - this.str += `${line}\n`; - } - - text(text: string) { - this.line(text); - this.line(); - } - - header(level: number, text: string) { - this.line(`${'#'.repeat(level)} ${text}`); - this.line(); - } - - headerLink(heading: string): string { - const slug = GithubSlugger.slug(heading); - return `#${slug}`; - } - - indexLink() { - return './README.md'; - } - - pageLink(name: string) { - return `./${name}.md`; - } - - srcLink( - { file, lineInFile }: { file: string; lineInFile: number }, - text?: string, - ): string { - const linkText = text ?? `${file}:${lineInFile}`; - const href = `${GH_BASE_URL}/blob/${COMMIT_SHA}/${file}#L${lineInFile}`; - return `[${linkText}](${href})`; - } - - paragraph(...text: string[]) { - this.line( - text - .join('\n') - .trim() - .split('\n') - .map(line => line.trim()) - .join('\n'), - ); - this.line(); - } - - code({ text, links = [] }: { text: string; links?: TypeLink[] }) { - this.line('
');
-    this.line(this.formatWithLinks({ text, links }));
-    this.line('
'); - this.line(); - } - - private escapeText: (text: string) => string = (() => { - const escapes: { [char in string]: string } = { - '&': '&', - '<': '<', - '>': '>', - }; - - return (text: string) => text.replace(/[&<>]/g, char => escapes[char]); - })(); - - private formatWithLinks({ - text, - links = [], - }: { - text: string; - links?: TypeLink[]; - }): string { - const sortedLinks = links.slice().sort(sortSelector(x => x.location[0])); - - sortedLinks.reduce((lastEnd, link) => { - if (link.location[0] <= lastEnd) { - throw new Error( - `overlapping link detected for ${link.path}, ${link.location}`, - ); - } - return link.location[1]; - }, -1); - - const parts: Array<{ text: string; link?: boolean }> = []; - - const endLocation = sortedLinks.reduce((prev, link) => { - const [start, end] = link.location; - parts.push( - { text: text.slice(prev, start) }, - { text: text.slice(start, end), link: true }, - ); - return end; - }, 0); - - parts.push({ text: text.slice(endLocation) }); - - return parts - .map(part => { - if (part.link) { - const link = this.headerLink(part.text); - return `${this.escapeText(part.text)}`; - } - return this.escapeText(part.text); - }) - .join(''); - } - - toBuffer(): Buffer { - return Buffer.from(this.str, 'utf8'); - } -} diff --git a/packages/docgen/src/docgen/TechdocsMarkdownPrinter.ts b/packages/docgen/src/docgen/TechdocsMarkdownPrinter.ts deleted file mode 100644 index c9e3010dda..0000000000 --- a/packages/docgen/src/docgen/TechdocsMarkdownPrinter.ts +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import sortSelector from './sortSelector'; -import { Highlighter, MarkdownPrinter, TypeLink } from './types'; -import { execSync } from 'child_process'; - -// TODO(Rugvip): provide through options? -const GH_BASE_URL = 'https://github.com/backstage/backstage'; - -const COMMIT_SHA = - process.env.COMMIT_SHA || execSync('git rev-parse HEAD').toString('utf8'); - -/** - * The TechdocsMarkdownPrinter is a MarkdownPrinter for building TechDocs markdown documents. - */ -export default class TechdocsMarkdownPrinter implements MarkdownPrinter { - private str: string = ''; - private readonly highlighter: Highlighter; - - constructor(highlighter: Highlighter) { - this.highlighter = highlighter; - - // Remove line numbers from codeblocks - this.style('.linenodiv{ display: none }'); - } - - private line(line: string = '') { - this.str += `${line}\n`; - } - - text(text: string) { - this.line(text); - this.line(); - } - - style(style: string) { - this.line(''); - } - - header(level: number, text: string, id?: string) { - this.line(`${'#'.repeat(level)} ${text}${id ? ` {#${id}}` : ''}`); - this.line(); - } - - headerLink(heading: string, id?: string): string { - return `#${id ?? heading}`; - } - - indexLink() { - return '../'; - } - - pageLink(name: string) { - return `./${name}/`; - } - - srcLink( - { file, lineInFile }: { file: string; lineInFile: number }, - text?: string, - ): string { - const linkText = text ?? `${file}:${lineInFile}`; - const href = `${GH_BASE_URL}/blob/${COMMIT_SHA}/${file}#L${lineInFile}`; - return `[${linkText}](${href})`; - } - - paragraph(...text: string[]) { - this.line( - text - .join('\n') - .trim() - .split('\n') - .map(line => line.trim()) - .join('\n'), - ); - this.line(); - } - - code({ text, links = [] }: { text: string; links?: TypeLink[] }) { - this.line('
'); - this.line( - '
', - ); - this.line('
');
-    this.line(this.formatWithLinks({ text, links }));
-    this.line('
'); - this.line('
'); - this.line('
'); - } - - private escapeText: (text: string) => string = (() => { - const escapes: { [char in string]: string } = { - '&': '&', - '<': '<', - '>': '>', - }; - - return (text: string) => text.replace(/[&<>]/g, char => escapes[char]); - })(); - - private formatWithLinks({ - text, - links = [], - }: { - text: string; - links?: TypeLink[]; - }): string { - const sortedLinks = links.slice().sort(sortSelector(x => x.location[0])); - - sortedLinks.reduce((lastEnd, link) => { - if (link.location[0] <= lastEnd) { - throw new Error( - `overlapping link detected for ${link.path}, ${link.location}`, - ); - } - return link.location[1]; - }, -1); - - const parts: Array<{ text: string; path?: string }> = []; - - const endLocation = sortedLinks.reduce((prev, link) => { - const [start, end] = link.location; - parts.push( - { text: text.slice(prev, start) }, - { text: text.slice(start, end), path: link.path }, - ); - return end; - }, 0); - - parts.push({ text: text.slice(endLocation) }); - - return parts - .map(part => { - if (part.path) { - const link = this.headerLink(part.text, part.path); - return `${this.escapeText(part.text)}`; - } - return this.highlighter.highlight(this.escapeText(part.text)); - }) - .join(''); - } - - toBuffer(): Buffer { - return Buffer.from(this.str, 'utf8'); - } -} diff --git a/packages/docgen/src/docgen/TypeLocator.test.ts b/packages/docgen/src/docgen/TypeLocator.test.ts deleted file mode 100644 index 8988b25814..0000000000 --- a/packages/docgen/src/docgen/TypeLocator.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import ts from 'typescript'; -import TypeLocator from './TypeLocator'; -import { createMemProgram } from './testUtils'; - -describe('TypeLocator', () => { - it('should find a default export', () => { - const program = createMemProgram('export default class MyApi {}'); - - const typeLocator = TypeLocator.fromProgram(program, '/mem'); - - const apiType = typeLocator.getExportedType('/mem/index.ts'); - expect(apiType.symbol.name).toBe('default'); - const [declaration] = apiType.symbol.declarations; - expect(declaration.kind).toBe(ts.SyntaxKind.ClassDeclaration); - expect((declaration as ts.ClassDeclaration).name).toBeDefined(); - expect((declaration as ts.ClassDeclaration).name!.text).toBe('MyApi'); - }, 10000); - - it('should find api instance export', () => { - const program = createMemProgram( - ` - import MyApi from './type'; - - type MyApiType = {}; - - export const myApi = new MyApi(); - `, - { - '/mem/type.ts': 'export default class MyApi {}', - }, - ); - - const typeLocator = TypeLocator.fromProgram(program, '/mem'); - - const { apiInstances } = typeLocator.findExportedInstances({ - apiInstances: typeLocator.getExportedType('/mem/type.ts'), - }); - - expect(apiInstances.length).toBe(1); - const [apiInstance] = apiInstances; - expect(apiInstance.name).toBe('myApi'); - expect(apiInstance.source.fileName).toBe('/mem/index.ts'); - expect(apiInstance.args).toEqual([]); - - expect(apiInstance.typeArgs.length).toBe(1); - const [typeArg] = apiInstance.typeArgs; - expect(typeArg.kind).toBe(ts.SyntaxKind.TypeReference); - expect((typeArg as ts.TypeReferenceNode).typeName.getText()).toBe( - 'MyApiType', - ); - }); -}); diff --git a/packages/docgen/src/docgen/TypeLocator.ts b/packages/docgen/src/docgen/TypeLocator.ts deleted file mode 100644 index adec0c2a42..0000000000 --- a/packages/docgen/src/docgen/TypeLocator.ts +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import ts from 'typescript'; -import { ExportedInstance } from './types'; - -/** - * The TypeLocator is used to extract typescrint Type structures from a compiled program, - * as well as finding locations where types are used in according to a matching pattern. - * - * This is used to e.g. find exported APIs that we should generate documentation for. - */ -export default class TypeLocator { - static fromProgram(program: ts.Program, sourcePath: string) { - return new TypeLocator(program.getTypeChecker(), program, sourcePath); - } - - constructor( - private readonly checker: ts.TypeChecker, - private readonly program: ts.Program, - private readonly sourcePath: string, - ) {} - - /** - * Get the type of a symbol by export path and name - */ - getExportedType(path: string, exportedName: string = 'default'): ts.Type { - const source = this.program.getSourceFile(path); - if (!source) { - throw new Error(`Source not found for path '${path}'`); - } - const exported = this.checker.getExportsOfModule( - this.checker.getSymbolAtLocation(source)!, - ); - const [symbol] = exported.filter(e => e.name === exportedName); - if (!symbol) { - throw new Error(`No export '${exportedName}' found in ${path}`); - } - const type = this.checker.getTypeOfSymbolAtLocation(symbol, source); - return type; - } - - /** - * Find exported instances and return values from calls using the types - * provided in the lookup table. - */ - findExportedInstances(typeLookupTable: { - [key in T]: ts.Type; - }): { [key in T]: ExportedInstance[] } { - const docMap = new Map(); - for (const type of Object.values(typeLookupTable)) { - docMap.set(type, []); - } - - this.program.getSourceFiles().forEach(source => { - const inRoot = source.fileName.startsWith(this.sourcePath); - if (!inRoot) { - return; - } - ts.forEachChild(source, node => { - const decl = this.getExportedConstructorDeclaration(node); - if (!decl || !docMap.has(decl.constructorType)) { - return; - } - - docMap.get(decl.constructorType)!.push({ node, source, ...decl }); - }); - }); - - const result: { [key in T]?: ExportedInstance[] } = {}; - - for (const key in typeLookupTable) { - if (typeLookupTable.hasOwnProperty(key)) { - const type = typeLookupTable[key]; - result[key] = docMap.get(type)!; - } - } - - return result as { [key in T]: ExportedInstance[] }; - } - - private getExportedConstructorDeclaration(node: ts.Node): - | { - constructorType: ts.Type; - args: ts.Expression[]; - typeArgs: ts.TypeNode[]; - name: string; - } - | undefined { - if (!ts.isVariableStatement(node)) { - return undefined; - } - if ( - !node.modifiers || - !node.modifiers.some(mod => mod.kind === ts.SyntaxKind.ExportKeyword) - ) { - return undefined; - } - const { declarations } = node.declarationList; - if (declarations.length !== 1) { - return undefined; - } - - const [declaration] = declarations; - const { initializer, name } = declaration; - - if (!initializer || !name) { - return undefined; - } - if (!ts.isCallOrNewExpression(initializer)) { - return undefined; - } - if (!ts.isIdentifier(name)) { - return undefined; - } - - const constructorType = this.checker.getTypeAtLocation( - initializer.expression, - ); - const args = Array.from(initializer.arguments ?? []); - const typeNode = declaration.type; - const typeArgs = Array.from( - (typeNode && ts.isTypeReferenceNode(typeNode) - ? typeNode.typeArguments - : initializer.typeArguments) ?? [], - ); - - return { constructorType, args, typeArgs, name: name.text }; - } -} diff --git a/packages/docgen/src/docgen/TypescriptHighlighter.ts b/packages/docgen/src/docgen/TypescriptHighlighter.ts deleted file mode 100644 index ab70ea8110..0000000000 --- a/packages/docgen/src/docgen/TypescriptHighlighter.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Highlighter } from './types'; - -// Simple syntax highlighter that mimics hilite -export default class TypescriptHighlighter implements Highlighter { - private static readonly basicTypes = [ - 'boolean', - 'number', - 'string', - 'Array', - 'object', - 'Record', - 'Set', - 'Map', - 'true', - 'false', - 'null', - 'undefined', - 'void', - 'Promise', - 'any', - '[0-9\\.]+', - ]; - - // List of highlightings to apply, each with a match regex and the style that should be applied - private static readonly highlighters = [ - [/(\/\*\*?(?:.|\n)+?\*\/)/g, 'color: #60a0b0; font-style: italic'], // block comment - [/(\/\/.*)/gm, 'color: #60a0b0; font-style: italic'], // line comment - [/('[^']*?'|"[^"]*?")/g, 'color: #4070a0'], // string literals - [ - new RegExp( - `\\b(${TypescriptHighlighter.basicTypes.join('|')})\\b(?!:|,)`, - 'g', - ), - 'color: #902000', - ], // basic types - [ - /^((?:export\s)?(?:type\s)?(?:interface\s)?)/g, - 'color: #007020; font-weight: bold', - ], // keywords - ] as readonly [RegExp, string][]; - - highlight(fullText: string): string { - // Each part is either plain text that can be highlighted or text that is already highlighted - type HighlightPart = { text: string; highlighted?: boolean }; - - const painter = (regex: RegExp, style: string) => (part: HighlightPart) => { - if (part.highlighted) { - return [part]; - } - // Apply highlighting to all matches of the regex by splitting into parts - return part.text.split(regex).map((text, index) => { - // Odd parts are the ones that matched the regex and should be highlighted. - if (index % 2 === 1) { - return { - text: `${text}`, - highlighted: true, - }; - } - return { text }; - }); - }; - - // Order here is important, e.g. comments must be first to avoid string literals inside comments being highlighted - return TypescriptHighlighter.highlighters - .reduce( - (parts, highlighter) => parts.flatMap(painter(...highlighter)), - [{ text: fullText }], - ) - .map(({ text }) => text) - .join(''); - } -} diff --git a/packages/docgen/src/docgen/sortSelector.test.ts b/packages/docgen/src/docgen/sortSelector.test.ts deleted file mode 100644 index 277b06faa5..0000000000 --- a/packages/docgen/src/docgen/sortSelector.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import sortSelector from './sortSelector'; - -describe('sortSelector', () => { - it('should stable sort', () => { - const arr = [ - [3, 1], - [1, 2], - [1, 1], - [1, 3], - [2, 1], - ]; - - const sortedByFirst = arr.slice().sort(sortSelector(([first]) => first)); - expect(sortedByFirst).toEqual([ - [1, 2], - [1, 1], - [1, 3], - [2, 1], - [3, 1], - ]); - - const sortedBySecond = arr - .slice() - .sort(sortSelector(([, second]) => second)); - expect(sortedBySecond).toEqual([ - [3, 1], - [1, 1], - [2, 1], - [1, 2], - [1, 3], - ]); - }); -}); diff --git a/packages/docgen/src/docgen/sortSelector.ts b/packages/docgen/src/docgen/sortSelector.ts deleted file mode 100644 index e8cb577ba5..0000000000 --- a/packages/docgen/src/docgen/sortSelector.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * The sortSelector is a utility that makes a sort function by selecting the value to sort on with a lambda. - */ -export default function sortSelector( - selector: (x: T) => any, -): (a: T, b: T) => -1 | 1 | 0 { - return (a: T, b: T) => { - const aV = selector(a); - const bV = selector(b); - if (aV < bV) { - return -1; - } else if (aV > bV) { - return 1; - } - return 0; - }; -} diff --git a/packages/docgen/src/docgen/testUtils.ts b/packages/docgen/src/docgen/testUtils.ts deleted file mode 100644 index c449dd7461..0000000000 --- a/packages/docgen/src/docgen/testUtils.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import ts from 'typescript'; - -export function createMemProgram( - indexSource: string, - otherSourceFiles: { [fileName in string]: string } = {}, -): ts.Program { - const rootDir = '/mem'; - - const options = { noEmit: true }; - const baseHost = ts.createCompilerHost(options); - const files: { [fileName in string]: string } = { - [`${rootDir}/index.ts`]: indexSource, - ...otherSourceFiles, - }; - - // Custom compiler hosts that reads from a map of in-memory files, but - // falls back to reading from disc for ts libs etc. - const compilerHost: ts.CompilerHost = { - ...baseHost, - readFile(fileName): string | undefined { - if (fileName in files) { - return files[fileName]; - } - return baseHost.readFile(fileName); - }, - getCurrentDirectory(): string { - return rootDir; - }, - directoryExists(dir) { - if (dir === rootDir) { - return true; - } - if (baseHost.directoryExists) { - return baseHost.directoryExists(dir); - } - return false; - }, - fileExists(fileName: string): boolean { - return !!files[fileName] || baseHost.fileExists(fileName); - }, - getSourceFile(fileName, ...rest): ts.SourceFile | undefined { - const file = files[fileName]; - if (file) { - return ts.createSourceFile(fileName, file, ts.ScriptTarget.ES2017); - } - return baseHost.getSourceFile(fileName, ...rest); - }, - }; - - return ts.createProgram(['/mem/index.ts'], options, compilerHost); -} diff --git a/packages/docgen/src/docgen/types.ts b/packages/docgen/src/docgen/types.ts deleted file mode 100644 index 60f3d35007..0000000000 --- a/packages/docgen/src/docgen/types.ts +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import ts from 'typescript'; - -/** - * A TypeLink is a link to a different type. - */ -export type TypeLink = { - // The ID of the linked type - id: number; - // The path to the type from the project root - path: string; - // The name of the type, to display - name: string; - // The location of the type name as it appears in it's parent text. - location: readonly [number, number]; -}; - -/** - * TypeInfo describes a TypeScript Type. - */ -export type TypeInfo = { - id: number; - name: string; - path: string; - file: string; - lineInFile: number; - text: string; - docs: string[]; - links: TypeLink[]; - children: TypeInfo[]; -}; - -/** - * FieldInfo describes a property or method in a documented API. - */ -export type FieldInfo = { - type: 'prop' | 'method'; - name: string; - path: string; - text: string; - docs: string[]; - links: TypeLink[]; -}; - -/** - * InterfaceInfo describes the type of a documented API. - */ -export type InterfaceInfo = { - name: string; - docs: string[]; - file: string; - lineInFile: number; - members: Array; - dependentTypes: TypeInfo[]; -}; - -/** - * ApiDoc describes a documented API. - */ -export type ApiDoc = { - id: string; - name: string; - description: string; - file: string; - lineInFile: number; - interfaceInfos: InterfaceInfo[]; -}; - -/** - * ExportedInstance describes an expression matching `export {name} = new {Contructor}<{typeArgs}...>({args}...)` - */ -export type ExportedInstance = { - node: ts.Node; - name: string; - source: ts.SourceFile; - args: Array; - typeArgs: Array; -}; - -export type Highlighter = { - highlight(test: string): string; -}; - -/** - * Markdown printer is an abstraction for printing markdown documents of different flavors. - */ -export type MarkdownPrinter = { - text(text: string): void; - header(level: number, text: string, id?: string): void; - paragraph(...text: string[]): void; - code(options: { text: string; links?: TypeLink[] }): void; - - headerLink(header: string, id?: string): string; - /** Link from pages to index */ - indexLink(): string; - /** Link from index to pages */ - pageLink(name: string): string; - srcLink( - { file, lineInFile }: { file: string; lineInFile: number }, - text?: string, - ): string; - - toBuffer(): Buffer; -}; diff --git a/packages/docgen/src/generate.ts b/packages/docgen/src/generate.ts deleted file mode 100644 index bbc18e48ab..0000000000 --- a/packages/docgen/src/generate.ts +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as ts from 'typescript'; -import fs from 'fs-extra'; -import { resolve as resolvePath, join as joinPath } from 'path'; -import ApiDocGenerator from './docgen/ApiDocGenerator'; -import sortSelector from './docgen/sortSelector'; -import TypeLocator from './docgen/TypeLocator'; -import ApiDocPrinter from './docgen/ApiDocsPrinter'; -import TypescriptHighlighter from './docgen/TypescriptHighlighter'; -import GitHubMarkdownPrinter from './docgen/GitHubMarkdownPrinter'; -import TechdocsMarkdownPrinter from './docgen/TechdocsMarkdownPrinter'; - -const FORMATS = ['github', 'techdocs'] as const; - -export async function generate( - targetPath: string, - format: typeof FORMATS[number], -) { - if (!FORMATS.includes(format)) { - throw new TypeError( - `Invalid format, '${format}', must be one of ${FORMATS.join(', ')}`, - ); - } - - /* eslint-disable-next-line no-restricted-syntax */ - const rootDir = resolvePath(__dirname, '../../..'); - const srcDir = resolvePath(rootDir, 'packages', 'core-api', 'src'); - const targetDir = resolvePath(targetPath); - - const options = await fs.readJson(resolvePath('../cli/config/tsconfig.json')); - - delete options.moduleResolution; - options.noEmit = true; - - const program = ts.createProgram([resolvePath(srcDir, 'index.ts')], options); - - const typeLocator = TypeLocator.fromProgram(program, srcDir); - - const { apis } = typeLocator.findExportedInstances({ - apis: typeLocator.getExportedType( - resolvePath(srcDir, 'index.ts'), - 'createApiRef', - ), - }); - - const apiDocGenerator = ApiDocGenerator.fromProgram(program, rootDir); - const apiDocs = apis - .map(api => { - try { - return apiDocGenerator.toDoc(api); - } catch (error) { - throw new Error( - `Doc generation failed for API in ${api.source.fileName}, ${error.stack}`, - ); - } - }) - .sort(sortSelector(x => x.name)); - - const apiTypes = Object.values( - Object.fromEntries( - apiDocs.flatMap(d => d.interfaceInfos).map(i => [i.name, i]), - ), - ).sort(sortSelector(i => i.name)); - - if (format === 'techdocs') { - const docsDir = resolvePath(targetDir, 'docs'); - await fs.ensureDir(docsDir); - - const apiDocPrinter = new ApiDocPrinter( - () => new TechdocsMarkdownPrinter(new TypescriptHighlighter()), - ); - - await fs.writeFile( - joinPath(docsDir, 'README.md'), - apiDocPrinter.printApiIndex(apiDocs), - ); - - for (const apiType of Object.values(apiTypes)) { - const data = apiDocPrinter.printInterface(apiType, apiDocs); - - await fs.writeFile(joinPath(docsDir, `${apiType.name}.md`), data); - } - - await fs.writeFile( - resolvePath(targetDir, 'mkdocs.yml'), - [ - 'site_name: Backstage Core Utility API References', - 'nav:', - ` - API Index: 'README.md'`, - ...apiTypes.map(({ name }) => ` - ${name}: '${name}.md'`), - 'plugins:', - ' - techdocs-core', - ].join('\n'), - 'utf8', - ); - } else { - await fs.ensureDir(targetDir); - - const apiDocPrinter = new ApiDocPrinter(() => new GitHubMarkdownPrinter()); - - await fs.writeFile( - joinPath(targetDir, 'README.md'), - apiDocPrinter.printApiIndex(apiDocs), - ); - - for (const apiType of Object.values(apiTypes)) { - const data = apiDocPrinter.printInterface(apiType, apiDocs); - - await fs.writeFile(joinPath(targetDir, `${apiType.name}.md`), data); - } - } -} diff --git a/packages/docgen/src/index.ts b/packages/docgen/src/index.ts deleted file mode 100644 index 755bc9cb98..0000000000 --- a/packages/docgen/src/index.ts +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import program from 'commander'; -import { resolve as resolvePath } from 'path'; -import chalk from 'chalk'; -import fs from 'fs-extra'; -import { generate } from './generate'; - -const main = (argv: string[]) => { - /* eslint-disable-next-line no-restricted-syntax */ - const pkgJson = fs.readJsonSync(resolvePath(__dirname, '../package.json')); - program.name('docgen').version(pkgJson.version); - - program - .command('generate') - .description( - 'Generate documentation for the declarations in the core-api package', - ) - .option('--output ', 'Output directory [./dist]') - .option( - '--format ', - 'Output format, either techdocs or github [techdocs]', - ) - .action(async cmd => { - await generate(cmd.output ?? './dist', cmd.format ?? 'techdocs'); - }); - - program.on('command:*', () => { - console.log(); - console.log( - chalk.red(`Invalid command: ${chalk.cyan(program.args.join(' '))}`), - ); - console.log(chalk.red('See --help for a list of available commands.')); - console.log(); - process.exit(1); - }); - - program.parse(argv); -}; - -process.on('unhandledRejection', rejection => { - console.error(String(rejection)); - process.exit(1); -}); - -main(process.argv); diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index 5e8393fc78..6b34b4a82b 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -95,7 +95,6 @@ const SKIPPED_PACKAGES = [ 'packages/cli', 'packages/codemods', 'packages/create-app', - 'packages/docgen', 'packages/e2e-test', 'packages/storybook', 'packages/techdocs-cli', From 9ae77fc3a7d861091c74d9ae435491d7072ad82e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Sep 2021 04:12:15 +0000 Subject: [PATCH 105/125] chore(deps-dev): bump @types/passport-github2 from 1.2.4 to 1.2.5 Bumps [@types/passport-github2](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/passport-github2) from 1.2.4 to 1.2.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/passport-github2) --- updated-dependencies: - dependency-name: "@types/passport-github2" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1d408ff5ae..4a77aa2dcc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7039,9 +7039,9 @@ integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== "@types/passport-github2@^1.2.4": - version "1.2.4" - resolved "https://registry.npmjs.org/@types/passport-github2/-/passport-github2-1.2.4.tgz#f56c386d1fe6435e359430e57adc1747a627bd86" - integrity sha512-dtGtA0Uyzk6ne3SrgQi/I1ClClLE3i7JmSiMaJgkGH8v1nbE9JdBpG7QWJ1XPlLdcf7EvoPdHmkWN2+Kln9y8g== + version "1.2.5" + resolved "https://registry.npmjs.org/@types/passport-github2/-/passport-github2-1.2.5.tgz#79064e213ff33ca0a9d21af3da09a3230fac8099" + integrity sha512-+WLyrd8JPsCxroK34EjegR0j3FMxp6wqB9cw/sRCFkWT9qic1dymAn021gr336EpyjzdhjUd2KKrqyxvdFSvOA== dependencies: "@types/express" "*" "@types/passport" "*" From 36bc77c709f7aec559c04cbc21f1b1056f0c77b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Sep 2021 04:15:57 +0000 Subject: [PATCH 106/125] chore(deps): bump react-hook-form from 7.12.2 to 7.15.3 Bumps [react-hook-form](https://github.com/react-hook-form/react-hook-form) from 7.12.2 to 7.15.3. - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.12.2...v7.15.3) --- updated-dependencies: - dependency-name: react-hook-form dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1d408ff5ae..1989c7ee3d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22496,9 +22496,9 @@ react-hook-form@^6.15.4: integrity sha512-prq82ofMbnRyj5wqDe8hsTRcdR25jQ+B8KtCS7BLCzjFHAwNuCjRwzPuP4eYLsEBjEIeYd6try+pdLdw0kPkpg== react-hook-form@^7.12.2: - version "7.12.2" - resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.12.2.tgz#2660afbf03c4ef360a9314ebf46ce3d972296c77" - integrity sha512-cpxocjrgpMAJCMJQR51BQhMoEx80/EQqePNihMTgoTYTqCRbd2GExi+N4GJIr+cFqrmbwNj9wxk5oLWYQsUefg== + version "7.15.3" + resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.15.3.tgz#7d222dcfd43137be127dca2843149f09bd25d4b1" + integrity sha512-z30aZoEHkWE8oZvad4OcYSBI0kQua/T5sFGH9tB2HfeykFnP/pGXNap8lDio4/U1yPj2ffpbvRIvqKd/6jjBVA== react-hot-loader@^4.12.21: version "4.13.0" From 3aea283beef8de1abbcb967a54fae36ba8c02be1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Sep 2021 04:17:08 +0000 Subject: [PATCH 107/125] chore(deps-dev): bump @types/http-proxy from 1.17.5 to 1.17.7 Bumps [@types/http-proxy](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/http-proxy) from 1.17.5 to 1.17.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/http-proxy) --- updated-dependencies: - dependency-name: "@types/http-proxy" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1d408ff5ae..2eaa12b384 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6703,9 +6703,9 @@ "@types/node" "*" "@types/http-proxy@*", "@types/http-proxy@^1.17.4", "@types/http-proxy@^1.17.5": - version "1.17.5" - resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.5.tgz#c203c5e6e9dc6820d27a40eb1e511c70a220423d" - integrity sha512-GNkDE7bTv6Sf8JbV2GksknKOsk7OznNYHSdrtvPJXO0qJ9odZig6IZKUi5RFGi6d1bf6dgIAe4uXi3DBc7069Q== + version "1.17.7" + resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.7.tgz#30ea85cc2c868368352a37f0d0d3581e24834c6f" + integrity sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w== dependencies: "@types/node" "*" From 01bd068fb7be8ec6436c4dbdb4946a37cd7b269c Mon Sep 17 00:00:00 2001 From: irma12 Date: Mon, 13 Sep 2021 09:21:29 +0200 Subject: [PATCH 108/125] Remove contained from button Signed-off-by: irma12 --- .../components/OAuthRequestDialog/OAuthRequestDialog.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx b/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx index 14b0789ff8..e4434a4339 100644 --- a/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx +++ b/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx @@ -40,7 +40,7 @@ const useStyles = makeStyles(theme => ({ padding: 0, }, actionButtons: { - padding: theme.spacing(2), + padding: theme.spacing(2, 0), }, })); @@ -82,9 +82,7 @@ export const OAuthRequestDialog = () => { - + ); From 1c6dff7501089de08c249d21e40d84e43edf982d Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 13 Sep 2021 10:15:35 +0200 Subject: [PATCH 109/125] chore: reworking the types a little bit here to get them to work with the new version Signed-off-by: blam --- .../StepPrepareCreatePullRequest/AutocompleteTextField.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/AutocompleteTextField.tsx b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/AutocompleteTextField.tsx index a2da75edd4..63115b69b0 100644 --- a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/AutocompleteTextField.tsx +++ b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/AutocompleteTextField.tsx @@ -25,7 +25,7 @@ type Props = { options: string[]; required?: boolean; - errors?: FieldErrors>; + errors?: FieldErrors; rules?: React.ComponentProps['rules']; loading?: boolean; @@ -37,7 +37,7 @@ type Props = { textFieldProps?: Omit; }; -export const AutocompleteTextField = ({ +export const AutocompleteTextField = ({ name, options, required, From 8c63332b22b72a710c54933ddf949c9c99eeed0e Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 13 Sep 2021 10:23:56 +0200 Subject: [PATCH 110/125] chore: running prettier on top of the documentation Signed-off-by: blam --- .../software-catalog/extending-the-model.md | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/docs/features/software-catalog/extending-the-model.md b/docs/features/software-catalog/extending-the-model.md index 5895cfaa12..ed106bb5dd 100644 --- a/docs/features/software-catalog/extending-the-model.md +++ b/docs/features/software-catalog/extending-the-model.md @@ -401,11 +401,31 @@ Example intent: > "I have multiple versions of my API deployed in different environments so I > want to have `mytool-dev` and `mytool-prod` as different entities." -While it's possible to have different versions of the same thing represented -as separate entities, it's something we generally recommend against. We believe that a -developer should be able to just find for example one `Component` representing a service, and to be able to see the -different code versions that are deployed throughout your stack within its view. This reasoning works similarly for other kinds as well, such as `API`. +While it's possible to have different versions of the same thing represented as +separate entities, it's something we generally recommend against. We believe +that a developer should be able to just find for example one `Component` +representing a service, and to be able to see the different code versions that +are deployed throughout your stack within its view. This reasoning works +similarly for other kinds as well, such as `API`. -That being said - sometimes the differences between versions are so large, that they represent what is for all intents and purposes an entirely new entity as seen from the consumer's point of view. This can happen for example for different _significant_ major versions of an API, and in particular if the two major versions coexist in the ecosystem for some time. In those cases, it can be motivated to have one `my-api-v2` and one `my-api-v3` named entity. This matches the end user's expectations when searching for the API, and matches the desire to maybe have separate documentation for the two and similar. But use this sparingly - only do it if the extra modelling burden is outweighed by any potential better clarity for users. +That being said - sometimes the differences between versions are so large, that +they represent what is for all intents and purposes an entirely new entity as +seen from the consumer's point of view. This can happen for example for +different _significant_ major versions of an API, and in particular if the two +major versions coexist in the ecosystem for some time. In those cases, it can be +motivated to have one `my-api-v2` and one `my-api-v3` named entity. This matches +the end user's expectations when searching for the API, and matches the desire +to maybe have separate documentation for the two and similar. But use this +sparingly - only do it if the extra modelling burden is outweighed by any +potential better clarity for users. -When writing your custom plugins, we encourage designing them such that they can show all the different variations through environments etc under one canonical reference to your software in the catalog. For example for a continuous deployment plugin, a user is likely to be greatly helped by being able to see the entity's versions deployed in all different environments next to each other in one view. That is also where they might be offered the ability to promote from one environment to the other, do rollbacks, see their relative performance metrics, and similar. This coherency and collection of tooling in one place is where something like Backstage can offer the most value and effectiveness of use. Splitting your entities apart into small islands makes this harder. +When writing your custom plugins, we encourage designing them such that they can +show all the different variations through environments etc under one canonical +reference to your software in the catalog. For example for a continuous +deployment plugin, a user is likely to be greatly helped by being able to see +the entity's versions deployed in all different environments next to each other +in one view. That is also where they might be offered the ability to promote +from one environment to the other, do rollbacks, see their relative performance +metrics, and similar. This coherency and collection of tooling in one place is +where something like Backstage can offer the most value and effectiveness of +use. Splitting your entities apart into small islands makes this harder. From 509cde8892af8b61f0fece1f109d784eb7309dc9 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 13 Sep 2021 10:31:27 +0200 Subject: [PATCH 111/125] chore: reverting the smol changes to the public API Signed-off-by: blam --- .../StepPrepareCreatePullRequest/AutocompleteTextField.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/AutocompleteTextField.tsx b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/AutocompleteTextField.tsx index 63115b69b0..98d741df15 100644 --- a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/AutocompleteTextField.tsx +++ b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/AutocompleteTextField.tsx @@ -37,7 +37,7 @@ type Props = { textFieldProps?: Omit; }; -export const AutocompleteTextField = ({ +export const AutocompleteTextField = ({ name, options, required, From 8cb54a22bc5ee0e7d0a495c0d7093ef56f19cfb0 Mon Sep 17 00:00:00 2001 From: Ben Lambert Date: Mon, 13 Sep 2021 11:12:26 +0200 Subject: [PATCH 112/125] Fix changeset Signed-off-by: Ben Lambert --- .changeset/grumpy-beds-design.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/grumpy-beds-design.md b/.changeset/grumpy-beds-design.md index 3e15e9c5ea..afca4e0eb3 100644 --- a/.changeset/grumpy-beds-design.md +++ b/.changeset/grumpy-beds-design.md @@ -1,5 +1,5 @@ --- -"@backstage/plugin-user-settings": patch +'@backstage/plugin-user-settings': patch --- -Fix import for createPlugin in example snippet +Fix import for `createPlugin` in example snippet From 048f479fc30ebf481d9f85ef0d7c1e907dc3f3a8 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 13 Sep 2021 12:11:45 +0200 Subject: [PATCH 113/125] cli: ignore some more ReDos vulnerabilities Signed-off-by: Patrik Oldsberg --- packages/cli/.snyk | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/packages/cli/.snyk b/packages/cli/.snyk index 8fbbfa574c..119cb19e7e 100644 --- a/packages/cli/.snyk +++ b/packages/cli/.snyk @@ -7,4 +7,52 @@ ignore: reason: Developer tools are not a valid target for ReDoS attacks expires: 2022-03-06T17:18:55.019Z created: 2021-09-06T17:18:55.027Z + + SNYK-JS-ANSIREGEX-1583908: + - '*': + reason: Developer tools are not a valid target for ReDoS attacks + expires: 2022-03-06T17:18:55.019Z + created: 2021-09-06T17:18:55.027Z + + SNYK-JS-CSSWHAT-1298035: + - '*': + reason: Developer tools are not a valid target for ReDoS attacks + expires: 2022-03-06T17:18:55.019Z + created: 2021-09-06T17:18:55.027Z + + SNYK-JS-BROWSERSLIST-1090194: + - '*': + reason: Developer tools are not a valid target for ReDoS attacks + expires: 2022-03-06T17:18:55.019Z + created: 2021-09-06T17:18:55.027Z + + SNYK-JS-ISSVG-1243891: + - '*': + reason: Developer tools are not a valid target for ReDoS attacks + expires: 2022-03-06T17:18:55.019Z + created: 2021-09-06T17:18:55.027Z + + SNYK-JS-ISSVG-1085627: + - '*': + reason: Developer tools are not a valid target for ReDoS attacks + expires: 2022-03-06T17:18:55.019Z + created: 2021-09-06T17:18:55.027Z + + SNYK-JS-POSTCSS-1255640: + - '*': + reason: Developer tools are not a valid target for ReDoS attacks + expires: 2022-03-06T17:18:55.019Z + created: 2021-09-06T17:18:55.027Z + + SNYK-JS-POSTCSS-1090595: + - '*': + reason: Developer tools are not a valid target for ReDoS attacks + expires: 2022-03-06T17:18:55.019Z + created: 2021-09-06T17:18:55.027Z + + SNYK-JS-WS-1296835: + - '*': + reason: Developer tools are not a valid target for ReDoS attacks + expires: 2022-03-06T17:18:55.019Z + created: 2021-09-06T17:18:55.027Z patch: {} From 299966d9bf97c731276266d87bcec03379f67151 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 13 Sep 2021 12:19:55 +0200 Subject: [PATCH 114/125] yarn.lock: bump y18n Signed-off-by: Patrik Oldsberg --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1d408ff5ae..0856a88020 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27739,14 +27739,14 @@ y18n@^3.2.1: integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + version "4.0.3" + resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== y18n@^5.0.5: - version "5.0.5" - resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" - integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== + version "5.0.8" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yallist@^2.1.2: version "2.1.2" From 8fda212c48eaced6d695b1092985834f545b69da Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 13 Sep 2021 12:20:10 +0200 Subject: [PATCH 115/125] cli: ignore some prototype pollution vulnerabilities Signed-off-by: Patrik Oldsberg --- packages/cli/.snyk | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/cli/.snyk b/packages/cli/.snyk index 119cb19e7e..612b4b0525 100644 --- a/packages/cli/.snyk +++ b/packages/cli/.snyk @@ -55,4 +55,16 @@ ignore: reason: Developer tools are not a valid target for ReDoS attacks expires: 2022-03-06T17:18:55.019Z created: 2021-09-06T17:18:55.027Z + + SNYK-JS-IMMER-1540542: + - '*': + reason: Prototype pollution is not an effective attack against a CLI as it already executes arbitrary code + expires: 2022-03-06T17:18:55.019Z + created: 2021-09-06T17:18:55.027Z + + SNYK-JS-SETVALUE-1540541: + - '*': + reason: Prototype pollution is not an effective attack against a CLI as it already executes arbitrary code + expires: 2022-03-06T17:18:55.019Z + created: 2021-09-06T17:18:55.027Z patch: {} From 0db5cce1630d41cd091db9efba812706eb0090be Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 13 Sep 2021 12:38:11 +0200 Subject: [PATCH 116/125] yarn.lock: bump thenify Signed-off-by: Patrik Oldsberg --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0856a88020..f7f8f57fc0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25750,9 +25750,9 @@ thenify-all@^1.0.0: thenify ">= 3.1.0 < 4" "thenify@>= 3.1.0 < 4": - version "3.3.0" - resolved "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" - integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk= + version "3.3.1" + resolved "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== dependencies: any-promise "^1.0.0" From f848618987a4bd2ead210b757a92102a32230390 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 13 Sep 2021 12:51:09 +0200 Subject: [PATCH 117/125] test-utils: ignore some vulnerabilities Signed-off-by: Patrik Oldsberg --- packages/test-utils/.snyk | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 packages/test-utils/.snyk diff --git a/packages/test-utils/.snyk b/packages/test-utils/.snyk new file mode 100644 index 0000000000..7737037634 --- /dev/null +++ b/packages/test-utils/.snyk @@ -0,0 +1,17 @@ +# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. +version: v1.22.1 +# ignores vulnerabilities until expiry date; change duration by modifying expiry date +ignore: + SNYK-JS-ANSIREGEX-1583908: + - '*': + reason: Self-inflicted ReDos in tests is not an issue + expires: 2022-03-06T17:18:55.019Z + created: 2021-09-06T17:18:55.027Z + + SNYK-JS-XMLDOM-1534562: + - 'msw@0.29.0 > @mswjs/interceptors@0.10.0 > xmldom@0.6.0': + reason: Self-inflicted XML injection attacks in tests is not an issue + expires: 2022-03-06T17:18:55.019Z + created: 2021-09-06T17:18:55.027Z + +patch: {} From a76040bc5c21466caa7d3e87c0d783869433a89f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 13 Sep 2021 12:58:42 +0200 Subject: [PATCH 118/125] yarn.lock: bump strip-ansi and ansi-regex Signed-off-by: Patrik Oldsberg --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index f7f8f57fc0..a050671f5c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8297,10 +8297,10 @@ ansi-regex@^5.0.0: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== -ansi-regex@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.0.tgz#ecc7f5933cbe5ac7b33e209a5ff409ab1669c6b2" - integrity sha512-tAaOSrWCHF+1Ear1Z4wnJCXA9GGox4K6Ic85a5qalES2aeEwQGr7UC93mwef49536PkCYjzkp0zIxfFvexJ6zQ== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== ansi-styles@^2.2.1: version "2.2.1" @@ -25090,11 +25090,11 @@ strip-ansi@^4.0.0: ansi-regex "^3.0.0" strip-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.0.tgz#1dc49b980c3a4100366617adac59327eefdefcb0" - integrity sha512-UhDTSnGF1dc0DRbUqr1aXwNoY3RgVkSWG8BrpnuFIxhP57IqbS7IRta2Gfiavds4yCxc5+fEAVVOgBZWnYkvzg== + version "7.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" + integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== dependencies: - ansi-regex "^6.0.0" + ansi-regex "^6.0.1" strip-bom@^2.0.0: version "2.0.0" From 1da51fec2b8949c7f4007f4939ce761c0fb46f9f Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Mon, 13 Sep 2021 13:53:14 +0200 Subject: [PATCH 119/125] Adjust dependencies to `@types/react` and `react-router` to follow the pattern used by all other Backstage packages Signed-off-by: Oliver Sand --- .changeset/techdocs-small-bugs-exist.md | 6 ++++++ plugins/home/package.json | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 .changeset/techdocs-small-bugs-exist.md diff --git a/.changeset/techdocs-small-bugs-exist.md b/.changeset/techdocs-small-bugs-exist.md new file mode 100644 index 0000000000..5e7c01c1a4 --- /dev/null +++ b/.changeset/techdocs-small-bugs-exist.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-home': patch +--- + +Adjust dependencies to `@types/react` and `react-router` to follow the pattern +used by all other Backstage packages. diff --git a/plugins/home/package.json b/plugins/home/package.json index 8ae92e8ace..8fe7826e2e 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -26,10 +26,10 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", - "@types/react": "^16.9", + "@types/react": "*", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-router": "^6.0.0-beta.0", + "react-router": "6.0.0-beta.0", "react-use": "^17.2.4" }, "devDependencies": { From 8b1db3ecfe9a0e9167fb48d1be9df9b18600e06c Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Mon, 13 Sep 2021 13:53:27 +0200 Subject: [PATCH 120/125] Fix mistake in readme Signed-off-by: Oliver Sand --- plugins/home/README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/home/README.md b/plugins/home/README.md index a09c85775b..42cd88b879 100644 --- a/plugins/home/README.md +++ b/plugins/home/README.md @@ -43,9 +43,14 @@ import { HomepageCompositionRoot } from '@backstage/plugin-home'; import { HomePage } from './components/home/HomePage'; // ... -}> - -; + + + + } +/>; // ... ``` From 5aab2fc7c36216db2a03f0295f1dee632369573e Mon Sep 17 00:00:00 2001 From: Shivam Bisht Date: Mon, 13 Sep 2021 13:07:41 +0530 Subject: [PATCH 121/125] adding search and pagination to new Relic component Signed-off-by: Shivam Bisht --- .../NewRelicFetchComponent/NewRelicFetchComponent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/newrelic/src/components/NewRelicFetchComponent/NewRelicFetchComponent.tsx b/plugins/newrelic/src/components/NewRelicFetchComponent/NewRelicFetchComponent.tsx index 72945155fc..40f82d4beb 100644 --- a/plugins/newrelic/src/components/NewRelicFetchComponent/NewRelicFetchComponent.tsx +++ b/plugins/newrelic/src/components/NewRelicFetchComponent/NewRelicFetchComponent.tsx @@ -54,7 +54,7 @@ export const NewRelicAPMTable = ({ applications }: NewRelicApplications) => { return ( From be455f10250aa6dae7aba120531527ca18018217 Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Mon, 13 Sep 2021 14:38:30 +0200 Subject: [PATCH 122/125] Restore readme Signed-off-by: Oliver Sand --- plugins/home/README.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/plugins/home/README.md b/plugins/home/README.md index 42cd88b879..a09c85775b 100644 --- a/plugins/home/README.md +++ b/plugins/home/README.md @@ -43,14 +43,9 @@ import { HomepageCompositionRoot } from '@backstage/plugin-home'; import { HomePage } from './components/home/HomePage'; // ... - - - - } -/>; +}> + +; // ... ``` From a41ac6b95216f6a53355c94043cfae078ae77b7c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 13 Sep 2021 15:37:08 +0200 Subject: [PATCH 123/125] catalog-backend: add missing type exports Signed-off-by: Patrik Oldsberg --- .changeset/perfect-keys-hide.md | 5 + plugins/catalog-backend/api-report.md | 370 +++++++++++++++--- plugins/catalog-backend/src/catalog/index.ts | 13 +- plugins/catalog-backend/src/database/index.ts | 8 + .../catalog-backend/src/ingestion/index.ts | 15 +- .../processors/LocationEntityProcessor.ts | 4 +- .../processors/PlaceholderProcessor.test.ts | 14 +- .../processors/PlaceholderProcessor.ts | 31 +- .../src/ingestion/processors/index.ts | 10 +- .../catalog-backend/src/ingestion/types.ts | 6 +- .../src/next/NextCatalogBuilder.ts | 16 +- .../catalog-backend/src/next/NextRouter.ts | 4 +- plugins/catalog-backend/src/next/index.ts | 4 + .../src/next/processing/index.ts | 1 + plugins/catalog-backend/src/search/index.ts | 1 + plugins/catalog-backend/src/service/index.ts | 1 + 16 files changed, 415 insertions(+), 88 deletions(-) create mode 100644 .changeset/perfect-keys-hide.md diff --git a/.changeset/perfect-keys-hide.md b/.changeset/perfect-keys-hide.md new file mode 100644 index 0000000000..cab9967363 --- /dev/null +++ b/.changeset/perfect-keys-hide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Fill in most missing type exports. diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md index 01a824d049..9d542c674d 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/api-report.md @@ -40,6 +40,36 @@ export type AddLocationResult = { entities: Entity[]; }; +// Warning: (ae-missing-release-tag) "AnalyzeLocationEntityField" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type AnalyzeLocationEntityField = { + field: string; + state: + | 'analysisSuggestedValue' + | 'analysisSuggestedNoValue' + | 'needsUserInput'; + value: string | null; + description: string; +}; + +// Warning: (ae-missing-release-tag) "AnalyzeLocationExistingEntity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type AnalyzeLocationExistingEntity = { + location: LocationSpec; + isRegistered: boolean; + entity: Entity; +}; + +// Warning: (ae-missing-release-tag) "AnalyzeLocationGenerateEntity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type AnalyzeLocationGenerateEntity = { + entity: RecursivePartial; + fields: AnalyzeLocationEntityField[]; +}; + // Warning: (ae-missing-release-tag) "AnalyzeLocationRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -111,8 +141,6 @@ export class AwsOrganizationCloudAccountProcessor implements CatalogProcessor { normalizeName(name: string): string; // (undocumented) organizations: Organizations; - // Warning: (ae-forgotten-export) The symbol "AwsOrganizationProviderConfig" needs to be exported by the entry point index.d.ts - // // (undocumented) provider: AwsOrganizationProviderConfig; // (undocumented) @@ -123,6 +151,13 @@ export class AwsOrganizationCloudAccountProcessor implements CatalogProcessor { ): Promise; } +// Warning: (ae-missing-release-tag) "AwsOrganizationProviderConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type AwsOrganizationProviderConfig = { + roleArn?: string; +}; + // Warning: (ae-missing-release-tag) "BitbucketDiscoveryProcessor" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -186,8 +221,6 @@ export class CatalogBuilder { higherOrderOperation: HigherOrderOperation; locationAnalyzer: LocationAnalyzer; }>; - // Warning: (ae-forgotten-export) The symbol "CatalogEnvironment" needs to be exported by the entry point index.d.ts - // // (undocumented) static create(env: CatalogEnvironment): Promise; // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen @@ -206,6 +239,42 @@ export class CatalogBuilder { ): CatalogBuilder; } +// Warning: (ae-missing-release-tag) "CatalogEntityDocument" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface CatalogEntityDocument extends IndexableDocument { + // (undocumented) + componentType: string; + // (undocumented) + kind: string; + // (undocumented) + lifecycle: string; + // (undocumented) + namespace: string; + // (undocumented) + owner: string; +} + +// Warning: (ae-missing-release-tag) "CatalogEnvironment" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type CatalogEnvironment = { + logger: Logger_2; + database: PluginDatabaseManager; + config: Config; + reader: UrlReader; +}; + +// Warning: (ae-missing-release-tag) "CatalogProcessingEngine" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface CatalogProcessingEngine { + // (undocumented) + start(): Promise; + // (undocumented) + stop(): Promise; +} + // Warning: (ae-missing-release-tag) "CatalogProcessingOrchestrator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -332,15 +401,11 @@ export class CommonDatabase implements Database { txOpaque: Transaction, request: DbEntityRequest[], ): Promise; - // Warning: (ae-forgotten-export) The symbol "DbLocationsRow" needs to be exported by the entry point index.d.ts - // // (undocumented) addLocation( txOpaque: Transaction, location: Location_2, ): Promise; - // Warning: (ae-forgotten-export) The symbol "DatabaseLocationUpdateLogStatus" needs to be exported by the entry point index.d.ts - // // (undocumented) addLocationUpdateLogEvent( locationId: string, @@ -348,9 +413,6 @@ export class CommonDatabase implements Database { entityName?: string | string[], message?: string, ): Promise; - // Warning: (ae-forgotten-export) The symbol "DbEntitiesRequest" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "DbEntitiesResponse" needs to be exported by the entry point index.d.ts - // // (undocumented) entities( txOpaque: Transaction, @@ -366,12 +428,8 @@ export class CommonDatabase implements Database { txOpaque: Transaction, uid: string, ): Promise; - // Warning: (ae-forgotten-export) The symbol "DbLocationsRowWithStatus" needs to be exported by the entry point index.d.ts - // // (undocumented) location(id: string): Promise; - // Warning: (ae-forgotten-export) The symbol "DatabaseLocationUpdateLogEvent" needs to be exported by the entry point index.d.ts - // // (undocumented) locationHistory(id: string): Promise; // (undocumented) @@ -397,12 +455,18 @@ export class CommonDatabase implements Database { ): Promise; } -// Warning: (ae-forgotten-export) The symbol "RouterOptions" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "CreateDatabaseOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type CreateDatabaseOptions = { + logger: Logger_2; +}; + // Warning: (ae-missing-release-tag) "createNextRouter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function createNextRouter( - options: RouterOptions_2, + options: NextRouterOptions, ): Promise; // Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag @@ -471,9 +535,6 @@ export type Database = { // @public (undocumented) export class DatabaseEntitiesCatalog implements EntitiesCatalog { constructor(database: Database, logger: Logger_2); - // Warning: (ae-forgotten-export) The symbol "EntityUpsertRequest" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "EntityUpsertResponse" needs to be exported by the entry point index.d.ts - // // (undocumented) batchAddOrUpdateEntities( requests: EntityUpsertRequest[], @@ -483,9 +544,6 @@ export class DatabaseEntitiesCatalog implements EntitiesCatalog { outputEntities?: boolean; }, ): Promise; - // Warning: (ae-forgotten-export) The symbol "EntitiesRequest" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "EntitiesResponse" needs to be exported by the entry point index.d.ts - // // (undocumented) entities(request?: EntitiesRequest): Promise; // (undocumented) @@ -503,8 +561,6 @@ export class DatabaseLocationsCatalog implements LocationsCatalog { location(id: string): Promise; // (undocumented) locationHistory(id: string): Promise; - // Warning: (ae-forgotten-export) The symbol "LocationResponse" needs to be exported by the entry point index.d.ts - // // (undocumented) locations(): Promise; // (undocumented) @@ -522,12 +578,32 @@ export class DatabaseLocationsCatalog implements LocationsCatalog { removeLocation(id: string): Promise; } +// Warning: (ae-missing-release-tag) "DatabaseLocationUpdateLogEvent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type DatabaseLocationUpdateLogEvent = { + id: string; + status: DatabaseLocationUpdateLogStatus; + location_id: string; + entity_name: string; + created_at?: string; + message?: string; +}; + +// Warning: (ae-missing-release-tag) "DatabaseLocationUpdateLogStatus" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export enum DatabaseLocationUpdateLogStatus { + // (undocumented) + FAIL = 'fail', + // (undocumented) + SUCCESS = 'success', +} + // Warning: (ae-missing-release-tag) "DatabaseManager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export class DatabaseManager { - // Warning: (ae-forgotten-export) The symbol "CreateDatabaseOptions" needs to be exported by the entry point index.d.ts - // // (undocumented) static createDatabase( knex: Knex, @@ -543,6 +619,22 @@ export class DatabaseManager { static createTestDatabaseConnection(): Promise; } +// Warning: (ae-missing-release-tag) "DbEntitiesRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type DbEntitiesRequest = { + filter?: EntityFilter; + pagination?: EntityPagination; +}; + +// Warning: (ae-missing-release-tag) "DbEntitiesResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type DbEntitiesResponse = { + entities: DbEntityResponse[]; + pageInfo: DbPageInfo; +}; + // Warning: (ae-missing-release-tag) "DbEntityRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -560,6 +652,36 @@ export type DbEntityResponse = { entity: Entity; }; +// Warning: (ae-missing-release-tag) "DbLocationsRow" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type DbLocationsRow = { + id: string; + type: string; + target: string; +}; + +// Warning: (ae-missing-release-tag) "DbLocationsRowWithStatus" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type DbLocationsRowWithStatus = DbLocationsRow & { + status: string | null; + timestamp: string | null; + message: string | null; +}; + +// Warning: (ae-missing-release-tag) "DbPageInfo" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type DbPageInfo = + | { + hasNextPage: false; + } + | { + hasNextPage: true; + endCursor: string; + }; + // Warning: (ae-missing-release-tag) "DefaultCatalogCollator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -584,8 +706,6 @@ export class DefaultCatalogCollator implements DocumentCollator { protected readonly catalogClient: CatalogApi; // (undocumented) protected discovery: PluginEndpointDiscovery; - // Warning: (ae-forgotten-export) The symbol "CatalogEntityDocument" needs to be exported by the entry point index.d.ts - // // (undocumented) execute(): Promise; // (undocumented) @@ -621,6 +741,14 @@ export class DefaultCatalogProcessingOrchestrator process(request: EntityProcessingRequest): Promise; } +// Warning: (ae-missing-release-tag) "DeferredEntity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type DeferredEntity = { + entity: Entity; + locationKey?: string; +}; + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // Warning: (ae-missing-release-tag) "durationText" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -643,6 +771,23 @@ export type EntitiesCatalog = { ): Promise; }; +// Warning: (ae-missing-release-tag) "EntitiesRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type EntitiesRequest = { + filter?: EntityFilter; + fields?: (entity: Entity) => Entity; + pagination?: EntityPagination; +}; + +// Warning: (ae-missing-release-tag) "EntitiesResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type EntitiesResponse = { + entities: Entity[]; + pageInfo: PageInfo; +}; + // Warning: (ae-missing-release-tag) "EntitiesSearchFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @@ -735,6 +880,22 @@ export type EntityProviderMutation = removed: DeferredEntity[]; }; +// Warning: (ae-missing-release-tag) "EntityUpsertRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type EntityUpsertRequest = { + entity: Entity; + relations: EntityRelationSpec[]; +}; + +// Warning: (ae-missing-release-tag) "EntityUpsertResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type EntityUpsertResponse = { + entityId: string; + entity?: Entity; +}; + // Warning: (ae-missing-release-tag) "FileReaderProcessor" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -900,8 +1061,7 @@ export type LocationAnalyzer = { // // @public (undocumented) export class LocationEntityProcessor implements CatalogProcessor { - // Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts - constructor(options: Options_3); + constructor(options: LocationEntityProcessorOptions); // (undocumented) postProcessEntity( entity: Entity, @@ -910,6 +1070,13 @@ export class LocationEntityProcessor implements CatalogProcessor { ): Promise; } +// Warning: (ae-missing-release-tag) "LocationEntityProcessorOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type LocationEntityProcessorOptions = { + integrations: ScmIntegrationRegistry; +}; + // Warning: (ae-missing-release-tag) "LocationReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -927,6 +1094,14 @@ export class LocationReaders implements LocationReader { read(location: LocationSpec): Promise; } +// Warning: (ae-missing-release-tag) "LocationResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type LocationResponse = { + data: Location_2; + currentStatus: LocationUpdateStatus; +}; + // Warning: (ae-missing-release-tag) "LocationsCatalog" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -947,12 +1122,66 @@ export type LocationsCatalog = { ): Promise; }; +// Warning: (ae-missing-release-tag) "LocationService" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface LocationService { + // (undocumented) + createLocation( + spec: LocationSpec, + dryRun: boolean, + ): Promise<{ + location: Location_2; + entities: Entity[]; + }>; + // (undocumented) + deleteLocation(id: string): Promise; + // (undocumented) + getLocation(id: string): Promise; + // (undocumented) + listLocations(): Promise; +} + +// Warning: (ae-missing-release-tag) "LocationStore" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface LocationStore { + // (undocumented) + createLocation(spec: LocationSpec): Promise; + // (undocumented) + deleteLocation(id: string): Promise; + // (undocumented) + getLocation(id: string): Promise; + // (undocumented) + listLocations(): Promise; +} + +// Warning: (ae-missing-release-tag) "LocationUpdateLogEvent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type LocationUpdateLogEvent = { + id: string; + status: 'fail' | 'success'; + location_id: string; + entity_name: string; + created_at?: string; + message?: string; +}; + +// Warning: (ae-missing-release-tag) "LocationUpdateStatus" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type LocationUpdateStatus = { + timestamp: string | null; + status: string | null; + message: string | null; +}; + // Warning: (ae-missing-release-tag) "NextCatalogBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public export class NextCatalogBuilder { - // Warning: (ae-forgotten-export) The symbol "CatalogEnvironment" needs to be exported by the entry point index.d.ts - constructor(env: CatalogEnvironment_2); + constructor(env: CatalogEnvironment); // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen addEntityPolicy(...policies: EntityPolicy[]): NextCatalogBuilder; // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen @@ -986,6 +1215,22 @@ export class NextCatalogBuilder { setRefreshIntervalSeconds(seconds: number): NextCatalogBuilder; } +// Warning: (ae-missing-release-tag) "NextRouterOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface NextRouterOptions { + // (undocumented) + config: Config; + // (undocumented) + entitiesCatalog?: EntitiesCatalog; + // (undocumented) + locationAnalyzer?: LocationAnalyzer; + // (undocumented) + locationService: LocationService; + // (undocumented) + logger: Logger_2; +} + // Warning: (ae-missing-release-tag) "notFoundError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -994,6 +1239,18 @@ function notFoundError( message: string, ): CatalogProcessorResult; +// Warning: (ae-missing-release-tag) "PageInfo" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type PageInfo = + | { + hasNextPage: false; + } + | { + hasNextPage: true; + endCursor: string; + }; + // Warning: (ae-missing-release-tag) "parseEntityYaml" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1006,20 +1263,51 @@ export function parseEntityYaml( // // @public export class PlaceholderProcessor implements CatalogProcessor { - // Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts - constructor(options: Options_4); + constructor(options: PlaceholderProcessorOptions); // (undocumented) preProcessEntity(entity: Entity, location: LocationSpec): Promise; } -// Warning: (ae-forgotten-export) The symbol "ResolverParams" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "PlaceholderProcessorOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type PlaceholderProcessorOptions = { + resolvers: Record; + reader: UrlReader; + integrations: ScmIntegrationRegistry; +}; + // Warning: (ae-missing-release-tag) "PlaceholderResolver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type PlaceholderResolver = ( - params: ResolverParams, + params: PlaceholderResolverParams, ) => Promise; +// Warning: (ae-missing-release-tag) "PlaceholderResolverParams" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type PlaceholderResolverParams = { + key: string; + value: JsonValue; + baseUrl: string; + read: PlaceholderResolverRead; + resolveUrl: PlaceholderResolverResolveUrl; +}; + +// Warning: (ae-missing-release-tag) "PlaceholderResolverRead" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type PlaceholderResolverRead = (url: string) => Promise; + +// Warning: (ae-missing-release-tag) "PlaceholderResolverResolveUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type PlaceholderResolverResolveUrl = ( + url: string, + base: string, +) => string; + // Warning: (ae-missing-release-tag) "ReadLocationEntity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1132,7 +1420,7 @@ export type Transaction = { // @public (undocumented) export class UrlReaderProcessor implements CatalogProcessor { // Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts - constructor(options: Options_5); + constructor(options: Options_3); // (undocumented) readLocation( location: LocationSpec, @@ -1150,7 +1438,6 @@ export class UrlReaderProcessor implements CatalogProcessor { // src/catalog/types.d.ts:43:8 - (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters // src/catalog/types.d.ts:44:8 - (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters // src/catalog/types.d.ts:45:8 - (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters -// src/catalog/types.d.ts:75:5 - (ae-forgotten-export) The symbol "LocationUpdateLogEvent" needs to be exported by the entry point index.d.ts // src/database/types.d.ts:125:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/database/types.d.ts:131:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/database/types.d.ts:132:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen @@ -1179,11 +1466,6 @@ export class UrlReaderProcessor implements CatalogProcessor { // src/ingestion/processors/types.d.ts:58:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/ingestion/types.d.ts:17:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/ingestion/types.d.ts:41:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/ingestion/types.d.ts:49:5 - (ae-forgotten-export) The symbol "AnalyzeLocationExistingEntity" needs to be exported by the entry point index.d.ts -// src/ingestion/types.d.ts:50:5 - (ae-forgotten-export) The symbol "AnalyzeLocationGenerateEntity" needs to be exported by the entry point index.d.ts -// src/next/NextCatalogBuilder.d.ts:147:9 - (ae-forgotten-export) The symbol "CatalogProcessingEngine" needs to be exported by the entry point index.d.ts -// src/next/NextCatalogBuilder.d.ts:148:9 - (ae-forgotten-export) The symbol "LocationService" needs to be exported by the entry point index.d.ts -// src/next/processing/types.d.ts:11:5 - (ae-forgotten-export) The symbol "DeferredEntity" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-backend/src/catalog/index.ts b/plugins/catalog-backend/src/catalog/index.ts index bc33031d67..04cc358568 100644 --- a/plugins/catalog-backend/src/catalog/index.ts +++ b/plugins/catalog-backend/src/catalog/index.ts @@ -16,4 +16,15 @@ export { DatabaseEntitiesCatalog } from './DatabaseEntitiesCatalog'; export { DatabaseLocationsCatalog } from './DatabaseLocationsCatalog'; -export type { EntitiesCatalog, LocationsCatalog } from './types'; +export type { + EntitiesCatalog, + LocationsCatalog, + EntityUpsertRequest, + EntityUpsertResponse, + EntitiesRequest, + EntitiesResponse, + LocationResponse, + PageInfo, + LocationUpdateLogEvent, + LocationUpdateStatus, +} from './types'; diff --git a/plugins/catalog-backend/src/database/index.ts b/plugins/catalog-backend/src/database/index.ts index 1a07f3825f..028b0caa4b 100644 --- a/plugins/catalog-backend/src/database/index.ts +++ b/plugins/catalog-backend/src/database/index.ts @@ -16,6 +16,7 @@ export { CommonDatabase } from './CommonDatabase'; export { DatabaseManager } from './DatabaseManager'; +export type { CreateDatabaseOptions } from './DatabaseManager'; export type { Database, DbEntityRequest, @@ -24,4 +25,11 @@ export type { EntityFilter, EntityPagination, Transaction, + DbEntitiesRequest, + DbEntitiesResponse, + DbLocationsRowWithStatus, + DatabaseLocationUpdateLogEvent, + DbLocationsRow, + DatabaseLocationUpdateLogStatus, + DbPageInfo, } from './types'; diff --git a/plugins/catalog-backend/src/ingestion/index.ts b/plugins/catalog-backend/src/ingestion/index.ts index eace66b220..e27a3ef0ac 100644 --- a/plugins/catalog-backend/src/ingestion/index.ts +++ b/plugins/catalog-backend/src/ingestion/index.ts @@ -16,5 +16,18 @@ export { HigherOrderOperations } from './HigherOrderOperations'; export { LocationReaders } from './LocationReaders'; -export * from './types'; +export type { + AddLocationResult, + AnalyzeLocationRequest, + AnalyzeLocationResponse, + HigherOrderOperation, + LocationAnalyzer, + LocationReader, + ReadLocationEntity, + ReadLocationError, + ReadLocationResult, + AnalyzeLocationEntityField, + AnalyzeLocationExistingEntity, + AnalyzeLocationGenerateEntity, +} from './types'; export * from './processors'; diff --git a/plugins/catalog-backend/src/ingestion/processors/LocationEntityProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/LocationEntityProcessor.ts index 964a769e55..c6b7def5fc 100644 --- a/plugins/catalog-backend/src/ingestion/processors/LocationEntityProcessor.ts +++ b/plugins/catalog-backend/src/ingestion/processors/LocationEntityProcessor.ts @@ -38,12 +38,12 @@ export function toAbsoluteUrl( } } -type Options = { +export type LocationEntityProcessorOptions = { integrations: ScmIntegrationRegistry; }; export class LocationEntityProcessor implements CatalogProcessor { - constructor(private readonly options: Options) {} + constructor(private readonly options: LocationEntityProcessorOptions) {} async postProcessEntity( entity: Entity, diff --git a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts index c60b01d53d..c7a49353ae 100644 --- a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts +++ b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts @@ -21,8 +21,8 @@ import { jsonPlaceholderResolver, PlaceholderProcessor, PlaceholderResolver, - ResolverParams, - ResolverRead, + PlaceholderResolverParams, + PlaceholderResolverRead, textPlaceholderResolver, yamlPlaceholderResolver, } from './PlaceholderProcessor'; @@ -30,7 +30,7 @@ import { const integrations = ScmIntegrations.fromConfig(new ConfigReader({})); describe('PlaceholderProcessor', () => { - const read: jest.MockedFunction = jest.fn(); + const read: jest.MockedFunction = jest.fn(); const reader: UrlReader = { read, readTree: jest.fn(), search: jest.fn() }; beforeEach(() => { @@ -353,8 +353,8 @@ describe('PlaceholderProcessor', () => { }); describe('yamlPlaceholderResolver', () => { - const read: jest.MockedFunction = jest.fn(); - const params: ResolverParams = { + const read: jest.MockedFunction = jest.fn(); + const params: PlaceholderResolverParams = { key: 'a', value: './file.yaml', baseUrl: 'https://github.com/backstage/backstage/a/b/catalog-info.yaml', @@ -398,8 +398,8 @@ describe('yamlPlaceholderResolver', () => { }); describe('jsonPlaceholderResolver', () => { - const read: jest.MockedFunction = jest.fn(); - const params: ResolverParams = { + const read: jest.MockedFunction = jest.fn(); + const params: PlaceholderResolverParams = { key: 'a', value: './file.json', baseUrl: 'https://github.com/backstage/backstage/a/b/catalog-info.yaml', diff --git a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts index 611e166605..9ddef1ab3b 100644 --- a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts +++ b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts @@ -21,22 +21,25 @@ import { ScmIntegrationRegistry } from '@backstage/integration'; import yaml from 'yaml'; import { CatalogProcessor } from './types'; -export type ResolverRead = (url: string) => Promise; -export type ResolverResolveUrl = (url: string, base: string) => string; +export type PlaceholderResolverRead = (url: string) => Promise; +export type PlaceholderResolverResolveUrl = ( + url: string, + base: string, +) => string; -export type ResolverParams = { +export type PlaceholderResolverParams = { key: string; value: JsonValue; baseUrl: string; - read: ResolverRead; - resolveUrl: ResolverResolveUrl; + read: PlaceholderResolverRead; + resolveUrl: PlaceholderResolverResolveUrl; }; export type PlaceholderResolver = ( - params: ResolverParams, + params: PlaceholderResolverParams, ) => Promise; -type Options = { +export type PlaceholderProcessorOptions = { resolvers: Record; reader: UrlReader; integrations: ScmIntegrationRegistry; @@ -47,7 +50,7 @@ type Options = { * that it then fills in with actual data. */ export class PlaceholderProcessor implements CatalogProcessor { - constructor(private readonly options: Options) {} + constructor(private readonly options: PlaceholderProcessorOptions) {} async preProcessEntity( entity: Entity, @@ -135,7 +138,7 @@ export class PlaceholderProcessor implements CatalogProcessor { */ export async function yamlPlaceholderResolver( - params: ResolverParams, + params: PlaceholderResolverParams, ): Promise { const text = await readTextLocation(params); @@ -166,7 +169,7 @@ export async function yamlPlaceholderResolver( } export async function jsonPlaceholderResolver( - params: ResolverParams, + params: PlaceholderResolverParams, ): Promise { const text = await readTextLocation(params); @@ -180,7 +183,7 @@ export async function jsonPlaceholderResolver( } export async function textPlaceholderResolver( - params: ResolverParams, + params: PlaceholderResolverParams, ): Promise { return await readTextLocation(params); } @@ -189,7 +192,9 @@ export async function textPlaceholderResolver( * Helpers */ -async function readTextLocation(params: ResolverParams): Promise { +async function readTextLocation( + params: PlaceholderResolverParams, +): Promise { const newUrl = relativeUrl(params); try { @@ -207,7 +212,7 @@ function relativeUrl({ value, baseUrl, resolveUrl, -}: ResolverParams): string { +}: PlaceholderResolverParams): string { if (typeof value !== 'string') { throw new Error( `Placeholder \$${key} expected a string value parameter, in the form of an absolute URL or a relative path`, diff --git a/plugins/catalog-backend/src/ingestion/processors/index.ts b/plugins/catalog-backend/src/ingestion/processors/index.ts index fe4d374829..fbdadba667 100644 --- a/plugins/catalog-backend/src/ingestion/processors/index.ts +++ b/plugins/catalog-backend/src/ingestion/processors/index.ts @@ -19,6 +19,7 @@ import * as results from './results'; export { AnnotateLocationEntityProcessor } from './AnnotateLocationEntityProcessor'; export { AnnotateScmSlugEntityProcessor } from './AnnotateScmSlugEntityProcessor'; export { AwsOrganizationCloudAccountProcessor } from './AwsOrganizationCloudAccountProcessor'; +export type { AwsOrganizationProviderConfig } from './awsOrganization/config'; export { BitbucketDiscoveryProcessor } from './BitbucketDiscoveryProcessor'; export { BuiltinKindsEntityProcessor } from './BuiltinKindsEntityProcessor'; export { CodeOwnersProcessor } from './CodeOwnersProcessor'; @@ -28,8 +29,15 @@ export { GithubOrgReaderProcessor } from './GithubOrgReaderProcessor'; export { GithubMultiOrgReaderProcessor } from './GithubMultiOrgReaderProcessor'; export { GitLabDiscoveryProcessor } from './GitLabDiscoveryProcessor'; export { LocationEntityProcessor } from './LocationEntityProcessor'; +export type { LocationEntityProcessorOptions } from './LocationEntityProcessor'; export { PlaceholderProcessor } from './PlaceholderProcessor'; -export type { PlaceholderResolver } from './PlaceholderProcessor'; +export type { + PlaceholderProcessorOptions, + PlaceholderResolver, + PlaceholderResolverParams, + PlaceholderResolverRead, + PlaceholderResolverResolveUrl, +} from './PlaceholderProcessor'; export { StaticLocationProcessor } from './StaticLocationProcessor'; export * from './types'; export { UrlReaderProcessor } from './UrlReaderProcessor'; diff --git a/plugins/catalog-backend/src/ingestion/types.ts b/plugins/catalog-backend/src/ingestion/types.ts index 297234b3b4..eb7b84e95f 100644 --- a/plugins/catalog-backend/src/ingestion/types.ts +++ b/plugins/catalog-backend/src/ingestion/types.ts @@ -99,7 +99,7 @@ export type AnalyzeLocationResponse = { // read and emitted like this so that the frontend can inform the user that it // located them and can make sure to register them as well if they weren't // already -type AnalyzeLocationExistingEntity = { +export type AnalyzeLocationExistingEntity = { location: LocationSpec; isRegistered: boolean; entity: Entity; @@ -110,7 +110,7 @@ type AnalyzeLocationExistingEntity = { // the frontend. It'll probably contain a (possibly incomplete) entity, plus // enough info for the frontend to know what form data to show to the user // for overriding/completing the info. -type AnalyzeLocationGenerateEntity = { +export type AnalyzeLocationGenerateEntity = { // Some form of partial representation of the entity entity: RecursivePartial; // Lists the suggestions that the user may want to override @@ -120,7 +120,7 @@ type AnalyzeLocationGenerateEntity = { // This is where I get really vague. Something like this perhaps? Or it could be // something like a json-schema that contains enough info for the frontend to // be able to present a form and explanations -type AnalyzeLocationEntityField = { +export type AnalyzeLocationEntityField = { // e.g. "spec.owner"? The frontend needs to know how to "inject" the field into the // entity again if the user wants to change it field: string; diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index 262df7525e..fa43286777 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -14,11 +14,7 @@ * limitations under the License. */ -import { - PluginDatabaseManager, - resolvePackagePath, - UrlReader, -} from '@backstage/backend-common'; +import { resolvePackagePath } from '@backstage/backend-common'; import { DefaultNamespaceEntityPolicy, EntityPolicies, @@ -29,11 +25,9 @@ import { SchemaValidEntityPolicy, Validators, } from '@backstage/catalog-model'; -import { Config } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { createHash } from 'crypto'; import lodash from 'lodash'; -import { Logger } from 'winston'; import { DatabaseLocationsCatalog, EntitiesCatalog, @@ -80,13 +74,7 @@ import { createRandomRefreshInterval, RefreshIntervalFunction, } from './refresh'; - -export type CatalogEnvironment = { - logger: Logger; - database: PluginDatabaseManager; - config: Config; - reader: UrlReader; -}; +import { CatalogEnvironment } from '../service/CatalogBuilder'; /** * A builder that helps wire up all of the component parts of the catalog. diff --git a/plugins/catalog-backend/src/next/NextRouter.ts b/plugins/catalog-backend/src/next/NextRouter.ts index 849d2ee36d..99073be421 100644 --- a/plugins/catalog-backend/src/next/NextRouter.ts +++ b/plugins/catalog-backend/src/next/NextRouter.ts @@ -36,7 +36,7 @@ import { import { disallowReadonlyMode, validateRequestBody } from '../service/util'; import { LocationService } from './types'; -export interface RouterOptions { +export interface NextRouterOptions { entitiesCatalog?: EntitiesCatalog; locationAnalyzer?: LocationAnalyzer; locationService: LocationService; @@ -45,7 +45,7 @@ export interface RouterOptions { } export async function createNextRouter( - options: RouterOptions, + options: NextRouterOptions, ): Promise { const { entitiesCatalog, locationAnalyzer, locationService, config, logger } = options; diff --git a/plugins/catalog-backend/src/next/index.ts b/plugins/catalog-backend/src/next/index.ts index 2afdff63fb..cdd81d9f4d 100644 --- a/plugins/catalog-backend/src/next/index.ts +++ b/plugins/catalog-backend/src/next/index.ts @@ -16,6 +16,7 @@ export { NextCatalogBuilder } from './NextCatalogBuilder'; export { createNextRouter } from './NextRouter'; +export type { NextRouterOptions } from './NextRouter'; export * from './processing'; export { createRandomRefreshInterval } from './refresh'; export type { RefreshIntervalFunction } from './refresh'; @@ -24,4 +25,7 @@ export type { EntityProvider, EntityProviderConnection, EntityProviderMutation, + CatalogProcessingEngine, + LocationService, + LocationStore, } from './types'; diff --git a/plugins/catalog-backend/src/next/processing/index.ts b/plugins/catalog-backend/src/next/processing/index.ts index e2f5a99507..9e03f18f28 100644 --- a/plugins/catalog-backend/src/next/processing/index.ts +++ b/plugins/catalog-backend/src/next/processing/index.ts @@ -18,5 +18,6 @@ export type { CatalogProcessingOrchestrator, EntityProcessingRequest, EntityProcessingResult, + DeferredEntity, } from './types'; export { DefaultCatalogProcessingOrchestrator } from './DefaultCatalogProcessingOrchestrator'; diff --git a/plugins/catalog-backend/src/search/index.ts b/plugins/catalog-backend/src/search/index.ts index dfe1cf541e..5641670333 100644 --- a/plugins/catalog-backend/src/search/index.ts +++ b/plugins/catalog-backend/src/search/index.ts @@ -15,3 +15,4 @@ */ export { DefaultCatalogCollator } from './DefaultCatalogCollator'; +export type { CatalogEntityDocument } from './DefaultCatalogCollator'; diff --git a/plugins/catalog-backend/src/service/index.ts b/plugins/catalog-backend/src/service/index.ts index baf3f499d7..865e611de4 100644 --- a/plugins/catalog-backend/src/service/index.ts +++ b/plugins/catalog-backend/src/service/index.ts @@ -15,5 +15,6 @@ */ export { CatalogBuilder } from './CatalogBuilder'; +export type { CatalogEnvironment } from './CatalogBuilder'; export { createRouter } from './router'; export type { RouterOptions } from './router'; From 52a5a46372db04aa886f9601b2a32bd4af6bd179 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 13 Sep 2021 15:54:28 +0200 Subject: [PATCH 124/125] changeset: added a changeset for new relic plugin Signed-off-by: blam --- .changeset/hot-otters-taste.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/hot-otters-taste.md diff --git a/.changeset/hot-otters-taste.md b/.changeset/hot-otters-taste.md new file mode 100644 index 0000000000..1e41f980f1 --- /dev/null +++ b/.changeset/hot-otters-taste.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-newrelic': patch +--- + +Added pagination and searching to the table From 0671a8b71ca79e02fd3e9d9a49740fb8cbd47830 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 13 Sep 2021 19:18:15 +0200 Subject: [PATCH 125/125] workflows: upload snyk report to GitHub Signed-off-by: Patrik Oldsberg --- .github/workflows/snyk-monitor.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/snyk-monitor.yml b/.github/workflows/snyk-monitor.yml index 89a32a4429..0adb6c5bcb 100644 --- a/.github/workflows/snyk-monitor.yml +++ b/.github/workflows/snyk-monitor.yml @@ -31,3 +31,21 @@ jobs: --remote-repo-url=https://github.com/backstage/backstage env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + + # Above we run the `monitor` command, this runs the `test` command which is + # the one that generates the SARIF report that we can upload to GitHub. + - name: Create Snyk report + uses: snyk/actions/node@master + continue-on-error: true # To make sure that SARIF upload gets called + with: + args: > + --yarn-workspaces + --org=backstage-dgh + --strict-out-of-sync=false + --sarif-file-output=snyk.sarif + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + - name: Upload Snyk report + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: snyk.sarif
-
- logo -

- Edit src/App.tsx and save to reload. -

-
- Learn React - -
-