diff --git a/.changeset/angry-phones-wash.md b/.changeset/angry-phones-wash.md new file mode 100644 index 0000000000..ac59a924a2 --- /dev/null +++ b/.changeset/angry-phones-wash.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-devtools': patch +--- + +Allow specifying custom title for `DevToolsLayout` diff --git a/.changeset/cli-always-yarn-pack-freal.md b/.changeset/cli-always-yarn-pack-freal.md new file mode 100644 index 0000000000..b58ffea857 --- /dev/null +++ b/.changeset/cli-always-yarn-pack-freal.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Fixed the `--alwaysYarnPack` flag on the`backstage-cli build-workspace` command. diff --git a/.changeset/cyan-shirts-deny.md b/.changeset/cyan-shirts-deny.md new file mode 100644 index 0000000000..d6d3a2a2ba --- /dev/null +++ b/.changeset/cyan-shirts-deny.md @@ -0,0 +1,10 @@ +--- +'@backstage/plugin-catalog-unprocessed-entities': patch +--- + +The Catalog Unprocessed Entities plugin can now be integrated as a tab within the DevTools plugin + +- Added an export for `UnprocessedEntitiesContent` +- Updated the `README` with images of the features +- Adjusted the styles to fill in the available space +- Set the table page size to 20 as 40 was causing errors in the browser console diff --git a/.changeset/dirty-wasps-draw.md b/.changeset/dirty-wasps-draw.md new file mode 100644 index 0000000000..5686191cab --- /dev/null +++ b/.changeset/dirty-wasps-draw.md @@ -0,0 +1,5 @@ +--- +'@backstage/errors': patch +--- + +Set `this.name` in all error classes that extend `CustomErrorBase` class to their actual name diff --git a/.changeset/dull-onions-remember.md b/.changeset/dull-onions-remember.md new file mode 100644 index 0000000000..f309bf5c4c --- /dev/null +++ b/.changeset/dull-onions-remember.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-stackstorm': patch +--- + +Add props to StackstormHome for Header Customization diff --git a/.changeset/green-otters-wait.md b/.changeset/green-otters-wait.md new file mode 100644 index 0000000000..02bc30f6aa --- /dev/null +++ b/.changeset/green-otters-wait.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-catalog-unprocessed-entities': patch +--- + +Export some types and API items. This allows people to call the API from different places with the ApiRef, as well +as completely customize the client if required. Check the [README.md](https://github.com/backstage/backstage/blob/master/plugins/catalog-unprocessed-entities/README.md) to +note what needs to be added in order to use the new `catalogUnprocessedEntitiesApiRef` exported function. diff --git a/.changeset/lazy-frogs-destroy.md b/.changeset/lazy-frogs-destroy.md new file mode 100644 index 0000000000..eb2b320e0a --- /dev/null +++ b/.changeset/lazy-frogs-destroy.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-devtools': patch +--- + +Updated the `README` with instructions on how to integrate the Catalog Unprocessed Entities plugin as a tab within DevTools diff --git a/.changeset/many-ants-poke.md b/.changeset/many-ants-poke.md new file mode 100644 index 0000000000..e6d94fdee5 --- /dev/null +++ b/.changeset/many-ants-poke.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +use `Readable.from` to explicitly convert the `buffer` from `node-fetch` to a `Readable` stream diff --git a/.changeset/mighty-shoes-refuse.md b/.changeset/mighty-shoes-refuse.md new file mode 100644 index 0000000000..ec17e5e357 --- /dev/null +++ b/.changeset/mighty-shoes-refuse.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-dynatrace': patch +--- + +updated the link that the "View Entity in Dynatrace" redirects the user to. diff --git a/.changeset/old-rules-give.md b/.changeset/old-rules-give.md new file mode 100644 index 0000000000..e28e2778ed --- /dev/null +++ b/.changeset/old-rules-give.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog-backend-module-unprocessed': patch +'@backstage/plugin-catalog-unprocessed-entities': patch +--- + +Fix and improve documentation for the unprocessed entities modules. diff --git a/.changeset/popular-kangaroos-accept.md b/.changeset/popular-kangaroos-accept.md new file mode 100644 index 0000000000..c297b3220f --- /dev/null +++ b/.changeset/popular-kangaroos-accept.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-home': patch +--- + +fix: update plugin home dependency for `@rjsf/material-ui` to `@rjsf/material-ui-v5` diff --git a/.changeset/purple-starfishes-design.md b/.changeset/purple-starfishes-design.md new file mode 100644 index 0000000000..d10602ee3d --- /dev/null +++ b/.changeset/purple-starfishes-design.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-catalog-backend-module-github': patch +'@backstage/core-components': patch +'@backstage/plugin-playlist': patch +'@backstage/plugin-nomad': patch +--- + +Break some internal circular import chains diff --git a/.changeset/short-rabbits-roll.md b/.changeset/short-rabbits-roll.md new file mode 100644 index 0000000000..4ed0768485 --- /dev/null +++ b/.changeset/short-rabbits-roll.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-entity-feedback-backend': patch +--- + +Added support for the new backend system diff --git a/.changeset/sour-humans-begin.md b/.changeset/sour-humans-begin.md new file mode 100644 index 0000000000..1f090f1c89 --- /dev/null +++ b/.changeset/sour-humans-begin.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog-backend': minor +'@backstage/plugin-catalog-node': minor +--- + +Support placeholder resolvers in the CatalogPlugin, also moves `PlaceholderResolver` and related types from `@backstage/plugin-catalog-backend` to `@backstage/plugin-catalog-node`. diff --git a/.changeset/tough-flowers-suffer.md b/.changeset/tough-flowers-suffer.md new file mode 100644 index 0000000000..784d331107 --- /dev/null +++ b/.changeset/tough-flowers-suffer.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +--- + +Update readme with a valid link to k8s documentation diff --git a/.changeset/twenty-seas-float.md b/.changeset/twenty-seas-float.md new file mode 100644 index 0000000000..3ee79ba4e5 --- /dev/null +++ b/.changeset/twenty-seas-float.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Fix keyboard navigation & focus highlight on Select component. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 33097b505a..82a9eb499d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -39,6 +39,9 @@ yarn.lock @backstage/maintainers @back /plugins/code-coverage-backend @backstage/maintainers @alde @nissayeva /plugins/cost-insights @backstage/maintainers @backstage/silver-lining /plugins/cost-insights-* @backstage/maintainers @backstage/silver-lining +/plugins/devtools @backstage/maintainers @awanlin +/plugins/devtools-backend @backstage/maintainers @awanlin +/plugins/devtools-common @backstage/maintainers @awanlin /plugins/entity-feedback @backstage/maintainers @kuangp /plugins/entity-feedback-* @backstage/maintainers @kuangp /plugins/events-backend @backstage/maintainers @pjungermann @@ -64,6 +67,9 @@ yarn.lock @backstage/maintainers @back /plugins/kafka-backend @backstage/maintainers @nirga @andrewthauer /plugins/kubernetes @backstage/maintainers @backstage/kubernetes-maintainers /plugins/kubernetes-* @backstage/maintainers @backstage/kubernetes-maintainers +/plugins/linguist @backstage/maintainers @awanlin +/plugins/linguist-backend @backstage/maintainers @awanlin +/plugins/linguist-common @backstage/maintainers @awanlin /plugins/microsoft-calendar @backstage/maintainers @abhay-soni-developer @NishkarshRaj /plugins/newrelic-dashboard @backstage/maintainers @mufaddal7 /plugins/permission-* @backstage/permission-maintainers diff --git a/cypress/yarn.lock b/cypress/yarn.lock index 36dd0b056d..290f441c4c 100644 --- a/cypress/yarn.lock +++ b/cypress/yarn.lock @@ -1230,13 +1230,13 @@ __metadata: linkType: hard "semver@npm:^7.3.2": - version: 7.3.7 - resolution: "semver@npm:7.3.7" + version: 7.5.3 + resolution: "semver@npm:7.5.3" dependencies: lru-cache: ^6.0.0 bin: semver: bin/semver.js - checksum: 2fa3e877568cd6ce769c75c211beaed1f9fce80b28338cadd9d0b6c40f2e2862bafd62c19a6cff42f3d54292b7c623277bcab8816a2b5521cf15210d43e75232 + checksum: 9d58db16525e9f749ad0a696a1f27deabaa51f66e91d2fa2b0db3de3e9644e8677de3b7d7a03f4c15bc81521e0c3916d7369e0572dbde250d9bedf5194e2a8a7 languageName: node linkType: hard diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index 1c9825d5ca..0be2bf0292 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -351,7 +351,7 @@ component, like `java` or `go`. This field is optional, and currently has no special semantics. -Each tag must be sequences of `[a-z0-9]` separated by `-`, at most 63 characters +Each tag must be sequences of `[a-z0-9:+#]` separated by `-`, at most 63 characters in total. ### `links` [optional] diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md index f04940a418..c2f14d0ca0 100644 --- a/docs/features/software-templates/writing-custom-actions.md +++ b/docs/features/software-templates/writing-custom-actions.md @@ -4,8 +4,8 @@ title: Writing Custom Actions description: How to write your own actions --- -If you're wanting to extend the functionality of the Scaffolder, you can do so -by writing custom actions which can be used along side our +If you want to extend the functionality of the Scaffolder, you can do so +by writing custom actions which can be used alongside our [built-in actions](./builtin-actions.md). > Note: When adding custom actions, the actions array will **replace the @@ -65,7 +65,7 @@ The `createTemplateAction` takes an object which specifies the following: - `schema.input` - A `zod` or JSON schema object for input values to your function - `schema.output` - A `zod` or JSON schema object for values which are output from the function using `ctx.output` -- `handler` - the actual code which is run part of the action, with a context +- `handler` - the actual code which is run as part of the action, with a context You can also choose to define your custom action using JSON schema instead of `zod`: diff --git a/docs/getting-started/homepage.md b/docs/getting-started/homepage.md index 9c6f6380a1..04dfb13d6a 100644 --- a/docs/getting-started/homepage.md +++ b/docs/getting-started/homepage.md @@ -40,7 +40,7 @@ Inside your `packages/app` directory, create a new file where our new homepage c ```tsx import React from 'react'; -export const homePage = ( +export const HomePage = () => ( /* We will shortly compose a pretty homepage here. */

Welcome to Backstage!

); diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md index 820f5ef394..773b5bd5a2 100644 --- a/docs/getting-started/index.md +++ b/docs/getting-started/index.md @@ -53,6 +53,8 @@ create a subdirectory inside your current working directory. npx @backstage/create-app@latest ``` +> Note: If this fails on the `yarn install` step, it's likely that you will need to install some additional dependencies which are used to configure `isolated-vm`. You can find out more in their [requirements section](https://github.com/laverdet/isolated-vm#requirements), and then run `yarn install` manually again after you've completed those steps. + The wizard will ask you for the name of the app, which will also be the name of the directory ![Screenshot of the wizard asking for a name for the app.](../assets/getting-started/wizard.png) diff --git a/docs/integrations/azure/org.md b/docs/integrations/azure/org.md index f855b29bb9..8b7bd3c5b8 100644 --- a/docs/integrations/azure/org.md +++ b/docs/integrations/azure/org.md @@ -37,7 +37,7 @@ catalog: ``` Finally, register the plugin in `catalog.ts`. -For large organizations, this plugin can take a long time, so be careful setting low frequency / timeouts. +For large organizations, this plugin can take a long time, so be careful setting low frequency / timeouts and importing a large amount of users / groups for the first try. ```ts title="packages/backend/src/plugins/catalog.ts" /* highlight-add-next-line */ @@ -106,7 +106,7 @@ To grant the managed identity the same permissions as mentioned in _App Registra ## Filtering imported Users and Groups By default, the plugin will import all users and groups from your directory. -This can be customized through [filters](https://learn.microsoft.com/en-us/graph/filter-query-parameter) and [search](https://learn.microsoft.com/en-us/graph/search-query-parameter) queries. +This can be customized through [filters](https://learn.microsoft.com/en-us/graph/filter-query-parameter) and [search](https://learn.microsoft.com/en-us/graph/search-query-parameter) queries. Keep in mind that if you omit filters and search queries for the user or group properties, the plugin will automatically import all available users or groups. ### Groups diff --git a/microsite/data/plugins/devtools.yaml b/microsite/data/plugins/devtools.yaml new file mode 100644 index 0000000000..b531195c04 --- /dev/null +++ b/microsite/data/plugins/devtools.yaml @@ -0,0 +1,10 @@ +--- +title: 'DevTools' +author: Keyloop +authorUrl: https://keyloop.com/ +category: Tools +description: Tools for helping with the Ops side of running a Backstage instance +documentation: https://github.com/backstage/backstage/blob/master/plugins/devtools/README.md +iconUrl: /img/devtools.svg +npmPackageName: '@backstage/plugin-devtools' +addedDate: '2023-06-17' diff --git a/microsite/data/plugins/linguist.yaml b/microsite/data/plugins/linguist.yaml new file mode 100644 index 0000000000..d76936391c --- /dev/null +++ b/microsite/data/plugins/linguist.yaml @@ -0,0 +1,10 @@ +--- +title: 'Linguist' +author: Keyloop +authorUrl: https://keyloop.com/ +category: Metadata +description: View the programming language break down for your entities within the Software Catalog +documentation: https://github.com/backstage/backstage/blob/master/plugins/linguist/README.md +iconUrl: /img/linguist.svg +npmPackageName: '@backstage/plugin-linguist' +addedDate: '2023-06-17' diff --git a/microsite/data/plugins/search-backend-module-azure-devops-wiki b/microsite/data/plugins/search-backend-module-azure-devops-wiki.yaml similarity index 98% rename from microsite/data/plugins/search-backend-module-azure-devops-wiki rename to microsite/data/plugins/search-backend-module-azure-devops-wiki.yaml index 0f421abfa8..02d4131cce 100644 --- a/microsite/data/plugins/search-backend-module-azure-devops-wiki +++ b/microsite/data/plugins/search-backend-module-azure-devops-wiki.yaml @@ -3,7 +3,7 @@ title: Azure DevOps Wiki Search author: Drew Hill authorUrl: https://github.com/arhill05 category: Search -description: Index wiki articles from an Azure DevOps wiki into Backstage to allow you to search them with the Backstage Search feature. +description: Index wiki articles from an Azure DevOps wiki into Backstage to allow you to search them with the Backstage Search feature. documentation: https://github.com/arhill05/backstage-plugin-search-backend-module-azure-devops-wiki#readme iconUrl: img/ado-wiki-search-icon.png npmPackageName: '@mdude2314/backstage-plugin-search-backend-module-azure-devops-wiki' diff --git a/microsite/docusaurus.config.js b/microsite/docusaurus.config.js index a13168472d..e78626e37c 100644 --- a/microsite/docusaurus.config.js +++ b/microsite/docusaurus.config.js @@ -127,6 +127,10 @@ module.exports = { from: '/docs/features/techdocs/techdocs-overview', to: '/docs/features/techdocs/', }, + { + from: '/docs/features/kubernetes/overview', + to: '/docs/features/kubernetes/', + }, { from: '/docs/features/search/search-overview', to: '/docs/features/search/', diff --git a/microsite/static/img/devtools.svg b/microsite/static/img/devtools.svg new file mode 100644 index 0000000000..6bd5dc17c5 --- /dev/null +++ b/microsite/static/img/devtools.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/microsite/static/img/linguist.svg b/microsite/static/img/linguist.svg new file mode 100644 index 0000000000..3cddc1affc --- /dev/null +++ b/microsite/static/img/linguist.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 3c19a6e05c..269f752352 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -2604,90 +2604,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-darwin-arm64@npm:1.3.62" +"@swc/core-darwin-arm64@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-darwin-arm64@npm:1.3.66" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-darwin-x64@npm:1.3.62" +"@swc/core-darwin-x64@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-darwin-x64@npm:1.3.66" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.62" +"@swc/core-linux-arm-gnueabihf@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.66" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.62" +"@swc/core-linux-arm64-gnu@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.66" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.62" +"@swc/core-linux-arm64-musl@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.66" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.62" +"@swc/core-linux-x64-gnu@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.66" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-x64-musl@npm:1.3.62" +"@swc/core-linux-x64-musl@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-x64-musl@npm:1.3.66" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.62" +"@swc/core-win32-arm64-msvc@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.66" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.62" +"@swc/core-win32-ia32-msvc@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.66" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.62" +"@swc/core-win32-x64-msvc@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.66" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.3.62 - resolution: "@swc/core@npm:1.3.62" + version: 1.3.66 + resolution: "@swc/core@npm:1.3.66" dependencies: - "@swc/core-darwin-arm64": 1.3.62 - "@swc/core-darwin-x64": 1.3.62 - "@swc/core-linux-arm-gnueabihf": 1.3.62 - "@swc/core-linux-arm64-gnu": 1.3.62 - "@swc/core-linux-arm64-musl": 1.3.62 - "@swc/core-linux-x64-gnu": 1.3.62 - "@swc/core-linux-x64-musl": 1.3.62 - "@swc/core-win32-arm64-msvc": 1.3.62 - "@swc/core-win32-ia32-msvc": 1.3.62 - "@swc/core-win32-x64-msvc": 1.3.62 + "@swc/core-darwin-arm64": 1.3.66 + "@swc/core-darwin-x64": 1.3.66 + "@swc/core-linux-arm-gnueabihf": 1.3.66 + "@swc/core-linux-arm64-gnu": 1.3.66 + "@swc/core-linux-arm64-musl": 1.3.66 + "@swc/core-linux-x64-gnu": 1.3.66 + "@swc/core-linux-x64-musl": 1.3.66 + "@swc/core-win32-arm64-msvc": 1.3.66 + "@swc/core-win32-ia32-msvc": 1.3.66 + "@swc/core-win32-x64-msvc": 1.3.66 peerDependencies: "@swc/helpers": ^0.5.0 dependenciesMeta: @@ -2714,7 +2714,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: a7a0d9ffdb8a2b0050e0ff89fdb86fe189d9bcb7f91cb6847f1bfe3e2b520a87ea2e83692dfd80b6d541fb5addb2194769484516b8ca6d3c62ad80f1c79a9368 + checksum: e6029c648ba47c522bed51a9f2fee606f82de1f9233e2e89197e43b0a4867054174ca05e825e688cdc4de332221c0da2e12ba7ba875549e8b5432aa70fe19263 languageName: node linkType: hard diff --git a/packages/app/src/components/devtools/CustomDevToolsPage.tsx b/packages/app/src/components/devtools/CustomDevToolsPage.tsx index dfe70426aa..788b555c6d 100644 --- a/packages/app/src/components/devtools/CustomDevToolsPage.tsx +++ b/packages/app/src/components/devtools/CustomDevToolsPage.tsx @@ -21,6 +21,7 @@ import { } from '@backstage/plugin-devtools'; import { DevToolsLayout } from '@backstage/plugin-devtools'; import React from 'react'; +import { UnprocessedEntitiesContent } from '@backstage/plugin-catalog-unprocessed-entities'; const DevToolsPage = () => { return ( @@ -37,6 +38,12 @@ const DevToolsPage = () => { > + + + ); }; diff --git a/packages/backend-common/src/reading/AzureUrlReader.ts b/packages/backend-common/src/reading/AzureUrlReader.ts index 26fe3f4a12..94abf3a178 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.ts @@ -158,7 +158,7 @@ export class AzureUrlReader implements UrlReader { } return await this.deps.treeResponseFactory.fromZipArchive({ - stream: archiveAzureResponse.body as unknown as Readable, + stream: Readable.from(archiveAzureResponse.body), etag: commitSha, filter, subpath, diff --git a/packages/backend-common/src/reading/BitbucketCloudUrlReader.ts b/packages/backend-common/src/reading/BitbucketCloudUrlReader.ts index 1522b7678d..93587cd6ae 100644 --- a/packages/backend-common/src/reading/BitbucketCloudUrlReader.ts +++ b/packages/backend-common/src/reading/BitbucketCloudUrlReader.ts @@ -160,7 +160,7 @@ export class BitbucketCloudUrlReader implements UrlReader { } return await this.deps.treeResponseFactory.fromTarArchive({ - stream: archiveResponse.body as unknown as Readable, + stream: Readable.from(archiveResponse.body), subpath: filepath, etag: lastCommitShortHash, filter: options?.filter, diff --git a/packages/backend-common/src/reading/BitbucketServerUrlReader.ts b/packages/backend-common/src/reading/BitbucketServerUrlReader.ts index 2b6b5a1f8f..8e2f1708c4 100644 --- a/packages/backend-common/src/reading/BitbucketServerUrlReader.ts +++ b/packages/backend-common/src/reading/BitbucketServerUrlReader.ts @@ -151,7 +151,7 @@ export class BitbucketServerUrlReader implements UrlReader { } return await this.deps.treeResponseFactory.fromTarArchive({ - stream: archiveResponse.body as unknown as Readable, + stream: Readable.from(archiveResponse.body), subpath: filepath, etag: lastCommitShortHash, filter: options?.filter, diff --git a/packages/backend-common/src/reading/BitbucketUrlReader.ts b/packages/backend-common/src/reading/BitbucketUrlReader.ts index 3a34c725c6..090fe9098d 100644 --- a/packages/backend-common/src/reading/BitbucketUrlReader.ts +++ b/packages/backend-common/src/reading/BitbucketUrlReader.ts @@ -171,7 +171,7 @@ export class BitbucketUrlReader implements UrlReader { } return await this.deps.treeResponseFactory.fromTarArchive({ - stream: archiveBitbucketResponse.body as unknown as Readable, + stream: Readable.from(archiveBitbucketResponse.body), subpath: filepath, etag: lastCommitShortHash, filter: options?.filter, diff --git a/packages/backend-common/src/reading/GerritUrlReader.ts b/packages/backend-common/src/reading/GerritUrlReader.ts index 5d86e5d9ac..8ac5452a4c 100644 --- a/packages/backend-common/src/reading/GerritUrlReader.ts +++ b/packages/backend-common/src/reading/GerritUrlReader.ts @@ -204,7 +204,7 @@ export class GerritUrlReader implements UrlReader { }); const tarArchive = Readable.from(data); return await this.deps.treeResponseFactory.fromTarArchive({ - stream: tarArchive as unknown as Readable, + stream: tarArchive, subpath: filePath === '/' ? undefined : filePath, etag: branchInfo.revision, filter: options?.filter, diff --git a/packages/backend-common/src/reading/GithubUrlReader.ts b/packages/backend-common/src/reading/GithubUrlReader.ts index 8300127c5b..764431386d 100644 --- a/packages/backend-common/src/reading/GithubUrlReader.ts +++ b/packages/backend-common/src/reading/GithubUrlReader.ts @@ -238,7 +238,7 @@ export class GithubUrlReader implements UrlReader { return await this.deps.treeResponseFactory.fromTarArchive({ // TODO(Rugvip): Underlying implementation of fetch will be node-fetch, we probably want // to stick to using that in exclusively backend code. - stream: archive.body as unknown as Readable, + stream: Readable.from(archive.body), subpath, etag: sha, filter: options?.filter, @@ -347,7 +347,6 @@ export class GithubUrlReader implements UrlReader { init: RequestInit, ): Promise { const urlAsString = url.toString(); - const response = await fetch(urlAsString, init); if (!response.ok) { diff --git a/packages/backend-common/src/reading/GitlabUrlReader.ts b/packages/backend-common/src/reading/GitlabUrlReader.ts index ab59c19b16..178e65b40a 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.ts @@ -229,7 +229,7 @@ export class GitlabUrlReader implements UrlReader { } return await this.deps.treeResponseFactory.fromTarArchive({ - stream: archiveGitLabResponse.body as unknown as Readable, + stream: Readable.from(archiveGitLabResponse.body), subpath: filepath, etag: commitSha, filter: options?.filter, diff --git a/packages/backend-common/src/reading/tree/TarArchiveResponse.ts b/packages/backend-common/src/reading/tree/TarArchiveResponse.ts index 493e283c5f..e1529c196a 100644 --- a/packages/backend-common/src/reading/tree/TarArchiveResponse.ts +++ b/packages/backend-common/src/reading/tree/TarArchiveResponse.ts @@ -151,7 +151,6 @@ export class TarArchiveResponse implements ReadTreeResponse { const strip = this.subPath ? this.subPath.split('/').length : 1; let filterError: Error | undefined = undefined; - await pipeline( this.stream, tar.extract({ diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index e13078890a..bc7d5e666f 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -30,6 +30,7 @@ "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-catalog-backend": "workspace:^", "@backstage/plugin-catalog-backend-module-unprocessed": "workspace:^", + "@backstage/plugin-entity-feedback-backend": "workspace:^", "@backstage/plugin-kubernetes-backend": "workspace:^", "@backstage/plugin-permission-backend": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", diff --git a/packages/backend-next/src/index.ts b/packages/backend-next/src/index.ts index cdba12e0e3..900062d61b 100644 --- a/packages/backend-next/src/index.ts +++ b/packages/backend-next/src/index.ts @@ -30,12 +30,16 @@ import { searchModuleTechDocsCollator } from '@backstage/plugin-search-backend-m import { searchPlugin } from '@backstage/plugin-search-backend/alpha'; import { techdocsPlugin } from '@backstage/plugin-techdocs-backend/alpha'; import { todoPlugin } from '@backstage/plugin-todo-backend'; +import { entityFeedbackPlugin } from '@backstage/plugin-entity-feedback-backend'; import { catalogModuleUnprocessedEntities } from '@backstage/plugin-catalog-backend-module-unprocessed'; const backend = createBackend(); backend.add(appPlugin({ appPackageName: 'example-app' })); +// Entity Feedback +backend.add(entityFeedbackPlugin()); + // Todo backend.add(todoPlugin()); diff --git a/packages/cli/src/commands/buildWorkspace.ts b/packages/cli/src/commands/buildWorkspace.ts index 97bf2f1239..685e4b1cb0 100644 --- a/packages/cli/src/commands/buildWorkspace.ts +++ b/packages/cli/src/commands/buildWorkspace.ts @@ -17,12 +17,17 @@ import fs from 'fs-extra'; import { createDistWorkspace } from '../lib/packager'; -export default async (dir: string, packages: string[]) => { +type Options = { + alwaysYarnPack?: boolean; +}; + +export default async (dir: string, packages: string[], options: Options) => { if (!(await fs.pathExists(dir))) { throw new Error(`Target workspace directory doesn't exist, '${dir}'`); } await createDistWorkspace(packages, { targetDir: dir, + alwaysYarnPack: options.alwaysYarnPack, }); }; diff --git a/packages/core-components/src/components/Select/Select.tsx b/packages/core-components/src/components/Select/Select.tsx index dbf5601112..918ce301fb 100644 --- a/packages/core-components/src/components/Select/Select.tsx +++ b/packages/core-components/src/components/Select/Select.tsx @@ -43,6 +43,9 @@ const BootstrapInput = withStyles( 'label + &': { marginTop: theme.spacing(3), }, + '&.Mui-focused > div[role=button]': { + borderColor: theme.palette.primary.main, + }, }, input: { borderRadius: theme.shape.borderRadius, @@ -75,7 +78,7 @@ const useStyles = makeStyles( (theme: Theme) => createStyles({ formControl: { - margin: `${theme.spacing(1)} 0px`, + margin: theme.spacing(1, 0), maxWidth: 300, }, label: { @@ -212,7 +215,6 @@ export function SelectComponent(props: SelectProps) { onClose={handleClose} input={} label={label} - tabIndex={0} renderValue={s => multiple && (value as any[]).length !== 0 ? ( diff --git a/packages/core-components/src/layout/ItemCard/ItemCard.stories.tsx b/packages/core-components/src/layout/ItemCard/ItemCard.stories.tsx index 1ba3dec3fd..a03ad9be41 100644 --- a/packages/core-components/src/layout/ItemCard/ItemCard.stories.tsx +++ b/packages/core-components/src/layout/ItemCard/ItemCard.stories.tsx @@ -22,7 +22,7 @@ import CardMedia from '@material-ui/core/CardMedia'; import Typography from '@material-ui/core/Typography'; import React from 'react'; import { MemoryRouter } from 'react-router-dom'; -import { LinkButton } from '../../components'; +import { LinkButton } from '../../components/LinkButton/LinkButton'; import { ItemCardGrid } from './ItemCardGrid'; import { ItemCardHeader } from './ItemCardHeader'; diff --git a/packages/core-components/src/layout/ItemCard/ItemCard.tsx b/packages/core-components/src/layout/ItemCard/ItemCard.tsx index 0b1ee34c0c..3d9963760b 100644 --- a/packages/core-components/src/layout/ItemCard/ItemCard.tsx +++ b/packages/core-components/src/layout/ItemCard/ItemCard.tsx @@ -21,7 +21,7 @@ import CardContent from '@material-ui/core/CardContent'; import CardMedia from '@material-ui/core/CardMedia'; import Chip from '@material-ui/core/Chip'; import React, { ReactNode } from 'react'; -import { LinkButton } from '../../components'; +import { LinkButton } from '../../components/LinkButton/LinkButton'; import { ItemCardHeader } from './ItemCardHeader'; type ItemCardProps = { diff --git a/packages/core-components/src/layout/Sidebar/SidebarGroup.tsx b/packages/core-components/src/layout/Sidebar/SidebarGroup.tsx index 1eb1423c61..1dd61d3170 100644 --- a/packages/core-components/src/layout/Sidebar/SidebarGroup.tsx +++ b/packages/core-components/src/layout/Sidebar/SidebarGroup.tsx @@ -22,7 +22,7 @@ import BottomNavigationAction, { import { makeStyles } from '@material-ui/core/styles'; import React, { useContext } from 'react'; import { useLocation } from 'react-router-dom'; -import { Link } from '../../components'; +import { Link } from '../../components/Link/Link'; import { SidebarConfig, SidebarConfigContext } from './config'; import { MobileSidebarContext } from './MobileSidebar'; import { useSidebarPinState } from './SidebarPinStateContext'; diff --git a/packages/errors/api-report.md b/packages/errors/api-report.md index 0d405d8ba6..3ece63035b 100644 --- a/packages/errors/api-report.md +++ b/packages/errors/api-report.md @@ -9,10 +9,16 @@ import { JsonObject } from '@backstage/types'; export function assertError(value: unknown): asserts value is ErrorLike; // @public -export class AuthenticationError extends CustomErrorBase {} +export class AuthenticationError extends CustomErrorBase { + // (undocumented) + name: 'AuthenticationError'; +} // @public -export class ConflictError extends CustomErrorBase {} +export class ConflictError extends CustomErrorBase { + // (undocumented) + name: 'ConflictError'; +} // @public export type ConsumedResponse = { @@ -73,22 +79,37 @@ export class ForwardedError extends CustomErrorBase { } // @public -export class InputError extends CustomErrorBase {} +export class InputError extends CustomErrorBase { + // (undocumented) + name: 'InputError'; +} // @public export function isError(value: unknown): value is ErrorLike; // @public -export class NotAllowedError extends CustomErrorBase {} +export class NotAllowedError extends CustomErrorBase { + // (undocumented) + name: 'NotAllowedError'; +} // @public -export class NotFoundError extends CustomErrorBase {} +export class NotFoundError extends CustomErrorBase { + // (undocumented) + name: 'NotFoundError'; +} // @public -export class NotImplementedError extends CustomErrorBase {} +export class NotImplementedError extends CustomErrorBase { + // (undocumented) + name: 'NotImplementedError'; +} // @public -export class NotModifiedError extends CustomErrorBase {} +export class NotModifiedError extends CustomErrorBase { + // (undocumented) + name: 'NotModifiedError'; +} // @public export function parseErrorResponseBody( diff --git a/packages/errors/src/errors/CustomErrorBase.ts b/packages/errors/src/errors/CustomErrorBase.ts index b831d4eea3..ea9c91f173 100644 --- a/packages/errors/src/errors/CustomErrorBase.ts +++ b/packages/errors/src/errors/CustomErrorBase.ts @@ -22,8 +22,11 @@ import { isError } from './assertion'; * * @public * @example - *```ts - * class MyCustomError extends CustomErrorBase {} + * + * ```ts + * class MyCustomError extends CustomErrorBase { + * name = 'MyCustomError' as const; + * } * * const e = new MyCustomError('Some message', cause); * // e.name === 'MyCustomError' @@ -53,7 +56,13 @@ export class CustomErrorBase extends Error { Error.captureStackTrace?.(this, this.constructor); - this.name = this.constructor.name; + if (!this.name || this.name === 'Error') { + const baseName = this.constructor.name; + if (baseName !== 'Error') { + this.name = this.constructor.name; + } + } + this.cause = isError(cause) ? cause : undefined; } } diff --git a/packages/errors/src/errors/common.ts b/packages/errors/src/errors/common.ts index a2ea20e99f..861c3a7c3a 100644 --- a/packages/errors/src/errors/common.ts +++ b/packages/errors/src/errors/common.ts @@ -33,21 +33,27 @@ import { CustomErrorBase } from './CustomErrorBase'; * * @public */ -export class InputError extends CustomErrorBase {} +export class InputError extends CustomErrorBase { + name = 'InputError' as const; +} /** * The request requires authentication, which was not properly supplied. * * @public */ -export class AuthenticationError extends CustomErrorBase {} +export class AuthenticationError extends CustomErrorBase { + name = 'AuthenticationError' as const; +} /** * The authenticated caller is not allowed to perform this request. * * @public */ -export class NotAllowedError extends CustomErrorBase {} +export class NotAllowedError extends CustomErrorBase { + name = 'NotAllowedError' as const; +} /** * The requested resource could not be found. @@ -57,7 +63,9 @@ export class NotAllowedError extends CustomErrorBase {} * * @public */ -export class NotFoundError extends CustomErrorBase {} +export class NotFoundError extends CustomErrorBase { + name = 'NotFoundError' as const; +} /** * The request could not complete due to a conflict in the current state of the @@ -65,21 +73,27 @@ export class NotFoundError extends CustomErrorBase {} * * @public */ -export class ConflictError extends CustomErrorBase {} +export class ConflictError extends CustomErrorBase { + name = 'ConflictError' as const; +} /** * The requested resource has not changed since last request. * * @public */ -export class NotModifiedError extends CustomErrorBase {} +export class NotModifiedError extends CustomErrorBase { + name = 'NotModifiedError' as const; +} /** * The server does not support the functionality required to fulfill the request. * * @public */ -export class NotImplementedError extends CustomErrorBase {} +export class NotImplementedError extends CustomErrorBase { + name = 'NotImplementedError' as const; +} /** * The server is not ready to handle the request. diff --git a/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts b/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts index c181510a67..bf82607c6b 100644 --- a/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts +++ b/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts @@ -28,48 +28,46 @@ import { ScmIntegrations, SingleInstanceGithubCredentialsProvider, } from '@backstage/integration'; -import { EventParams } from '@backstage/plugin-events-node'; -import { EventSubscriber } from '@backstage/plugin-events-node'; import { EntityProvider, EntityProviderConnection, } from '@backstage/plugin-catalog-node'; +import { EventParams, EventSubscriber } from '@backstage/plugin-events-node'; import { graphql } from '@octokit/graphql'; import { + MembershipEvent, OrganizationEvent, OrganizationMemberAddedEvent, OrganizationMemberRemovedEvent, - TeamEvent, TeamEditedEvent, - MembershipEvent, + TeamEvent, } from '@octokit/webhooks-types'; import { merge } from 'lodash'; import * as uuid from 'uuid'; import { Logger } from 'winston'; -import { - assignGroupsToUsers, - buildOrgHierarchy, - defaultOrganizationTeamTransformer, - defaultUserTransformer, - getOrganizationTeams, - getOrganizationUsers, - GithubTeam, - parseGithubOrgUrl, -} from '../lib'; -import { TeamTransformer, UserTransformer } from '../lib'; -import { - createAddEntitiesOperation, - createRemoveEntitiesOperation, - createReplaceEntitiesOperation, - DeferredEntitiesBuilder, - getOrganizationTeam, - getOrganizationTeamsFromUsers, -} from '../lib/github'; import { ANNOTATION_GITHUB_TEAM_SLUG, ANNOTATION_GITHUB_USER_LOGIN, } from '../lib/annotation'; -import { splitTeamSlug } from '../lib/util'; +import { + TeamTransformer, + UserTransformer, + defaultOrganizationTeamTransformer, + defaultUserTransformer, +} from '../lib/defaultTransformers'; +import { + DeferredEntitiesBuilder, + GithubTeam, + createAddEntitiesOperation, + createRemoveEntitiesOperation, + createReplaceEntitiesOperation, + getOrganizationTeam, + getOrganizationTeams, + getOrganizationTeamsFromUsers, + getOrganizationUsers, +} from '../lib/github'; +import { assignGroupsToUsers, buildOrgHierarchy } from '../lib/org'; +import { parseGithubOrgUrl, splitTeamSlug } from '../lib/util'; /** * Options for {@link GithubOrgEntityProvider}. diff --git a/plugins/catalog-backend-module-unprocessed/README.md b/plugins/catalog-backend-module-unprocessed/README.md index dc5e830fa4..92d9e59445 100644 --- a/plugins/catalog-backend-module-unprocessed/README.md +++ b/plugins/catalog-backend-module-unprocessed/README.md @@ -1,4 +1,4 @@ -# @backstage/plugin-catalog-backend-module-unprocessed-node +# @backstage/plugin-catalog-backend-module-unprocessed This catalog-backend module adds support for viewing unprocessed entities. An unprocessed entity is one that doesn't show up in the catalog. @@ -10,11 +10,15 @@ A `pending` entity has not been processed yet. ## Installation +```shell +yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-unprocessed +``` + ### backend In `packages/backend/src/plugins/catalog.ts` import the module and initialize it after invoking `CatalogBuilder.build()`: -```ts +```ts title="packages/backend/src/plugins/catalog.ts" import { UnprocessedEntitesModule } from '@backstage/plugin-catalog-backend-module-unprocessed'; //... @@ -22,7 +26,6 @@ import { UnprocessedEntitesModule } from '@backstage/plugin-catalog-backend-modu const unprocessed = new UnprocessedEntitesModule( await env.database.getClient(), router, - env.logger, ); unprocessed.registerRoutes(); ``` @@ -31,7 +34,7 @@ unprocessed.registerRoutes(); In `packages/backend-next/src/index.ts` add the module: -```ts +```ts title="packages/backend-next/src/index.ts" backend.add(catalogModuleUnprocessedEntities()); ``` diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md index 3e97442dd4..84d8de4753 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/api-report.md @@ -410,12 +410,12 @@ export type PlaceholderProcessorOptions = { integrations: ScmIntegrationRegistry; }; -// @public (undocumented) +// @public @deprecated (undocumented) export type PlaceholderResolver = ( params: PlaceholderResolverParams, ) => Promise; -// @public (undocumented) +// @public @deprecated (undocumented) export type PlaceholderResolverParams = { key: string; value: JsonValue; @@ -425,10 +425,10 @@ export type PlaceholderResolverParams = { emit: CatalogProcessorEmit_2; }; -// @public (undocumented) +// @public @deprecated (undocumented) export type PlaceholderResolverRead = (url: string) => Promise; -// @public (undocumented) +// @public @deprecated (undocumented) export type PlaceholderResolverResolveUrl = ( url: string, base: string, diff --git a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.ts b/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.ts index 79fcee960c..ee61e931e3 100644 --- a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.ts +++ b/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.ts @@ -26,16 +26,25 @@ import { processingResult, } from '@backstage/plugin-catalog-node'; -/** @public */ +/** + * @public + * @deprecated Use the exported value from `@backstage/plugin-catalog-node` instead. + */ export type PlaceholderResolverRead = (url: string) => Promise; -/** @public */ +/** + * @public + * @deprecated Use the exported value from `@backstage/plugin-catalog-node` instead. + */ export type PlaceholderResolverResolveUrl = ( url: string, base: string, ) => string; -/** @public */ +/** + * @public + * @deprecated Use the exported value from `@backstage/plugin-catalog-node` instead. + */ export type PlaceholderResolverParams = { key: string; value: JsonValue; @@ -45,7 +54,10 @@ export type PlaceholderResolverParams = { emit: CatalogProcessorEmit; }; -/** @public */ +/** + * @public + * @deprecated Use the exported value from `@backstage/plugin-catalog-node` instead. + */ export type PlaceholderResolver = ( params: PlaceholderResolverParams, ) => Promise; diff --git a/plugins/catalog-backend/src/service/CatalogPlugin.ts b/plugins/catalog-backend/src/service/CatalogPlugin.ts index e0399c1683..d77b034517 100644 --- a/plugins/catalog-backend/src/service/CatalogPlugin.ts +++ b/plugins/catalog-backend/src/service/CatalogPlugin.ts @@ -27,10 +27,12 @@ import { EntityProvider, } from '@backstage/plugin-catalog-node'; import { loggerToWinstonLogger } from '@backstage/backend-common'; +import { PlaceholderResolver } from '../modules'; class CatalogExtensionPointImpl implements CatalogProcessingExtensionPoint { #processors = new Array(); #entityProviders = new Array(); + #placeholderResolvers: Record = {}; addProcessor( ...processors: Array> @@ -44,6 +46,14 @@ class CatalogExtensionPointImpl implements CatalogProcessingExtensionPoint { this.#entityProviders.push(...providers.flat()); } + addPlaceholderResolver(key: string, resolver: PlaceholderResolver) { + if (key in this.#placeholderResolvers) + throw new Error( + `A placeholder resolver for '${key}' has already been set up, please check your config.`, + ); + this.#placeholderResolvers[key] = resolver; + } + get processors() { return this.#processors; } @@ -51,6 +61,10 @@ class CatalogExtensionPointImpl implements CatalogProcessingExtensionPoint { get entityProviders() { return this.#entityProviders; } + + get placeholderResolvers() { + return this.#placeholderResolvers; + } } /** @@ -99,6 +113,10 @@ export const catalogPlugin = createBackendPlugin({ }); builder.addProcessor(...processingExtensions.processors); builder.addEntityProvider(...processingExtensions.entityProviders); + Object.entries(processingExtensions.placeholderResolvers).forEach( + ([key, resolver]) => builder.setPlaceholderResolver(key, resolver), + ); + const { processingEngine, router } = await builder.build(); await processingEngine.start(); diff --git a/plugins/catalog-node/alpha-api-report.md b/plugins/catalog-node/alpha-api-report.md index ba1bcd47b2..082228a58e 100644 --- a/plugins/catalog-node/alpha-api-report.md +++ b/plugins/catalog-node/alpha-api-report.md @@ -7,6 +7,7 @@ import { CatalogApi } from '@backstage/catalog-client'; import { CatalogProcessor } from '@backstage/plugin-catalog-node'; import { EntityProvider } from '@backstage/plugin-catalog-node'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; +import { PlaceholderResolver } from '@backstage/plugin-catalog-node'; import { ServiceRef } from '@backstage/backend-plugin-api'; // @alpha (undocumented) @@ -16,6 +17,8 @@ export interface CatalogProcessingExtensionPoint { ...providers: Array> ): void; // (undocumented) + addPlaceholderResolver(key: string, resolver: PlaceholderResolver): void; + // (undocumented) addProcessor( ...processors: Array> ): void; diff --git a/plugins/catalog-node/api-report.md b/plugins/catalog-node/api-report.md index 47a8e66ca9..34d7a4bc9b 100644 --- a/plugins/catalog-node/api-report.md +++ b/plugins/catalog-node/api-report.md @@ -152,6 +152,30 @@ export function locationSpecToLocationEntity(opts: { // @public export function locationSpecToMetadataName(location: LocationSpec_2): string; +// @public (undocumented) +export type PlaceholderResolver = ( + params: PlaceholderResolverParams, +) => Promise; + +// @public (undocumented) +export type PlaceholderResolverParams = { + key: string; + value: JsonValue; + baseUrl: string; + read: PlaceholderResolverRead; + resolveUrl: PlaceholderResolverResolveUrl; + emit: CatalogProcessorEmit; +}; + +// @public (undocumented) +export type PlaceholderResolverRead = (url: string) => Promise; + +// @public (undocumented) +export type PlaceholderResolverResolveUrl = ( + url: string, + base: string, +) => string; + // @public export const processingResult: Readonly<{ readonly notFoundError: ( diff --git a/plugins/catalog-node/src/extensions.ts b/plugins/catalog-node/src/extensions.ts index 0466af36b0..5225ad7545 100644 --- a/plugins/catalog-node/src/extensions.ts +++ b/plugins/catalog-node/src/extensions.ts @@ -17,6 +17,7 @@ import { createExtensionPoint } from '@backstage/backend-plugin-api'; import { EntityProvider, CatalogProcessor, + PlaceholderResolver, } from '@backstage/plugin-catalog-node'; /** @@ -29,6 +30,7 @@ export interface CatalogProcessingExtensionPoint { addEntityProvider( ...providers: Array> ): void; + addPlaceholderResolver(key: string, resolver: PlaceholderResolver): void; } /** diff --git a/plugins/catalog-node/src/processing/index.ts b/plugins/catalog-node/src/processing/index.ts index 90b87aa850..40cee63e25 100644 --- a/plugins/catalog-node/src/processing/index.ts +++ b/plugins/catalog-node/src/processing/index.ts @@ -14,4 +14,10 @@ * limitations under the License. */ -export type { DeferredEntity } from './types'; +export type { + DeferredEntity, + PlaceholderResolver, + PlaceholderResolverParams, + PlaceholderResolverRead, + PlaceholderResolverResolveUrl, +} from './types'; diff --git a/plugins/catalog-node/src/processing/types.ts b/plugins/catalog-node/src/processing/types.ts index 25e76faea3..b98e2da1b7 100644 --- a/plugins/catalog-node/src/processing/types.ts +++ b/plugins/catalog-node/src/processing/types.ts @@ -15,6 +15,8 @@ */ import { Entity } from '@backstage/catalog-model'; +import { JsonValue } from '@backstage/types'; +import { CatalogProcessorEmit } from '../api'; /** * Entities that are not yet processed. @@ -24,3 +26,27 @@ export type DeferredEntity = { entity: Entity; locationKey?: string; }; + +/** @public */ +export type PlaceholderResolverRead = (url: string) => Promise; + +/** @public */ +export type PlaceholderResolverResolveUrl = ( + url: string, + base: string, +) => string; + +/** @public */ +export type PlaceholderResolverParams = { + key: string; + value: JsonValue; + baseUrl: string; + read: PlaceholderResolverRead; + resolveUrl: PlaceholderResolverResolveUrl; + emit: CatalogProcessorEmit; +}; + +/** @public */ +export type PlaceholderResolver = ( + params: PlaceholderResolverParams, +) => Promise; diff --git a/plugins/catalog-unprocessed-entities/README.md b/plugins/catalog-unprocessed-entities/README.md index fd824bec94..699629e0b2 100644 --- a/plugins/catalog-unprocessed-entities/README.md +++ b/plugins/catalog-unprocessed-entities/README.md @@ -1,16 +1,40 @@ -# catalog-unprocessed-entities +# Catalog Unprocessed Entities + +## Features Frontend plugin to view unprocessed entities. +### Failed Entities + +You can see entities that are in a failed state: + +![Example of failed entities tab](./docs/catalog-unprocessed-entities-failed.png) + +### Pending Entities + +You can see entities that are in a pending state: + +![Example of pending entities tab](./docs/catalog-unprocessed-entities-pending.png) + +### Raw View + +In either of the failed or pending tabs you have the option to see the raw entity as JSON: + +![Example of raw entity](./docs/catalog-unprocessed-entities-raw.png) + ## Requirements Requires the `@backstage/plugin-catalog-backend-module-unprocessed` module to be installed. ## Installation -Import into your App.tsx and include into the `` component: +```shell +yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-unprocessed +``` -```tsx +Import into your `App.tsx` and include into the `` component: + +```tsx title="packages/app/src/App.tsx" import { CatalogUnprocessedEntitiesPage } from '@backstage/plugin-catalog-unprocessed-entities'; //... @@ -20,9 +44,44 @@ import { CatalogUnprocessedEntitiesPage } from '@backstage/plugin-catalog-unproc />; ``` +## Customization + +If you want to use the provided endpoints in a different way, you can use the ApiRef doing the following: + +```typescript +import { catalogUnprocessedEntitiesApiRef } from '@backstage/plugin-catalog-unprocessed-entities'; +import { useApi } from '@backstage/core-plugin-api'; + +const catalogUnprocessedEntitiesApi = useApi(catalogUnprocessedEntitiesApiRef); +``` + +Note that if you are not rendering the `CatalogUnprocessedEntitiesPage` in the `App.tsx` tree, you will need to export the `catalogUnproccessedEntitiesPlugin` from your `plugins.ts` file to setup the plugin otherwise you will receive an error like `No implementation available for apiRef{plugin.catalog-unprocessed-entities.service}` + +```typescript +// In packages/app/src/plugins.ts +... +export { catalogUnprocessedEntitiesPlugin } from '@backstage/plugin-catalog-unprocessed-entities'; +``` + +If you don't have a `plugins.ts` file, you can create it with the path `packages/app/src/plugins.ts` and then import it into your `App.tsx`: + +```diff ++ import * as plugins from './plugins'; + +const app = createApp({ + apis, ++ plugins: Object.values(plugins), + bindRoutes({ bind }) { + /* ... */ + }, +}); +``` + ## Getting started -Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/catalog-unprocessed-entities](http://localhost:3000/catalog-unprocessed-entities). +Your plugin has been added to the example app in this repository, +meaning you'll be able to access it by running `yarn start` in the root directory, +and then navigating to [/catalog-unprocessed-entities](http://localhost:3000/catalog-unprocessed-entities). You can also serve the plugin in isolation by running `yarn start` in the plugin directory. This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. diff --git a/plugins/catalog-unprocessed-entities/api-report.md b/plugins/catalog-unprocessed-entities/api-report.md index b1e0d6f53d..0ccf9716f2 100644 --- a/plugins/catalog-unprocessed-entities/api-report.md +++ b/plugins/catalog-unprocessed-entities/api-report.md @@ -5,9 +5,25 @@ ```ts /// +import { ApiRef } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { Entity } from '@backstage/catalog-model'; import { RouteRef } from '@backstage/core-plugin-api'; +// @public +export interface CatalogUnprocessedEntitiesApi { + failed(): Promise; + pending(): Promise; +} + +// @public +export const catalogUnprocessedEntitiesApiRef: ApiRef; + +// @public +export type CatalogUnprocessedEntitiesApiResponse = { + entities: UnprocessedEntity[]; +}; + // @public export const CatalogUnprocessedEntitiesPage: () => JSX.Element; @@ -20,5 +36,40 @@ export const catalogUnprocessedEntitiesPlugin: BackstagePlugin< {} >; +// @public (undocumented) +export const UnprocessedEntitiesContent: () => JSX.Element; + +// @public +export type UnprocessedEntity = { + entity_id: string; + entity_ref: string; + unprocessed_entity: Entity; + unprocessed_hash?: string; + processed_entity?: Entity; + result_hash?: string; + cache?: UnprocessedEntityCache; + next_update_at: string | Date; + last_discovery_at: string | Date; + errors?: UnprocessedEntityError[]; + location_key?: string; +}; + +// @public +export type UnprocessedEntityCache = { + ttl: number; + cache: object; +}; + +// @public +export type UnprocessedEntityError = { + name: string; + message: string; + cause: { + name: string; + message: string; + stack: string; + }; +}; + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-unprocessed-entities/docs/catalog-unprocessed-entities-failed.png b/plugins/catalog-unprocessed-entities/docs/catalog-unprocessed-entities-failed.png new file mode 100644 index 0000000000..9a65654630 Binary files /dev/null and b/plugins/catalog-unprocessed-entities/docs/catalog-unprocessed-entities-failed.png differ diff --git a/plugins/catalog-unprocessed-entities/docs/catalog-unprocessed-entities-pending.png b/plugins/catalog-unprocessed-entities/docs/catalog-unprocessed-entities-pending.png new file mode 100644 index 0000000000..d2924b0d7e Binary files /dev/null and b/plugins/catalog-unprocessed-entities/docs/catalog-unprocessed-entities-pending.png differ diff --git a/plugins/catalog-unprocessed-entities/docs/catalog-unprocessed-entities-raw.png b/plugins/catalog-unprocessed-entities/docs/catalog-unprocessed-entities-raw.png new file mode 100644 index 0000000000..3b63b00cda Binary files /dev/null and b/plugins/catalog-unprocessed-entities/docs/catalog-unprocessed-entities-raw.png differ diff --git a/plugins/catalog-unprocessed-entities/package.json b/plugins/catalog-unprocessed-entities/package.json index 2058da0d6c..0297220148 100644 --- a/plugins/catalog-unprocessed-entities/package.json +++ b/plugins/catalog-unprocessed-entities/package.json @@ -12,6 +12,12 @@ "backstage": { "role": "frontend-plugin" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-unprocessed-entities" + }, "scripts": { "start": "backstage-cli package start", "build": "backstage-cli package build", diff --git a/plugins/catalog-unprocessed-entities/src/api/index.ts b/plugins/catalog-unprocessed-entities/src/api/index.ts index 5be81c8331..92dde93a93 100644 --- a/plugins/catalog-unprocessed-entities/src/api/index.ts +++ b/plugins/catalog-unprocessed-entities/src/api/index.ts @@ -32,20 +32,43 @@ export const catalogUnprocessedEntitiesApiRef = }); /** - * API client for the Catalog Unprocessed Entities plugin + * Response expected by the {@link CatalogUnprocessedEntitiesApi} * * @public */ -export class CatalogUnprocessedEntitiesApi { - url: string = ''; +export type CatalogUnprocessedEntitiesApiResponse = { + entities: UnprocessedEntity[]; +}; +/** + * Interface for the CatalogUnprocessedEntitiesApi. + * + * @public + */ +export interface CatalogUnprocessedEntitiesApi { + /** + * Returns a list of entities with state 'pending' + */ + pending(): Promise; + /** + * Returns a list of entities with state 'failed' + */ + failed(): Promise; +} + +/** + * Default API implementation for the Catalog Unprocessed Entities plugin + * + * @public + */ +export class CatalogUnprocessedEntitiesClient + implements CatalogUnprocessedEntitiesApi +{ constructor(public discovery: DiscoveryApi, public fetchApi: FetchApi) {} private async fetch(path: string, init?: RequestInit): Promise { - if (!this.url) { - this.url = await this.discovery.getBaseUrl('catalog'); - } - const resp = await this.fetchApi.fetch(`${this.url}/${path}`, init); + const url = await this.discovery.getBaseUrl('catalog'); + const resp = await this.fetchApi.fetch(`${url}/${path}`, init); if (!resp.ok) { throw await ResponseError.fromResponse(resp); } @@ -53,11 +76,11 @@ export class CatalogUnprocessedEntitiesApi { return await resp.json(); } - async pending(): Promise<{ entities: UnprocessedEntity[] }> { + async pending(): Promise { return await this.fetch('entities/unprocessed/pending'); } - async failed(): Promise<{ entities: UnprocessedEntity[] }> { + async failed(): Promise { return await this.fetch('entities/unprocessed/failed'); } } diff --git a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx index 44a146f027..662c5c9db6 100644 --- a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx +++ b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx @@ -126,7 +126,7 @@ export const FailedEntities = () => { return ( <> { return ( <>
({ + tabPanel: { + paddingLeft: '0px', + paddingRight: '0px', + }, +})); + +/** @public */ export const UnprocessedEntitiesContent = () => { + const classes = useStyles(); const [tab, setTab] = useState('failed'); const handleChange = (_event: React.ChangeEvent<{}>, tabValue: string) => { setTab(tabValue); }; return ( - - - - - - - - - - - - - - + + + + + + + + + + + + ); }; export const UnprocessedEntities = () => { return ( -
- +
+ + + ); }; diff --git a/plugins/catalog-unprocessed-entities/src/index.ts b/plugins/catalog-unprocessed-entities/src/index.ts index a65283926e..4fcc9a8fcd 100644 --- a/plugins/catalog-unprocessed-entities/src/index.ts +++ b/plugins/catalog-unprocessed-entities/src/index.ts @@ -17,3 +17,14 @@ export { catalogUnprocessedEntitiesPlugin, CatalogUnprocessedEntitiesPage, } from './plugin'; +export { UnprocessedEntitiesContent } from './components/UnprocessedEntities'; +export { + type CatalogUnprocessedEntitiesApiResponse, + type CatalogUnprocessedEntitiesApi, + catalogUnprocessedEntitiesApiRef, +} from './api'; +export type { + UnprocessedEntity, + UnprocessedEntityCache, + UnprocessedEntityError, +} from './types'; diff --git a/plugins/catalog-unprocessed-entities/src/plugin.ts b/plugins/catalog-unprocessed-entities/src/plugin.ts index 14598c825b..baf7278454 100644 --- a/plugins/catalog-unprocessed-entities/src/plugin.ts +++ b/plugins/catalog-unprocessed-entities/src/plugin.ts @@ -23,7 +23,7 @@ import { import { rootRouteRef } from './routes'; import { - CatalogUnprocessedEntitiesApi, + CatalogUnprocessedEntitiesClient, catalogUnprocessedEntitiesApiRef, } from './api'; @@ -42,7 +42,7 @@ export const catalogUnprocessedEntitiesPlugin = createPlugin({ api: catalogUnprocessedEntitiesApiRef, deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef }, factory: ({ discoveryApi, fetchApi }) => - new CatalogUnprocessedEntitiesApi(discoveryApi, fetchApi), + new CatalogUnprocessedEntitiesClient(discoveryApi, fetchApi), }), ], }); diff --git a/plugins/catalog-unprocessed-entities/src/types.ts b/plugins/catalog-unprocessed-entities/src/types.ts index 490027b57a..65f21970f5 100644 --- a/plugins/catalog-unprocessed-entities/src/types.ts +++ b/plugins/catalog-unprocessed-entities/src/types.ts @@ -15,6 +15,10 @@ */ import { Entity } from '@backstage/catalog-model'; +/** + * Unprocessed entity data stored in the database. + * @public + */ export type UnprocessedEntity = { entity_id: string; entity_ref: string; @@ -29,11 +33,19 @@ export type UnprocessedEntity = { location_key?: string; }; +/** + * Unprocessed entity cache stored in the database. + * @public + */ export type UnprocessedEntityCache = { ttl: number; cache: object; }; +/** + * Unprocessed entity error information stored in the database. + * @public + */ export type UnprocessedEntityError = { name: string; message: string; diff --git a/plugins/devtools/README.md b/plugins/devtools/README.md index 0ad7bfae61..09e76caaa4 100644 --- a/plugins/devtools/README.md +++ b/plugins/devtools/README.md @@ -44,6 +44,12 @@ Lists the status of configured External Dependencies based on your current runni ![Example of external dependencies tab](./docs/devtools-external-dependencies.png) +### Catalog Unprocessed Entities + +The [Catalog Unprocessed Entities plugin](https://github.com/backstage/backstage/tree/master/plugins/catalog-unprocessed-entities) has an optional tab that you can also be added that will show unprocessed entities: + +![Example of unprocessed entities tab](./docs/catalog-unprocessed-entities-tab.png) + ## Setup The following sections will help you get the DevTools plugin setup and running. @@ -149,6 +155,43 @@ The DevTools plugin has been designed so that you can customize the tabs to suit With this setup you can add or remove the tabs as you'd like or add your own simply by editing your `CustomDevToolsPage.tsx` file +### Adding Tabs From Other Plugins + +You can also add tabs to show content from other plugins that fit well with the other DevTools content. + +#### Catalog Unprocessed Entities Tab + +Here's how to add the Catalog Unprocessed Entities tab: + +1. Install and setup the [Catalog Unprocessed Entities plugin](https://github.com/backstage/backstage/tree/master/plugins/catalog-unprocessed-entities) as per its documentation +2. Add the following import to your `CustomDevToolsPage.tsx`: + + `import { UnprocessedEntitiesContent } from '@backstage/plugin-catalog-unprocessed-entities';` + +3. Then add a new `DevToolsLayout.Route` to the end of your `DevToolsLayout` like this: + + ```diff + + + + + + + + + + + + + + + + + + ``` + +4. Now run `yarn dev` and navigate to the DevTools you'll see a new tab for Unprocessed Entities + ## Permissions The DevTools plugin supports the [permissions framework](https://backstage.io/docs/permissions/overview), the following sections outline how you can use them with the assumption that you have the permissions framework setup and working. diff --git a/plugins/devtools/api-report.md b/plugins/devtools/api-report.md index c9cfbf77e5..3e3fb99ff7 100644 --- a/plugins/devtools/api-report.md +++ b/plugins/devtools/api-report.md @@ -15,12 +15,14 @@ export const ConfigContent: () => JSX.Element; // @public export const DevToolsLayout: { - ({ children }: DevToolsLayoutProps): JSX.Element; + ({ children, title, subtitle }: DevToolsLayoutProps): JSX.Element; Route: (props: SubRoute) => null; }; // @public (undocumented) export type DevToolsLayoutProps = { + title?: string; + subtitle?: string; children?: default_2.ReactNode; }; diff --git a/plugins/devtools/docs/catalog-unprocessed-entities-tab.png b/plugins/devtools/docs/catalog-unprocessed-entities-tab.png new file mode 100644 index 0000000000..82afdcb759 Binary files /dev/null and b/plugins/devtools/docs/catalog-unprocessed-entities-tab.png differ diff --git a/plugins/devtools/src/components/DevToolsLayout/DevToolsLayout.tsx b/plugins/devtools/src/components/DevToolsLayout/DevToolsLayout.tsx index 12cd3f7666..ae9a337ced 100644 --- a/plugins/devtools/src/components/DevToolsLayout/DevToolsLayout.tsx +++ b/plugins/devtools/src/components/DevToolsLayout/DevToolsLayout.tsx @@ -40,6 +40,8 @@ attachComponentData(Route, 'core.gatherMountPoints', true); /** @public */ export type DevToolsLayoutProps = { + title?: string; + subtitle?: string; children?: React.ReactNode; }; @@ -56,7 +58,11 @@ export type DevToolsLayoutProps = { * ``` * @public */ -export const DevToolsLayout = ({ children }: DevToolsLayoutProps) => { +export const DevToolsLayout = ({ + children, + title, + subtitle, +}: DevToolsLayoutProps) => { const routes = useElementFilter(children, elements => elements .selectByComponentData({ @@ -70,7 +76,7 @@ export const DevToolsLayout = ({ children }: DevToolsLayoutProps) => { return ( -
+
); diff --git a/plugins/dynatrace/src/components/Problems/ProblemsList/ProblemsList.tsx b/plugins/dynatrace/src/components/Problems/ProblemsList/ProblemsList.tsx index 2ee0dda48d..9a4ef4d9b9 100644 --- a/plugins/dynatrace/src/components/Problems/ProblemsList/ProblemsList.tsx +++ b/plugins/dynatrace/src/components/Problems/ProblemsList/ProblemsList.tsx @@ -43,6 +43,31 @@ const cardContents = ( ); }; +const dynatraceEntityPrefixes = (idPrefix: string): string => { + switch (idPrefix) { + case 'APPLICATION': + return '#uemapplications/uemappmetrics;uemapplicationId='; + + case 'SERVICE': + return '#services/serviceOverview;id='; + + case `MOBILE_APPLICATION`: + return '#mobileappoverview;appID='; + + case 'SYNTHETIC_TEST': + return 'ui/browser-monitor/'; + + case 'KUBERNETES_CLUSTER': + return 'ui/kubernetes/'; + + case 'PROCESS_GROUP_INSTANCE': + return '#processdetails;id='; + + default: + return 'ui/entity/'; + } +}; + export const ProblemsList = (props: ProblemsListProps) => { const { dynatraceEntityId } = props; const configApi = useApi(configApiRef); @@ -54,6 +79,10 @@ export const ProblemsList = (props: ProblemsListProps) => { }, [dynatraceApi, dynatraceEntityId]); const problems = value?.problems; + const deepLinkPrefix = dynatraceEntityPrefixes( + `${dynatraceEntityId.split('-')[0]}`, + ); + if (loading) { return ; } else if (error) { @@ -65,7 +94,7 @@ export const ProblemsList = (props: ProblemsListProps) => { subheader={`Last 2 hours - ${dynatraceEntityId}`} deepLink={{ title: 'View Entity in Dynatrace', - link: `${dynatraceBaseUrl}/#serviceOverview;id=${dynatraceEntityId}`, + link: `${dynatraceBaseUrl}/${deepLinkPrefix}${dynatraceEntityId}`, }} > {cardContents(problems || [], dynatraceBaseUrl)} diff --git a/plugins/entity-feedback-backend/README.md b/plugins/entity-feedback-backend/README.md index ef180dbae5..99489e28b2 100644 --- a/plugins/entity-feedback-backend/README.md +++ b/plugins/entity-feedback-backend/README.md @@ -48,3 +48,18 @@ async function main() { apiRouter.use(notFoundHandler()); ``` + +### New Backend System + +The Entity Feedback backend plugin has support for the [new backend system](https://backstage.io/docs/backend-system/), here's how you can set that up: +In your `packages/backend/src/index.ts` make the following changes: + +```diff ++ import { entityFeedbackPlugin } from '@backstage/plugin-entity-feedback-backend'; + +const backend = createBackend(); ++ backend.add(entityFeedbackPlugin()); +// ... other feature additions + +backend.start(); +``` diff --git a/plugins/entity-feedback-backend/api-report.md b/plugins/entity-feedback-backend/api-report.md index 3909ac3056..3e8f90220e 100644 --- a/plugins/entity-feedback-backend/api-report.md +++ b/plugins/entity-feedback-backend/api-report.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; import express from 'express'; import { IdentityApi } from '@backstage/plugin-auth-node'; import { Logger } from 'winston'; @@ -12,6 +13,9 @@ import { PluginEndpointDiscovery } from '@backstage/backend-common'; // @public (undocumented) export function createRouter(options: RouterOptions): Promise; +// @public +export const entityFeedbackPlugin: () => BackendFeature; + // @public (undocumented) export interface RouterOptions { // (undocumented) diff --git a/plugins/entity-feedback-backend/package.json b/plugins/entity-feedback-backend/package.json index c09b011533..7cf3c40ffe 100644 --- a/plugins/entity-feedback-backend/package.json +++ b/plugins/entity-feedback-backend/package.json @@ -23,6 +23,7 @@ }, "dependencies": { "@backstage/backend-common": "workspace:^", + "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", diff --git a/plugins/entity-feedback-backend/src/index.ts b/plugins/entity-feedback-backend/src/index.ts index b3c4139eed..74e545de04 100644 --- a/plugins/entity-feedback-backend/src/index.ts +++ b/plugins/entity-feedback-backend/src/index.ts @@ -20,3 +20,4 @@ * @packageDocumentation */ export * from './service/router'; +export { entityFeedbackPlugin } from './plugin'; diff --git a/plugins/entity-feedback-backend/src/plugin.ts b/plugins/entity-feedback-backend/src/plugin.ts new file mode 100644 index 0000000000..6a4ff442ce --- /dev/null +++ b/plugins/entity-feedback-backend/src/plugin.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { loggerToWinstonLogger } from '@backstage/backend-common'; +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { createRouter } from './service/router'; + +/** + * The Entity Feedback backend plugin. + * + * @public + */ +export const entityFeedbackPlugin = createBackendPlugin({ + pluginId: 'entity-feedback', + register(env) { + env.registerInit({ + deps: { + discovery: coreServices.discovery, + database: coreServices.database, + identity: coreServices.identity, + logger: coreServices.logger, + httpRouter: coreServices.httpRouter, + }, + async init({ database, discovery, identity, logger, httpRouter }) { + httpRouter.use( + await createRouter({ + database, + discovery, + identity, + logger: loggerToWinstonLogger(logger), + }), + ); + }, + }); + }, +}); diff --git a/plugins/home/package.json b/plugins/home/package.json index ae2ea7ea1f..c5aa8ee238 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -44,7 +44,7 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@rjsf/core-v5": "npm:@rjsf/core@5.7.3", - "@rjsf/material-ui": "5.7.3", + "@rjsf/material-ui-v5": "npm:@rjsf/material-ui@5.7.3", "@rjsf/utils": "5.7.3", "@rjsf/validator-ajv8": "5.7.3", "@types/react": "^16.13.1 || ^17.0.0", diff --git a/plugins/home/src/components/CustomHomepage/WidgetSettingsOverlay.tsx b/plugins/home/src/components/CustomHomepage/WidgetSettingsOverlay.tsx index 65e0917fb1..1d863c020d 100644 --- a/plugins/home/src/components/CustomHomepage/WidgetSettingsOverlay.tsx +++ b/plugins/home/src/components/CustomHomepage/WidgetSettingsOverlay.tsx @@ -30,7 +30,7 @@ import { Widget } from './types'; import { withTheme } from '@rjsf/core-v5'; import validator from '@rjsf/validator-ajv8'; -const Form = withTheme(require('@rjsf/material-ui').Theme); +const Form = withTheme(require('@rjsf/material-ui-v5').Theme); const useStyles = makeStyles((theme: Theme) => createStyles({ diff --git a/plugins/kubernetes-backend/README.md b/plugins/kubernetes-backend/README.md index b724babca3..742ef79692 100644 --- a/plugins/kubernetes-backend/README.md +++ b/plugins/kubernetes-backend/README.md @@ -16,4 +16,4 @@ The plugin requires configuration in the Backstage `app-config.yaml` to connect In addition, configuration of an entity's `catalog-info.yaml` helps identify which specific Kubernetes object(s) should be presented on a specific entity catalog page. -For more information, see the [formal documentation about the Kubernetes feature in Backstage](https://backstage.io/docs/features/kubernetes/overview). +For more information, see the [formal documentation about the Kubernetes feature in Backstage](https://backstage.io/docs/features/kubernetes/). diff --git a/plugins/nomad/src/Router.tsx b/plugins/nomad/src/Router.tsx index d7e6db1b44..4a3377779a 100644 --- a/plugins/nomad/src/Router.tsx +++ b/plugins/nomad/src/Router.tsx @@ -15,29 +15,15 @@ */ import React from 'react'; -import { Entity } from '@backstage/catalog-model'; import { useEntity } from '@backstage/plugin-catalog-react'; import { MissingAnnotationEmptyState } from '@backstage/core-components'; import { Route, Routes } from 'react-router-dom'; import { EntityNomadAllocationListTable } from './components/EntityNomadAllocationListTable/EntityNomadAllocationListTable'; - -/** @public */ -export const NOMAD_NAMESPACE_ANNOTATION = 'nomad.io/namespace'; - -/** @public */ -export const NOMAD_JOB_ID_ANNOTATION = 'nomad.io/job-id'; - -/** @public */ -export const NOMAD_GROUP_ANNOTATION = 'nomad.io/group'; - -/** @public */ -export const isNomadJobIDAvailable = (entity: Entity) => - Boolean(entity.metadata.annotations?.[NOMAD_JOB_ID_ANNOTATION]); - -/** @public */ -export const isNomadAllocationsAvailable = (entity: Entity) => - Boolean(entity.metadata.annotations?.[NOMAD_JOB_ID_ANNOTATION]) || - Boolean(entity.metadata.annotations?.[NOMAD_GROUP_ANNOTATION]); +import { + NOMAD_GROUP_ANNOTATION, + NOMAD_JOB_ID_ANNOTATION, + isNomadAllocationsAvailable, +} from './annotations'; export const EmbeddedRouter = () => { const { entity } = useEntity(); diff --git a/plugins/nomad/src/annotations.ts b/plugins/nomad/src/annotations.ts new file mode 100644 index 0000000000..9854288e5d --- /dev/null +++ b/plugins/nomad/src/annotations.ts @@ -0,0 +1,35 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; + +/** @public */ +export const NOMAD_NAMESPACE_ANNOTATION = 'nomad.io/namespace'; + +/** @public */ +export const NOMAD_JOB_ID_ANNOTATION = 'nomad.io/job-id'; + +/** @public */ +export const NOMAD_GROUP_ANNOTATION = 'nomad.io/group'; + +/** @public */ +export const isNomadJobIDAvailable = (entity: Entity) => + Boolean(entity.metadata.annotations?.[NOMAD_JOB_ID_ANNOTATION]); + +/** @public */ +export const isNomadAllocationsAvailable = (entity: Entity) => + Boolean(entity.metadata.annotations?.[NOMAD_JOB_ID_ANNOTATION]) || + Boolean(entity.metadata.annotations?.[NOMAD_GROUP_ANNOTATION]); diff --git a/plugins/nomad/src/components/EntityNomadAllocationListTable/EntityNomadAllocationListTable.tsx b/plugins/nomad/src/components/EntityNomadAllocationListTable/EntityNomadAllocationListTable.tsx index 6d7a79c002..cc19d1ec53 100644 --- a/plugins/nomad/src/components/EntityNomadAllocationListTable/EntityNomadAllocationListTable.tsx +++ b/plugins/nomad/src/components/EntityNomadAllocationListTable/EntityNomadAllocationListTable.tsx @@ -35,7 +35,7 @@ import { NOMAD_JOB_ID_ANNOTATION, NOMAD_NAMESPACE_ANNOTATION, isNomadAllocationsAvailable, -} from '../../Router'; +} from '../../annotations'; import useAsync from 'react-use/lib/useAsync'; type rowType = Allocation & { nomadAddr: string }; diff --git a/plugins/nomad/src/components/EntityNomadJobVersionListCard/EntityNomadJobVersionListCard.tsx b/plugins/nomad/src/components/EntityNomadJobVersionListCard/EntityNomadJobVersionListCard.tsx index 0c1863b95e..bb4e4b0fad 100644 --- a/plugins/nomad/src/components/EntityNomadJobVersionListCard/EntityNomadJobVersionListCard.tsx +++ b/plugins/nomad/src/components/EntityNomadJobVersionListCard/EntityNomadJobVersionListCard.tsx @@ -30,7 +30,7 @@ import { NOMAD_JOB_ID_ANNOTATION, NOMAD_NAMESPACE_ANNOTATION, isNomadJobIDAvailable, -} from '../../Router'; +} from '../../annotations'; import OpenInNewIcon from '@material-ui/icons/OpenInNew'; import { Chip } from '@material-ui/core'; diff --git a/plugins/nomad/src/components/index.ts b/plugins/nomad/src/components/index.ts index 3951061b23..dcdae8cc99 100644 --- a/plugins/nomad/src/components/index.ts +++ b/plugins/nomad/src/components/index.ts @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { EntityNomadJobVersionListCard } from './EntityNomadJobVersionListCard/EntityNomadJobVersionListCard'; -import { EntityNomadAllocationListTable } from './EntityNomadAllocationListTable/EntityNomadAllocationListTable'; -export { EntityNomadJobVersionListCard, EntityNomadAllocationListTable }; +export { EntityNomadJobVersionListCard } from './EntityNomadJobVersionListCard/EntityNomadJobVersionListCard'; +export { EntityNomadAllocationListTable } from './EntityNomadAllocationListTable/EntityNomadAllocationListTable'; diff --git a/plugins/nomad/src/index.ts b/plugins/nomad/src/index.ts index 3785a5c7b5..d139935f1f 100644 --- a/plugins/nomad/src/index.ts +++ b/plugins/nomad/src/index.ts @@ -18,4 +18,7 @@ export { EntityNomadJobVersionListCard, EntityNomadAllocationListTable, } from './plugin'; -export { isNomadAllocationsAvailable, isNomadJobIDAvailable } from './Router'; +export { + isNomadAllocationsAvailable, + isNomadJobIDAvailable, +} from './annotations'; diff --git a/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.tsx b/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.tsx index 21c961eb91..01e3bd08ff 100644 --- a/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.tsx +++ b/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.tsx @@ -26,7 +26,7 @@ import SwapVertIcon from '@material-ui/icons/SwapVert'; import React from 'react'; import useEffectOnce from 'react-use/lib/useEffectOnce'; -import { usePlaylistList } from '../../hooks'; +import { usePlaylistList } from '../../hooks/usePlaylistList'; import { PlaylistSortCompareFunction } from '../../types'; export const enum DefaultPlaylistSortTypes { diff --git a/plugins/search-react/src/components/SearchBar/SearchBar.test.tsx b/plugins/search-react/src/components/SearchBar/SearchBar.test.tsx index e4859861d9..9b4664aceb 100644 --- a/plugins/search-react/src/components/SearchBar/SearchBar.test.tsx +++ b/plugins/search-react/src/components/SearchBar/SearchBar.test.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { screen, render, waitFor, act } from '@testing-library/react'; +import { screen, waitFor, act } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { configApiRef, analyticsApiRef } from '@backstage/core-plugin-api'; import { ConfigReader } from '@backstage/core-app-api'; @@ -41,16 +41,23 @@ const createInitialState = ({ }); describe('SearchBar', () => { + const user = userEvent.setup({ delay: null }); + const query = jest.fn().mockResolvedValue({ results: [] }); - const analyticsApiMock = new MockAnalyticsApi(); + const searchApiMock = { query }; const configApiMock = new ConfigReader({ - app: { title: 'Mock title' }, + app: { + title: 'Mock title', + analytics: { + ga: { + trackingId: 'xyz123', + }, + }, + }, }); - const searchApiMock = { query }; - beforeEach(() => { jest.clearAllMocks(); }); @@ -64,20 +71,20 @@ describe('SearchBar', () => { ]} > - + , ); - await waitFor(() => { - expect(screen.getByLabelText('Search')).toBeInTheDocument(); - }); + await waitFor(() => + expect(screen.getByLabelText('Search')).toBeInTheDocument(), + ); }); it('Renders with custom label', async () => { const label = 'label'; - const result = await renderWithEffects( + await renderWithEffects( { ]} > - + , ); - await waitFor(() => { - expect(result.getByLabelText(label)).toBeInTheDocument(); - }); + await waitFor(() => + expect(screen.getByLabelText(label)).toBeInTheDocument(), + ); }); it('Renders with custom placeholder', async () => { @@ -106,20 +113,20 @@ describe('SearchBar', () => { ]} > - + , ); - await waitFor(() => { - expect(screen.getByPlaceholderText(placeholder)).toBeInTheDocument(); - }); + await waitFor(() => + expect(screen.getByPlaceholderText(placeholder)).toBeInTheDocument(), + ); }); it('Renders based on initial search', async () => { const term = 'term'; - render( + await renderWithEffects( { ]} > - + , ); - await waitFor(() => { - expect(screen.getByRole('textbox', { name: 'Search' })).toHaveValue(term); - }); + await waitFor(() => + expect(screen.getByLabelText('Search')).toHaveValue(term), + ); }); it('Updates term state when text is entered', async () => { jest.useFakeTimers(); - const user = userEvent.setup({ delay: null }); await renderWithEffects( { , ); - const textbox = screen.getByRole('textbox', { name: 'Search' }); + const textbox = screen.getByLabelText('Search'); const value = 'value'; @@ -164,14 +170,13 @@ describe('SearchBar', () => { jest.advanceTimersByTime(200); }); - await waitFor(() => { - expect(textbox).toHaveValue(value); - }); + await waitFor(() => expect(textbox).toHaveValue(value)); expect(query).toHaveBeenLastCalledWith( expect.objectContaining({ term: value }), ); + jest.runAllTimers(); jest.useRealTimers(); }); @@ -186,22 +191,18 @@ describe('SearchBar', () => { ]} > - + , ); - const textbox = screen.getByRole('textbox', { name: 'Search' }); + const textbox = screen.getByLabelText('Search'); - await waitFor(() => { - expect(textbox).toHaveValue(term); - }); + await waitFor(() => expect(textbox).toHaveValue(term)); - await userEvent.click(screen.getByRole('button', { name: 'Clear' })); + await user.click(screen.getByLabelText('Clear')); - await waitFor(() => { - expect(textbox).toHaveValue(''); - }); + await waitFor(() => expect(textbox).toHaveValue('')); expect(query).toHaveBeenLastCalledWith( expect.objectContaining({ term: '' }), @@ -219,22 +220,20 @@ describe('SearchBar', () => { ]} > - + , ); - await waitFor(() => { - expect( - screen.queryByRole('button', { name: 'Clear' }), - ).not.toBeInTheDocument(); - }); + await waitFor(() => + expect(screen.queryByLabelText('Clear')).not.toBeInTheDocument(), + ); }); it('Adheres to provided debounceTime', async () => { jest.useFakeTimers(); - const user = userEvent.setup({ delay: null }); - const debounceTime = 600; + + const debounceTime = 100; await renderWithEffects( { , ); - const textbox = await screen.findByRole('textbox', { name: 'Search' }); + const textbox = screen.getByLabelText('Search'); const value = 'value'; await user.type(textbox, value); - await waitFor(() => { + await waitFor(() => expect(query).not.toHaveBeenLastCalledWith( expect.objectContaining({ term: value }), - ); - }); + ), + ); act(() => { jest.advanceTimersByTime(debounceTime); }); - await waitFor(() => { - expect(textbox).toHaveValue(value); - }); + await waitFor(() => expect(textbox).toHaveValue(value)); expect(query).toHaveBeenLastCalledWith( expect.objectContaining({ term: value }), ); + jest.runAllTimers(); jest.useRealTimers(); }); - it('does not capture analytics event if not enabled in app', async () => { - jest.useFakeTimers(); - const user = userEvent.setup({ delay: null }); + it('Does not capture analytics event if not enabled in app', async () => { + const analyticsApiMock = new MockAnalyticsApi(); await renderWithEffects( { ]} > - + , ); - const textbox = await screen.findByRole('textbox', { name: 'Search' }); + const textbox = screen.getByLabelText('Search'); const value = 'value'; await user.type(textbox, value); - act(() => { - jest.advanceTimersByTime(200); - }); - - await waitFor(() => { - expect(textbox).toHaveValue(value); - }); + await waitFor(() => expect(textbox).toHaveValue(value)); expect(analyticsApiMock.getEvents()).toHaveLength(0); - - jest.useRealTimers(); }); - it('captures analytics events if enabled in app', async () => { - jest.useFakeTimers(); - const user = userEvent.setup({ delay: null }); + it('Captures analytics events if enabled in app', async () => { + const analyticsApiMock = new MockAnalyticsApi(); + const types = ['techdocs', 'software-catalog']; await renderWithEffects( - + , ); - const textbox = await screen.findByRole('textbox', { name: 'Search' }); + const textbox = screen.getByLabelText('Search'); let value = 'value'; - await user.type(textbox, value); - - expect(analyticsApiMock.getEvents()).toHaveLength(0); - - act(() => { - jest.advanceTimersByTime(200); + await waitFor(() => { + expect(analyticsApiMock.getEvents()).toHaveLength(1); + expect(textbox).toHaveValue(value); + expect(analyticsApiMock.getEvents()[0]).toEqual({ + action: 'search', + context: { + extension: 'SearchBar', + pluginId: 'search', + routeRef: 'unknown', + searchTypes: types.toString(), + }, + subject: value, + }); }); - await waitFor(() => expect(textbox).toHaveValue(value)); - - expect(analyticsApiMock.getEvents()).toHaveLength(1); - expect(analyticsApiMock.getEvents()[0]).toEqual({ - action: 'search', - context: { - extension: 'SearchBar', - pluginId: 'search', - routeRef: 'unknown', - searchTypes: types.toString(), - }, - subject: value, - }); - - await user.clear(textbox); - value = 'new value'; - + await user.clear(textbox); // make sure new term is captured await user.type(textbox, value); - - act(() => { - jest.advanceTimersByTime(200); + await waitFor(() => { + expect(analyticsApiMock.getEvents()).toHaveLength(2); + expect(textbox).toHaveValue(value); + expect(analyticsApiMock.getEvents()[1]).toEqual({ + action: 'search', + context: { + extension: 'SearchBar', + pluginId: 'search', + routeRef: 'unknown', + searchTypes: types.toString(), + }, + subject: value, + }); }); - - await waitFor(() => expect(textbox).toHaveValue(value)); - - expect(analyticsApiMock.getEvents()).toHaveLength(2); - expect(analyticsApiMock.getEvents()[1]).toEqual({ - action: 'search', - context: { - extension: 'SearchBar', - pluginId: 'search', - routeRef: 'unknown', - searchTypes: types.toString(), - }, - subject: value, - }); - - jest.useRealTimers(); }); }); diff --git a/plugins/stackstorm/api-report.md b/plugins/stackstorm/api-report.md index 3e3d79fe27..7a307847cd 100644 --- a/plugins/stackstorm/api-report.md +++ b/plugins/stackstorm/api-report.md @@ -6,10 +6,18 @@ /// import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; +// @public (undocumented) +export type StackstormHomeProps = { + title?: string; + subtitle?: string; + headerButtons?: React_2.ReactNode[]; +}; + // @public -export const StackstormPage: () => JSX.Element; +export const StackstormPage: (props: StackstormHomeProps) => JSX.Element; // @public export const stackstormPlugin: BackstagePlugin< diff --git a/plugins/stackstorm/package.json b/plugins/stackstorm/package.json index 1f3a014b0a..9125ac08af 100644 --- a/plugins/stackstorm/package.json +++ b/plugins/stackstorm/package.json @@ -40,6 +40,7 @@ "@backstage/theme": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", + "@types/react": "^16.13.1 || ^17.0.0", "react-use": "^17.2.4" }, "peerDependencies": { @@ -57,7 +58,6 @@ "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "*", - "@types/react": "^16.13.1 || ^17.0.0", "msw": "^1.0.0" }, "files": [ diff --git a/plugins/stackstorm/src/components/StackstormHome/StackstormHome.test.tsx b/plugins/stackstorm/src/components/StackstormHome/StackstormHome.test.tsx index 897cec61c1..e3db4c0cac 100644 --- a/plugins/stackstorm/src/components/StackstormHome/StackstormHome.test.tsx +++ b/plugins/stackstorm/src/components/StackstormHome/StackstormHome.test.tsx @@ -35,4 +35,19 @@ describe('StackstormHome', () => { ); expect(screen.getByText('Welcome to StackStorm!')).toBeInTheDocument(); }); + + it('should render props', async () => { + await renderInTestApp( + + Test Header Button]} + /> + , + ); + expect(screen.getByText('Test Title')).toBeInTheDocument(); + expect(screen.getByText('Test Subtitle')).toBeInTheDocument(); + expect(screen.getByText('Test Header Button')).toBeInTheDocument(); + }); }); diff --git a/plugins/stackstorm/src/components/StackstormHome/StackstormHome.tsx b/plugins/stackstorm/src/components/StackstormHome/StackstormHome.tsx index d96d45e82d..1bb9031815 100644 --- a/plugins/stackstorm/src/components/StackstormHome/StackstormHome.tsx +++ b/plugins/stackstorm/src/components/StackstormHome/StackstormHome.tsx @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react'; +import React, { Fragment } from 'react'; import { IconButton } from '@material-ui/core'; import { Header, @@ -27,12 +27,30 @@ import { ExecutionsTable } from '../ExecutionsTable'; import { PacksTable } from '../PacksTable/PacksTable'; import { ActionsList } from '../ActionsList'; -export const StackstormHome = () => ( +/** + * @public + */ +export type StackstormHomeProps = { + title?: string; + subtitle?: string; + headerButtons?: React.ReactNode[]; +}; + +export const StackstormHome = (props: StackstormHomeProps) => ( -
- - - +
+ {props.headerButtons ? ( + props.headerButtons.map((headerButton, idx) => ( + {headerButton} + )) + ) : ( + + + + )}
diff --git a/plugins/stackstorm/src/components/StackstormHome/index.ts b/plugins/stackstorm/src/components/StackstormHome/index.ts index 2063d21f34..7809223ede 100644 --- a/plugins/stackstorm/src/components/StackstormHome/index.ts +++ b/plugins/stackstorm/src/components/StackstormHome/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { StackstormHome } from './StackstormHome'; +export { StackstormHome, type StackstormHomeProps } from './StackstormHome'; diff --git a/plugins/stackstorm/src/index.ts b/plugins/stackstorm/src/index.ts index b64ae207e4..6775a000fa 100644 --- a/plugins/stackstorm/src/index.ts +++ b/plugins/stackstorm/src/index.ts @@ -21,3 +21,4 @@ */ export { stackstormPlugin, StackstormPage } from './plugin'; +export { type StackstormHomeProps } from './components/StackstormHome'; diff --git a/storybook/yarn.lock b/storybook/yarn.lock index 4143a2fa67..cc6dbbc07b 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -2943,90 +2943,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-darwin-arm64@npm:1.3.62" +"@swc/core-darwin-arm64@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-darwin-arm64@npm:1.3.66" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-darwin-x64@npm:1.3.62" +"@swc/core-darwin-x64@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-darwin-x64@npm:1.3.66" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.62" +"@swc/core-linux-arm-gnueabihf@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.66" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.62" +"@swc/core-linux-arm64-gnu@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.66" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.62" +"@swc/core-linux-arm64-musl@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.66" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.62" +"@swc/core-linux-x64-gnu@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.66" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-x64-musl@npm:1.3.62" +"@swc/core-linux-x64-musl@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-x64-musl@npm:1.3.66" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.62" +"@swc/core-win32-arm64-msvc@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.66" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.62" +"@swc/core-win32-ia32-msvc@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.66" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.62" +"@swc/core-win32-x64-msvc@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.66" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.3.62 - resolution: "@swc/core@npm:1.3.62" + version: 1.3.66 + resolution: "@swc/core@npm:1.3.66" dependencies: - "@swc/core-darwin-arm64": 1.3.62 - "@swc/core-darwin-x64": 1.3.62 - "@swc/core-linux-arm-gnueabihf": 1.3.62 - "@swc/core-linux-arm64-gnu": 1.3.62 - "@swc/core-linux-arm64-musl": 1.3.62 - "@swc/core-linux-x64-gnu": 1.3.62 - "@swc/core-linux-x64-musl": 1.3.62 - "@swc/core-win32-arm64-msvc": 1.3.62 - "@swc/core-win32-ia32-msvc": 1.3.62 - "@swc/core-win32-x64-msvc": 1.3.62 + "@swc/core-darwin-arm64": 1.3.66 + "@swc/core-darwin-x64": 1.3.66 + "@swc/core-linux-arm-gnueabihf": 1.3.66 + "@swc/core-linux-arm64-gnu": 1.3.66 + "@swc/core-linux-arm64-musl": 1.3.66 + "@swc/core-linux-x64-gnu": 1.3.66 + "@swc/core-linux-x64-musl": 1.3.66 + "@swc/core-win32-arm64-msvc": 1.3.66 + "@swc/core-win32-ia32-msvc": 1.3.66 + "@swc/core-win32-x64-msvc": 1.3.66 peerDependencies: "@swc/helpers": ^0.5.0 dependenciesMeta: @@ -3053,7 +3053,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: a7a0d9ffdb8a2b0050e0ff89fdb86fe189d9bcb7f91cb6847f1bfe3e2b520a87ea2e83692dfd80b6d541fb5addb2194769484516b8ca6d3c62ad80f1c79a9368 + checksum: e6029c648ba47c522bed51a9f2fee606f82de1f9233e2e89197e43b0a4867054174ca05e825e688cdc4de332221c0da2e12ba7ba875549e8b5432aa70fe19263 languageName: node linkType: hard @@ -5513,13 +5513,13 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.14.1": - version: 5.14.1 - resolution: "enhanced-resolve@npm:5.14.1" +"enhanced-resolve@npm:^5.15.0": + version: 5.15.0 + resolution: "enhanced-resolve@npm:5.15.0" dependencies: graceful-fs: ^4.2.4 tapable: ^2.2.0 - checksum: ad2a31928b6649eed40d364838449587f731baa63863e83d2629bebaa8be1eabac18b90f89c1784bc805b0818363e99b22547159edd485d7e5ccf18cdc640642 + checksum: fbd8cdc9263be71cc737aa8a7d6c57b43d6aa38f6cc75dde6fcd3598a130cc465f979d2f4d01bb3bf475acb43817749c79f8eef9be048683602ca91ab52e4f11 languageName: node linkType: hard @@ -10282,14 +10282,14 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1, schema-utils@npm:^3.1.2": - version: 3.1.2 - resolution: "schema-utils@npm:3.1.2" +"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1, schema-utils@npm:^3.2.0": + version: 3.3.0 + resolution: "schema-utils@npm:3.3.0" dependencies: "@types/json-schema": ^7.0.8 ajv: ^6.12.5 ajv-keywords: ^3.5.2 - checksum: 39683edfe3beff018cdb1ae4fa296fc55cea13a080aa2b4d9351895cd64b22ba4d87e2e548c2a2ac1bc76e60980670adb0f413a58104479f1a0c12e5663cb8ca + checksum: ea56971926fac2487f0757da939a871388891bc87c6a82220d125d587b388f1704788f3706e7f63a7b70e49fc2db974c41343528caea60444afd5ce0fe4b85c0 languageName: node linkType: hard @@ -11863,8 +11863,8 @@ __metadata: linkType: hard "webpack@npm:^5.73.0": - version: 5.85.0 - resolution: "webpack@npm:5.85.0" + version: 5.88.0 + resolution: "webpack@npm:5.88.0" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.0 @@ -11875,7 +11875,7 @@ __metadata: acorn-import-assertions: ^1.9.0 browserslist: ^4.14.5 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^5.14.1 + enhanced-resolve: ^5.15.0 es-module-lexer: ^1.2.1 eslint-scope: 5.1.1 events: ^3.2.0 @@ -11885,7 +11885,7 @@ __metadata: loader-runner: ^4.2.0 mime-types: ^2.1.27 neo-async: ^2.6.2 - schema-utils: ^3.1.2 + schema-utils: ^3.2.0 tapable: ^2.1.1 terser-webpack-plugin: ^5.3.7 watchpack: ^2.4.0 @@ -11895,7 +11895,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: b013be9fbc7f6810d1f229f570c70710ddbc7290f817411acffe4214b2b6c783a041ab1f2005d9e1109f4ab21c136f0f8d8c067a5fb64f20a82dcbc1ee0d3f42 + checksum: 9fd1568b34ec2e99ba97c8509a15ab2576ec80c396e7015551ec814b24cfc11de173acba3e114dafe95f1a6d460781b09d6201e6a1fb15110e1d01a09f61a283 languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index bd1fbc6204..a2b10a747c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -192,8 +192,8 @@ __metadata: linkType: hard "@apollo/server@npm:^4.0.0": - version: 4.7.3 - resolution: "@apollo/server@npm:4.7.3" + version: 4.7.4 + resolution: "@apollo/server@npm:4.7.4" dependencies: "@apollo/cache-control-types": ^1.0.2 "@apollo/server-gateway-interface": ^1.1.0 @@ -223,7 +223,7 @@ __metadata: whatwg-mimetype: ^3.0.0 peerDependencies: graphql: ^16.6.0 - checksum: afc97f4f2280a1b541efee92de4d6296c72109d4c0db59db534a0e47055494a24e28c6892c5fb612966ef4d024dae3ce6906022e8a44ab351449d9da0ecca5d7 + checksum: 8cdde1ead8b0cae3ce6063ae8ca979c0a56c35b474a52a9b76b14eb9f95ecd715d40a760b9c1ec4d3690ea5b6cac71fb4cd990b4b76fbeeed4d62b963d5510eb languageName: node linkType: hard @@ -6288,6 +6288,7 @@ __metadata: resolution: "@backstage/plugin-entity-feedback-backend@workspace:plugins/entity-feedback-backend" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" "@backstage/catalog-model": "workspace:^" @@ -7138,7 +7139,7 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@rjsf/core-v5": "npm:@rjsf/core@5.7.3" - "@rjsf/material-ui": 5.7.3 + "@rjsf/material-ui-v5": "npm:@rjsf/material-ui@5.7.3" "@rjsf/utils": 5.7.3 "@rjsf/validator-ajv8": 5.7.3 "@testing-library/dom": ^8.0.0 @@ -10881,27 +10882,27 @@ __metadata: languageName: node linkType: hard -"@frsource/base64@npm:1.0.14": - version: 1.0.14 - resolution: "@frsource/base64@npm:1.0.14" - checksum: 9a5b718e4ac12fd1b5bfdefcdf669fb0a125599fb6cd55564da3beeccd7a5707f58bc41f572268a8120af15ccca32355e8384341561f738397521020e0c2564c +"@frsource/base64@npm:1.0.17": + version: 1.0.17 + resolution: "@frsource/base64@npm:1.0.17" + checksum: a01689ef785516ff0b7460f55792685fc782f8507518768396acb9283270d50a8149774f3acd5fa690ccd5a48b5ec4ace90a491458ffdd9e9f591c6b23eb5da5 languageName: node linkType: hard "@frsource/cypress-plugin-visual-regression-diff@npm:^3.2.8": - version: 3.3.9 - resolution: "@frsource/cypress-plugin-visual-regression-diff@npm:3.3.9" + version: 3.3.10 + resolution: "@frsource/cypress-plugin-visual-regression-diff@npm:3.3.10" dependencies: - "@frsource/base64": 1.0.14 - glob: 8.0.3 + "@frsource/base64": 1.0.17 + glob: 8.1.0 meta-png: 1.0.6 move-file: 2.1.0 pixelmatch: 5.3.0 pngjs: 7.0.0 - sharp: 0.31.2 + sharp: 0.32.1 peerDependencies: cypress: ">=4.5.0" - checksum: da3bfaec2d54a314e8bcda915f85e9bc9f7cf53224e588a24ab594d7f0047ad9b5bbda3be8d6f63602f8612d2c7e35c8ca4de307b4f9eb098e04c3af593f090c + checksum: 879954ecba8829fd870379a1f4150a511fceab4c5a5c3df8abbab54e655e6560d52d925109364ea7f2d3484467ed5e9c3e4cfaf0058c12bbfbfc21d76ed79b40 languageName: node linkType: hard @@ -13629,8 +13630,8 @@ __metadata: linkType: hard "@octokit/oauth-app@npm:^4.0.7, @octokit/oauth-app@npm:^4.2.0, @octokit/oauth-app@npm:^4.2.1": - version: 4.2.2 - resolution: "@octokit/oauth-app@npm:4.2.2" + version: 4.2.4 + resolution: "@octokit/oauth-app@npm:4.2.4" dependencies: "@octokit/auth-oauth-app": ^5.0.0 "@octokit/auth-oauth-user": ^2.0.0 @@ -13641,7 +13642,7 @@ __metadata: "@types/aws-lambda": ^8.10.83 fromentries: ^1.3.1 universal-user-agent: ^6.0.0 - checksum: a15a849fce7c9b95d3d28583ee20a3a6b4df3d972bf65506204e05ef36998b8bc3359f918524b090157153fb3461e222b7094894bd85374159e84ad774f06ccd + checksum: 6d9798c9e63e84f3cb3031ac3f06f45c6ea053fd201be9a07a508786fd400479d7d9f6f85707d0fff7f094a265c7e966a2fa4c884001b99f02ddd927bf499d06 languageName: node linkType: hard @@ -13774,14 +13775,14 @@ __metadata: languageName: node linkType: hard -"@octokit/request-error@npm:^3.0.0": - version: 3.0.1 - resolution: "@octokit/request-error@npm:3.0.1" +"@octokit/request-error@npm:^3.0.0, @octokit/request-error@npm:^v3.0.3": + version: 3.0.3 + resolution: "@octokit/request-error@npm:3.0.3" dependencies: - "@octokit/types": ^7.0.0 + "@octokit/types": ^9.0.0 deprecation: ^2.0.0 once: ^1.4.0 - checksum: ae386b5181b3cb66b844047a21d062b683cd7ec4daf70cb9868406c1a51608a72d683955e692c7cc6237d66a09b12c6bcf102a712985da68bcedcc3820117e75 + checksum: 5db0b514732686b627e6ed9ef1ccdbc10501f1b271a9b31f784783f01beee70083d7edcfeb35fbd7e569fa31fdd6762b1ff6b46101700d2d97e7e48e749520d0 languageName: node linkType: hard @@ -13800,8 +13801,8 @@ __metadata: linkType: hard "@octokit/request@npm:^6.0.0": - version: 6.2.6 - resolution: "@octokit/request@npm:6.2.6" + version: 6.2.8 + resolution: "@octokit/request@npm:6.2.8" dependencies: "@octokit/endpoint": ^7.0.0 "@octokit/request-error": ^3.0.0 @@ -13809,19 +13810,19 @@ __metadata: is-plain-object: ^5.0.0 node-fetch: ^2.6.7 universal-user-agent: ^6.0.0 - checksum: 0732fb60e20b0348fc61d856c9e234038e34f9ce062b04b968df18c2f106da094055d55c93f653284298b03e6dac2ea5a4b5c5a97686b529ed30447bd37f2773 + checksum: 3747106f50d7c462131ff995b13defdd78024b7becc40283f4ac9ea0af2391ff33a0bb476a05aa710346fe766d20254979079a1d6f626112015ba271fe38f3e2 languageName: node linkType: hard "@octokit/rest@npm:^19.0.3": - version: 19.0.11 - resolution: "@octokit/rest@npm:19.0.11" + version: 19.0.13 + resolution: "@octokit/rest@npm:19.0.13" dependencies: "@octokit/core": ^4.2.1 "@octokit/plugin-paginate-rest": ^6.1.2 "@octokit/plugin-request-log": ^1.0.4 "@octokit/plugin-rest-endpoint-methods": ^7.1.2 - checksum: 147518ad51d214ead88adc717b5fdc4f33317949d58c124f4069bdf07d2e6b49fa66861036b9e233aed71fcb88ff367a6da0357653484e466175ab4fb7183b3b + checksum: ca1553e3fe46efabffef60e68e4a228d4cc0f0d545daf7f019560f666d3e934c6f3a6402a42bbd786af4f3c0a6e69380776312f01b7d52998fe1bbdd1b068f69 languageName: node linkType: hard @@ -14295,7 +14296,7 @@ __metadata: languageName: node linkType: hard -"@rjsf/material-ui-v5@npm:@rjsf/material-ui@5.7.3, @rjsf/material-ui@npm:5.7.3": +"@rjsf/material-ui-v5@npm:@rjsf/material-ui@5.7.3": version: 5.7.3 resolution: "@rjsf/material-ui@npm:5.7.3" peerDependencies: @@ -14350,8 +14351,8 @@ __metadata: linkType: hard "@roadiehq/backstage-plugin-buildkite@npm:^2.0.8": - version: 2.1.10 - resolution: "@roadiehq/backstage-plugin-buildkite@npm:2.1.10" + version: 2.1.11 + resolution: "@roadiehq/backstage-plugin-buildkite@npm:2.1.11" dependencies: "@backstage/catalog-model": ^1.3.0 "@backstage/core-components": ^0.13.1 @@ -14369,13 +14370,13 @@ __metadata: react-dom: ^16.13.1 || ^17.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 7463cecec0329d5b19cb539a234699d6857234a045c5eb5b1589643b2d6e2817c0942274a71aa788047c32270fc095d9e27bb389cd0fe4430058fc1e43f572d7 + checksum: 7458942f74b259782b116b50424665cd8130a00e7bd9b900499c3fdc34c67916aa382f947fcceb1b87a539842efc8f6466518e9fd74507055d4225ed28886913 languageName: node linkType: hard "@roadiehq/backstage-plugin-github-insights@npm:^2.0.5": - version: 2.3.13 - resolution: "@roadiehq/backstage-plugin-github-insights@npm:2.3.13" + version: 2.3.14 + resolution: "@roadiehq/backstage-plugin-github-insights@npm:2.3.14" dependencies: "@backstage/catalog-model": ^1.3.0 "@backstage/core-components": ^0.13.1 @@ -14397,13 +14398,13 @@ __metadata: react: ^16.13.1 || ^17.0.0 react-dom: ^16.13.1 || ^17.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 - checksum: eb555d1b4bab82cd6cf66ea823b35fedb72d1ca3a6615b619d6cd2ff24af131501346b9ac2b1dcfb83f5d69b42ac95fb96f081e644a82b75a77a71b45344f2fc + checksum: 990667bcbdbd9f2504b4c020b79bd1e809c165ac4ff93f277fe3be9e9a1247ed4e2034f992146c5e7a153aa8d268c06e3777b693a9337564117be43d321f894c languageName: node linkType: hard "@roadiehq/backstage-plugin-github-pull-requests@npm:^2.2.7": - version: 2.5.11 - resolution: "@roadiehq/backstage-plugin-github-pull-requests@npm:2.5.11" + version: 2.5.12 + resolution: "@roadiehq/backstage-plugin-github-pull-requests@npm:2.5.12" dependencies: "@backstage/catalog-model": ^1.3.0 "@backstage/core-components": ^0.13.1 @@ -14426,13 +14427,13 @@ __metadata: react: ^16.13.1 || ^17.0.0 react-dom: ^16.13.1 || ^17.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 - checksum: fe7c6cd35bbf23b4464fe94dbbd9a085b1b164bab214e095e6efc4e7ec5b5ca19670a9384541d83eeaa1a6d6ba2aa22a3f457c7166165ec0f078f18c2355e3e1 + checksum: 4113de2eb3f207e05581033c05879c98d858ef3534fb1256d5dc4f8e1f4cc33e0530952d4fd74c62df063c22af6c1e0f28af770bd55d8b41b4402df68450f98c languageName: node linkType: hard "@roadiehq/backstage-plugin-travis-ci@npm:^2.0.5": - version: 2.1.10 - resolution: "@roadiehq/backstage-plugin-travis-ci@npm:2.1.10" + version: 2.1.11 + resolution: "@roadiehq/backstage-plugin-travis-ci@npm:2.1.11" dependencies: "@backstage/catalog-model": ^1.3.0 "@backstage/core-components": ^0.13.1 @@ -14452,7 +14453,7 @@ __metadata: react-dom: ^16.13.1 || ^17.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 974422b46513af167bb34057e196cd27bb48224690a16f9f42540fe8c85ddc51201fc71fc1ded023825932b4fcbdb3787a3dab74ce174c4694db9f3d2d465921 + checksum: 1da335f35de55e77bafdf4893fd1a66d3fa5b5adc05a6d88a97b484bd4c4a5ac3c23e6a2104ceef64fcbdf45f950d489536ceb3ec01e0f3f51dbae9392159a62 languageName: node linkType: hard @@ -14506,8 +14507,8 @@ __metadata: linkType: hard "@rollup/plugin-yaml@npm:^4.0.0": - version: 4.1.0 - resolution: "@rollup/plugin-yaml@npm:4.1.0" + version: 4.1.1 + resolution: "@rollup/plugin-yaml@npm:4.1.1" dependencies: "@rollup/pluginutils": ^5.0.1 js-yaml: ^4.1.0 @@ -14517,7 +14518,7 @@ __metadata: peerDependenciesMeta: rollup: optional: true - checksum: e8dcfbb6032ebd493e3cf1f3fcc7ee7e50509e3848a283ab21c743ec59b65b587d3755f744c7135f49db97aee1fc7eee818375519f293e7227e278ccf9d8b3dc + checksum: 99c8f9d4a354056bec8a9398786777203d87db32db0cad681f65ee896cbbbb8a61ace0b1c3d801622782ccf28e56eac6cdde950541fb1f7b3e651ad9c705d5c3 languageName: node linkType: hard @@ -15623,90 +15624,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-darwin-arm64@npm:1.3.62" +"@swc/core-darwin-arm64@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-darwin-arm64@npm:1.3.66" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-darwin-x64@npm:1.3.62" +"@swc/core-darwin-x64@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-darwin-x64@npm:1.3.66" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.62" +"@swc/core-linux-arm-gnueabihf@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.66" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.62" +"@swc/core-linux-arm64-gnu@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.66" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.62" +"@swc/core-linux-arm64-musl@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.66" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.62" +"@swc/core-linux-x64-gnu@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.66" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-linux-x64-musl@npm:1.3.62" +"@swc/core-linux-x64-musl@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-linux-x64-musl@npm:1.3.66" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.62" +"@swc/core-win32-arm64-msvc@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.66" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.62" +"@swc/core-win32-ia32-msvc@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.66" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.62": - version: 1.3.62 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.62" +"@swc/core-win32-x64-msvc@npm:1.3.66": + version: 1.3.66 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.66" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.3.62 - resolution: "@swc/core@npm:1.3.62" + version: 1.3.66 + resolution: "@swc/core@npm:1.3.66" dependencies: - "@swc/core-darwin-arm64": 1.3.62 - "@swc/core-darwin-x64": 1.3.62 - "@swc/core-linux-arm-gnueabihf": 1.3.62 - "@swc/core-linux-arm64-gnu": 1.3.62 - "@swc/core-linux-arm64-musl": 1.3.62 - "@swc/core-linux-x64-gnu": 1.3.62 - "@swc/core-linux-x64-musl": 1.3.62 - "@swc/core-win32-arm64-msvc": 1.3.62 - "@swc/core-win32-ia32-msvc": 1.3.62 - "@swc/core-win32-x64-msvc": 1.3.62 + "@swc/core-darwin-arm64": 1.3.66 + "@swc/core-darwin-x64": 1.3.66 + "@swc/core-linux-arm-gnueabihf": 1.3.66 + "@swc/core-linux-arm64-gnu": 1.3.66 + "@swc/core-linux-arm64-musl": 1.3.66 + "@swc/core-linux-x64-gnu": 1.3.66 + "@swc/core-linux-x64-musl": 1.3.66 + "@swc/core-win32-arm64-msvc": 1.3.66 + "@swc/core-win32-ia32-msvc": 1.3.66 + "@swc/core-win32-x64-msvc": 1.3.66 peerDependencies: "@swc/helpers": ^0.5.0 dependenciesMeta: @@ -15733,7 +15734,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: a7a0d9ffdb8a2b0050e0ff89fdb86fe189d9bcb7f91cb6847f1bfe3e2b520a87ea2e83692dfd80b6d541fb5addb2194769484516b8ca6d3c62ad80f1c79a9368 + checksum: e6029c648ba47c522bed51a9f2fee606f82de1f9233e2e89197e43b0a4867054174ca05e825e688cdc4de332221c0da2e12ba7ba875549e8b5432aa70fe19263 languageName: node linkType: hard @@ -15767,18 +15768,19 @@ __metadata: languageName: node linkType: hard -"@tanstack/query-core@npm:4.29.11": - version: 4.29.11 - resolution: "@tanstack/query-core@npm:4.29.11" - checksum: 2a17223f34e99e17d564a15206668eb79324da72e630a47cf41690f92fb091a8669bdc89e9ab1b0d8f0e3e8f579529cfb0aa6f10b4fc58ea81cc7e5caede9229 +"@tanstack/query-core@npm:4.29.17": + version: 4.29.17 + resolution: "@tanstack/query-core@npm:4.29.17" + checksum: 0440d58a566fc3d6791a27eae439f497acc0142cb629ca0fb6e536f9c0a29d150b816ae33c9375411582da0b849a2ef141ef3b2284b8b313d5a4d6671b2548a3 languageName: node linkType: hard "@tanstack/react-query@npm:^4.1.3": - version: 4.29.12 - resolution: "@tanstack/react-query@npm:4.29.12" + version: 4.29.17 + resolution: "@tanstack/react-query@npm:4.29.17" dependencies: - "@tanstack/query-core": 4.29.11 + "@tanstack/query-core": 4.29.17 + client-only: 0.0.1 use-sync-external-store: ^1.2.0 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -15789,7 +15791,7 @@ __metadata: optional: true react-native: optional: true - checksum: aea231af648688c5eafdbbda0667034221cca8b77e00690ab54950b7cc0296d14646931aee44fc5f18d5ce4d683b5d234b053eed5c0a5c340bbbacdab873a70b + checksum: 5630dcb93100a48165464188aef2f53ed8e6bcb65669ff919f0916b7a21b58c7e21b06f4e4a331d1b9bfb8a89677266e79bc2a3bc80af62d763b08b3b195f7ea languageName: node linkType: hard @@ -16439,12 +16441,12 @@ __metadata: linkType: hard "@types/dockerode@npm:^3.3.0, @types/dockerode@npm:^3.3.8": - version: 3.3.18 - resolution: "@types/dockerode@npm:3.3.18" + version: 3.3.19 + resolution: "@types/dockerode@npm:3.3.19" dependencies: "@types/docker-modem": "*" "@types/node": "*" - checksum: 7ad51a0d6db9343637760a86e3d2ffd2c706db545630806ebfda428f5e8f5e458d4c6cb46657832b0638df7caee7c6922fcfbdc9271f88084e236adddaba7fa2 + checksum: 96d6cd3811a778d12382432413c3b0a935912c175ca939c77aaa0db2630c205daf14d5fa52e458a6fd44355c444f4fa1bd821e0364d4d0b6388061b5fe889431 languageName: node linkType: hard @@ -17072,9 +17074,9 @@ __metadata: linkType: hard "@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0": - version: 20.3.0 - resolution: "@types/node@npm:20.3.0" - checksum: 613e878174febc0104dae210088645cbb5096a19ae5fdf57fbc06fa6ef71755b839858c2b313fb8c1df8b7c6660e1b5f7a64db2126af9d47d1d9238e2bc0a86d + version: 20.3.1 + resolution: "@types/node@npm:20.3.1" + checksum: 63a393ab6d947be17320817b35d7277ef03728e231558166ed07ee30b09fd7c08861be4d746f10fdc63ca7912e8cd023939d4eab887ff6580ff704ff24ed810c languageName: node linkType: hard @@ -17093,9 +17095,9 @@ __metadata: linkType: hard "@types/node@npm:^14.14.31": - version: 14.18.50 - resolution: "@types/node@npm:14.18.50" - checksum: afaa48355811f377f1f7e70b397ef26297024ebc213cf9338d230d2f5ef228a9bf6a36800aa0952c519ac64f02cee8506c7bdf6e96b0abe0d90636bfce7804ae + version: 14.18.51 + resolution: "@types/node@npm:14.18.51" + checksum: 0960a31d2ac605763fe79c8edcee3cb48257d345ce417c019d84ff5d8cd92dd0937674814ab3f169346b4259c29f640556006bcb2c54cfb3e63fa0cf728d320e languageName: node linkType: hard @@ -17107,16 +17109,16 @@ __metadata: linkType: hard "@types/node@npm:^16.0.0, @types/node@npm:^16.11.26, @types/node@npm:^16.9.2": - version: 16.18.35 - resolution: "@types/node@npm:16.18.35" - checksum: 68e3015eb24f009d2b5a7ad959d1e1090016847248f22242c520b75a2780eb19e2d212e775e68022ed474fac00bcc8edaebcd02712f1dfee542efa23e2a4027e + version: 16.18.36 + resolution: "@types/node@npm:16.18.36" + checksum: a9d138fa1269079c60daad6984713dc0b713983f8b34a83edbc6d7957b2e38beab9b2598c9fe99f19d073e20bc212a18aaf82eabdc23ef64dce7d2089a9aab2a languageName: node linkType: hard "@types/node@npm:^18.11.17": - version: 18.16.17 - resolution: "@types/node@npm:18.16.17" - checksum: 2f7e3a552d525ef4b7a2620ef5ef59b3fdfb1d8ab20627b537e090732b35c2bd103944933d347a319cc7d478b3866b0d1bc3d629ee5899ca663a4547ca078cee + version: 18.16.18 + resolution: "@types/node@npm:18.16.18" + checksum: d32d8a0a04cd3f5ecb361bcb42f3a07623881ac90d680e06bf626defb3c663a94860d11690babe607cfe67265eceeb8a59ba5fe40c0e49f5a1b01e0088640469 languageName: node linkType: hard @@ -18125,9 +18127,9 @@ __metadata: languageName: node linkType: hard -"@uiw/codemirror-extensions-basic-setup@npm:4.21.3": - version: 4.21.3 - resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.21.3" +"@uiw/codemirror-extensions-basic-setup@npm:4.21.5": + version: 4.21.5 + resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.21.5" dependencies: "@codemirror/autocomplete": ^6.0.0 "@codemirror/commands": ^6.0.0 @@ -18144,19 +18146,19 @@ __metadata: "@codemirror/search": ">=6.0.0" "@codemirror/state": ">=6.0.0" "@codemirror/view": ">=6.0.0" - checksum: 6e6081c363391192c9f83c8277cc6e9de15ac6d9ad54a1318a165dae17a0ac944c2ed0fac6c955cf89dfefbd2c66ccac4ca43a085002dd70f580a02ca725fd46 + checksum: 8684dbc75c37b9942a1545914378291203feda78ff7196fdf50584f5bdf6176b4387a2b1d7f911dde2fdec108aefcf40273497ba8725ae10a69b264e9e6633ac languageName: node linkType: hard "@uiw/react-codemirror@npm:^4.9.3": - version: 4.21.3 - resolution: "@uiw/react-codemirror@npm:4.21.3" + version: 4.21.5 + resolution: "@uiw/react-codemirror@npm:4.21.5" dependencies: "@babel/runtime": ^7.18.6 "@codemirror/commands": ^6.1.0 "@codemirror/state": ^6.1.1 "@codemirror/theme-one-dark": ^6.0.0 - "@uiw/codemirror-extensions-basic-setup": 4.21.3 + "@uiw/codemirror-extensions-basic-setup": 4.21.5 codemirror: ^6.0.0 peerDependencies: "@babel/runtime": ">=7.11.0" @@ -18166,7 +18168,7 @@ __metadata: codemirror: ">=6.0.0" react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 7864f63b23283c2cab85e1bfce6cc00b0cd8787867ad878b359fa047676f70eac0b96d68d98dc0925ed8b2f6ba4e1cc4ee7196ddc70053bacbd5ca0948e67944 + checksum: b3c8c9134b1e8520488682be0a711bbe3283e1323673ed9b0a1a53ee572684311d9a495c73b572e226963b6d0f235215f5da87ef9ab194ee7e6e6ffd74340211 languageName: node linkType: hard @@ -20803,6 +20805,13 @@ __metadata: languageName: node linkType: hard +"client-only@npm:0.0.1": + version: 0.0.1 + resolution: "client-only@npm:0.0.1" + checksum: 0c16bf660dadb90610553c1d8946a7fdfb81d624adea073b8440b7d795d5b5b08beb3c950c6a2cf16279365a3265158a236876d92bce16423c485c322d7dfaf8 + languageName: node + linkType: hard + "clipboard@npm:^2.0.4": version: 2.0.11 resolution: "clipboard@npm:2.0.11" @@ -23378,13 +23387,13 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.14.1": - version: 5.14.1 - resolution: "enhanced-resolve@npm:5.14.1" +"enhanced-resolve@npm:^5.15.0": + version: 5.15.0 + resolution: "enhanced-resolve@npm:5.15.0" dependencies: graceful-fs: ^4.2.4 tapable: ^2.2.0 - checksum: ad2a31928b6649eed40d364838449587f731baa63863e83d2629bebaa8be1eabac18b90f89c1784bc805b0818363e99b22547159edd485d7e5ccf18cdc640642 + checksum: fbd8cdc9263be71cc737aa8a7d6c57b43d6aa38f6cc75dde6fcd3598a130cc465f979d2f4d01bb3bf475acb43817749c79f8eef9be048683602ca91ab52e4f11 languageName: node linkType: hard @@ -24147,19 +24156,20 @@ __metadata: linkType: hard "eslint-plugin-jest@npm:^27.0.0": - version: 27.2.1 - resolution: "eslint-plugin-jest@npm:27.2.1" + version: 27.2.2 + resolution: "eslint-plugin-jest@npm:27.2.2" dependencies: "@typescript-eslint/utils": ^5.10.0 peerDependencies: "@typescript-eslint/eslint-plugin": ^5.0.0 eslint: ^7.0.0 || ^8.0.0 + jest: "*" peerDependenciesMeta: "@typescript-eslint/eslint-plugin": optional: true jest: optional: true - checksum: 579a4d26304cc6748b2e6dff6c965ea7a21b618d8b051eb02727d25cf5c7767f6db8ef5237531635ff77e242b983b973e7cb8c820a4d20d5bda73358c452a8ab + checksum: 98b63252d985f5dedf36ce9587dd4a0d24daf71ca8a997258343402c0d33ddd5070502378dafd9ac7fc0ef2e0d557b5c77f18e09ad73c71a52de8061db88293f languageName: node linkType: hard @@ -24658,6 +24668,7 @@ __metadata: "@backstage/plugin-auth-node": "workspace:^" "@backstage/plugin-catalog-backend": "workspace:^" "@backstage/plugin-catalog-backend-module-unprocessed": "workspace:^" + "@backstage/plugin-entity-feedback-backend": "workspace:^" "@backstage/plugin-kubernetes-backend": "workspace:^" "@backstage/plugin-permission-backend": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" @@ -26141,16 +26152,16 @@ __metadata: languageName: node linkType: hard -"glob@npm:8.0.3": - version: 8.0.3 - resolution: "glob@npm:8.0.3" +"glob@npm:8.1.0, glob@npm:^8.0.0, glob@npm:^8.0.1, glob@npm:^8.0.3": + version: 8.1.0 + resolution: "glob@npm:8.1.0" dependencies: fs.realpath: ^1.0.0 inflight: ^1.0.4 inherits: 2 minimatch: ^5.0.1 once: ^1.3.0 - checksum: 50bcdea19d8e79d8de5f460b1939ffc2b3299eac28deb502093fdca22a78efebc03e66bf54f0abc3d3d07d8134d19a32850288b7440d77e072aa55f9d33b18c5 + checksum: 92fbea3221a7d12075f26f0227abac435de868dd0736a17170663783296d0dd8d3d532a5672b4488a439bf5d7fb85cdd07c11185d6cd39184f0385cbdfb86a47 languageName: node linkType: hard @@ -26183,19 +26194,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:^8.0.0, glob@npm:^8.0.1, glob@npm:^8.0.3": - version: 8.1.0 - resolution: "glob@npm:8.1.0" - dependencies: - fs.realpath: ^1.0.0 - inflight: ^1.0.4 - inherits: 2 - minimatch: ^5.0.1 - once: ^1.3.0 - checksum: 92fbea3221a7d12075f26f0227abac435de868dd0736a17170663783296d0dd8d3d532a5672b4488a439bf5d7fb85cdd07c11185d6cd39184f0385cbdfb86a47 - languageName: node - linkType: hard - "global-agent@npm:^3.0.0": version: 3.0.0 resolution: "global-agent@npm:3.0.0" @@ -32562,12 +32560,12 @@ __metadata: languageName: node linkType: hard -"node-addon-api@npm:^5.0.0": - version: 5.1.0 - resolution: "node-addon-api@npm:5.1.0" +"node-addon-api@npm:^6.1.0": + version: 6.1.0 + resolution: "node-addon-api@npm:6.1.0" dependencies: node-gyp: latest - checksum: 2508bd2d2981945406243a7bd31362fc7af8b70b8b4d65f869c61731800058fb818cc2fd36c8eac714ddd0e568cc85becf5e165cebbdf7b5024d5151bbc75ea1 + checksum: 3a539510e677cfa3a833aca5397300e36141aca064cdc487554f2017110709a03a95da937e98c2a14ec3c626af7b2d1b6dabe629a481f9883143d0d5bff07bf2 languageName: node linkType: hard @@ -33191,8 +33189,8 @@ __metadata: linkType: hard "octokit@npm:^2.0.0, octokit@npm:^2.0.4": - version: 2.0.19 - resolution: "octokit@npm:2.0.19" + version: 2.1.0 + resolution: "octokit@npm:2.1.0" dependencies: "@octokit/app": ^13.1.5 "@octokit/core": ^4.2.1 @@ -33201,8 +33199,9 @@ __metadata: "@octokit/plugin-rest-endpoint-methods": ^7.1.1 "@octokit/plugin-retry": ^4.1.3 "@octokit/plugin-throttling": ^5.2.2 + "@octokit/request-error": ^v3.0.3 "@octokit/types": ^9.2.2 - checksum: cc0acd5427a3dc25f70ca0ffd2e828cc7bcd51c7e4586caf06e40353f87084addd4ed6df59d441b087b9cf597540069d21bc75c27b2836e78a59e5f9f3fbec38 + checksum: 612f3c40c0d8d330793476066fcf2a6ed77ad52690201d7c2df11044c4b3dfbefefbe13443ac4037a2128c6f13d59a2f481bc0b315b1bc650e5ff6da9a811e61 languageName: node linkType: hard @@ -37635,14 +37634,14 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1, schema-utils@npm:^3.1.2": - version: 3.1.2 - resolution: "schema-utils@npm:3.1.2" +"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1, schema-utils@npm:^3.2.0": + version: 3.3.0 + resolution: "schema-utils@npm:3.3.0" dependencies: "@types/json-schema": ^7.0.8 ajv: ^6.12.5 ajv-keywords: ^3.5.2 - checksum: 39683edfe3beff018cdb1ae4fa296fc55cea13a080aa2b4d9351895cd64b22ba4d87e2e548c2a2ac1bc76e60980670adb0f413a58104479f1a0c12e5663cb8ca + checksum: ea56971926fac2487f0757da939a871388891bc87c6a82220d125d587b388f1704788f3706e7f63a7b70e49fc2db974c41343528caea60444afd5ce0fe4b85c0 languageName: node linkType: hard @@ -37759,7 +37758,18 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.1.3, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:~7.3.0": +"semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.1.3, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.0": + version: 7.5.3 + resolution: "semver@npm:7.5.3" + dependencies: + lru-cache: ^6.0.0 + bin: + semver: bin/semver.js + checksum: 9d58db16525e9f749ad0a696a1f27deabaa51f66e91d2fa2b0db3de3e9644e8677de3b7d7a03f4c15bc81521e0c3916d7369e0572dbde250d9bedf5194e2a8a7 + languageName: node + linkType: hard + +"semver@npm:~7.3.0": version: 7.3.8 resolution: "semver@npm:7.3.8" dependencies: @@ -37959,20 +37969,20 @@ __metadata: languageName: node linkType: hard -"sharp@npm:0.31.2": - version: 0.31.2 - resolution: "sharp@npm:0.31.2" +"sharp@npm:0.32.1": + version: 0.32.1 + resolution: "sharp@npm:0.32.1" dependencies: color: ^4.2.3 detect-libc: ^2.0.1 - node-addon-api: ^5.0.0 + node-addon-api: ^6.1.0 node-gyp: latest prebuild-install: ^7.1.1 - semver: ^7.3.8 + semver: ^7.5.0 simple-get: ^4.0.1 tar-fs: ^2.1.1 tunnel-agent: ^0.6.0 - checksum: 076717b7a073ea47bb522ff2931b74b6608daeb6f7ae334e4848d47fdf4d23bcb18cd49044fd5fb27ef27a1a4aa87d141894d67d1c4bb15a6e2e63cf4dbe329e + checksum: 99f50df380442aa8f3f952dd6f2e27634f9cab249cce47aa7f1a97c468334979ea94d71555f782aae5f5016e44b7832799f1c5ea1cb3ca975c089acd00e62e2e languageName: node linkType: hard @@ -41492,8 +41502,8 @@ __metadata: linkType: hard "webpack@npm:^5, webpack@npm:^5.70.0": - version: 5.85.0 - resolution: "webpack@npm:5.85.0" + version: 5.88.0 + resolution: "webpack@npm:5.88.0" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.0 @@ -41504,7 +41514,7 @@ __metadata: acorn-import-assertions: ^1.9.0 browserslist: ^4.14.5 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^5.14.1 + enhanced-resolve: ^5.15.0 es-module-lexer: ^1.2.1 eslint-scope: 5.1.1 events: ^3.2.0 @@ -41514,7 +41524,7 @@ __metadata: loader-runner: ^4.2.0 mime-types: ^2.1.27 neo-async: ^2.6.2 - schema-utils: ^3.1.2 + schema-utils: ^3.2.0 tapable: ^2.1.1 terser-webpack-plugin: ^5.3.7 watchpack: ^2.4.0 @@ -41524,7 +41534,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: b013be9fbc7f6810d1f229f570c70710ddbc7290f817411acffe4214b2b6c783a041ab1f2005d9e1109f4ab21c136f0f8d8c067a5fb64f20a82dcbc1ee0d3f42 + checksum: 9fd1568b34ec2e99ba97c8509a15ab2576ec80c396e7015551ec814b24cfc11de173acba3e114dafe95f1a6d460781b09d6201e6a1fb15110e1d01a09f61a283 languageName: node linkType: hard